Bug Summary

File:root/firefox-clang/parser/expat/expat/lib/xmlparse.c
Warning:line 768, column 8
Excessive padding in 'struct XML_ParserStruct' (55 padding bytes, where 7 is optimal). Optimal fields order: m_userData, m_handlerArg, m_buffer, m_bufferPtr, m_bufferEnd, m_bufferLim, m_parseEndByteIndex, m_parseEndPtr, m_partialTokenBytesBefore, m_dataBuf, m_dataBufEnd, m_startElementHandler, m_endElementHandler, m_characterDataHandler, m_processingInstructionHandler, m_commentHandler, m_startCdataSectionHandler, m_endCdataSectionHandler, m_defaultHandler, m_startDoctypeDeclHandler, m_endDoctypeDeclHandler, m_unparsedEntityDeclHandler, m_notationDeclHandler, m_startNamespaceDeclHandler, m_endNamespaceDeclHandler, m_notStandaloneHandler, m_externalEntityRefHandler, m_externalEntityRefHandlerArg, m_skippedEntityHandler, m_unknownEncodingHandler, m_elementDeclHandler, m_attlistDeclHandler, m_entityDeclHandler, m_xmlDeclHandler, m_encoding, m_internalEncoding, m_protocolEncodingName, m_unknownEncodingMem, m_unknownEncodingData, m_unknownEncodingHandlerData, m_unknownEncodingConvert, m_unknownEncodingRelease, m_processor, m_eventPtr, m_eventEndPtr, m_positionPtr, m_openInternalEntities, m_openAttributeEntities, m_openValueEntities, m_freeEntities, m_declEntity, m_doctypeName, m_doctypeSysid, m_doctypePubid, m_declAttributeType, m_declNotationName, m_declNotationPublicId, m_declElementType, m_declAttributeId, m_dtd, m_curBase, m_tagStack, m_freeTagList, m_inheritedBindings, m_freeBindingList, m_attsSize, m_atts, m_nsAtts, m_nsAttsVersion, m_groupConnector, m_groupSize, m_parentParser, m_mismatch, m_position, m_hash_secret_salt_128, m_mem, m_alloc_tracker, m_prologState, m_accounting, m_tempPool, m_temp2Pool, m_initEncoding, m_lastBufferRequestSize, m_errorCode, m_tagLevel, m_nSpecifiedAtts, m_idAttIndex, m_paramEntityParsing, m_handlerCallDepth, m_parsingStatus, m_namespaceSeparator, m_entity_stats, m_reparseDeferralEnabled, m_ns, m_ns_triplets, m_defaultExpandInternalEntities, m_declAttributeIsCdata, m_declAttributeIsId, m_nsAttsPower, m_isParamEntity, m_useForeignDTD, m_hash_secret_salt_set, m_reenter, consider reordering the fields or adding explicit padding members

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name moz_xmlparse.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/parser/expat -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/parser/expat -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D HAVE_EXPAT_CONFIG_H -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/parser/expat -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/parser/expat -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/security/rlbox -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-character-conversion -Wno-unreachable-code-fallthrough -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-10-17-231001-351276-1 -x c /root/firefox-clang/parser/expat/expat/lib/moz_xmlparse.c
1/* 13c4e8da8fccffb0e8e599684e0d447ad14c1bb0b48792cf5dd77d8712301871 (2.8.4+)
2 __ __ _
3 ___\ \/ /_ __ __ _| |_
4 / _ \\ /| '_ \ / _` | __|
5 | __// \| |_) | (_| | |_
6 \___/_/\_\ .__/ \__,_|\__|
7 |_| XML parser
8
9 Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
10 Copyright (c) 2000 Clark Cooper <coopercc@users.sourceforge.net>
11 Copyright (c) 2000-2006 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
12 Copyright (c) 2001-2002 Greg Stein <gstein@users.sourceforge.net>
13 Copyright (c) 2002-2016 Karl Waclawek <karl@waclawek.net>
14 Copyright (c) 2005-2009 Steven Solie <steven@solie.ca>
15 Copyright (c) 2016 Eric Rahm <erahm@mozilla.com>
16 Copyright (c) 2016-2026 Sebastian Pipping <sebastian@pipping.org>
17 Copyright (c) 2016 Gaurav <g.gupta@samsung.com>
18 Copyright (c) 2016 Thomas Beutlich <tc@tbeu.de>
19 Copyright (c) 2016 Gustavo Grieco <gustavo.grieco@imag.fr>
20 Copyright (c) 2016 Pascal Cuoq <cuoq@trust-in-soft.com>
21 Copyright (c) 2016 Ed Schouten <ed@nuxi.nl>
22 Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
23 Copyright (c) 2017 Václav Slavík <vaclav@slavik.io>
24 Copyright (c) 2017 Viktor Szakats <commit@vsz.me>
25 Copyright (c) 2017 Chanho Park <chanho61.park@samsung.com>
26 Copyright (c) 2017 Rolf Eike Beer <eike@sf-mail.de>
27 Copyright (c) 2017 Hans Wennborg <hans@chromium.org>
28 Copyright (c) 2018 Anton Maklakov <antmak.pub@gmail.com>
29 Copyright (c) 2018 Benjamin Peterson <benjamin@python.org>
30 Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
31 Copyright (c) 2018 Mariusz Zaborski <oshogbo@vexillium.org>
32 Copyright (c) 2019 David Loffredo <loffredo@steptools.com>
33 Copyright (c) 2019-2020 Ben Wagner <bungeman@chromium.org>
34 Copyright (c) 2019 Vadim Zeitlin <vadim@zeitlins.org>
35 Copyright (c) 2021 Donghee Na <donghee.na@python.org>
36 Copyright (c) 2022 Samanta Navarro <ferivoz@riseup.net>
37 Copyright (c) 2022 Jeffrey Walton <noloader@gmail.com>
38 Copyright (c) 2022 Jann Horn <jannh@google.com>
39 Copyright (c) 2022 Sean McBride <sean@rogue-research.com>
40 Copyright (c) 2023 Owain Davies <owaind@bath.edu>
41 Copyright (c) 2023-2024 Sony Corporation / Snild Dolkow <snild@sony.com>
42 Copyright (c) 2024-2025 Berkay Eren Ürün <berkay.ueruen@siemens.com>
43 Copyright (c) 2024 Hanno Böck <hanno@gentoo.org>
44 Copyright (c) 2025-2026 Matthew Fernandez <matthew.fernandez@gmail.com>
45 Copyright (c) 2025 Atrem Borovik <polzovatellllk@gmail.com>
46 Copyright (c) 2025 Alfonso Gregory <gfunni234@gmail.com>
47 Copyright (c) 2026 Rosen Penev <rosenp@gmail.com>
48 Copyright (c) 2026 Francesco Bertolaccini
49 Copyright (c) 2026 Christian Ng <christianrng@berkeley.edu>
50 Copyright (c) 2026 Nick Begg <nick@stunttruck.net>
51 Copyright (c) 2026 Kartik Kenchi <netliomax25@gmail.com>
52 Copyright (c) 2026 Haris Hussain <hextheshadow0x@gmail.com>
53 Copyright (c) 2026 Evgeny Kotkov <kotkov@apache.org>
54 Copyright (c) 2026 Darren Carreras <carrerasdarren@gmail.com>
55 Copyright (c) 2026 Alberto Maschietto <albertomaschietto9@gmail.com>
56 Copyright (c) 2026 Zeyou Liu <zeyouliu@tencent.com>
57 Licensed under the MIT license:
58
59 Permission is hereby granted, free of charge, to any person obtaining
60 a copy of this software and associated documentation files (the
61 "Software"), to deal in the Software without restriction, including
62 without limitation the rights to use, copy, modify, merge, publish,
63 distribute, sublicense, and/or sell copies of the Software, and to permit
64 persons to whom the Software is furnished to do so, subject to the
65 following conditions:
66
67 The above copyright notice and this permission notice shall be included
68 in all copies or substantial portions of the Software.
69
70 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
71 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
72 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
73 NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
74 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
75 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
76 USE OR OTHER DEALINGS IN THE SOFTWARE.
77
78 SPDX-License-Identifier: MIT
79*/
80
81#define XML_BUILDING_EXPAT1 1
82
83#include "expat_config.h"
84
85#if ! defined(XML_GE1) || (1 - XML_GE1 - 1 == 2) || (XML_GE1 < 0) || (XML_GE1 > 1)
86# error XML_GE1 (for general entities) must be defined, non-empty, either 1 or 0 (0 to disable, 1 to enable; 1 is a common default)
87#endif
88
89#if defined(XML_DTD) && XML_GE1 == 0
90# error Either undefine XML_DTD or define XML_GE1 to 1.
91#endif
92
93#if ! defined(XML_CONTEXT_BYTES0) || (1 - XML_CONTEXT_BYTES0 - 1 == 2) \
94 || (XML_CONTEXT_BYTES0 + 0 < 0)
95# error XML_CONTEXT_BYTES0 must be defined, non-empty and >=0 (0 to disable, >=1 to enable; 1024 is a common default)
96#endif
97
98#include <stdbool.h>
99#include <stddef.h>
100#include <string.h> /* memset(), memcpy() */
101#include <assert.h>
102#include <limits.h> /* INT_MAX, UINT_MAX */
103#include <stdio.h> /* fprintf */
104#include <stdlib.h> /* getenv */
105#include <stdint.h> /* SIZE_MAX, UINT64_MAX, uint64_t, uintptr_t */
106#include <math.h> /* isnan */
107#include <errno(*__errno_location ()).h>
108
109#ifdef _WIN32
110# define getpid GetCurrentProcessId
111#else
112# include <sys/time.h> /* gettimeofday() */
113# include <sys/types.h> /* getpid() */
114# include <unistd.h> /* getpid() */
115# include <fcntl.h> /* O_RDONLY */
116# include <errno(*__errno_location ()).h>
117#endif
118
119#ifdef _WIN32
120# include "winconfig.h"
121#endif
122
123#include "ascii.h"
124#include "expat.h"
125#include "siphash.h"
126#include "xcsinc.c"
127
128/* BEGIN MOZILLA CHANGE (we already set a salt through XML_SetHashSalt16Bytes) */
129#if 0
130#if defined(HAVE_ARC4RANDOM1)
131# include "random_arc4random.h"
132#endif /* defined(HAVE_ARC4RANDOM) */
133
134#if defined(HAVE_ARC4RANDOM_BUF1)
135# include "random_arc4random_buf.h"
136#endif // defined(HAVE_ARC4RANDOM_BUF)
137
138#if defined(XML_DEV_URANDOM)
139# include "random_dev_urandom.h"
140#endif /* defined(XML_DEV_URANDOM) */
141
142#if defined(HAVE_GETENTROPY)
143# include "random_getentropy.h"
144#endif // defined(HAVE_GETENTROPY)
145
146#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
147# include "random_getrandom.h"
148#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
149
150#if defined(_WIN32)
151# include "random_rand_s.h"
152#endif /* defined(_WIN32) */
153#endif
154/* END MOZILLA CHANGE */
155
156#if ! defined(HAVE_GETRANDOM) && ! defined(HAVE_SYSCALL_GETRANDOM) \
157 && ! defined(HAVE_ARC4RANDOM_BUF1) && ! defined(HAVE_ARC4RANDOM1) \
158 && ! defined(HAVE_GETENTROPY) && ! defined(XML_DEV_URANDOM) \
159 && ! defined(_WIN32) && ! defined(XML_POOR_ENTROPY1)
160# error You do not have support for any sources of high quality entropy \
161 enabled. For end user security, that is probably not what you want. \
162 \
163 Your options include: \
164 * Linux >=3.17 + glibc >=2.25 (getrandom): HAVE_GETRANDOM, \
165 * Linux >=3.17 + glibc (including <2.25) (syscall SYS_getrandom): HAVE_SYSCALL_GETRANDOM, \
166 * BSD / macOS >=10.7 / glibc >=2.36 (arc4random_buf): HAVE_ARC4RANDOM_BUF1, \
167 * BSD / macOS (including <10.7) / glibc >=2.36 (arc4random): HAVE_ARC4RANDOM1, \
168 * BSD / macOS >=10.12 / glibc >=2.25 (getentropy): HAVE_GETENTROPY, \
169 * Linux (including <3.17) / BSD / macOS (including <10.7) / Solaris >=8 (/dev/urandom): XML_DEV_URANDOM, \
170 * Windows >=Vista (rand_s): _WIN32. \
171 \
172 If you insist on not using any of these, bypass this error by defining \
173 XML_POOR_ENTROPY1 and be vulnerable to hash flooding; you have been warned. \
174 \
175 If you have reasons to patch this detection code away or need changes \
176 to the build system, please open a bug. Thank you!
177#endif
178
179#ifdef XML_UNICODE
180# define XML_ENCODE_MAX2 XML_UTF16_ENCODE_MAX2
181# define XmlConvertXmlUtf16Convert XmlUtf16Convert
182# define XmlGetInternalEncodingXmlGetUtf16InternalEncoding XmlGetUtf16InternalEncoding
183# define XmlGetInternalEncodingNSXmlGetUtf16InternalEncodingNS XmlGetUtf16InternalEncodingNS
184# define XmlEncodeXmlUtf16Encode XmlUtf16Encode
185# define MUST_CONVERT(enc, s)(! (enc)->isUtf16 || (((uintptr_t)(s)) & 1)) (! (enc)->isUtf16 || (((uintptr_t)(s)) & 1))
186typedef unsigned short ICHAR;
187#else
188# define XML_ENCODE_MAX2 XML_UTF8_ENCODE_MAX4
189# define XmlConvertXmlUtf16Convert XmlUtf8Convert
190# define XmlGetInternalEncodingXmlGetUtf16InternalEncoding XmlGetUtf8InternalEncoding
191# define XmlGetInternalEncodingNSXmlGetUtf16InternalEncodingNS XmlGetUtf8InternalEncodingNS
192# define XmlEncodeXmlUtf16Encode XmlUtf8Encode
193# define MUST_CONVERT(enc, s)(! (enc)->isUtf16 || (((uintptr_t)(s)) & 1)) (! (enc)->isUtf8)
194typedef char ICHAR;
195#endif
196
197#ifndef XML_NS
198
199# define XmlInitEncodingNS XmlInitEncoding
200# define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
201# undef XmlGetInternalEncodingNSXmlGetUtf16InternalEncodingNS
202# define XmlGetInternalEncodingNSXmlGetUtf16InternalEncodingNS XmlGetInternalEncodingXmlGetUtf16InternalEncoding
203# define XmlParseXmlDeclNS XmlParseXmlDecl
204
205#endif
206
207/* BEGIN MOZILLA CHANGE (typedef XML_Char to char16_t) */
208#if 0
209
210#ifdef XML_UNICODE
211
212# ifdef XML_UNICODE_WCHAR_T
213# define XML_T(x)(uint16_t)x (const wchar_t) x
214# define XML_L(x) L##x
215# else
216# define XML_T(x)(uint16_t)x (const unsigned short)x
217# define XML_L(x) x
218# endif
219
220#else
221
222# define XML_T(x)(uint16_t)x x
223# define XML_L(x) x
224
225#endif
226
227#endif
228/* END MOZILLA CHANGE */
229
230/* Round up n to be a multiple of sz, where sz is a power of 2. */
231#define ROUND_UP(n, sz)(((n) + ((sz) - 1)) & ~((sz) - 1)) (((n) + ((sz) - 1)) & ~((sz) - 1))
232
233/* Do safe (NULL-aware) pointer arithmetic */
234#define EXPAT_SAFE_PTR_DIFF(p, q)(((p) && (q)) ? ((p) - (q)) : 0) (((p) && (q)) ? ((p) - (q)) : 0)
235
236#define EXPAT_MIN(a, b)(((a) < (b)) ? (a) : (b)) (((a) < (b)) ? (a) : (b))
237
238#include "internal.h"
239#include "xmltok.h"
240#include "xmlrole.h"
241
242typedef const XML_Char *KEY;
243
244typedef struct {
245 KEY name;
246} NAMED;
247
248typedef struct {
249 NAMED **v;
250 unsigned char power;
251 size_t size;
252 size_t used;
253 XML_Parser parser;
254} HASH_TABLE;
255
256static size_t keylen(KEY s);
257
258static void copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key);
259
260/* For probing (after a collision) we need a step size relative prime
261 to the hash table size, which is a power of 2. We use double-hashing,
262 since we can calculate a second hash value cheaply by taking those bits
263 of the first hash value that were discarded (masked out) when the table
264 index was calculated: index = hash & mask, where mask = table->size - 1.
265 We limit the maximum step size to table->size / 4 (mask >> 2) and make
266 it odd, since odd numbers are always relative prime to a power of 2.
267*/
268#define SECOND_HASH(hash, mask, power)((((hash) & ~(mask)) >> ((power) - 1)) & ((mask
) >> 2))
\
269 ((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
270#define PROBE_STEP(hash, mask, power)((unsigned char)((((((hash) & ~(mask)) >> ((power) -
1)) & ((mask) >> 2))) | 1))
\
271 ((unsigned char)((SECOND_HASH(hash, mask, power)((((hash) & ~(mask)) >> ((power) - 1)) & ((mask
) >> 2))
) | 1))
272
273typedef struct {
274 NAMED **p;
275 NAMED **end;
276} HASH_TABLE_ITER;
277
278#define INIT_TAG_BUF_SIZE32 32 /* must be a multiple of sizeof(XML_Char) */
279#define INIT_DATA_BUF_SIZE1024 1024
280#define INIT_ATTS_SIZE16 16
281#define INIT_ATTS_VERSION0xFFFFFFFF 0xFFFFFFFF
282#define INIT_BLOCK_SIZE1024 1024
283#define INIT_BUFFER_SIZE1024 1024
284
285#define EXPAND_SPARE24 24
286
287typedef struct binding {
288 struct prefix *prefix;
289 struct binding *nextTagBinding;
290 struct binding *prevPrefixBinding;
291 const struct attribute_id *attId;
292 XML_Char *uri;
293 size_t uriLen;
294 size_t uriAlloc;
295} BINDING;
296
297typedef struct prefix {
298 const XML_Char *name;
299 BINDING *binding;
300} PREFIX;
301
302typedef struct {
303 const XML_Char *str;
304 const XML_Char *localPart;
305 const XML_Char *prefix;
306 size_t strLen;
307 size_t uriLen;
308 size_t prefixLen;
309} TAG_NAME;
310
311/* TAG represents an open element.
312 The name of the element is stored in both the document and API
313 encodings. The memory buffer 'buf' is a separately-allocated
314 memory area which stores the name. During the XML_Parse()/
315 XML_ParseBuffer() when the element is open, the memory for the 'raw'
316 version of the name (in the document encoding) is shared with the
317 document buffer. If the element is open across calls to
318 XML_Parse()/XML_ParseBuffer(), the buffer is re-allocated to
319 contain the 'raw' name as well.
320
321 A parser reuses these structures, maintaining a list of allocated
322 TAG objects in a free list.
323*/
324typedef struct tag {
325 struct tag *parent; /* parent of this element */
326 const char *rawName; /* tagName in the original encoding */
327 int rawNameLength;
328 TAG_NAME name; /* tagName in the API encoding */
329 union {
330 char *raw; /* for byte-level access (rawName storage) */
331 XML_Char *str; /* for character-level access (converted name) */
332 } buf; /* buffer for name components */
333 char *bufEnd; /* end of the buffer */
334 BINDING *bindings;
335} TAG;
336
337typedef struct {
338 const XML_Char *name;
339 const XML_Char *textPtr;
340 int textLen; /* length in XML_Chars */
341 int processed; /* # of processed bytes - when suspended */
342 const XML_Char *systemId;
343 const XML_Char *base;
344 const XML_Char *publicId;
345 const XML_Char *notation;
346 bool_Bool open;
347 XML_Bool hasMore; /* true if entity has not been completely processed */
348 /* An entity can be open while being already completely processed (hasMore ==
349 XML_FALSE). The reason is the delayed closing of entities until their inner
350 entities are processed and closed */
351 XML_Bool is_param;
352 XML_Bool is_internal; /* true if declared in internal subset outside PE */
353} ENTITY;
354
355typedef struct {
356 enum XML_Content_Type type;
357 enum XML_Content_Quant quant;
358 const XML_Char *name;
359 int firstchild;
360 int lastchild;
361 int childcnt;
362 int nextsib;
363} CONTENT_SCAFFOLD;
364
365#define INIT_SCAFFOLD_ELEMENTS32 32
366
367typedef struct block {
368 struct block *next;
369 int size;
370 XML_Char s[];
371} BLOCK;
372
373typedef struct {
374 BLOCK *blocks;
375 BLOCK *freeBlocks;
376 const XML_Char *end;
377 XML_Char *ptr;
378 XML_Char *start;
379 XML_Parser parser;
380} STRING_POOL;
381
382/* The XML_Char before the name is used to determine whether
383 an attribute has been specified. */
384typedef struct attribute_id {
385 XML_Char *name;
386 PREFIX *prefix;
387 XML_Bool maybeTokenized;
388 XML_Bool xmlns;
389} ATTRIBUTE_ID;
390
391typedef struct {
392 const ATTRIBUTE_ID *id;
393 XML_Bool isCdata;
394 const XML_Char *value;
395} DEFAULT_ATTRIBUTE;
396
397// This structure allows mapping attribute names to instances of
398// `DEFAULT_ATTRIBUTE`.
399typedef struct {
400 // Member `name` goes first to make this structure compatible with structure
401 // `NAMED` (further up), which is needed to support use of structure
402 // `NAME_AND_DEFAULT_ATTRIBUTE` in a hash table as implemented by function
403 // `lookup` (further down).
404 const XML_Char *name;
405 // We would store a `DEFAULT_ATTRIBUTE *` here but the backing array
406 // can be reallocated which would invalidate the pointer. Using an index
407 // into the array instead, avoids that problem.
408 size_t attIndex;
409 // This is set to `false` by function `lookup`.
410 bool_Bool initialized;
411} NAME_AND_DEFAULT_ATTRIBUTE;
412
413typedef struct {
414 unsigned long version;
415 unsigned long hash;
416 const XML_Char *uriName;
417} NS_ATT;
418
419typedef struct {
420 const XML_Char *name;
421 PREFIX *prefix;
422 const ATTRIBUTE_ID *idAtt;
423 size_t nDefaultAtts;
424 size_t allocDefaultAtts;
425 DEFAULT_ATTRIBUTE *defaultAtts;
426 HASH_TABLE defaultAttForName;
427} ELEMENT_TYPE;
428
429typedef struct {
430 HASH_TABLE generalEntities;
431 HASH_TABLE elementTypes;
432 HASH_TABLE attributeIds;
433 HASH_TABLE prefixes;
434 STRING_POOL pool;
435 STRING_POOL entityValuePool;
436 /* false once a parameter entity reference has been skipped */
437 XML_Bool keepProcessing;
438 /* true once an internal or external PE reference has been encountered;
439 this includes the reference to an external subset */
440 XML_Bool hasParamEntityRefs;
441 XML_Bool standalone;
442#ifdef XML_DTD
443 /* indicates if external PE has been read */
444 XML_Bool paramEntityRead;
445 HASH_TABLE paramEntities;
446#endif /* XML_DTD */
447 PREFIX defaultPrefix;
448 /* === scaffolding for building content model === */
449 XML_Bool in_eldecl;
450 CONTENT_SCAFFOLD *scaffold;
451 unsigned contentStringLen;
452 unsigned scaffSize;
453 unsigned scaffCount;
454 int scaffLevel;
455 int *scaffIndex;
456 size_t scaffIndexSize;
457} DTD;
458
459enum EntityType {
460 ENTITY_INTERNAL,
461 ENTITY_ATTRIBUTE,
462 ENTITY_VALUE,
463};
464
465typedef struct open_internal_entity {
466 const char *internalEventPtr;
467 const char *internalEventEndPtr;
468 struct open_internal_entity *next;
469 ENTITY *entity;
470 int startTagLevel;
471 XML_Bool betweenDecl; /* WFC: PE Between Declarations */
472 enum EntityType type;
473} OPEN_INTERNAL_ENTITY;
474
475enum XML_Account {
476 XML_ACCOUNT_DIRECT, /* bytes directly passed to the Expat parser */
477 XML_ACCOUNT_ENTITY_EXPANSION, /* intermediate bytes produced during entity
478 expansion */
479 XML_ACCOUNT_NONE /* i.e. do not account, was accounted already */
480};
481
482#if XML_GE1 == 1
483typedef unsigned long long XmlBigCount;
484typedef struct accounting {
485 XmlBigCount countBytesDirect;
486 XmlBigCount countBytesIndirect;
487/* BEGIN MOZILLA CHANGE (don't report debug information) */
488#if 0
489 unsigned long debugLevel;
490#endif
491/* END MOZILLA CHANGE */
492 float maximumAmplificationFactor; // >=1.0
493 unsigned long long activationThresholdBytes;
494} ACCOUNTING;
495
496typedef struct MALLOC_TRACKER {
497 XmlBigCount bytesAllocated;
498/* BEGIN MOZILLA CHANGE (don't report debug information) */
499# if 0
500 XmlBigCount peakBytesAllocated; // updated live only for debug level >=2
501 unsigned long debugLevel;
502#endif
503/* END MOZILLA CHANGE */
504 float maximumAmplificationFactor; // >=1.0
505 XmlBigCount activationThresholdBytes;
506} MALLOC_TRACKER;
507
508typedef struct entity_stats {
509/* BEGIN MOZILLA CHANGE (don't report debug information) */
510#if 0
511 unsigned int countEverOpened;
512 unsigned int currentDepth;
513 unsigned int maximumDepthSeen;
514 unsigned long debugLevel;
515#endif
516/* END MOZILLA CHANGE */
517} ENTITY_STATS;
518#endif /* XML_GE == 1 */
519
520typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start,
521 const char *end, const char **endPtr);
522
523static Processor prologProcessor;
524static Processor prologInitProcessor;
525static Processor contentProcessor;
526static Processor cdataSectionProcessor;
527#ifdef XML_DTD
528static Processor ignoreSectionProcessor;
529static Processor externalParEntProcessor;
530static Processor externalParEntInitProcessor;
531static Processor entityValueProcessor;
532static Processor entityValueInitProcessor;
533#endif /* XML_DTD */
534static Processor epilogProcessor;
535static Processor errorProcessor;
536static Processor externalEntityInitProcessor;
537static Processor externalEntityInitProcessor2;
538static Processor externalEntityInitProcessor3;
539static Processor externalEntityContentProcessor;
540static Processor internalEntityProcessor;
541
542static enum XML_Error handleUnknownEncoding(XML_Parser parser,
543 const XML_Char *encodingName);
544static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
545 const char *s, const char *next);
546static enum XML_Error initializeEncoding(XML_Parser parser);
547static enum XML_Error doProlog(XML_Parser parser, const ENCODING *enc,
548 const char *s, const char *end, int tok,
549 const char *next, const char **nextPtr,
550 XML_Bool haveMore, XML_Bool allowClosingDoctype,
551 enum XML_Account account);
552static enum XML_Error processEntity(XML_Parser parser, ENTITY *entity,
553 XML_Bool betweenDecl, enum EntityType type);
554/* BEGIN MOZILLA CHANGE (Bug 1746996 - Ensure that storeRawNames is always called) */
555static enum XML_Error doContentInternal(XML_Parser parser, int startTagLevel,
556 const ENCODING *enc, const char *start,
557 const char *end, const char **endPtr,
558 XML_Bool haveMore,
559 enum XML_Account account);
560/* END MOZILLA CHANGE */
561static enum XML_Error doContent(XML_Parser parser, int startTagLevel,
562 const ENCODING *enc, const char *start,
563 const char *end, const char **endPtr,
564 XML_Bool haveMore, enum XML_Account account);
565static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *enc,
566 const char **startPtr, const char *end,
567 const char **nextPtr, XML_Bool haveMore,
568 enum XML_Account account);
569#ifdef XML_DTD
570static enum XML_Error doIgnoreSection(XML_Parser parser, const ENCODING *enc,
571 const char **startPtr, const char *end,
572 const char **nextPtr, XML_Bool haveMore);
573#endif /* XML_DTD */
574
575static void freeBindings(XML_Parser parser, BINDING *bindings);
576static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
577 const char *attStr, TAG_NAME *tagNamePtr,
578 BINDING **bindingsPtr,
579 enum XML_Account account);
580static enum XML_Error addBinding(XML_Parser parser, PREFIX *prefix,
581 const ATTRIBUTE_ID *attId, const XML_Char *uri,
582 BINDING **bindingsPtr);
583static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId,
584 XML_Bool isCdata, XML_Bool isId,
585 const XML_Char *value, XML_Parser parser);
586static enum XML_Error storeAttributeValue(XML_Parser parser,
587 const ENCODING *enc, XML_Bool isCdata,
588 const char *ptr, const char *end,
589 STRING_POOL *pool,
590 enum XML_Account account);
591static enum XML_Error
592appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
593 const char *ptr, const char *end, STRING_POOL *pool,
594 enum XML_Account account, const char **nextPtr);
595static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc,
596 const char *start, const char *end);
597static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType);
598#if XML_GE1 == 1
599static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc,
600 const char *start, const char *end,
601 enum XML_Account account,
602 const char **nextPtr);
603static enum XML_Error callStoreEntityValue(XML_Parser parser,
604 const ENCODING *enc,
605 const char *start, const char *end,
606 enum XML_Account account);
607#else
608static enum XML_Error storeSelfEntityValue(XML_Parser parser, ENTITY *entity);
609#endif
610static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
611 const char *start, const char *end);
612static int reportComment(XML_Parser parser, const ENCODING *enc,
613 const char *start, const char *end);
614static void reportDefault(XML_Parser parser, const ENCODING *enc,
615 const char *start, const char *end);
616
617static const XML_Char *getContext(XML_Parser parser);
618static XML_Bool setContext(XML_Parser parser, const XML_Char *context);
619
620static void FASTCALL normalizePublicId(XML_Char *s);
621
622static DTD *dtdCreate(XML_Parser parser);
623/* BEGIN MOZILLA CHANGE (unused API) */
624#if 0
625/* do not call if m_parentParser != NULL */
626static void dtdReset(DTD *p, XML_Parser parser);
627#endif
628/* END MOZILLA CHANGE */
629static void dtdDestroy(DTD *p, XML_Bool isDocEntity, XML_Parser parser);
630static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
631 XML_Parser parser);
632static int copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
633 STRING_POOL *newPool, const HASH_TABLE *oldTable);
634static NAMED *lookupWithLength(XML_Parser parser, HASH_TABLE *table, KEY name,
635 size_t nameLen, size_t createSize);
636static NAMED *lookup(XML_Parser parser, HASH_TABLE *table, KEY name,
637 size_t createSize);
638static void FASTCALL hashTableInit(HASH_TABLE *table, XML_Parser parser);
639/* BEGIN MOZILLA CHANGE (unused API) */
640#if 0
641static void FASTCALL hashTableClear(HASH_TABLE *table);
642#endif
643/* END MOZILLA CHANGE */
644static void FASTCALL hashTableDestroy(HASH_TABLE *table);
645static void FASTCALL hashTableIterInit(HASH_TABLE_ITER *iter,
646 const HASH_TABLE *table);
647static NAMED *FASTCALL hashTableIterNext(HASH_TABLE_ITER *iter);
648
649static void FASTCALL poolInit(STRING_POOL *pool, XML_Parser parser);
650static void FASTCALL poolClear(STRING_POOL *pool);
651static void FASTCALL poolDestroy(STRING_POOL *pool);
652static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
653 const char *ptr, const char *end);
654static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
655 const char *ptr, const char *end);
656static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
657static bool_Bool FASTCALL poolGrowUntil(STRING_POOL *pool, size_t needed);
658static const XML_Char *FASTCALL poolCopyString(STRING_POOL *pool,
659 const XML_Char *s);
660static const XML_Char *FASTCALL poolCopyStringNoFinish(STRING_POOL *pool,
661 const XML_Char *s);
662static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s,
663 int n);
664static const XML_Char *FASTCALL poolAppendString(STRING_POOL *pool,
665 const XML_Char *s);
666
667static int FASTCALL nextScaffoldPart(XML_Parser parser);
668static XML_Content *build_model(XML_Parser parser);
669static ELEMENT_TYPE *getElementType(XML_Parser parser, const ENCODING *enc,
670 const char *ptr, const char *end);
671
672static XML_Char *copyString(const XML_Char *s, XML_Parser parser);
673
674static struct sipkey generate_hash_secret_salt(void);
675static XML_Bool startParsing(XML_Parser parser);
676
677static XML_Parser parserCreate(const XML_Char *encodingName,
678 const XML_Memory_Handling_Suite *memsuite,
679 const XML_Char *nameSep, DTD *dtd,
680 XML_Parser parentParser);
681
682static void parserInit(XML_Parser parser, const XML_Char *encodingName);
683
684#if XML_GE1 == 1
685static float accountingGetCurrentAmplification(XML_Parser rootParser);
686static void accountingReportStats(XML_Parser originParser, const char *epilog);
687static void accountingOnAbort(XML_Parser originParser);
688/* BEGIN MOZILLA CHANGE (don't report debug information) */
689#if 0
690static void accountingReportDiff(XML_Parser rootParser,
691 unsigned int levelsAwayFromRootParser,
692 const char *before, const char *after,
693 ptrdiff_t bytesMore, int source_line,
694 enum XML_Account account);
695#endif
696/* END MOZILLA CHANGE */
697static XML_Bool accountingDiffTolerated(XML_Parser originParser, int tok,
698 const char *before, const char *after,
699 int source_line,
700 enum XML_Account account);
701
702/* BEGIN MOZILLA CHANGE (don't report debug information) */
703#if 0
704static void entityTrackingReportStats(XML_Parser parser, ENTITY *entity,
705 const char *action, int sourceLine);
706#endif
707/* END MOZILLA CHANGE */
708static void entityTrackingOnOpen(XML_Parser parser, ENTITY *entity,
709 int sourceLine);
710static void entityTrackingOnClose(XML_Parser parser, ENTITY *entity,
711 int sourceLine);
712#endif /* XML_GE == 1 */
713
714static XML_Parser getRootParserOf(XML_Parser parser,
715 unsigned int *outLevelDiff);
716
717/* BEGIN MOZILLA CHANGE (don't report debug information) */
718#if 0
719static unsigned long getDebugLevel(const char *variableName,
720 unsigned long defaultDebugLevel);
721#endif
722/* END MOZILLA CHANGE */
723
724static bool_Bool poolAppendChar(STRING_POOL *pool, XML_Char c);
725
726static bool_Bool poolAppendChars(STRING_POOL *pool, const XML_Char *s, size_t len);
727
728#define poolStart(pool)((pool)->start) ((pool)->start)
729#define poolLength(pool)((pool)->ptr - (pool)->start) ((pool)->ptr - (pool)->start)
730#define poolChop(pool)((void)--(pool->ptr)) ((void)--(pool->ptr))
731#define poolLastChar(pool)(((pool)->ptr)[-1]) (((pool)->ptr)[-1])
732#define poolDiscard(pool)((pool)->ptr = (pool)->start) ((pool)->ptr = (pool)->start)
733#define poolFinish(pool)((pool)->start = (pool)->ptr) ((pool)->start = (pool)->ptr)
734
735bool_Bool
736poolAppendChar(STRING_POOL *pool, XML_Char c) {
737 if (pool->ptr == pool->end && ! poolGrow(pool))
738 return false0;
739
740 *(pool->ptr)++ = c;
741 return true1;
742}
743
744bool_Bool
745poolAppendChars(STRING_POOL *pool, const XML_Char *s, size_t len) {
746 // Detect and prevent integer overflow
747 if (len > SIZE_MAX(18446744073709551615UL) / sizeof(XML_Char))
748 return false0;
749
750 if (! poolGrowUntil(pool, len))
751 return false0;
752
753 memcpy(pool->ptr, s, len * sizeof(XML_Char));
754 pool->ptr += len;
755
756 return true1;
757}
758
759#if ! defined(XML_TESTING)
760const
761#endif
762 XML_Bool g_reparseDeferralEnabledDefault
763 = XML_TRUE((XML_Bool)1); // write ONLY in runtests.c
764#if defined(XML_TESTING)
765unsigned int g_bytesScanned = 0; // used for testing only
766#endif
767
768struct XML_ParserStruct {
Excessive padding in 'struct XML_ParserStruct' (55 padding bytes, where 7 is optimal). Optimal fields order: m_userData, m_handlerArg, m_buffer, m_bufferPtr, m_bufferEnd, m_bufferLim, m_parseEndByteIndex, m_parseEndPtr, m_partialTokenBytesBefore, m_dataBuf, m_dataBufEnd, m_startElementHandler, m_endElementHandler, m_characterDataHandler, m_processingInstructionHandler, m_commentHandler, m_startCdataSectionHandler, m_endCdataSectionHandler, m_defaultHandler, m_startDoctypeDeclHandler, m_endDoctypeDeclHandler, m_unparsedEntityDeclHandler, m_notationDeclHandler, m_startNamespaceDeclHandler, m_endNamespaceDeclHandler, m_notStandaloneHandler, m_externalEntityRefHandler, m_externalEntityRefHandlerArg, m_skippedEntityHandler, m_unknownEncodingHandler, m_elementDeclHandler, m_attlistDeclHandler, m_entityDeclHandler, m_xmlDeclHandler, m_encoding, m_internalEncoding, m_protocolEncodingName, m_unknownEncodingMem, m_unknownEncodingData, m_unknownEncodingHandlerData, m_unknownEncodingConvert, m_unknownEncodingRelease, m_processor, m_eventPtr, m_eventEndPtr, m_positionPtr, m_openInternalEntities, m_openAttributeEntities, m_openValueEntities, m_freeEntities, m_declEntity, m_doctypeName, m_doctypeSysid, m_doctypePubid, m_declAttributeType, m_declNotationName, m_declNotationPublicId, m_declElementType, m_declAttributeId, m_dtd, m_curBase, m_tagStack, m_freeTagList, m_inheritedBindings, m_freeBindingList, m_attsSize, m_atts, m_nsAtts, m_nsAttsVersion, m_groupConnector, m_groupSize, m_parentParser, m_mismatch, m_position, m_hash_secret_salt_128, m_mem, m_alloc_tracker, m_prologState, m_accounting, m_tempPool, m_temp2Pool, m_initEncoding, m_lastBufferRequestSize, m_errorCode, m_tagLevel, m_nSpecifiedAtts, m_idAttIndex, m_paramEntityParsing, m_handlerCallDepth, m_parsingStatus, m_namespaceSeparator, m_entity_stats, m_reparseDeferralEnabled, m_ns, m_ns_triplets, m_defaultExpandInternalEntities, m_declAttributeIsCdata, m_declAttributeIsId, m_nsAttsPower, m_isParamEntity, m_useForeignDTD, m_hash_secret_salt_set, m_reenter, consider reordering the fields or adding explicit padding members
769 /* The first member must be m_userData so that the XML_GetUserData
770 macro works. */
771 void *m_userData;
772 void *m_handlerArg;
773
774 // How the four parse buffer pointers below relate in time and space:
775 //
776 // m_buffer <= m_bufferPtr <= m_bufferEnd <= m_bufferLim
777 // | | | |
778 // <--parsed-->| | |
779 // <---parsing--->| |
780 // <--unoccupied-->|
781 // <---------total-malloced/realloced-------->|
782
783 char *m_buffer; // malloc/realloc base pointer of parse buffer
784 const XML_Memory_Handling_Suite m_mem;
785 const char *m_bufferPtr; // first character to be parsed
786 char *m_bufferEnd; // past last character to be parsed
787 const char *m_bufferLim; // allocated end of m_buffer
788
789 uint64_t m_parseEndByteIndex;
790 const char *m_parseEndPtr;
791 size_t m_partialTokenBytesBefore; /* used in heuristic to avoid O(n^2) */
792 XML_Bool m_reparseDeferralEnabled;
793 int m_lastBufferRequestSize;
794 XML_Char *m_dataBuf;
795 XML_Char *m_dataBufEnd;
796 XML_StartElementHandler m_startElementHandler;
797 XML_EndElementHandler m_endElementHandler;
798 XML_CharacterDataHandler m_characterDataHandler;
799 XML_ProcessingInstructionHandler m_processingInstructionHandler;
800 XML_CommentHandler m_commentHandler;
801 XML_StartCdataSectionHandler m_startCdataSectionHandler;
802 XML_EndCdataSectionHandler m_endCdataSectionHandler;
803 XML_DefaultHandler m_defaultHandler;
804 XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
805 XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
806 XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
807 XML_NotationDeclHandler m_notationDeclHandler;
808 XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
809 XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
810 XML_NotStandaloneHandler m_notStandaloneHandler;
811 XML_ExternalEntityRefHandler m_externalEntityRefHandler;
812 XML_Parser m_externalEntityRefHandlerArg;
813 XML_SkippedEntityHandler m_skippedEntityHandler;
814 XML_UnknownEncodingHandler m_unknownEncodingHandler;
815 XML_ElementDeclHandler m_elementDeclHandler;
816 XML_AttlistDeclHandler m_attlistDeclHandler;
817 XML_EntityDeclHandler m_entityDeclHandler;
818 XML_XmlDeclHandler m_xmlDeclHandler;
819 const ENCODING *m_encoding;
820 INIT_ENCODING m_initEncoding;
821 const ENCODING *m_internalEncoding;
822 const XML_Char *m_protocolEncodingName;
823 XML_Bool m_ns;
824 XML_Bool m_ns_triplets;
825 void *m_unknownEncodingMem;
826 void *m_unknownEncodingData;
827 void *m_unknownEncodingHandlerData;
828 // Application callback invoked by callUnknownEncodingConvert.
829 int(XMLCALL *m_unknownEncodingConvert)(void *, const char *);
830 void(XMLCALL *m_unknownEncodingRelease)(void *);
831 PROLOG_STATE m_prologState;
832 Processor *m_processor;
833 enum XML_Error m_errorCode;
834 const char *m_eventPtr;
835 const char *m_eventEndPtr;
836 const char *m_positionPtr;
837 OPEN_INTERNAL_ENTITY *m_openInternalEntities;
838 OPEN_INTERNAL_ENTITY *m_openAttributeEntities;
839 OPEN_INTERNAL_ENTITY *m_openValueEntities;
840 OPEN_INTERNAL_ENTITY *m_freeEntities;
841 XML_Bool m_defaultExpandInternalEntities;
842 int m_tagLevel;
843 ENTITY *m_declEntity;
844 const XML_Char *m_doctypeName;
845 const XML_Char *m_doctypeSysid;
846 const XML_Char *m_doctypePubid;
847 const XML_Char *m_declAttributeType;
848 const XML_Char *m_declNotationName;
849 const XML_Char *m_declNotationPublicId;
850 ELEMENT_TYPE *m_declElementType;
851 ATTRIBUTE_ID *m_declAttributeId;
852 XML_Bool m_declAttributeIsCdata;
853 XML_Bool m_declAttributeIsId;
854 DTD *m_dtd;
855 const XML_Char *m_curBase;
856 TAG *m_tagStack;
857 TAG *m_freeTagList;
858 BINDING *m_inheritedBindings;
859 BINDING *m_freeBindingList;
860 size_t m_attsSize;
861 int m_nSpecifiedAtts;
862 int m_idAttIndex;
863 ATTRIBUTE *m_atts;
864 NS_ATT *m_nsAtts;
865 unsigned long m_nsAttsVersion;
866 unsigned char m_nsAttsPower;
867#ifdef XML_ATTR_INFO
868 XML_AttrInfo *m_attInfo;
869#endif
870 POSITION m_position;
871 STRING_POOL m_tempPool;
872 STRING_POOL m_temp2Pool;
873 char *m_groupConnector;
874 size_t m_groupSize;
875 XML_Char m_namespaceSeparator;
876 XML_Parser m_parentParser;
877 XML_ParsingStatus m_parsingStatus;
878#ifdef XML_DTD
879 XML_Bool m_isParamEntity;
880 XML_Bool m_useForeignDTD;
881 enum XML_ParamEntityParsing m_paramEntityParsing;
882#endif
883 struct sipkey m_hash_secret_salt_128;
884 XML_Bool m_hash_secret_salt_set;
885#if XML_GE1 == 1
886 ACCOUNTING m_accounting;
887 MALLOC_TRACKER m_alloc_tracker;
888 ENTITY_STATS m_entity_stats;
889#endif
890 XML_Bool m_reenter;
891/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
892 const XML_Char* m_mismatch;
893/* END MOZILLA CHANGE */
894 unsigned m_handlerCallDepth;
895};
896
897#if XML_GE1 == 1
898# define MALLOC(parser, s)(expat_malloc((parser), (s), 898)) (expat_malloc((parser), (s), __LINE__898))
899# define REALLOC(parser, p, s)(expat_realloc((parser), (p), (s), 899)) (expat_realloc((parser), (p), (s), __LINE__899))
900# define FREE(parser, p)(expat_free((parser), (p), 900)) (expat_free((parser), (p), __LINE__900))
901#else
902# define MALLOC(parser, s)(expat_malloc((parser), (s), 902)) (parser->m_mem.malloc_fcn((s)))
903# define REALLOC(parser, p, s)(expat_realloc((parser), (p), (s), 903)) (parser->m_mem.realloc_fcn((p), (s)))
904# define FREE(parser, p)(expat_free((parser), (p), 904)) (parser->m_mem.free_fcn((p)))
905#endif
906
907#if XML_GE1 == 1
908/* BEGIN MOZILLA CHANGE (don't report debug information) */
909#if 0
910static void
911expat_heap_stat(XML_Parser rootParser, char operator, XmlBigCount absDiff,
912 XmlBigCount newTotal, XmlBigCount peakTotal, int sourceLine) {
913 // NOTE: This can be +infinity or -nan
914 const float amplification
915 = (float)newTotal / (float)rootParser->m_accounting.countBytesDirect;
916 fprintf(
917 stderrstderr,
918 "expat: Allocations(%p): Direct " EXPAT_FMT_ULL("10")"%" "10" "llu" ", allocated %c" EXPAT_FMT_ULL("%" "10" "llu"
919 "10")"%" "10" "llu" " to " EXPAT_FMT_ULL("10")"%" "10" "llu" " (" EXPAT_FMT_ULL("10")"%" "10" "llu" " peak), amplification %8.2f (xmlparse.c:%d)\n",
920 (void *)rootParser, rootParser->m_accounting.countBytesDirect, operator,
921 absDiff, newTotal, peakTotal, (double)amplification, sourceLine);
922}
923#endif
924/* END MOZILLA CHANGE */
925
926static bool_Bool
927expat_heap_increase_tolerable(XML_Parser rootParser, XmlBigCount increase,
928 int sourceLine) {
929 assert(rootParser != NULL)((void) sizeof ((rootParser != ((void*)0)) ? 1 : 0), __extension__
({ if (rootParser != ((void*)0)) ; else __assert_fail ("rootParser != NULL"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 929
, __extension__ __PRETTY_FUNCTION__); }))
;
930 assert(increase > 0)((void) sizeof ((increase > 0) ? 1 : 0), __extension__ ({ if
(increase > 0) ; else __assert_fail ("increase > 0", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 930, __extension__ __PRETTY_FUNCTION__); }))
;
931
932 XmlBigCount newTotal = 0;
933 bool_Bool tolerable = true1;
934
935 // Detect integer overflow
936 if ((XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated < increase) {
937 tolerable = false0;
938 } else {
939 newTotal = rootParser->m_alloc_tracker.bytesAllocated + increase;
940
941 if (newTotal >= rootParser->m_alloc_tracker.activationThresholdBytes) {
942 assert(newTotal > 0)((void) sizeof ((newTotal > 0) ? 1 : 0), __extension__ ({ if
(newTotal > 0) ; else __assert_fail ("newTotal > 0", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 942, __extension__ __PRETTY_FUNCTION__); }))
;
943 // NOTE: This can be +infinity when dividing by zero but not -nan
944 const float amplification
945 = (float)newTotal / (float)rootParser->m_accounting.countBytesDirect;
946 if (amplification
947 > rootParser->m_alloc_tracker.maximumAmplificationFactor) {
948 tolerable = false0;
949 }
950 }
951 }
952
953/* BEGIN MOZILLA CHANGE (don't report debug information) */
954#if 0
955 if (! tolerable && (rootParser->m_alloc_tracker.debugLevel >= 1)) {
956 expat_heap_stat(rootParser, '+', increase, newTotal, newTotal, sourceLine);
957 }
958#endif
959/* END MOZILLA CHANGE */
960
961 return tolerable;
962}
963
964# if defined(XML_TESTING)
965void *
966# else
967static void *
968# endif
969expat_malloc(XML_Parser parser, size_t size, int sourceLine) {
970 // Detect integer overflow
971 if (SIZE_MAX(18446744073709551615UL) - size < sizeof(size_t) + EXPAT_MALLOC_PADDING((sizeof(long long)) - sizeof(size_t))) {
972 return NULL((void*)0);
973 }
974
975 const XML_Parser rootParser = getRootParserOf(parser, NULL((void*)0));
976 assert(rootParser->m_parentParser == NULL)((void) sizeof ((rootParser->m_parentParser == ((void*)0))
? 1 : 0), __extension__ ({ if (rootParser->m_parentParser
== ((void*)0)) ; else __assert_fail ("rootParser->m_parentParser == NULL"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 976
, __extension__ __PRETTY_FUNCTION__); }))
;
977
978 const size_t bytesToAllocate = sizeof(size_t) + EXPAT_MALLOC_PADDING((sizeof(long long)) - sizeof(size_t)) + size;
979
980 if ((XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated
981 < bytesToAllocate) {
982 return NULL((void*)0); // i.e. signal integer overflow as out-of-memory
983 }
984
985 if (! expat_heap_increase_tolerable(rootParser, bytesToAllocate,
986 sourceLine)) {
987 return NULL((void*)0); // i.e. signal violation as out-of-memory
988 }
989
990 // Actually allocate
991 void *const mallocedPtr = parser->m_mem.malloc_fcn(bytesToAllocate);
992
993 if (mallocedPtr == NULL((void*)0)) {
994 return NULL((void*)0);
995 }
996
997 // Update in-block recorded size
998 *(size_t *)mallocedPtr = size;
999
1000 // Update accounting
1001 rootParser->m_alloc_tracker.bytesAllocated += bytesToAllocate;
1002
1003/* BEGIN MOZILLA CHANGE (don't report debug information) */
1004#if 0
1005 // Report as needed
1006 if (rootParser->m_alloc_tracker.debugLevel >= 2) {
1007 if (rootParser->m_alloc_tracker.bytesAllocated
1008 > rootParser->m_alloc_tracker.peakBytesAllocated) {
1009 rootParser->m_alloc_tracker.peakBytesAllocated
1010 = rootParser->m_alloc_tracker.bytesAllocated;
1011 }
1012 expat_heap_stat(rootParser, '+', bytesToAllocate,
1013 rootParser->m_alloc_tracker.bytesAllocated,
1014 rootParser->m_alloc_tracker.peakBytesAllocated, sourceLine);
1015 }
1016#endif
1017/* END MOZILLA CHANGE */
1018
1019 return (char *)mallocedPtr + sizeof(size_t) + EXPAT_MALLOC_PADDING((sizeof(long long)) - sizeof(size_t));
1020}
1021
1022# if defined(XML_TESTING)
1023void
1024# else
1025static void
1026# endif
1027expat_free(XML_Parser parser, void *ptr, int sourceLine) {
1028 assert(parser != NULL)((void) sizeof ((parser != ((void*)0)) ? 1 : 0), __extension__
({ if (parser != ((void*)0)) ; else __assert_fail ("parser != NULL"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 1028
, __extension__ __PRETTY_FUNCTION__); }))
;
1029
1030 if (ptr == NULL((void*)0)) {
1031 return;
1032 }
1033
1034 const XML_Parser rootParser = getRootParserOf(parser, NULL((void*)0));
1035 assert(rootParser->m_parentParser == NULL)((void) sizeof ((rootParser->m_parentParser == ((void*)0))
? 1 : 0), __extension__ ({ if (rootParser->m_parentParser
== ((void*)0)) ; else __assert_fail ("rootParser->m_parentParser == NULL"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 1035
, __extension__ __PRETTY_FUNCTION__); }))
;
1036
1037 // Extract size (to the eyes of malloc_fcn/realloc_fcn) and
1038 // the original pointer returned by malloc/realloc
1039 void *const mallocedPtr = (char *)ptr - EXPAT_MALLOC_PADDING((sizeof(long long)) - sizeof(size_t)) - sizeof(size_t);
1040 const size_t bytesAllocated
1041 = sizeof(size_t) + EXPAT_MALLOC_PADDING((sizeof(long long)) - sizeof(size_t)) + *(size_t *)mallocedPtr;
1042
1043 // Update accounting
1044 assert(rootParser->m_alloc_tracker.bytesAllocated >= bytesAllocated)((void) sizeof ((rootParser->m_alloc_tracker.bytesAllocated
>= bytesAllocated) ? 1 : 0), __extension__ ({ if (rootParser
->m_alloc_tracker.bytesAllocated >= bytesAllocated) ; else
__assert_fail ("rootParser->m_alloc_tracker.bytesAllocated >= bytesAllocated"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 1044
, __extension__ __PRETTY_FUNCTION__); }))
;
1045 rootParser->m_alloc_tracker.bytesAllocated -= bytesAllocated;
1046
1047/* BEGIN MOZILLA CHANGE (don't report debug information) */
1048#if 0
1049 // Report as needed
1050 if (rootParser->m_alloc_tracker.debugLevel >= 2) {
1051 expat_heap_stat(rootParser, '-', bytesAllocated,
1052 rootParser->m_alloc_tracker.bytesAllocated,
1053 rootParser->m_alloc_tracker.peakBytesAllocated, sourceLine);
1054 }
1055#endif
1056/* END MOZILLA CHANGE */
1057
1058 // NOTE: This may be freeing rootParser, so freeing has to come last
1059 parser->m_mem.free_fcn(mallocedPtr);
1060}
1061
1062# if defined(XML_TESTING)
1063void *
1064# else
1065static void *
1066# endif
1067expat_realloc(XML_Parser parser, void *ptr, size_t size, int sourceLine) {
1068 assert(parser != NULL)((void) sizeof ((parser != ((void*)0)) ? 1 : 0), __extension__
({ if (parser != ((void*)0)) ; else __assert_fail ("parser != NULL"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 1068
, __extension__ __PRETTY_FUNCTION__); }))
;
1069
1070 if (ptr == NULL((void*)0)) {
1071 return expat_malloc(parser, size, sourceLine);
1072 }
1073
1074 if (size == 0) {
1075 expat_free(parser, ptr, sourceLine);
1076 return NULL((void*)0);
1077 }
1078
1079 const XML_Parser rootParser = getRootParserOf(parser, NULL((void*)0));
1080 assert(rootParser->m_parentParser == NULL)((void) sizeof ((rootParser->m_parentParser == ((void*)0))
? 1 : 0), __extension__ ({ if (rootParser->m_parentParser
== ((void*)0)) ; else __assert_fail ("rootParser->m_parentParser == NULL"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 1080
, __extension__ __PRETTY_FUNCTION__); }))
;
1081
1082 // Extract original size (to the eyes of the caller) and the original
1083 // pointer returned by malloc/realloc
1084 void *mallocedPtr = (char *)ptr - EXPAT_MALLOC_PADDING((sizeof(long long)) - sizeof(size_t)) - sizeof(size_t);
1085 const size_t prevSize = *(size_t *)mallocedPtr;
1086
1087 // Classify upcoming change
1088 const bool_Bool isIncrease = (size > prevSize);
1089 const size_t absDiff
1090 = (size > prevSize) ? (size - prevSize) : (prevSize - size);
1091
1092 // Ask for permission from accounting
1093 if (isIncrease) {
1094 if (! expat_heap_increase_tolerable(rootParser, absDiff, sourceLine)) {
1095 return NULL((void*)0); // i.e. signal violation as out-of-memory
1096 }
1097 }
1098
1099 // NOTE: Integer overflow detection has already been done for us
1100 // by expat_heap_increase_tolerable(..) above
1101 assert(SIZE_MAX - sizeof(size_t) - EXPAT_MALLOC_PADDING >= size)((void) sizeof (((18446744073709551615UL) - sizeof(size_t) - (
(sizeof(long long)) - sizeof(size_t)) >= size) ? 1 : 0), __extension__
({ if ((18446744073709551615UL) - sizeof(size_t) - ((sizeof(
long long)) - sizeof(size_t)) >= size) ; else __assert_fail
("SIZE_MAX - sizeof(size_t) - EXPAT_MALLOC_PADDING >= size"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 1101
, __extension__ __PRETTY_FUNCTION__); }))
;
1102
1103 // Actually allocate
1104 mallocedPtr = parser->m_mem.realloc_fcn(
1105 mallocedPtr, sizeof(size_t) + EXPAT_MALLOC_PADDING((sizeof(long long)) - sizeof(size_t)) + size);
1106
1107 if (mallocedPtr == NULL((void*)0)) {
1108 return NULL((void*)0);
1109 }
1110
1111 // Update accounting
1112 if (isIncrease) {
1113 assert((XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated((void) sizeof (((XmlBigCount)-1 - rootParser->m_alloc_tracker
.bytesAllocated >= absDiff) ? 1 : 0), __extension__ ({ if (
(XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated
>= absDiff) ; else __assert_fail ("(XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated >= absDiff"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 1114
, __extension__ __PRETTY_FUNCTION__); }))
1114 >= absDiff)((void) sizeof (((XmlBigCount)-1 - rootParser->m_alloc_tracker
.bytesAllocated >= absDiff) ? 1 : 0), __extension__ ({ if (
(XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated
>= absDiff) ; else __assert_fail ("(XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated >= absDiff"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 1114
, __extension__ __PRETTY_FUNCTION__); }))
;
1115 rootParser->m_alloc_tracker.bytesAllocated += absDiff;
1116 } else { // i.e. decrease
1117 assert(rootParser->m_alloc_tracker.bytesAllocated >= absDiff)((void) sizeof ((rootParser->m_alloc_tracker.bytesAllocated
>= absDiff) ? 1 : 0), __extension__ ({ if (rootParser->
m_alloc_tracker.bytesAllocated >= absDiff) ; else __assert_fail
("rootParser->m_alloc_tracker.bytesAllocated >= absDiff"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 1117
, __extension__ __PRETTY_FUNCTION__); }))
;
1118 rootParser->m_alloc_tracker.bytesAllocated -= absDiff;
1119 }
1120
1121/* BEGIN MOZILLA CHANGE (don't report debug information) */
1122#if 0
1123 // Report as needed
1124 if (rootParser->m_alloc_tracker.debugLevel >= 2) {
1125 if (rootParser->m_alloc_tracker.bytesAllocated
1126 > rootParser->m_alloc_tracker.peakBytesAllocated) {
1127 rootParser->m_alloc_tracker.peakBytesAllocated
1128 = rootParser->m_alloc_tracker.bytesAllocated;
1129 }
1130 expat_heap_stat(rootParser, isIncrease ? '+' : '-', absDiff,
1131 rootParser->m_alloc_tracker.bytesAllocated,
1132 rootParser->m_alloc_tracker.peakBytesAllocated, sourceLine);
1133 }
1134#endif
1135/* END MOZILLA CHANGE */
1136
1137 // Update in-block recorded size
1138 *(size_t *)mallocedPtr = size;
1139
1140 return (char *)mallocedPtr + sizeof(size_t) + EXPAT_MALLOC_PADDING((sizeof(long long)) - sizeof(size_t));
1141}
1142#endif // XML_GE == 1
1143
1144/* BEGIN MOZILLA CHANGE (unused API) */
1145#if 0
1146XML_Parser XMLCALL
1147XML_ParserCreate(const XML_Char *encodingName) {
1148 return XML_ParserCreate_MM(encodingName, NULL((void*)0), NULL((void*)0));
1149}
1150
1151XML_Parser XMLCALL
1152XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) {
1153 XML_Char tmp[2] = {nsSep, 0};
1154 return XML_ParserCreate_MM(encodingName, NULL((void*)0), tmp);
1155}
1156#endif
1157/* END MOZILLA CHANGE */
1158
1159// "xml=http://www.w3.org/XML/1998/namespace"
1160static const XML_Char implicitContext[]
1161 = {ASCII_x0x78, ASCII_m0x6D, ASCII_l0x6C, ASCII_EQUALS0x3D, ASCII_h0x68,
1162 ASCII_t0x74, ASCII_t0x74, ASCII_p0x70, ASCII_COLON0x3A, ASCII_SLASH0x2F,
1163 ASCII_SLASH0x2F, ASCII_w0x77, ASCII_w0x77, ASCII_w0x77, ASCII_PERIOD0x2E,
1164 ASCII_w0x77, ASCII_30x33, ASCII_PERIOD0x2E, ASCII_o0x6F, ASCII_r0x72,
1165 ASCII_g0x67, ASCII_SLASH0x2F, ASCII_X0x58, ASCII_M0x4D, ASCII_L0x4C,
1166 ASCII_SLASH0x2F, ASCII_10x31, ASCII_90x39, ASCII_90x39, ASCII_80x38,
1167 ASCII_SLASH0x2F, ASCII_n0x6E, ASCII_a0x61, ASCII_m0x6D, ASCII_e0x65,
1168 ASCII_s0x73, ASCII_p0x70, ASCII_a0x61, ASCII_c0x63, ASCII_e0x65,
1169 '\0'};
1170
1171/* BEGIN MOZILLA CHANGE (we already set a salt through XML_SetHashSalt16Bytes) */
1172#if 0
1173#if ! defined(HAVE_ARC4RANDOM_BUF1) && ! defined(HAVE_ARC4RANDOM1)
1174
1175static unsigned long
1176gather_time_entropy(void) {
1177# ifdef _WIN32
1178 FILETIME ft;
1179 GetSystemTimeAsFileTime(&ft); /* never fails */
1180 return ft.dwHighDateTime ^ ft.dwLowDateTime;
1181# else
1182 struct timeval tv;
1183 int gettimeofday_res;
1184
1185 gettimeofday_res = gettimeofday(&tv, NULL((void*)0));
1186
1187# if defined(NDEBUG)
1188 (void)gettimeofday_res;
1189# else
1190 assert(gettimeofday_res == 0)((void) sizeof ((gettimeofday_res == 0) ? 1 : 0), __extension__
({ if (gettimeofday_res == 0) ; else __assert_fail ("gettimeofday_res == 0"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 1190
, __extension__ __PRETTY_FUNCTION__); }))
;
1191# endif /* defined(NDEBUG) */
1192
1193 /* Microseconds time is <20 bits entropy */
1194 return tv.tv_usec;
1195# endif
1196}
1197
1198#endif /* ! defined(HAVE_ARC4RANDOM_BUF) && ! defined(HAVE_ARC4RANDOM) */
1199#endif
1200/* END MOZILLA CHANGE */
1201
1202static struct sipkey
1203ENTROPY_DEBUG(const char *label, struct sipkey entropy_128) {
1204/* BEGIN MOZILLA CHANGE (we already set a salt through XML_SetHashSalt16Bytes) */
1205 (void)label;
1206#if 0
1207 if (getDebugLevel("EXPAT_ENTROPY_DEBUG", 0) >= 1u) {
1208 fprintf(stderrstderr,
1209 "expat: Entropy: %s --> [0x" EXPAT_FMT_LLX("%" "016" "llx"
1210 "016")"%" "016" "llx" ", 0x" EXPAT_FMT_LLX("016")"%" "016" "llx" "] (16 bytes)\n",
1211 label, (unsigned long long)entropy_128.k[0],
1212 (unsigned long long)entropy_128.k[1]);
1213 }
1214#endif
1215/* END MOZILLA CHANGE */
1216 return entropy_128;
1217}
1218
1219static struct sipkey
1220generate_hash_secret_salt(void) {
1221/* BEGIN MOZILLA CHANGE (we already set a salt through XML_SetHashSalt16Bytes) */
1222 abort();
1223#if 0
1224 struct sipkey entropy;
1225
1226 /* "Failproof" high quality providers: */
1227#if defined(HAVE_ARC4RANDOM_BUF1)
1228 writeRandomBytes_arc4random_buf(&entropy, sizeof(entropy));
1229 return ENTROPY_DEBUG("arc4random_buf", entropy);
1230#elif defined(HAVE_ARC4RANDOM1)
1231 writeRandomBytes_arc4random(&entropy, sizeof(entropy));
1232 return ENTROPY_DEBUG("arc4random", entropy);
1233#else
1234 /* Try high quality providers first .. */
1235# ifdef _WIN32
1236 if (writeRandomBytes_rand_s(&entropy, sizeof(entropy))) {
1237 return ENTROPY_DEBUG("rand_s", entropy);
1238 }
1239# elif defined(HAVE_GETENTROPY)
1240 if (writeRandomBytes_getentropy(&entropy, sizeof(entropy))) {
1241 return ENTROPY_DEBUG("getentropy", entropy);
1242 }
1243 errno(*__errno_location ()) = 0;
1244# elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
1245 if (writeRandomBytes_getrandom_nonblock(&entropy, sizeof(entropy))) {
1246 return ENTROPY_DEBUG("getrandom", entropy);
1247 }
1248# endif
1249# if ! defined(_WIN32) && defined(XML_DEV_URANDOM)
1250 if (writeRandomBytes_dev_urandom(&entropy, sizeof(entropy))) {
1251 return ENTROPY_DEBUG("/dev/urandom", entropy);
1252 }
1253# endif /* ! defined(_WIN32) && defined(XML_DEV_URANDOM) */
1254 /* .. and self-made low quality for backup: */
1255
1256 entropy.k[0] = 0;
1257 entropy.k[1] = gather_time_entropy();
1258# if ! defined(__wasi__)
1259 /* Process ID is 0 bits entropy if attacker has local access */
1260 entropy.k[1] ^= getpid();
1261# endif
1262
1263 /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
1264 if (sizeof(unsigned long) == 4) {
1265 entropy.k[1] *= 2147483647;
1266 return ENTROPY_DEBUG("fallback(4)", entropy);
1267 } else {
1268 entropy.k[1] *= 2305843009213693951ULL;
1269 return ENTROPY_DEBUG("fallback(8)", entropy);
1270 }
1271#endif
1272#endif
1273/* END MOZILLA CHANGE */
1274}
1275
1276static void
1277beforeHandler(XML_Parser parser) {
1278 assert(parser->m_handlerCallDepth < UINT_MAX)((void) sizeof ((parser->m_handlerCallDepth < (2147483647
*2U +1U)) ? 1 : 0), __extension__ ({ if (parser->m_handlerCallDepth
< (2147483647 *2U +1U)) ; else __assert_fail ("parser->m_handlerCallDepth < UINT_MAX"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 1278
, __extension__ __PRETTY_FUNCTION__); }))
;
1279 parser->m_handlerCallDepth++;
1280}
1281
1282static void
1283afterHandler(XML_Parser parser) {
1284 assert(parser->m_handlerCallDepth > 0)((void) sizeof ((parser->m_handlerCallDepth > 0) ? 1 : 0
), __extension__ ({ if (parser->m_handlerCallDepth > 0)
; else __assert_fail ("parser->m_handlerCallDepth > 0"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 1284
, __extension__ __PRETTY_FUNCTION__); }))
;
1285 parser->m_handlerCallDepth--;
1286}
1287
1288static bool_Bool
1289isCalledFromInsideHandler(XML_Parser parser) {
1290 return parser->m_handlerCallDepth > 0;
1291}
1292
1293static void
1294callUnknownEncodingRelease(XML_Parser parser) {
1295 beforeHandler(parser);
1296 parser->m_unknownEncodingRelease(parser->m_unknownEncodingData);
1297 afterHandler(parser);
1298 parser->m_unknownEncodingRelease = NULL((void*)0);
1299 parser->m_unknownEncodingData = NULL((void*)0);
1300}
1301
1302static int XMLCALL
1303callUnknownEncodingConvert(void *data, const char *p) {
1304 XML_Parser parser = data;
1305 beforeHandler(parser);
1306 const int result
1307 = parser->m_unknownEncodingConvert(parser->m_unknownEncodingData, p);
1308 afterHandler(parser);
1309 return result;
1310}
1311
1312static enum XML_Error
1313callProcessor(XML_Parser parser, const char *start, const char *end,
1314 const char **endPtr) {
1315 const size_t have_now = EXPAT_SAFE_PTR_DIFF(end, start)(((end) && (start)) ? ((end) - (start)) : 0);
1316
1317 if (parser->m_reparseDeferralEnabled
1318 && ! parser->m_parsingStatus.finalBuffer) {
1319 // Heuristic: don't try to parse a partial token again until the amount of
1320 // available data has increased significantly.
1321 const size_t had_before = parser->m_partialTokenBytesBefore;
1322 // ...but *do* try anyway if we're close to causing a reallocation.
1323 size_t available_buffer
1324 = EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)(((parser->m_bufferPtr) && (parser->m_buffer)) ?
((parser->m_bufferPtr) - (parser->m_buffer)) : 0)
;
1325#if XML_CONTEXT_BYTES0 > 0
1326 available_buffer -= EXPAT_MIN(available_buffer, XML_CONTEXT_BYTES)(((available_buffer) < (0)) ? (available_buffer) : (0));
1327#endif
1328 available_buffer
1329 += EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)(((parser->m_bufferLim) && (parser->m_bufferEnd
)) ? ((parser->m_bufferLim) - (parser->m_bufferEnd)) : 0
)
;
1330 // m_lastBufferRequestSize is never assigned a value < 0, so the cast is ok
1331 const bool_Bool enough
1332 = (have_now >= 2 * had_before)
1333 || ((size_t)parser->m_lastBufferRequestSize > available_buffer);
1334
1335 if (! enough) {
1336 *endPtr = start; // callers may expect this to be set
1337 return XML_ERROR_NONE;
1338 }
1339 }
1340#if defined(XML_TESTING)
1341 g_bytesScanned += (unsigned)have_now;
1342#endif
1343 // Run in a loop to eliminate dangerous recursion depths
1344 enum XML_Error ret;
1345 *endPtr = start;
1346 while (1) {
1347 // Use endPtr as the new start in each iteration, since it will
1348 // be set to the next start point by m_processor.
1349 ret = parser->m_processor(parser, *endPtr, end, endPtr);
1350
1351 // Make parsing status (and in particular XML_SUSPENDED) take
1352 // precedence over re-enter flag when they disagree
1353 if (parser->m_parsingStatus.parsing != XML_PARSING) {
1354 parser->m_reenter = XML_FALSE((XML_Bool)0);
1355 }
1356
1357 if (! parser->m_reenter) {
1358 break;
1359 }
1360
1361 parser->m_reenter = XML_FALSE((XML_Bool)0);
1362 if (ret != XML_ERROR_NONE)
1363 return ret;
1364 }
1365
1366 if (ret == XML_ERROR_NONE) {
1367 // if we consumed nothing, remember what we had on this parse attempt.
1368 if (*endPtr == start) {
1369 parser->m_partialTokenBytesBefore = have_now;
1370 } else {
1371 parser->m_partialTokenBytesBefore = 0;
1372 }
1373 }
1374 return ret;
1375}
1376
1377static XML_Bool /* only valid for root parser */
1378startParsing(XML_Parser parser) {
1379 /* hash functions must be initialized before setContext() is called */
1380 if (parser->m_hash_secret_salt_set != XML_TRUE((XML_Bool)1)) {
1381 parser->m_hash_secret_salt_128 = generate_hash_secret_salt();
1382 parser->m_hash_secret_salt_set = XML_TRUE((XML_Bool)1);
1383 }
1384 if (parser->m_ns) {
1385 /* implicit context only set for root parser, since child
1386 parsers (i.e. external entity parsers) will inherit it
1387 */
1388 return setContext(parser, implicitContext);
1389 }
1390 return XML_TRUE((XML_Bool)1);
1391}
1392
1393XML_Parser XMLCALL
1394XML_ParserCreate_MM(const XML_Char *encodingName,
1395 const XML_Memory_Handling_Suite *memsuite,
1396 const XML_Char *nameSep) {
1397 return parserCreate(encodingName, memsuite, nameSep, NULL((void*)0), NULL((void*)0));
1398}
1399
1400static XML_Parser
1401parserCreate(const XML_Char *encodingName,
1402 const XML_Memory_Handling_Suite *memsuite, const XML_Char *nameSep,
1403 DTD *dtd, XML_Parser parentParser) {
1404 XML_Parser parser = NULL((void*)0);
1405
1406#if XML_GE1 == 1
1407 const size_t increase
1408 = sizeof(size_t) + EXPAT_MALLOC_PADDING((sizeof(long long)) - sizeof(size_t)) + sizeof(struct XML_ParserStruct);
1409
1410 if (parentParser != NULL((void*)0)) {
1411 const XML_Parser rootParser = getRootParserOf(parentParser, NULL((void*)0));
1412 if (! expat_heap_increase_tolerable(rootParser, increase, __LINE__1412)) {
1413 return NULL((void*)0);
1414 }
1415 }
1416#else
1417 UNUSED_P(parentParser)(void)parentParser;
1418#endif
1419
1420 if (memsuite) {
1421 XML_Memory_Handling_Suite *mtemp;
1422#if XML_GE1 == 1
1423 void *const sizeAndParser
1424 = memsuite->malloc_fcn(sizeof(size_t) + EXPAT_MALLOC_PADDING((sizeof(long long)) - sizeof(size_t))
1425 + sizeof(struct XML_ParserStruct));
1426 if (sizeAndParser != NULL((void*)0)) {
1427 *(size_t *)sizeAndParser = sizeof(struct XML_ParserStruct);
1428 parser = (XML_Parser)((char *)sizeAndParser + sizeof(size_t)
1429 + EXPAT_MALLOC_PADDING((sizeof(long long)) - sizeof(size_t)));
1430#else
1431 parser = memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
1432 if (parser != NULL((void*)0)) {
1433#endif
1434 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
1435 mtemp->malloc_fcn = memsuite->malloc_fcn;
1436 mtemp->realloc_fcn = memsuite->realloc_fcn;
1437 mtemp->free_fcn = memsuite->free_fcn;
1438 }
1439 } else {
1440 XML_Memory_Handling_Suite *mtemp;
1441#if XML_GE1 == 1
1442 void *const sizeAndParser = malloc(sizeof(size_t) + EXPAT_MALLOC_PADDING((sizeof(long long)) - sizeof(size_t))
1443 + sizeof(struct XML_ParserStruct));
1444 if (sizeAndParser != NULL((void*)0)) {
1445 *(size_t *)sizeAndParser = sizeof(struct XML_ParserStruct);
1446 parser = (XML_Parser)((char *)sizeAndParser + sizeof(size_t)
1447 + EXPAT_MALLOC_PADDING((sizeof(long long)) - sizeof(size_t)));
1448#else
1449 parser = malloc(sizeof(struct XML_ParserStruct));
1450 if (parser != NULL((void*)0)) {
1451#endif
1452 mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
1453 mtemp->malloc_fcn = malloc;
1454 mtemp->realloc_fcn = realloc;
1455 mtemp->free_fcn = free;
1456 }
1457 } // cppcheck-suppress[memleak symbolName=sizeAndParser] // Cppcheck >=2.18.0
1458
1459 if (! parser)
1460 return parser;
1461
1462#if XML_GE1 == 1
1463 // Initialize .m_alloc_tracker
1464 memset(&parser->m_alloc_tracker, 0, sizeof(MALLOC_TRACKER));
1465 if (parentParser == NULL((void*)0)) {
1466/* BEGIN MOZILLA CHANGE (don't report debug information) */
1467#if 0
1468 parser->m_alloc_tracker.debugLevel
1469 = getDebugLevel("EXPAT_MALLOC_DEBUG", 0u);
1470#endif
1471/* END MOZILLA CHANGE */
1472 parser->m_alloc_tracker.maximumAmplificationFactor
1473 = EXPAT_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT100.0f;
1474 parser->m_alloc_tracker.activationThresholdBytes
1475 = EXPAT_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT67108864;
1476
1477 // NOTE: This initialization needs to come this early because these fields
1478 // are read by allocation tracking code
1479 parser->m_parentParser = NULL((void*)0);
1480 parser->m_accounting.countBytesDirect = 0;
1481 } else {
1482 parser->m_parentParser = parentParser;
1483 }
1484
1485 // Record XML_ParserStruct allocation we did a few lines up before
1486 const XML_Parser rootParser = getRootParserOf(parser, NULL((void*)0));
1487 assert(rootParser->m_parentParser == NULL)((void) sizeof ((rootParser->m_parentParser == ((void*)0))
? 1 : 0), __extension__ ({ if (rootParser->m_parentParser
== ((void*)0)) ; else __assert_fail ("rootParser->m_parentParser == NULL"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 1487
, __extension__ __PRETTY_FUNCTION__); }))
;
1488 assert(SIZE_MAX - rootParser->m_alloc_tracker.bytesAllocated >= increase)((void) sizeof (((18446744073709551615UL) - rootParser->m_alloc_tracker
.bytesAllocated >= increase) ? 1 : 0), __extension__ ({ if
((18446744073709551615UL) - rootParser->m_alloc_tracker.bytesAllocated
>= increase) ; else __assert_fail ("SIZE_MAX - rootParser->m_alloc_tracker.bytesAllocated >= increase"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 1488
, __extension__ __PRETTY_FUNCTION__); }))
;
1489 rootParser->m_alloc_tracker.bytesAllocated += increase;
1490
1491/* BEGIN MOZILLA CHANGE (don't report debug information) */
1492#if 0
1493 // Report on allocation
1494 if (rootParser->m_alloc_tracker.debugLevel >= 2) {
1495 if (rootParser->m_alloc_tracker.bytesAllocated
1496 > rootParser->m_alloc_tracker.peakBytesAllocated) {
1497 rootParser->m_alloc_tracker.peakBytesAllocated
1498 = rootParser->m_alloc_tracker.bytesAllocated;
1499 }
1500
1501 expat_heap_stat(rootParser, '+', increase,
1502 rootParser->m_alloc_tracker.bytesAllocated,
1503 rootParser->m_alloc_tracker.peakBytesAllocated, __LINE__1503);
1504 }
1505#endif
1506/* END MOZILLA CHANGE */
1507#else
1508 parser->m_parentParser = NULL((void*)0);
1509#endif // XML_GE == 1
1510
1511 parser->m_buffer = NULL((void*)0);
1512 parser->m_bufferLim = NULL((void*)0);
1513
1514 parser->m_attsSize = INIT_ATTS_SIZE16;
1515 parser->m_atts = MALLOC(parser, parser->m_attsSize * sizeof(ATTRIBUTE))(expat_malloc((parser), (parser->m_attsSize * sizeof(ATTRIBUTE
)), 1515))
;
1516 if (parser->m_atts == NULL((void*)0)) {
1517 FREE(parser, parser)(expat_free((parser), (parser), 1517));
1518 return NULL((void*)0);
1519 }
1520#ifdef XML_ATTR_INFO
1521 parser->m_attInfo = MALLOC(parser, parser->m_attsSize * sizeof(XML_AttrInfo))(expat_malloc((parser), (parser->m_attsSize * sizeof(XML_AttrInfo
)), 1521))
;
1522 if (parser->m_attInfo == NULL((void*)0)) {
1523 FREE(parser, parser->m_atts)(expat_free((parser), (parser->m_atts), 1523));
1524 FREE(parser, parser)(expat_free((parser), (parser), 1524));
1525 return NULL((void*)0);
1526 }
1527#endif
1528 parser->m_dataBuf = MALLOC(parser, INIT_DATA_BUF_SIZE * sizeof(XML_Char))(expat_malloc((parser), (1024 * sizeof(XML_Char)), 1528));
1529 if (parser->m_dataBuf == NULL((void*)0)) {
1530 FREE(parser, parser->m_atts)(expat_free((parser), (parser->m_atts), 1530));
1531#ifdef XML_ATTR_INFO
1532 FREE(parser, parser->m_attInfo)(expat_free((parser), (parser->m_attInfo), 1532));
1533#endif
1534 FREE(parser, parser)(expat_free((parser), (parser), 1534));
1535 return NULL((void*)0);
1536 }
1537 parser->m_dataBufEnd = parser->m_dataBuf + INIT_DATA_BUF_SIZE1024;
1538
1539 if (dtd)
1540 parser->m_dtd = dtd;
1541 else {
1542 parser->m_dtd = dtdCreate(parser);
1543 if (parser->m_dtd == NULL((void*)0)) {
1544 FREE(parser, parser->m_dataBuf)(expat_free((parser), (parser->m_dataBuf), 1544));
1545 FREE(parser, parser->m_atts)(expat_free((parser), (parser->m_atts), 1545));
1546#ifdef XML_ATTR_INFO
1547 FREE(parser, parser->m_attInfo)(expat_free((parser), (parser->m_attInfo), 1547));
1548#endif
1549 FREE(parser, parser)(expat_free((parser), (parser), 1549));
1550 return NULL((void*)0);
1551 }
1552 }
1553
1554 parser->m_freeBindingList = NULL((void*)0);
1555 parser->m_freeTagList = NULL((void*)0);
1556 parser->m_freeEntities = NULL((void*)0);
1557
1558 parser->m_groupSize = 0;
1559 parser->m_groupConnector = NULL((void*)0);
1560
1561 parser->m_unknownEncodingHandler = NULL((void*)0);
1562 parser->m_unknownEncodingHandlerData = NULL((void*)0);
1563
1564 parser->m_namespaceSeparator = ASCII_EXCL0x21;
1565 parser->m_ns = XML_FALSE((XML_Bool)0);
1566 parser->m_ns_triplets = XML_FALSE((XML_Bool)0);
1567
1568 parser->m_nsAtts = NULL((void*)0);
1569 parser->m_nsAttsVersion = 0;
1570 parser->m_nsAttsPower = 0;
1571
1572 parser->m_protocolEncodingName = NULL((void*)0);
1573
1574 poolInit(&parser->m_tempPool, parser);
1575 poolInit(&parser->m_temp2Pool, parser);
1576 parserInit(parser, encodingName);
1577
1578 if (encodingName && ! parser->m_protocolEncodingName) {
1579 if (dtd) {
1580 // We need to stop the upcoming call to XML_ParserFree from happily
1581 // destroying parser->m_dtd because the DTD is shared with the parent
1582 // parser and the only guard that keeps XML_ParserFree from destroying
1583 // parser->m_dtd is parser->m_isParamEntity but it will be set to
1584 // XML_TRUE only later in XML_ExternalEntityParserCreate (or not at all).
1585 parser->m_dtd = NULL((void*)0);
1586 }
1587 XML_ParserFree(parser);
1588 return NULL((void*)0);
1589 }
1590
1591 if (nameSep) {
1592 parser->m_ns = XML_TRUE((XML_Bool)1);
1593 parser->m_internalEncoding = XmlGetInternalEncodingNSXmlGetUtf16InternalEncodingNS();
1594 parser->m_namespaceSeparator = *nameSep;
1595 } else {
1596 parser->m_internalEncoding = XmlGetInternalEncodingXmlGetUtf16InternalEncoding();
1597 }
1598
1599/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
1600 parser->m_mismatch = NULL((void*)0);
1601/* END MOZILLA CHANGE */
1602
1603 return parser;
1604}
1605
1606static void
1607parserInit(XML_Parser parser, const XML_Char *encodingName) {
1608 parser->m_processor = prologInitProcessor;
1609 XmlPrologStateInit(&parser->m_prologState);
1610 if (encodingName != NULL((void*)0)) {
1611 parser->m_protocolEncodingName = copyString(encodingName, parser);
1612 }
1613 parser->m_curBase = NULL((void*)0);
1614 XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0);
1615 parser->m_userData = NULL((void*)0);
1616 parser->m_handlerArg = NULL((void*)0);
1617 parser->m_startElementHandler = NULL((void*)0);
1618 parser->m_endElementHandler = NULL((void*)0);
1619 parser->m_characterDataHandler = NULL((void*)0);
1620 parser->m_processingInstructionHandler = NULL((void*)0);
1621 parser->m_commentHandler = NULL((void*)0);
1622 parser->m_startCdataSectionHandler = NULL((void*)0);
1623 parser->m_endCdataSectionHandler = NULL((void*)0);
1624 parser->m_defaultHandler = NULL((void*)0);
1625 parser->m_startDoctypeDeclHandler = NULL((void*)0);
1626 parser->m_endDoctypeDeclHandler = NULL((void*)0);
1627 parser->m_unparsedEntityDeclHandler = NULL((void*)0);
1628 parser->m_notationDeclHandler = NULL((void*)0);
1629 parser->m_startNamespaceDeclHandler = NULL((void*)0);
1630 parser->m_endNamespaceDeclHandler = NULL((void*)0);
1631 parser->m_notStandaloneHandler = NULL((void*)0);
1632 parser->m_externalEntityRefHandler = NULL((void*)0);
1633 parser->m_externalEntityRefHandlerArg = parser;
1634 parser->m_skippedEntityHandler = NULL((void*)0);
1635 parser->m_elementDeclHandler = NULL((void*)0);
1636 parser->m_attlistDeclHandler = NULL((void*)0);
1637 parser->m_entityDeclHandler = NULL((void*)0);
1638 parser->m_xmlDeclHandler = NULL((void*)0);
1639 parser->m_bufferPtr = parser->m_buffer;
1640 parser->m_bufferEnd = parser->m_buffer;
1641 parser->m_parseEndByteIndex = 0;
1642 parser->m_parseEndPtr = NULL((void*)0);
1643 parser->m_partialTokenBytesBefore = 0;
1644 parser->m_reparseDeferralEnabled = g_reparseDeferralEnabledDefault;
1645 parser->m_lastBufferRequestSize = 0;
1646 parser->m_declElementType = NULL((void*)0);
1647 parser->m_declAttributeId = NULL((void*)0);
1648 parser->m_declEntity = NULL((void*)0);
1649 parser->m_doctypeName = NULL((void*)0);
1650 parser->m_doctypeSysid = NULL((void*)0);
1651 parser->m_doctypePubid = NULL((void*)0);
1652 parser->m_declAttributeType = NULL((void*)0);
1653 parser->m_declNotationName = NULL((void*)0);
1654 parser->m_declNotationPublicId = NULL((void*)0);
1655 parser->m_declAttributeIsCdata = XML_FALSE((XML_Bool)0);
1656 parser->m_declAttributeIsId = XML_FALSE((XML_Bool)0);
1657 memset(&parser->m_position, 0, sizeof(POSITION));
1658 parser->m_errorCode = XML_ERROR_NONE;
1659 parser->m_eventPtr = NULL((void*)0);
1660 parser->m_eventEndPtr = NULL((void*)0);
1661 parser->m_positionPtr = NULL((void*)0);
1662 parser->m_openInternalEntities = NULL((void*)0);
1663 parser->m_openAttributeEntities = NULL((void*)0);
1664 parser->m_openValueEntities = NULL((void*)0);
1665 parser->m_defaultExpandInternalEntities = XML_TRUE((XML_Bool)1);
1666 parser->m_tagLevel = 0;
1667 parser->m_tagStack = NULL((void*)0);
1668 parser->m_inheritedBindings = NULL((void*)0);
1669 parser->m_nSpecifiedAtts = 0;
1670 parser->m_unknownEncodingMem = NULL((void*)0);
1671 parser->m_unknownEncodingConvert = NULL((void*)0);
1672 parser->m_unknownEncodingRelease = NULL((void*)0);
1673 parser->m_unknownEncodingData = NULL((void*)0);
1674 parser->m_parsingStatus.parsing = XML_INITIALIZED;
1675 // Reentry can only be triggered inside m_processor calls
1676 parser->m_reenter = XML_FALSE((XML_Bool)0);
1677 parser->m_handlerCallDepth = 0;
1678#ifdef XML_DTD
1679 parser->m_isParamEntity = XML_FALSE((XML_Bool)0);
1680 parser->m_useForeignDTD = XML_FALSE((XML_Bool)0);
1681 parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
1682#endif
1683 parser->m_hash_secret_salt_128.k[0] = 0;
1684 parser->m_hash_secret_salt_128.k[1] = 0;
1685 parser->m_hash_secret_salt_set = XML_FALSE((XML_Bool)0);
1686
1687#if XML_GE1 == 1
1688 memset(&parser->m_accounting, 0, sizeof(ACCOUNTING));
1689/* BEGIN MOZILLA CHANGE (don't report debug information) */
1690#if 0
1691 parser->m_accounting.debugLevel = getDebugLevel("EXPAT_ACCOUNTING_DEBUG", 0u);
1692#endif
1693/* END MOZILLA CHANGE */
1694 parser->m_accounting.maximumAmplificationFactor
1695 = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT100.0f;
1696 parser->m_accounting.activationThresholdBytes
1697 = EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT8388608;
1698
1699 memset(&parser->m_entity_stats, 0, sizeof(ENTITY_STATS));
1700/* BEGIN MOZILLA CHANGE (don't report debug information) */
1701#if 0
1702 parser->m_entity_stats.debugLevel = getDebugLevel("EXPAT_ENTITY_DEBUG", 0u);
1703#endif
1704/* END MOZILLA CHANGE */
1705#endif
1706}
1707
1708/* BEGIN MOZILLA CHANGE (unused API) */
1709#if 0
1710/* moves list of bindings to m_freeBindingList */
1711static void FASTCALL
1712moveToFreeBindingList(XML_Parser parser, BINDING *bindings) {
1713 while (bindings) {
1714 BINDING *b = bindings;
1715 bindings = bindings->nextTagBinding;
1716 b->nextTagBinding = parser->m_freeBindingList;
1717 parser->m_freeBindingList = b;
1718 }
1719}
1720
1721/* Moves a list of entities onto the start of another list. */
1722static void
1723moveEntityList(OPEN_INTERNAL_ENTITY **dst, OPEN_INTERNAL_ENTITY **src) {
1724 for (OPEN_INTERNAL_ENTITY *head = *src; head != NULL((void*)0);) {
1725 OPEN_INTERNAL_ENTITY *const openEntity = head;
1726 head = head->next;
1727 openEntity->next = *dst;
1728 *dst = openEntity;
1729 }
1730}
1731
1732XML_Bool XMLCALL
1733XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
1734 TAG *tStk;
1735
1736 if ((parser == NULL((void*)0)) || isCalledFromInsideHandler(parser))
1737 return XML_FALSE((XML_Bool)0);
1738
1739 if (parser->m_parentParser)
1740 return XML_FALSE((XML_Bool)0);
1741 /* move m_tagStack to m_freeTagList */
1742 tStk = parser->m_tagStack;
1743 while (tStk) {
1744 TAG *tag = tStk;
1745 tStk = tStk->parent;
1746 tag->parent = parser->m_freeTagList;
1747 moveToFreeBindingList(parser, tag->bindings);
1748 tag->bindings = NULL((void*)0);
1749 parser->m_freeTagList = tag;
1750 }
1751 /* move m_openInternalEntities to m_freeEntities */
1752 moveEntityList(&parser->m_freeEntities, &parser->m_openInternalEntities);
1753 /* move m_openAttributeEntities to m_freeEntities (i.e. same task but for
1754 * attributes) */
1755 moveEntityList(&parser->m_freeEntities, &parser->m_openAttributeEntities);
1756 /* move m_openValueEntities to m_freeEntities (i.e. same task but for value
1757 * entities) */
1758 moveEntityList(&parser->m_freeEntities, &parser->m_openValueEntities);
1759 moveToFreeBindingList(parser, parser->m_inheritedBindings);
1760 FREE(parser, parser->m_unknownEncodingMem)(expat_free((parser), (parser->m_unknownEncodingMem), 1760
))
;
1761 if (parser->m_unknownEncodingRelease)
1762 callUnknownEncodingRelease(parser);
1763 poolClear(&parser->m_tempPool);
1764 poolClear(&parser->m_temp2Pool);
1765 FREE(parser, (void *)parser->m_protocolEncodingName)(expat_free((parser), ((void *)parser->m_protocolEncodingName
), 1765))
;
1766 parser->m_protocolEncodingName = NULL((void*)0);
1767 parserInit(parser, encodingName);
1768 dtdReset(parser->m_dtd, parser);
1769 return XML_TRUE((XML_Bool)1);
1770}
1771#endif
1772/* END MOZILLA CHANGE */
1773
1774static XML_Bool
1775parserBusy(XML_Parser parser) {
1776 switch (parser->m_parsingStatus.parsing) {
1777 case XML_PARSING:
1778 case XML_SUSPENDED:
1779 return XML_TRUE((XML_Bool)1);
1780 case XML_INITIALIZED:
1781 case XML_FINISHED:
1782 default:
1783 return XML_FALSE((XML_Bool)0);
1784 }
1785}
1786
1787/* BEGIN MOZILLA CHANGE (unused API) */
1788#if 0
1789enum XML_Status XMLCALL
1790XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
1791 if (parser == NULL((void*)0))
1792 return XML_STATUS_ERRORXML_STATUS_ERROR;
1793 /* Block after XML_Parse()/XML_ParseBuffer() has been called.
1794 XXX There's no way for the caller to determine which of the
1795 XXX possible error cases caused the XML_STATUS_ERROR return.
1796 */
1797 if (parserBusy(parser))
1798 return XML_STATUS_ERRORXML_STATUS_ERROR;
1799
1800 /* Get rid of any previous encoding name */
1801 FREE(parser, (void *)parser->m_protocolEncodingName)(expat_free((parser), ((void *)parser->m_protocolEncodingName
), 1801))
;
1802
1803 if (encodingName == NULL((void*)0))
1804 /* No new encoding name */
1805 parser->m_protocolEncodingName = NULL((void*)0);
1806 else {
1807 /* Copy the new encoding name into allocated memory */
1808 parser->m_protocolEncodingName = copyString(encodingName, parser);
1809 if (! parser->m_protocolEncodingName)
1810 return XML_STATUS_ERRORXML_STATUS_ERROR;
1811 }
1812 return XML_STATUS_OKXML_STATUS_OK;
1813}
1814#endif
1815/* END MOZILLA CHANGE */
1816
1817XML_Parser XMLCALL
1818XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
1819 const XML_Char *encodingName) {
1820 XML_Parser parser = oldParser;
1821 DTD *newDtd = NULL((void*)0);
1822 DTD *oldDtd;
1823 XML_StartElementHandler oldStartElementHandler;
1824 XML_EndElementHandler oldEndElementHandler;
1825 XML_CharacterDataHandler oldCharacterDataHandler;
1826 XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
1827 XML_CommentHandler oldCommentHandler;
1828 XML_StartCdataSectionHandler oldStartCdataSectionHandler;
1829 XML_EndCdataSectionHandler oldEndCdataSectionHandler;
1830 XML_DefaultHandler oldDefaultHandler;
1831 XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
1832 XML_NotationDeclHandler oldNotationDeclHandler;
1833 XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
1834 XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
1835 XML_NotStandaloneHandler oldNotStandaloneHandler;
1836 XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
1837 XML_SkippedEntityHandler oldSkippedEntityHandler;
1838 XML_UnknownEncodingHandler oldUnknownEncodingHandler;
1839 void *oldUnknownEncodingHandlerData;
1840 XML_ElementDeclHandler oldElementDeclHandler;
1841 XML_AttlistDeclHandler oldAttlistDeclHandler;
1842 XML_EntityDeclHandler oldEntityDeclHandler;
1843 XML_XmlDeclHandler oldXmlDeclHandler;
1844 ELEMENT_TYPE *oldDeclElementType;
1845
1846 void *oldUserData;
1847 void *oldHandlerArg;
1848 XML_Bool oldDefaultExpandInternalEntities;
1849 XML_Parser oldExternalEntityRefHandlerArg;
1850#ifdef XML_DTD
1851 enum XML_ParamEntityParsing oldParamEntityParsing;
1852 int oldInEntityValue;
1853#endif
1854 XML_Bool oldns_triplets;
1855 /* Note that the new parser shares the same hash secret as the old
1856 parser, so that dtdCopy and copyEntityTable can lookup values
1857 from hash tables associated with either parser without us having
1858 to worry which hash secrets each table has.
1859 */
1860 struct sipkey oldhash_secret_salt_128;
1861 XML_Bool oldhash_secret_salt_set;
1862 XML_Bool oldReparseDeferralEnabled;
1863
1864 /* Validate the oldParser parameter before we pull everything out of it */
1865 if (oldParser == NULL((void*)0))
1866 return NULL((void*)0);
1867
1868 /* Stash the original parser contents on the stack */
1869 oldDtd = parser->m_dtd;
1870 oldStartElementHandler = parser->m_startElementHandler;
1871 oldEndElementHandler = parser->m_endElementHandler;
1872 oldCharacterDataHandler = parser->m_characterDataHandler;
1873 oldProcessingInstructionHandler = parser->m_processingInstructionHandler;
1874 oldCommentHandler = parser->m_commentHandler;
1875 oldStartCdataSectionHandler = parser->m_startCdataSectionHandler;
1876 oldEndCdataSectionHandler = parser->m_endCdataSectionHandler;
1877 oldDefaultHandler = parser->m_defaultHandler;
1878 oldUnparsedEntityDeclHandler = parser->m_unparsedEntityDeclHandler;
1879 oldNotationDeclHandler = parser->m_notationDeclHandler;
1880 oldStartNamespaceDeclHandler = parser->m_startNamespaceDeclHandler;
1881 oldEndNamespaceDeclHandler = parser->m_endNamespaceDeclHandler;
1882 oldNotStandaloneHandler = parser->m_notStandaloneHandler;
1883 oldExternalEntityRefHandler = parser->m_externalEntityRefHandler;
1884 oldSkippedEntityHandler = parser->m_skippedEntityHandler;
1885 oldUnknownEncodingHandler = parser->m_unknownEncodingHandler;
1886 oldUnknownEncodingHandlerData = parser->m_unknownEncodingHandlerData;
1887 oldElementDeclHandler = parser->m_elementDeclHandler;
1888 oldAttlistDeclHandler = parser->m_attlistDeclHandler;
1889 oldEntityDeclHandler = parser->m_entityDeclHandler;
1890 oldXmlDeclHandler = parser->m_xmlDeclHandler;
1891 oldDeclElementType = parser->m_declElementType;
1892
1893 oldUserData = parser->m_userData;
1894 oldHandlerArg = parser->m_handlerArg;
1895 oldDefaultExpandInternalEntities = parser->m_defaultExpandInternalEntities;
1896 oldExternalEntityRefHandlerArg = parser->m_externalEntityRefHandlerArg;
1897#ifdef XML_DTD
1898 oldParamEntityParsing = parser->m_paramEntityParsing;
1899 oldInEntityValue = parser->m_prologState.inEntityValue;
1900#endif
1901 oldns_triplets = parser->m_ns_triplets;
1902 /* Note that the new parser shares the same hash secret as the old
1903 parser, so that dtdCopy and copyEntityTable can lookup values
1904 from hash tables associated with either parser without us having
1905 to worry which hash secrets each table has.
1906 */
1907 oldhash_secret_salt_128 = parser->m_hash_secret_salt_128;
1908 oldhash_secret_salt_set = parser->m_hash_secret_salt_set;
1909 oldReparseDeferralEnabled = parser->m_reparseDeferralEnabled;
1910
1911#ifdef XML_DTD
1912 if (! context)
1913 newDtd = oldDtd;
1914#endif /* XML_DTD */
1915
1916 if (parser->m_ns) {
1917 XML_Char tmp[2] = {parser->m_namespaceSeparator, 0};
1918 parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd, oldParser);
1919 } else {
1920 parser
1921 = parserCreate(encodingName, &parser->m_mem, NULL((void*)0), newDtd, oldParser);
1922 }
1923
1924 if (! parser)
1925 return NULL((void*)0);
1926
1927 parser->m_startElementHandler = oldStartElementHandler;
1928 parser->m_endElementHandler = oldEndElementHandler;
1929 parser->m_characterDataHandler = oldCharacterDataHandler;
1930 parser->m_processingInstructionHandler = oldProcessingInstructionHandler;
1931 parser->m_commentHandler = oldCommentHandler;
1932 parser->m_startCdataSectionHandler = oldStartCdataSectionHandler;
1933 parser->m_endCdataSectionHandler = oldEndCdataSectionHandler;
1934 parser->m_defaultHandler = oldDefaultHandler;
1935 parser->m_unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
1936 parser->m_notationDeclHandler = oldNotationDeclHandler;
1937 parser->m_startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
1938 parser->m_endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
1939 parser->m_notStandaloneHandler = oldNotStandaloneHandler;
1940 parser->m_externalEntityRefHandler = oldExternalEntityRefHandler;
1941 parser->m_skippedEntityHandler = oldSkippedEntityHandler;
1942 parser->m_unknownEncodingHandler = oldUnknownEncodingHandler;
1943 parser->m_unknownEncodingHandlerData = oldUnknownEncodingHandlerData;
1944 parser->m_elementDeclHandler = oldElementDeclHandler;
1945 parser->m_attlistDeclHandler = oldAttlistDeclHandler;
1946 parser->m_entityDeclHandler = oldEntityDeclHandler;
1947 parser->m_xmlDeclHandler = oldXmlDeclHandler;
1948 parser->m_declElementType = oldDeclElementType;
1949 parser->m_userData = oldUserData;
1950 if (oldUserData == oldHandlerArg)
1951 parser->m_handlerArg = parser->m_userData;
1952 else
1953 parser->m_handlerArg = parser;
1954 if (oldExternalEntityRefHandlerArg != oldParser)
1955 parser->m_externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
1956 parser->m_defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
1957 parser->m_ns_triplets = oldns_triplets;
1958 parser->m_hash_secret_salt_128 = oldhash_secret_salt_128;
1959 parser->m_hash_secret_salt_set = oldhash_secret_salt_set;
1960 parser->m_reparseDeferralEnabled = oldReparseDeferralEnabled;
1961 parser->m_parentParser = oldParser;
1962#ifdef XML_DTD
1963 parser->m_paramEntityParsing = oldParamEntityParsing;
1964 parser->m_prologState.inEntityValue = oldInEntityValue;
1965 if (context) {
1966#endif /* XML_DTD */
1967 if (! dtdCopy(oldParser, parser->m_dtd, oldDtd, parser)
1968 || ! setContext(parser, context)) {
1969 XML_ParserFree(parser);
1970 return NULL((void*)0);
1971 }
1972 parser->m_processor = externalEntityInitProcessor;
1973#ifdef XML_DTD
1974 } else {
1975 /* The DTD instance referenced by parser->m_dtd is shared between the
1976 document's root parser and external PE parsers, therefore one does not
1977 need to call setContext. In addition, one also *must* not call
1978 setContext, because this would overwrite existing prefix->binding
1979 pointers in parser->m_dtd with ones that get destroyed with the external
1980 PE parser. This would leave those prefixes with dangling pointers.
1981 */
1982 parser->m_isParamEntity = XML_TRUE((XML_Bool)1);
1983 XmlPrologStateInitExternalEntity(&parser->m_prologState);
1984 parser->m_processor = externalParEntInitProcessor;
1985 }
1986#endif /* XML_DTD */
1987 return parser;
1988}
1989
1990static void FASTCALL
1991destroyBindings(BINDING *bindings, XML_Parser parser) {
1992 for (;;) {
1993 BINDING *b = bindings;
1994 if (! b)
1995 break;
1996 bindings = b->nextTagBinding;
1997 FREE(parser, b->uri)(expat_free((parser), (b->uri), 1997));
1998 FREE(parser, b)(expat_free((parser), (b), 1998));
1999 }
2000}
2001
2002void XMLCALL
2003XML_ParserFree(XML_Parser parser) {
2004 TAG *tagList;
2005 if ((parser == NULL((void*)0)) || isCalledFromInsideHandler(parser))
2006 return;
2007 /* free m_tagStack and m_freeTagList */
2008 tagList = parser->m_tagStack;
2009 for (;;) {
2010 TAG *p;
2011 if (tagList == NULL((void*)0)) {
2012 if (parser->m_freeTagList == NULL((void*)0))
2013 break;
2014 tagList = parser->m_freeTagList;
2015 parser->m_freeTagList = NULL((void*)0);
2016 }
2017 p = tagList;
2018 tagList = tagList->parent;
2019 FREE(parser, p->buf.raw)(expat_free((parser), (p->buf.raw), 2019));
2020 destroyBindings(p->bindings, parser);
2021 FREE(parser, p)(expat_free((parser), (p), 2021));
2022 }
2023 /* free m_openInternalEntities */
2024 for (OPEN_INTERNAL_ENTITY *entityList = parser->m_openInternalEntities;
2025 entityList != NULL((void*)0);) {
2026 OPEN_INTERNAL_ENTITY *const openEntity = entityList;
2027 entityList = entityList->next;
2028 FREE(parser, openEntity)(expat_free((parser), (openEntity), 2028));
2029 }
2030 /* free m_openAttributeEntities */
2031 for (OPEN_INTERNAL_ENTITY *entityList = parser->m_openAttributeEntities;
2032 entityList != NULL((void*)0);) {
2033 OPEN_INTERNAL_ENTITY *const openEntity = entityList;
2034 entityList = entityList->next;
2035 FREE(parser, openEntity)(expat_free((parser), (openEntity), 2035));
2036 }
2037 /* free m_openValueEntities */
2038 for (OPEN_INTERNAL_ENTITY *entityList = parser->m_openValueEntities;
2039 entityList != NULL((void*)0);) {
2040 OPEN_INTERNAL_ENTITY *const openEntity = entityList;
2041 entityList = entityList->next;
2042 FREE(parser, openEntity)(expat_free((parser), (openEntity), 2042));
2043 }
2044 /* free m_freeEntities */
2045 for (OPEN_INTERNAL_ENTITY *entityList = parser->m_freeEntities;
2046 entityList != NULL((void*)0);) {
2047 OPEN_INTERNAL_ENTITY *const openEntity = entityList;
2048 entityList = entityList->next;
2049 FREE(parser, openEntity)(expat_free((parser), (openEntity), 2049));
2050 }
2051 parser->m_freeEntities = NULL((void*)0);
2052 destroyBindings(parser->m_freeBindingList, parser);
2053 destroyBindings(parser->m_inheritedBindings, parser);
2054 poolDestroy(&parser->m_tempPool);
2055 poolDestroy(&parser->m_temp2Pool);
2056 FREE(parser, (void *)parser->m_protocolEncodingName)(expat_free((parser), ((void *)parser->m_protocolEncodingName
), 2056))
;
2057#ifdef XML_DTD
2058 /* external parameter entity parsers share the DTD structure
2059 parser->m_dtd with the root parser, so we must not destroy it
2060 */
2061 if (! parser->m_isParamEntity && parser->m_dtd)
2062#else
2063 if (parser->m_dtd)
2064#endif /* XML_DTD */
2065 dtdDestroy(parser->m_dtd, (XML_Bool)! parser->m_parentParser, parser);
2066 FREE(parser, parser->m_atts)(expat_free((parser), (parser->m_atts), 2066));
2067#ifdef XML_ATTR_INFO
2068 FREE(parser, parser->m_attInfo)(expat_free((parser), (parser->m_attInfo), 2068));
2069#endif
2070 FREE(parser, parser->m_groupConnector)(expat_free((parser), (parser->m_groupConnector), 2070));
2071 // NOTE: We are avoiding FREE(..) here because parser->m_buffer
2072 // is not being allocated with MALLOC(..) but with plain
2073 // .malloc_fcn(..).
2074 parser->m_mem.free_fcn(parser->m_buffer);
2075 FREE(parser, parser->m_dataBuf)(expat_free((parser), (parser->m_dataBuf), 2075));
2076 FREE(parser, parser->m_nsAtts)(expat_free((parser), (parser->m_nsAtts), 2076));
2077 FREE(parser, parser->m_unknownEncodingMem)(expat_free((parser), (parser->m_unknownEncodingMem), 2077
))
;
2078 if (parser->m_unknownEncodingRelease)
2079 callUnknownEncodingRelease(parser);
2080 FREE(parser, parser)(expat_free((parser), (parser), 2080));
2081}
2082
2083void XMLCALL
2084XML_UseParserAsHandlerArg(XML_Parser parser) {
2085 if (parser != NULL((void*)0))
2086 parser->m_handlerArg = parser;
2087}
2088
2089/* BEGIN MOZILLA CHANGE (unused API) */
2090#if 0
2091enum XML_Error XMLCALL
2092XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) {
2093 if (parser == NULL((void*)0))
2094 return XML_ERROR_INVALID_ARGUMENT;
2095#ifdef XML_DTD
2096 /* block after XML_Parse()/XML_ParseBuffer() has been called */
2097 if (parserBusy(parser))
2098 return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
2099 parser->m_useForeignDTD = useDTD;
2100 return XML_ERROR_NONE;
2101#else
2102 UNUSED_P(useDTD)(void)useDTD;
2103 return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
2104#endif
2105}
2106#endif
2107/* END MOZILLA CHANGE */
2108
2109void XMLCALL
2110XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
2111 if (parser == NULL((void*)0))
2112 return;
2113 /* block after XML_Parse()/XML_ParseBuffer() has been called */
2114 if (parserBusy(parser))
2115 return;
2116 parser->m_ns_triplets = do_nst ? XML_TRUE((XML_Bool)1) : XML_FALSE((XML_Bool)0);
2117}
2118
2119void XMLCALL
2120XML_SetUserData(XML_Parser parser, void *p) {
2121 if (parser == NULL((void*)0))
2122 return;
2123 if (parser->m_handlerArg == parser->m_userData)
2124 parser->m_handlerArg = parser->m_userData = p;
2125 else
2126 parser->m_userData = p;
2127}
2128
2129enum XML_Status XMLCALL
2130XML_SetBase(XML_Parser parser, const XML_Char *p) {
2131 if (parser == NULL((void*)0))
2132 return XML_STATUS_ERRORXML_STATUS_ERROR;
2133 if (p) {
2134 p = poolCopyString(&parser->m_dtd->pool, p);
2135 if (! p)
2136 return XML_STATUS_ERRORXML_STATUS_ERROR;
2137 parser->m_curBase = p;
2138 } else
2139 parser->m_curBase = NULL((void*)0);
2140 return XML_STATUS_OKXML_STATUS_OK;
2141}
2142
2143const XML_Char *XMLCALL
2144XML_GetBase(XML_Parser parser) {
2145 if (parser == NULL((void*)0))
2146 return NULL((void*)0);
2147 return parser->m_curBase;
2148}
2149
2150int XMLCALL
2151XML_GetSpecifiedAttributeCount(XML_Parser parser) {
2152 if (parser == NULL((void*)0))
2153 return -1;
2154 return parser->m_nSpecifiedAtts;
2155}
2156
2157int XMLCALL
2158XML_GetIdAttributeIndex(XML_Parser parser) {
2159 if (parser == NULL((void*)0))
2160 return -1;
2161 return parser->m_idAttIndex;
2162}
2163
2164#ifdef XML_ATTR_INFO
2165const XML_AttrInfo *XMLCALL
2166XML_GetAttributeInfo(XML_Parser parser) {
2167 if (parser == NULL((void*)0))
2168 return NULL((void*)0);
2169 return parser->m_attInfo;
2170}
2171#endif
2172
2173void XMLCALL
2174XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start,
2175 XML_EndElementHandler end) {
2176 if (parser == NULL((void*)0))
2177 return;
2178 parser->m_startElementHandler = start;
2179 parser->m_endElementHandler = end;
2180}
2181
2182/* BEGIN MOZILLA CHANGE (unused API) */
2183#if 0
2184void XMLCALL
2185XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) {
2186 if (parser != NULL((void*)0))
2187 parser->m_startElementHandler = start;
2188}
2189
2190void XMLCALL
2191XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) {
2192 if (parser != NULL((void*)0))
2193 parser->m_endElementHandler = end;
2194}
2195#endif
2196/* END MOZILLA CHANGE */
2197
2198void XMLCALL
2199XML_SetCharacterDataHandler(XML_Parser parser,
2200 XML_CharacterDataHandler handler) {
2201 if (parser != NULL((void*)0))
2202 parser->m_characterDataHandler = handler;
2203}
2204
2205void XMLCALL
2206XML_SetProcessingInstructionHandler(XML_Parser parser,
2207 XML_ProcessingInstructionHandler handler) {
2208 if (parser != NULL((void*)0))
2209 parser->m_processingInstructionHandler = handler;
2210}
2211
2212void XMLCALL
2213XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) {
2214 if (parser != NULL((void*)0))
2215 parser->m_commentHandler = handler;
2216}
2217
2218void XMLCALL
2219XML_SetCdataSectionHandler(XML_Parser parser,
2220 XML_StartCdataSectionHandler start,
2221 XML_EndCdataSectionHandler end) {
2222 if (parser == NULL((void*)0))
2223 return;
2224 parser->m_startCdataSectionHandler = start;
2225 parser->m_endCdataSectionHandler = end;
2226}
2227
2228/* BEGIN MOZILLA CHANGE (unused API) */
2229#if 0
2230void XMLCALL
2231XML_SetStartCdataSectionHandler(XML_Parser parser,
2232 XML_StartCdataSectionHandler start) {
2233 if (parser != NULL((void*)0))
2234 parser->m_startCdataSectionHandler = start;
2235}
2236
2237void XMLCALL
2238XML_SetEndCdataSectionHandler(XML_Parser parser,
2239 XML_EndCdataSectionHandler end) {
2240 if (parser != NULL((void*)0))
2241 parser->m_endCdataSectionHandler = end;
2242}
2243
2244void XMLCALL
2245XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) {
2246 if (parser == NULL((void*)0))
2247 return;
2248 parser->m_defaultHandler = handler;
2249 parser->m_defaultExpandInternalEntities = XML_FALSE((XML_Bool)0);
2250}
2251#endif
2252/* END MOZILLA CHANGE */
2253
2254void XMLCALL
2255XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) {
2256 if (parser == NULL((void*)0))
2257 return;
2258 parser->m_defaultHandler = handler;
2259 parser->m_defaultExpandInternalEntities = XML_TRUE((XML_Bool)1);
2260}
2261
2262void XMLCALL
2263XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start,
2264 XML_EndDoctypeDeclHandler end) {
2265 if (parser == NULL((void*)0))
2266 return;
2267 parser->m_startDoctypeDeclHandler = start;
2268 parser->m_endDoctypeDeclHandler = end;
2269}
2270
2271/* BEGIN MOZILLA CHANGE (unused API) */
2272#if 0
2273void XMLCALL
2274XML_SetStartDoctypeDeclHandler(XML_Parser parser,
2275 XML_StartDoctypeDeclHandler start) {
2276 if (parser != NULL((void*)0))
2277 parser->m_startDoctypeDeclHandler = start;
2278}
2279
2280void XMLCALL
2281XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) {
2282 if (parser != NULL((void*)0))
2283 parser->m_endDoctypeDeclHandler = end;
2284}
2285#endif
2286/* END MOZILLA CHANGE */
2287
2288void XMLCALL
2289XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
2290 XML_UnparsedEntityDeclHandler handler) {
2291 if (parser != NULL((void*)0))
2292 parser->m_unparsedEntityDeclHandler = handler;
2293}
2294
2295void XMLCALL
2296XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) {
2297 if (parser != NULL((void*)0))
2298 parser->m_notationDeclHandler = handler;
2299}
2300
2301void XMLCALL
2302XML_SetNamespaceDeclHandler(XML_Parser parser,
2303 XML_StartNamespaceDeclHandler start,
2304 XML_EndNamespaceDeclHandler end) {
2305 if (parser == NULL((void*)0))
2306 return;
2307 parser->m_startNamespaceDeclHandler = start;
2308 parser->m_endNamespaceDeclHandler = end;
2309}
2310
2311/* BEGIN MOZILLA CHANGE (unused API) */
2312#if 0
2313void XMLCALL
2314XML_SetStartNamespaceDeclHandler(XML_Parser parser,
2315 XML_StartNamespaceDeclHandler start) {
2316 if (parser != NULL((void*)0))
2317 parser->m_startNamespaceDeclHandler = start;
2318}
2319
2320void XMLCALL
2321XML_SetEndNamespaceDeclHandler(XML_Parser parser,
2322 XML_EndNamespaceDeclHandler end) {
2323 if (parser != NULL((void*)0))
2324 parser->m_endNamespaceDeclHandler = end;
2325}
2326
2327void XMLCALL
2328XML_SetNotStandaloneHandler(XML_Parser parser,
2329 XML_NotStandaloneHandler handler) {
2330 if (parser != NULL((void*)0))
2331 parser->m_notStandaloneHandler = handler;
2332}
2333#endif
2334/* END MOZILLA CHANGE */
2335
2336void XMLCALL
2337XML_SetExternalEntityRefHandler(XML_Parser parser,
2338 XML_ExternalEntityRefHandler handler) {
2339 if (parser != NULL((void*)0))
2340 parser->m_externalEntityRefHandler = handler;
2341}
2342
2343void XMLCALL
2344XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) {
2345 if (parser == NULL((void*)0))
2346 return;
2347 if (arg)
2348 parser->m_externalEntityRefHandlerArg = (XML_Parser)arg;
2349 else
2350 parser->m_externalEntityRefHandlerArg = parser;
2351}
2352
2353/* BEGIN MOZILLA CHANGE (unused API) */
2354#if 0
2355void XMLCALL
2356XML_SetSkippedEntityHandler(XML_Parser parser,
2357 XML_SkippedEntityHandler handler) {
2358 if (parser != NULL((void*)0))
2359 parser->m_skippedEntityHandler = handler;
2360}
2361
2362void XMLCALL
2363XML_SetUnknownEncodingHandler(XML_Parser parser,
2364 XML_UnknownEncodingHandler handler, void *data) {
2365 if (parser == NULL((void*)0))
2366 return;
2367 parser->m_unknownEncodingHandler = handler;
2368 parser->m_unknownEncodingHandlerData = data;
2369}
2370
2371void XMLCALL
2372XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) {
2373 if (parser != NULL((void*)0))
2374 parser->m_elementDeclHandler = eldecl;
2375}
2376
2377void XMLCALL
2378XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) {
2379 if (parser != NULL((void*)0))
2380 parser->m_attlistDeclHandler = attdecl;
2381}
2382
2383void XMLCALL
2384XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) {
2385 if (parser != NULL((void*)0))
2386 parser->m_entityDeclHandler = handler;
2387}
2388#endif
2389/* END MOZILLA CHANGE */
2390
2391void XMLCALL
2392XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) {
2393 if (parser != NULL((void*)0))
2394 parser->m_xmlDeclHandler = handler;
2395}
2396
2397int XMLCALL
2398XML_SetParamEntityParsing(XML_Parser parser,
2399 enum XML_ParamEntityParsing peParsing) {
2400 if (parser == NULL((void*)0))
2401 return 0;
2402 /* block after XML_Parse()/XML_ParseBuffer() has been called */
2403 if (parserBusy(parser))
2404 return 0;
2405#ifdef XML_DTD
2406 parser->m_paramEntityParsing = peParsing;
2407 return 1;
2408#else
2409 return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
2410#endif
2411}
2412
2413// DEPRECATED since Expat 2.8.0.
2414int XMLCALL
2415XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) {
2416 if (parser == NULL((void*)0))
2417 return 0;
2418
2419 const XML_Parser rootParser = getRootParserOf(parser, NULL((void*)0));
2420 assert(! rootParser->m_parentParser)((void) sizeof ((! rootParser->m_parentParser) ? 1 : 0), __extension__
({ if (! rootParser->m_parentParser) ; else __assert_fail
("! rootParser->m_parentParser", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 2420, __extension__ __PRETTY_FUNCTION__); }))
;
2421
2422 /* block after XML_Parse()/XML_ParseBuffer() has been called */
2423 if (parserBusy(rootParser))
2424 return 0;
2425
2426 rootParser->m_hash_secret_salt_128.k[0] = 0;
2427 rootParser->m_hash_secret_salt_128.k[1] = hash_salt;
2428
2429 if (hash_salt != 0) { // to remain backwards compatible
2430 rootParser->m_hash_secret_salt_set = XML_TRUE((XML_Bool)1);
2431
2432 if (sizeof(unsigned long) == 4)
2433 ENTROPY_DEBUG("explicit(4)", rootParser->m_hash_secret_salt_128);
2434 else
2435 ENTROPY_DEBUG("explicit(8)", rootParser->m_hash_secret_salt_128);
2436 }
2437
2438 return 1;
2439}
2440
2441XML_Bool XMLCALL
2442XML_SetHashSalt16Bytes(XML_Parser parser, const uint8_t entropy[16]) {
2443 if (parser == NULL((void*)0))
2444 return XML_FALSE((XML_Bool)0);
2445
2446 if (entropy == NULL((void*)0))
2447 return XML_FALSE((XML_Bool)0);
2448
2449 const XML_Parser rootParser = getRootParserOf(parser, NULL((void*)0));
2450 assert(! rootParser->m_parentParser)((void) sizeof ((! rootParser->m_parentParser) ? 1 : 0), __extension__
({ if (! rootParser->m_parentParser) ; else __assert_fail
("! rootParser->m_parentParser", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 2450, __extension__ __PRETTY_FUNCTION__); }))
;
2451
2452 /* block after XML_Parse()/XML_ParseBuffer() has been called */
2453 if (parserBusy(rootParser))
2454 return XML_FALSE((XML_Bool)0);
2455
2456 sip_tokey(&(rootParser->m_hash_secret_salt_128), entropy);
2457
2458 rootParser->m_hash_secret_salt_set = XML_TRUE((XML_Bool)1);
2459
2460 ENTROPY_DEBUG("explicit(16)", rootParser->m_hash_secret_salt_128);
2461
2462 return XML_TRUE((XML_Bool)1);
2463}
2464
2465enum XML_Status XMLCALL
2466XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) {
2467 if ((parser == NULL((void*)0)) || (len < 0) || ((s == NULL((void*)0)) && (len != 0))) {
2468 if (parser != NULL((void*)0))
2469 parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
2470 return XML_STATUS_ERRORXML_STATUS_ERROR;
2471 }
2472 if (isCalledFromInsideHandler(parser))
2473 return XML_STATUS_ERRORXML_STATUS_ERROR;
2474 switch (parser->m_parsingStatus.parsing) {
2475 case XML_SUSPENDED:
2476 parser->m_errorCode = XML_ERROR_SUSPENDED;
2477 return XML_STATUS_ERRORXML_STATUS_ERROR;
2478 case XML_FINISHED:
2479 parser->m_errorCode = XML_ERROR_FINISHED;
2480 return XML_STATUS_ERRORXML_STATUS_ERROR;
2481 case XML_INITIALIZED:
2482 if (parser->m_parentParser == NULL((void*)0) && ! startParsing(parser)) {
2483 parser->m_errorCode = XML_ERROR_NO_MEMORY;
2484 return XML_STATUS_ERRORXML_STATUS_ERROR;
2485 }
2486 EXPAT_FALLTHROUGH__attribute__((fallthrough));
2487 default:
2488 parser->m_parsingStatus.parsing = XML_PARSING;
2489 }
2490
2491#if XML_CONTEXT_BYTES0 == 0
2492 if (parser->m_bufferPtr == parser->m_bufferEnd) {
2493 const char *end;
2494 int nLeftOver;
2495 enum XML_Status result;
2496 /* Detect overflow (a+b > MAX <==> b > MAX-a) */
2497 if ((uint64_t)len > UINT64_MAX(18446744073709551615UL) - parser->m_parseEndByteIndex) {
2498 parser->m_errorCode = XML_ERROR_NO_MEMORY;
2499 parser->m_eventPtr = parser->m_eventEndPtr = NULL((void*)0);
2500 parser->m_processor = errorProcessor;
2501 return XML_STATUS_ERRORXML_STATUS_ERROR;
2502 }
2503 // though this isn't a buffer request, we assume that `len` is the app's
2504 // preferred buffer fill size, and therefore save it here.
2505 parser->m_lastBufferRequestSize = len;
2506 parser->m_parseEndByteIndex += len;
2507 parser->m_positionPtr = s;
2508 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
2509
2510 parser->m_errorCode
2511 = callProcessor(parser, s, parser->m_parseEndPtr = s + len, &end);
2512
2513 if (parser->m_errorCode != XML_ERROR_NONE) {
2514 parser->m_eventEndPtr = parser->m_eventPtr;
2515 parser->m_processor = errorProcessor;
2516 return XML_STATUS_ERRORXML_STATUS_ERROR;
2517 } else {
2518 switch (parser->m_parsingStatus.parsing) {
2519 case XML_SUSPENDED:
2520 result = XML_STATUS_SUSPENDEDXML_STATUS_SUSPENDED;
2521 break;
2522 case XML_INITIALIZED:
2523 case XML_PARSING:
2524 if (isFinal) {
2525 parser->m_parsingStatus.parsing = XML_FINISHED;
2526 return XML_STATUS_OKXML_STATUS_OK;
2527 }
2528 EXPAT_FALLTHROUGH__attribute__((fallthrough));
2529 default:
2530 result = XML_STATUS_OKXML_STATUS_OK;
2531 }
2532 }
2533
2534 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr, end,(((parser->m_encoding)->updatePosition)(parser->m_encoding
, parser->m_positionPtr, end, &parser->m_position))
2535 &parser->m_position)(((parser->m_encoding)->updatePosition)(parser->m_encoding
, parser->m_positionPtr, end, &parser->m_position))
;
2536 nLeftOver = s + len - end;
2537 if (nLeftOver) {
2538 // Back up and restore the parsing status to avoid XML_ERROR_SUSPENDED
2539 // (and XML_ERROR_FINISHED) from XML_GetBuffer.
2540 const enum XML_Parsing originalStatus = parser->m_parsingStatus.parsing;
2541 parser->m_parsingStatus.parsing = XML_PARSING;
2542 void *const temp = XML_GetBuffer(parser, nLeftOver);
2543 parser->m_parsingStatus.parsing = originalStatus;
2544 // GetBuffer may have overwritten this, but we want to remember what the
2545 // app requested, not how many bytes were left over after parsing.
2546 parser->m_lastBufferRequestSize = len;
2547 if (temp == NULL((void*)0)) {
2548 // NOTE: parser->m_errorCode has already been set by XML_GetBuffer().
2549 parser->m_eventPtr = parser->m_eventEndPtr = NULL((void*)0);
2550 parser->m_processor = errorProcessor;
2551 return XML_STATUS_ERRORXML_STATUS_ERROR;
2552 }
2553 // Since we know that the buffer was empty and XML_CONTEXT_BYTES is 0, we
2554 // don't have any data to preserve, and can copy straight into the start
2555 // of the buffer rather than the GetBuffer return pointer (which may be
2556 // pointing further into the allocated buffer).
2557 memcpy(parser->m_buffer, end, nLeftOver);
2558 }
2559 parser->m_bufferPtr = parser->m_buffer;
2560 parser->m_bufferEnd = parser->m_buffer + nLeftOver;
2561 parser->m_positionPtr = parser->m_bufferPtr;
2562 parser->m_parseEndPtr = parser->m_bufferEnd;
2563 parser->m_eventPtr = parser->m_bufferPtr;
2564 parser->m_eventEndPtr = parser->m_bufferPtr;
2565 return result;
2566 }
2567#endif /* XML_CONTEXT_BYTES == 0 */
2568 void *buff = XML_GetBuffer(parser, len);
2569 if (buff == NULL((void*)0))
2570 return XML_STATUS_ERRORXML_STATUS_ERROR;
2571 if (len > 0) {
2572 assert(s != NULL)((void) sizeof ((s != ((void*)0)) ? 1 : 0), __extension__ ({ if
(s != ((void*)0)) ; else __assert_fail ("s != NULL", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 2572, __extension__ __PRETTY_FUNCTION__); }))
; // make sure s==NULL && len!=0 was rejected above
2573 memcpy(buff, s, len);
2574 }
2575 return XML_ParseBuffer(parser, len, isFinal);
2576}
2577
2578enum XML_Status XMLCALL
2579XML_ParseBuffer(XML_Parser parser, int len, int isFinal) {
2580 const char *start;
2581 enum XML_Status result = XML_STATUS_OKXML_STATUS_OK;
2582
2583 if ((parser == NULL((void*)0)) || isCalledFromInsideHandler(parser))
2584 return XML_STATUS_ERRORXML_STATUS_ERROR;
2585
2586 if (len < 0) {
2587 parser->m_errorCode = XML_ERROR_INVALID_ARGUMENT;
2588 return XML_STATUS_ERRORXML_STATUS_ERROR;
2589 }
2590
2591 switch (parser->m_parsingStatus.parsing) {
2592 case XML_SUSPENDED:
2593 parser->m_errorCode = XML_ERROR_SUSPENDED;
2594 return XML_STATUS_ERRORXML_STATUS_ERROR;
2595 case XML_FINISHED:
2596 parser->m_errorCode = XML_ERROR_FINISHED;
2597 return XML_STATUS_ERRORXML_STATUS_ERROR;
2598 case XML_INITIALIZED:
2599 /* Has someone called XML_GetBuffer successfully before? */
2600 if (! parser->m_bufferPtr) {
2601 parser->m_errorCode = XML_ERROR_NO_BUFFER;
2602 return XML_STATUS_ERRORXML_STATUS_ERROR;
2603 }
2604
2605 if (parser->m_parentParser == NULL((void*)0) && ! startParsing(parser)) {
2606 parser->m_errorCode = XML_ERROR_NO_MEMORY;
2607 return XML_STATUS_ERRORXML_STATUS_ERROR;
2608 }
2609 EXPAT_FALLTHROUGH__attribute__((fallthrough));
2610 default:
2611 parser->m_parsingStatus.parsing = XML_PARSING;
2612 }
2613
2614 // Detect and avoid integer overflow
2615 if ((uint64_t)len > UINT64_MAX(18446744073709551615UL) - parser->m_parseEndByteIndex) {
2616 parser->m_errorCode = XML_ERROR_NO_MEMORY;
2617 parser->m_eventPtr = parser->m_eventEndPtr = NULL((void*)0);
2618 parser->m_processor = errorProcessor;
2619 return XML_STATUS_ERRORXML_STATUS_ERROR;
2620 }
2621
2622 start = parser->m_bufferPtr;
2623 parser->m_positionPtr = start;
2624 parser->m_bufferEnd += len;
2625 parser->m_parseEndPtr = parser->m_bufferEnd;
2626 parser->m_parseEndByteIndex += len;
2627 parser->m_parsingStatus.finalBuffer = (XML_Bool)isFinal;
2628
2629 parser->m_errorCode = callProcessor(parser, start, parser->m_parseEndPtr,
2630 &parser->m_bufferPtr);
2631
2632 if (parser->m_errorCode != XML_ERROR_NONE) {
2633 parser->m_eventEndPtr = parser->m_eventPtr;
2634 parser->m_processor = errorProcessor;
2635 return XML_STATUS_ERRORXML_STATUS_ERROR;
2636 } else {
2637 switch (parser->m_parsingStatus.parsing) {
2638 case XML_SUSPENDED:
2639 result = XML_STATUS_SUSPENDEDXML_STATUS_SUSPENDED;
2640 break;
2641 case XML_INITIALIZED:
2642 case XML_PARSING:
2643 if (isFinal) {
2644 parser->m_parsingStatus.parsing = XML_FINISHED;
2645 return result;
2646 }
2647 break;
2648 default:; /* should not happen */
2649 }
2650 }
2651
2652 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,(((parser->m_encoding)->updatePosition)(parser->m_encoding
, parser->m_positionPtr, parser->m_bufferPtr, &parser
->m_position))
2653 parser->m_bufferPtr, &parser->m_position)(((parser->m_encoding)->updatePosition)(parser->m_encoding
, parser->m_positionPtr, parser->m_bufferPtr, &parser
->m_position))
;
2654 parser->m_positionPtr = parser->m_bufferPtr;
2655/* BEGIN MOZILLA CHANGE (always set m_eventPtr/m_eventEndPtr) */
2656 parser->m_eventPtr = parser->m_bufferPtr;
2657 parser->m_eventEndPtr = parser->m_bufferPtr;
2658/* END MOZILLA CHANGE */
2659 return result;
2660}
2661
2662/* Modifies `parser`’s buffer to be backed by `newBuf`. */
2663static void
2664setParserBuffer(XML_Parser parser, char *newBuf, int newBufSize, int keep) {
2665 parser->m_bufferLim = newBuf + newBufSize;
2666 if (parser->m_bufferPtr) {
2667 const int parsing
2668 = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)(((parser->m_bufferEnd) && (parser->m_bufferPtr
)) ? ((parser->m_bufferEnd) - (parser->m_bufferPtr)) : 0
)
;
2669 memcpy(newBuf, parser->m_bufferPtr - keep, parsing + keep);
2670 // NOTE: We are avoiding FREE(..) here because parser->m_buffer
2671 // is not being allocated with MALLOC(..) but with plain
2672 // .malloc_fcn(..).
2673 parser->m_mem.free_fcn(parser->m_buffer);
2674 parser->m_buffer = newBuf;
2675 parser->m_bufferEnd = newBuf + parsing + keep;
2676 parser->m_bufferPtr = newBuf + keep;
2677 } else {
2678 /* This must be a brand new buffer with no data in it yet */
2679 parser->m_buffer = newBuf;
2680 parser->m_bufferEnd = newBuf;
2681 parser->m_bufferPtr = newBuf;
2682 }
2683}
2684
2685void *XMLCALL
2686XML_GetBuffer(XML_Parser parser, int len) {
2687 if ((parser == NULL((void*)0)) || isCalledFromInsideHandler(parser))
2688 return NULL((void*)0);
2689 if (len < 0) {
2690 parser->m_errorCode = XML_ERROR_NO_MEMORY;
2691 return NULL((void*)0);
2692 }
2693 switch (parser->m_parsingStatus.parsing) {
2694 case XML_SUSPENDED:
2695 parser->m_errorCode = XML_ERROR_SUSPENDED;
2696 return NULL((void*)0);
2697 case XML_FINISHED:
2698 parser->m_errorCode = XML_ERROR_FINISHED;
2699 return NULL((void*)0);
2700 default:;
2701 }
2702
2703 // whether or not the request succeeds, `len` seems to be the app's preferred
2704 // buffer fill size; remember it.
2705 parser->m_lastBufferRequestSize = len;
2706 if (len > EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_bufferEnd)(((parser->m_bufferLim) && (parser->m_bufferEnd
)) ? ((parser->m_bufferLim) - (parser->m_bufferEnd)) : 0
)
2707 || parser->m_buffer == NULL((void*)0)) {
2708 /* Do not invoke signed arithmetic overflow: */
2709 int neededSize = (int)((unsigned)len
2710 + (unsigned)EXPAT_SAFE_PTR_DIFF((((parser->m_bufferEnd) && (parser->m_bufferPtr
)) ? ((parser->m_bufferEnd) - (parser->m_bufferPtr)) : 0
)
2711 parser->m_bufferEnd, parser->m_bufferPtr)(((parser->m_bufferEnd) && (parser->m_bufferPtr
)) ? ((parser->m_bufferEnd) - (parser->m_bufferPtr)) : 0
)
);
2712 if (neededSize < 0) {
2713 parser->m_errorCode = XML_ERROR_NO_MEMORY;
2714 return NULL((void*)0);
2715 }
2716#if XML_CONTEXT_BYTES0 > 0
2717 const int parsed
2718 = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferPtr, parser->m_buffer)(((parser->m_bufferPtr) && (parser->m_buffer)) ?
((parser->m_bufferPtr) - (parser->m_buffer)) : 0)
;
2719 int keep = parsed;
2720 if (keep > XML_CONTEXT_BYTES0)
2721 keep = XML_CONTEXT_BYTES0;
2722 /* Detect and prevent integer overflow */
2723 if (keep > INT_MAX2147483647 - neededSize) {
2724 parser->m_errorCode = XML_ERROR_NO_MEMORY;
2725 return NULL((void*)0);
2726 }
2727#else
2728 int keep = 0;
2729#endif /* XML_CONTEXT_BYTES > 0 */
2730 neededSize += keep;
2731 if (parser->m_buffer && parser->m_bufferPtr
2732 && neededSize
2733 <= EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)(((parser->m_bufferLim) && (parser->m_buffer)) ?
((parser->m_bufferLim) - (parser->m_buffer)) : 0)
) {
2734#if XML_CONTEXT_BYTES0 > 0
2735 if (keep < parsed) {
2736 int offset = parsed - keep;
2737 /* The buffer pointers cannot be NULL here; we have at least some bytes
2738 * in the buffer */
2739 memmove(parser->m_buffer, &parser->m_buffer[offset],
2740 parser->m_bufferEnd - parser->m_bufferPtr + keep);
2741 parser->m_bufferEnd -= offset;
2742 parser->m_bufferPtr -= offset;
2743 }
2744#else
2745 memmove(parser->m_buffer, parser->m_bufferPtr,
2746 EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)(((parser->m_bufferEnd) && (parser->m_bufferPtr
)) ? ((parser->m_bufferEnd) - (parser->m_bufferPtr)) : 0
)
);
2747 parser->m_bufferEnd
2748 = parser->m_buffer
2749 + EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)(((parser->m_bufferEnd) && (parser->m_bufferPtr
)) ? ((parser->m_bufferEnd) - (parser->m_bufferPtr)) : 0
)
;
2750 parser->m_bufferPtr = parser->m_buffer;
2751#endif /* XML_CONTEXT_BYTES > 0 */
2752 } else {
2753 int bufferSize
2754 = (int)EXPAT_SAFE_PTR_DIFF(parser->m_bufferLim, parser->m_buffer)(((parser->m_bufferLim) && (parser->m_buffer)) ?
((parser->m_bufferLim) - (parser->m_buffer)) : 0)
;
2755 if (bufferSize == 0)
2756 bufferSize = INIT_BUFFER_SIZE1024;
2757 do {
2758 /* Do not invoke signed arithmetic overflow: */
2759 bufferSize = (int)(2U * (unsigned)bufferSize);
2760 } while (bufferSize < neededSize && bufferSize > 0);
2761 if (bufferSize <= 0) {
2762 parser->m_errorCode = XML_ERROR_NO_MEMORY;
2763 return NULL((void*)0);
2764 }
2765 // NOTE: We are avoiding MALLOC(..) here to leave limiting
2766 // the input size to the application using Expat.
2767 char *const newBuf = parser->m_mem.malloc_fcn(bufferSize);
2768 if (newBuf == NULL((void*)0)) {
2769 parser->m_errorCode = XML_ERROR_NO_MEMORY;
2770 return NULL((void*)0);
2771 }
2772 setParserBuffer(parser, newBuf, bufferSize, keep);
2773 }
2774 parser->m_eventPtr = parser->m_eventEndPtr = NULL((void*)0);
2775 parser->m_positionPtr = NULL((void*)0);
2776 }
2777 return parser->m_bufferEnd;
2778}
2779
2780static void
2781triggerReenter(XML_Parser parser) {
2782 parser->m_reenter = XML_TRUE((XML_Bool)1);
2783}
2784
2785enum XML_Status XMLCALL
2786XML_StopParser(XML_Parser parser, XML_Bool resumable) {
2787 if (parser == NULL((void*)0))
2788 return XML_STATUS_ERRORXML_STATUS_ERROR;
2789 switch (parser->m_parsingStatus.parsing) {
2790 case XML_INITIALIZED:
2791 parser->m_errorCode = XML_ERROR_NOT_STARTED;
2792 return XML_STATUS_ERRORXML_STATUS_ERROR;
2793 case XML_SUSPENDED:
2794 if (resumable) {
2795 parser->m_errorCode = XML_ERROR_SUSPENDED;
2796 return XML_STATUS_ERRORXML_STATUS_ERROR;
2797 }
2798 parser->m_parsingStatus.parsing = XML_FINISHED;
2799 break;
2800 case XML_FINISHED:
2801 parser->m_errorCode = XML_ERROR_FINISHED;
2802 return XML_STATUS_ERRORXML_STATUS_ERROR;
2803 case XML_PARSING:
2804 if (resumable) {
2805#ifdef XML_DTD
2806 if (parser->m_isParamEntity) {
2807 parser->m_errorCode = XML_ERROR_SUSPEND_PE;
2808 return XML_STATUS_ERRORXML_STATUS_ERROR;
2809 }
2810#endif
2811 parser->m_parsingStatus.parsing = XML_SUSPENDED;
2812 } else
2813 parser->m_parsingStatus.parsing = XML_FINISHED;
2814 break;
2815 default:
2816 assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 2816, __extension__ __PRETTY_FUNCTION__); }))
;
2817 }
2818 return XML_STATUS_OKXML_STATUS_OK;
2819}
2820
2821enum XML_Status XMLCALL
2822XML_ResumeParser(XML_Parser parser) {
2823 enum XML_Status result = XML_STATUS_OKXML_STATUS_OK;
2824
2825 if ((parser == NULL((void*)0)) || isCalledFromInsideHandler(parser))
2826 return XML_STATUS_ERRORXML_STATUS_ERROR;
2827 if (parser->m_parsingStatus.parsing != XML_SUSPENDED) {
2828 parser->m_errorCode = XML_ERROR_NOT_SUSPENDED;
2829 return XML_STATUS_ERRORXML_STATUS_ERROR;
2830 }
2831 parser->m_parsingStatus.parsing = XML_PARSING;
2832
2833 parser->m_errorCode = callProcessor(
2834 parser, parser->m_bufferPtr, parser->m_parseEndPtr, &parser->m_bufferPtr);
2835
2836 if (parser->m_errorCode != XML_ERROR_NONE) {
2837 parser->m_eventEndPtr = parser->m_eventPtr;
2838 parser->m_processor = errorProcessor;
2839 return XML_STATUS_ERRORXML_STATUS_ERROR;
2840 } else {
2841 switch (parser->m_parsingStatus.parsing) {
2842 case XML_SUSPENDED:
2843 result = XML_STATUS_SUSPENDEDXML_STATUS_SUSPENDED;
2844 break;
2845 case XML_INITIALIZED:
2846 case XML_PARSING:
2847 if (parser->m_parsingStatus.finalBuffer) {
2848 parser->m_parsingStatus.parsing = XML_FINISHED;
2849 return result;
2850 }
2851 break;
2852 default:;
2853 }
2854 }
2855
2856 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,(((parser->m_encoding)->updatePosition)(parser->m_encoding
, parser->m_positionPtr, parser->m_bufferPtr, &parser
->m_position))
2857 parser->m_bufferPtr, &parser->m_position)(((parser->m_encoding)->updatePosition)(parser->m_encoding
, parser->m_positionPtr, parser->m_bufferPtr, &parser
->m_position))
;
2858 parser->m_positionPtr = parser->m_bufferPtr;
2859 return result;
2860}
2861
2862void XMLCALL
2863XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) {
2864 if (parser == NULL((void*)0))
2865 return;
2866 assert(status != NULL)((void) sizeof ((status != ((void*)0)) ? 1 : 0), __extension__
({ if (status != ((void*)0)) ; else __assert_fail ("status != NULL"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 2866
, __extension__ __PRETTY_FUNCTION__); }))
;
2867 *status = parser->m_parsingStatus;
2868}
2869
2870enum XML_Error XMLCALL
2871XML_GetErrorCode(XML_Parser parser) {
2872 if (parser == NULL((void*)0))
2873 return XML_ERROR_INVALID_ARGUMENT;
2874 return parser->m_errorCode;
2875}
2876
2877XML_Index XMLCALL
2878XML_GetCurrentByteIndex(XML_Parser parser) {
2879 if (parser == NULL((void*)0))
2880 return -1;
2881 if (parser->m_eventPtr) {
2882 // NOTE: XML_Index is known to wrap around for >2 GiB content
2883 // on 32bit machines and 64bit Windows, unless (non-default and
2884 // uncommon) XML_LARGE_SIZE is defined.
2885 // That's a bug and it only lives on because we cannot break
2886 // ABI compatibility of public API.
2887 return (XML_Index)(parser->m_parseEndByteIndex
2888 - (parser->m_parseEndPtr - parser->m_eventPtr));
2889 }
2890/* BEGIN MOZILLA CHANGE (fix XML_GetCurrentByteIndex) */
2891#if 0
2892 return -1;
2893#else
2894 return (XML_Index)parser->m_parseEndByteIndex;
2895#endif
2896/* END MOZILLA CHANGE */
2897}
2898
2899/* BEGIN MOZILLA CHANGE (unused API) */
2900#if 0
2901int XMLCALL
2902XML_GetCurrentByteCount(XML_Parser parser) {
2903 if (parser == NULL((void*)0))
2904 return 0;
2905 if (parser->m_eventEndPtr && parser->m_eventPtr)
2906 return (int)(parser->m_eventEndPtr - parser->m_eventPtr);
2907 return 0;
2908}
2909
2910const char *XMLCALL
2911XML_GetInputContext(XML_Parser parser, int *offset, int *size) {
2912#if XML_CONTEXT_BYTES0 > 0
2913 if (parser == NULL((void*)0))
2914 return NULL((void*)0);
2915 if (parser->m_eventPtr && parser->m_buffer) {
2916 if (offset != NULL((void*)0))
2917 *offset = (int)(parser->m_eventPtr - parser->m_buffer);
2918 if (size != NULL((void*)0))
2919 *size = (int)(parser->m_bufferEnd - parser->m_buffer);
2920 return parser->m_buffer;
2921 }
2922#else
2923 (void)parser;
2924 (void)offset;
2925 (void)size;
2926#endif /* XML_CONTEXT_BYTES > 0 */
2927 return NULL((void*)0);
2928}
2929#endif
2930/* END MOZILLA CHANGE */
2931
2932XML_Size XMLCALL
2933XML_GetCurrentLineNumber(XML_Parser parser) {
2934 if (parser == NULL((void*)0))
2935 return 0;
2936 if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
2937 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,(((parser->m_encoding)->updatePosition)(parser->m_encoding
, parser->m_positionPtr, parser->m_eventPtr, &parser
->m_position))
2938 parser->m_eventPtr, &parser->m_position)(((parser->m_encoding)->updatePosition)(parser->m_encoding
, parser->m_positionPtr, parser->m_eventPtr, &parser
->m_position))
;
2939 parser->m_positionPtr = parser->m_eventPtr;
2940 }
2941 // NOTE: XML_Size is known to wrap around for >4 GiB content
2942 // on 32bit machines and 64bit Windows, unless (non-default and
2943 // uncommon) XML_LARGE_SIZE is defined.
2944 // That's a bug and it only lives on because we cannot break
2945 // ABI compatibility of public API.
2946 return (XML_Size)(parser->m_position.lineNumber + 1);
2947}
2948
2949XML_Size XMLCALL
2950XML_GetCurrentColumnNumber(XML_Parser parser) {
2951 if (parser == NULL((void*)0))
2952 return 0;
2953 if (parser->m_eventPtr && parser->m_eventPtr >= parser->m_positionPtr) {
2954 XmlUpdatePosition(parser->m_encoding, parser->m_positionPtr,(((parser->m_encoding)->updatePosition)(parser->m_encoding
, parser->m_positionPtr, parser->m_eventPtr, &parser
->m_position))
2955 parser->m_eventPtr, &parser->m_position)(((parser->m_encoding)->updatePosition)(parser->m_encoding
, parser->m_positionPtr, parser->m_eventPtr, &parser
->m_position))
;
2956 parser->m_positionPtr = parser->m_eventPtr;
2957 }
2958 // NOTE: XML_Size is known to wrap around for >4 GiB content
2959 // on 32bit machines and 64bit Windows, unless (non-default and
2960 // uncommon) XML_LARGE_SIZE is defined.
2961 // That's a bug and it only lives on because we cannot break
2962 // ABI compatibility of public API.
2963 return (XML_Size)parser->m_position.columnNumber;
2964}
2965
2966/* BEGIN MOZILLA CHANGE (unused API) */
2967#if 0
2968void XMLCALL
2969XML_FreeContentModel(XML_Parser parser, XML_Content *model) {
2970 if (parser == NULL((void*)0))
2971 return;
2972
2973 // NOTE: We are avoiding FREE(..) here because the content model
2974 // has been created using plain .malloc_fcn(..) rather than MALLOC(..).
2975 parser->m_mem.free_fcn(model);
2976}
2977
2978void *XMLCALL
2979XML_MemMalloc(XML_Parser parser, size_t size) {
2980 if (parser == NULL((void*)0))
2981 return NULL((void*)0);
2982
2983 // NOTE: We are avoiding MALLOC(..) here to not include
2984 // user allocations with allocation tracking and limiting.
2985 return parser->m_mem.malloc_fcn(size);
2986}
2987
2988void *XMLCALL
2989XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) {
2990 if (parser == NULL((void*)0))
2991 return NULL((void*)0);
2992
2993 // NOTE: We are avoiding REALLOC(..) here to not include
2994 // user allocations with allocation tracking and limiting.
2995 return parser->m_mem.realloc_fcn(ptr, size);
2996}
2997
2998void XMLCALL
2999XML_MemFree(XML_Parser parser, void *ptr) {
3000 if (parser == NULL((void*)0))
3001 return;
3002
3003 // NOTE: We are avoiding FREE(..) here because XML_MemMalloc and
3004 // XML_MemRealloc are not using MALLOC(..) and REALLOC(..)
3005 // but plain .malloc_fcn(..) and .realloc_fcn(..), internally.
3006 parser->m_mem.free_fcn(ptr);
3007}
3008
3009void XMLCALL
3010XML_DefaultCurrent(XML_Parser parser) {
3011 if (parser == NULL((void*)0))
3012 return;
3013 if (parser->m_defaultHandler) {
3014 if (parser->m_openInternalEntities)
3015 reportDefault(parser, parser->m_internalEncoding,
3016 parser->m_openInternalEntities->internalEventPtr,
3017 parser->m_openInternalEntities->internalEventEndPtr);
3018 else
3019 reportDefault(parser, parser->m_encoding, parser->m_eventPtr,
3020 parser->m_eventEndPtr);
3021 }
3022}
3023
3024const XML_LChar *XMLCALL
3025XML_ErrorString(enum XML_Error code) {
3026 switch (code) {
3027 case XML_ERROR_NONE:
3028 return NULL((void*)0);
3029 case XML_ERROR_NO_MEMORY:
3030 return XML_L("out of memory");
3031 case XML_ERROR_SYNTAX:
3032 return XML_L("syntax error");
3033 case XML_ERROR_NO_ELEMENTS:
3034 return XML_L("no element found");
3035 case XML_ERROR_INVALID_TOKEN:
3036 return XML_L("not well-formed (invalid token)");
3037 case XML_ERROR_UNCLOSED_TOKEN:
3038 return XML_L("unclosed token");
3039 case XML_ERROR_PARTIAL_CHAR:
3040 return XML_L("partial character");
3041 case XML_ERROR_TAG_MISMATCH:
3042 return XML_L("mismatched tag");
3043 case XML_ERROR_DUPLICATE_ATTRIBUTE:
3044 return XML_L("duplicate attribute");
3045 case XML_ERROR_JUNK_AFTER_DOC_ELEMENT:
3046 return XML_L("junk after document element");
3047 case XML_ERROR_PARAM_ENTITY_REF:
3048 return XML_L("illegal parameter entity reference");
3049 case XML_ERROR_UNDEFINED_ENTITY:
3050 return XML_L("undefined entity");
3051 case XML_ERROR_RECURSIVE_ENTITY_REF:
3052 return XML_L("recursive entity reference");
3053 case XML_ERROR_ASYNC_ENTITY:
3054 return XML_L("asynchronous entity");
3055 case XML_ERROR_BAD_CHAR_REF:
3056 return XML_L("reference to invalid character number");
3057 case XML_ERROR_BINARY_ENTITY_REF:
3058 return XML_L("reference to binary entity");
3059 case XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF:
3060 return XML_L("reference to external entity in attribute");
3061 case XML_ERROR_MISPLACED_XML_PI:
3062 return XML_L("XML or text declaration not at start of entity");
3063 case XML_ERROR_UNKNOWN_ENCODING:
3064 return XML_L("unknown encoding");
3065 case XML_ERROR_INCORRECT_ENCODING:
3066 return XML_L("encoding specified in XML declaration is incorrect");
3067 case XML_ERROR_UNCLOSED_CDATA_SECTION:
3068 return XML_L("unclosed CDATA section");
3069 case XML_ERROR_EXTERNAL_ENTITY_HANDLING:
3070 return XML_L("error in processing external entity reference");
3071 case XML_ERROR_NOT_STANDALONE:
3072 return XML_L("document is not standalone");
3073 case XML_ERROR_UNEXPECTED_STATE:
3074 return XML_L("unexpected parser state - please send a bug report");
3075 case XML_ERROR_ENTITY_DECLARED_IN_PE:
3076 return XML_L("entity declared in parameter entity");
3077 case XML_ERROR_FEATURE_REQUIRES_XML_DTD:
3078 return XML_L("requested feature requires XML_DTD support in Expat");
3079 case XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING:
3080 return XML_L("cannot change setting once parsing has begun");
3081 /* Added in 1.95.7. */
3082 case XML_ERROR_UNBOUND_PREFIX:
3083 return XML_L("unbound prefix");
3084 /* Added in 1.95.8. */
3085 case XML_ERROR_UNDECLARING_PREFIX:
3086 return XML_L("must not undeclare prefix");
3087 case XML_ERROR_INCOMPLETE_PE:
3088 return XML_L("incomplete markup in parameter entity");
3089 case XML_ERROR_XML_DECL:
3090 return XML_L("XML declaration not well-formed");
3091 case XML_ERROR_TEXT_DECL:
3092 return XML_L("text declaration not well-formed");
3093 case XML_ERROR_PUBLICID:
3094 return XML_L("illegal character(s) in public id");
3095 case XML_ERROR_SUSPENDED:
3096 return XML_L("parser suspended");
3097 case XML_ERROR_NOT_SUSPENDED:
3098 return XML_L("parser not suspended");
3099 case XML_ERROR_ABORTED:
3100 return XML_L("parsing aborted");
3101 case XML_ERROR_FINISHED:
3102 return XML_L("parsing finished");
3103 case XML_ERROR_SUSPEND_PE:
3104 return XML_L("cannot suspend in external parameter entity");
3105 /* Added in 2.0.0. */
3106 case XML_ERROR_RESERVED_PREFIX_XML:
3107 return XML_L(
3108 "reserved prefix (xml) must not be undeclared or bound to another namespace name");
3109 case XML_ERROR_RESERVED_PREFIX_XMLNS:
3110 return XML_L("reserved prefix (xmlns) must not be declared or undeclared");
3111 case XML_ERROR_RESERVED_NAMESPACE_URI:
3112 return XML_L(
3113 "prefix must not be bound to one of the reserved namespace names");
3114 /* Added in 2.2.5. */
3115 case XML_ERROR_INVALID_ARGUMENT: /* Constant added in 2.2.1, already */
3116 return XML_L("invalid argument");
3117 /* Added in 2.3.0. */
3118 case XML_ERROR_NO_BUFFER:
3119 return XML_L(
3120 "a successful prior call to function XML_GetBuffer is required");
3121 /* Added in 2.4.0. */
3122 case XML_ERROR_AMPLIFICATION_LIMIT_BREACH:
3123 return XML_L(
3124 "limit on input amplification factor (from DTD and entities) breached");
3125 /* Added in 2.6.4. */
3126 case XML_ERROR_NOT_STARTED:
3127 return XML_L("parser not started");
3128 }
3129 return NULL((void*)0);
3130}
3131
3132const XML_LChar *XMLCALL
3133XML_ExpatVersion(void) {
3134 /* V1 is used to string-ize the version number. However, it would
3135 string-ize the actual version macro *names* unless we get them
3136 substituted before being passed to V1. CPP is defined to expand
3137 a macro, then rescan for more expansions. Thus, we use V2 to expand
3138 the version macros, then CPP will expand the resulting V1() macro
3139 with the correct numerals. */
3140 /* ### I'm assuming cpp is portable in this respect... */
3141
3142#define V1(a, b, c) XML_L(#a) XML_L(".") XML_L(#b) XML_L(".") XML_L(#c)
3143#define V2(a, b, c) XML_L("expat_") V1(a, b, c)
3144
3145 return V2(XML_MAJOR_VERSION2, XML_MINOR_VERSION8, XML_MICRO_VERSION4);
3146
3147#undef V1
3148#undef V2
3149}
3150
3151XML_Expat_Version XMLCALL
3152XML_ExpatVersionInfo(void) {
3153 XML_Expat_Version version;
3154
3155 version.major = XML_MAJOR_VERSION2;
3156 version.minor = XML_MINOR_VERSION8;
3157 version.micro = XML_MICRO_VERSION4;
3158
3159 return version;
3160}
3161
3162const XML_Feature *XMLCALL
3163XML_GetFeatureList(void) {
3164 static const XML_Feature features[] = {
3165 {XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
3166 sizeof(XML_Char)},
3167 {XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
3168 sizeof(XML_LChar)},
3169#ifdef XML_UNICODE
3170 {XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
3171#endif
3172#ifdef XML_UNICODE_WCHAR_T
3173 {XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
3174#endif
3175#ifdef XML_DTD
3176 {XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
3177#endif
3178#if XML_CONTEXT_BYTES0 > 0
3179 {XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
3180 XML_CONTEXT_BYTES0},
3181#endif
3182#ifdef XML_MIN_SIZE
3183 {XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
3184#endif
3185#ifdef XML_NS
3186 {XML_FEATURE_NS, XML_L("XML_NS"), 0},
3187#endif
3188#ifdef XML_LARGE_SIZE
3189 {XML_FEATURE_LARGE_SIZE, XML_L("XML_LARGE_SIZE"), 0},
3190#endif
3191#ifdef XML_ATTR_INFO
3192 {XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
3193#endif
3194#if XML_GE1 == 1
3195 /* Added in Expat 2.4.0 for XML_DTD defined and
3196 * added in Expat 2.6.0 for XML_GE == 1. */
3197 {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
3198 XML_L("XML_BLAP_MAX_AMP"),
3199 (long int)
3200 EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT100.0f},
3201 {XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT,
3202 XML_L("XML_BLAP_ACT_THRES"),
3203 EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT8388608},
3204 /* Added in Expat 2.6.0. */
3205 {XML_FEATURE_GE, XML_L("XML_GE"), 0},
3206 /* Added in Expat 2.7.2. */
3207 {XML_FEATURE_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT,
3208 XML_L("XML_AT_MAX_AMP"),
3209 (long int)EXPAT_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT100.0f},
3210 {XML_FEATURE_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT,
3211 XML_L("XML_AT_ACT_THRES"),
3212 (long int)EXPAT_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT67108864},
3213#endif
3214 {XML_FEATURE_END, NULL((void*)0), 0}};
3215
3216 return features;
3217}
3218#endif
3219/* END MOZILLA CHANGE */
3220
3221#if XML_GE1 == 1
3222XML_Bool XMLCALL
3223XML_SetBillionLaughsAttackProtectionMaximumAmplification(
3224 XML_Parser parser, float maximumAmplificationFactor) {
3225 if ((parser == NULL((void*)0)) || (parser->m_parentParser != NULL((void*)0))
3226 || isnan(maximumAmplificationFactor)__builtin_isnan (maximumAmplificationFactor)
3227 || (maximumAmplificationFactor < 1.0f)) {
3228 return XML_FALSE((XML_Bool)0);
3229 }
3230 parser->m_accounting.maximumAmplificationFactor = maximumAmplificationFactor;
3231 return XML_TRUE((XML_Bool)1);
3232}
3233
3234XML_Bool XMLCALL
3235XML_SetBillionLaughsAttackProtectionActivationThreshold(
3236 XML_Parser parser, unsigned long long activationThresholdBytes) {
3237 if ((parser == NULL((void*)0)) || (parser->m_parentParser != NULL((void*)0))) {
3238 return XML_FALSE((XML_Bool)0);
3239 }
3240 parser->m_accounting.activationThresholdBytes = activationThresholdBytes;
3241 return XML_TRUE((XML_Bool)1);
3242}
3243
3244XML_Bool XMLCALL
3245XML_SetAllocTrackerMaximumAmplification(XML_Parser parser,
3246 float maximumAmplificationFactor) {
3247 if ((parser == NULL((void*)0)) || (parser->m_parentParser != NULL((void*)0))
3248 || isnan(maximumAmplificationFactor)__builtin_isnan (maximumAmplificationFactor)
3249 || (maximumAmplificationFactor < 1.0f)) {
3250 return XML_FALSE((XML_Bool)0);
3251 }
3252 parser->m_alloc_tracker.maximumAmplificationFactor
3253 = maximumAmplificationFactor;
3254 return XML_TRUE((XML_Bool)1);
3255}
3256
3257XML_Bool XMLCALL
3258XML_SetAllocTrackerActivationThreshold(
3259 XML_Parser parser, unsigned long long activationThresholdBytes) {
3260 if ((parser == NULL((void*)0)) || (parser->m_parentParser != NULL((void*)0))) {
3261 return XML_FALSE((XML_Bool)0);
3262 }
3263 parser->m_alloc_tracker.activationThresholdBytes = activationThresholdBytes;
3264 return XML_TRUE((XML_Bool)1);
3265}
3266#endif /* XML_GE == 1 */
3267
3268XML_Bool XMLCALL
3269XML_SetReparseDeferralEnabled(XML_Parser parser, XML_Bool enabled) {
3270 if (parser != NULL((void*)0) && (enabled == XML_TRUE((XML_Bool)1) || enabled == XML_FALSE((XML_Bool)0))) {
3271 parser->m_reparseDeferralEnabled = enabled;
3272 return XML_TRUE((XML_Bool)1);
3273 }
3274 return XML_FALSE((XML_Bool)0);
3275}
3276
3277/* Initially tag->rawName always points into the parse buffer;
3278 for those TAG instances opened while the current parse buffer was
3279 processed, and not yet closed, we need to store tag->rawName in a more
3280 permanent location, since the parse buffer is about to be discarded.
3281*/
3282static XML_Bool
3283storeRawNames(XML_Parser parser) {
3284 TAG *tag = parser->m_tagStack;
3285 while (tag) {
3286 size_t bufSize;
3287 size_t nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
3288 size_t rawNameLen;
3289 char *rawNameBuf = tag->buf.raw + nameLen;
3290 /* Stop if already stored. Since m_tagStack is a stack, we can stop
3291 at the first entry that has already been copied; everything
3292 below it in the stack is already been accounted for in a
3293 previous call to this function.
3294 */
3295 if (tag->rawName == rawNameBuf)
3296 break;
3297 /* For reuse purposes we need to ensure that the
3298 size of tag->buf is a multiple of sizeof(XML_Char).
3299 */
3300 rawNameLen = ROUND_UP(tag->rawNameLength, sizeof(XML_Char))(((tag->rawNameLength) + ((sizeof(XML_Char)) - 1)) & ~
((sizeof(XML_Char)) - 1))
;
3301 /* Detect and prevent integer overflow. */
3302 if (rawNameLen > SIZE_MAX(18446744073709551615UL) - nameLen)
3303 return XML_FALSE((XML_Bool)0);
3304 bufSize = nameLen + rawNameLen;
3305 if (bufSize > (size_t)(tag->bufEnd - tag->buf.raw)) {
3306 char *temp = REALLOC(parser, tag->buf.raw, bufSize)(expat_realloc((parser), (tag->buf.raw), (bufSize), 3306));
3307 if (temp == NULL((void*)0))
3308 return XML_FALSE((XML_Bool)0);
3309 /* if tag->name.str points to tag->buf.str (only when namespace
3310 processing is off) then we have to update it
3311 */
3312 if (tag->name.str == tag->buf.str)
3313 tag->name.str = (XML_Char *)temp;
3314 /* if tag->name.localPart is set (when namespace processing is on)
3315 then update it as well, since it will always point into tag->buf
3316 */
3317 if (tag->name.localPart)
3318 tag->name.localPart
3319 = (XML_Char *)temp + (tag->name.localPart - tag->buf.str);
3320 tag->buf.raw = temp;
3321 tag->bufEnd = temp + bufSize;
3322 rawNameBuf = temp + nameLen;
3323 }
3324 memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
3325 tag->rawName = rawNameBuf;
3326 tag = tag->parent;
3327 }
3328 return XML_TRUE((XML_Bool)1);
3329}
3330
3331static enum XML_Error PTRCALL
3332contentProcessor(XML_Parser parser, const char *start, const char *end,
3333 const char **endPtr) {
3334 enum XML_Error result = doContent(
3335 parser, parser->m_parentParser ? 1 : 0, parser->m_encoding, start, end,
3336 endPtr, (XML_Bool)! parser->m_parsingStatus.finalBuffer,
3337 XML_ACCOUNT_DIRECT);
3338/* BEGIN MOZILLA CHANGE (Bug 1746996 - Ensure that storeRawNames is always called) */
3339#if 0
3340 if (result == XML_ERROR_NONE) {
3341 if (! storeRawNames(parser))
3342 return XML_ERROR_NO_MEMORY;
3343 }
3344#endif
3345/* END MOZILLA CHANGE */
3346 return result;
3347}
3348
3349static enum XML_Error PTRCALL
3350externalEntityInitProcessor(XML_Parser parser, const char *start,
3351 const char *end, const char **endPtr) {
3352 enum XML_Error result = initializeEncoding(parser);
3353 if (result != XML_ERROR_NONE)
3354 return result;
3355 parser->m_processor = externalEntityInitProcessor2;
3356 return externalEntityInitProcessor2(parser, start, end, endPtr);
3357}
3358
3359static enum XML_Error PTRCALL
3360externalEntityInitProcessor2(XML_Parser parser, const char *start,
3361 const char *end, const char **endPtr) {
3362 const char *next = start; /* XmlContentTok doesn't always set the last arg */
3363 int tok = XmlContentTok(parser->m_encoding, start, end, &next)(((parser->m_encoding)->scanners[1])(parser->m_encoding
, start, end, &next))
;
3364 switch (tok) {
3365 case XML_TOK_BOM14:
3366#if XML_GE1 == 1
3367 if (! accountingDiffTolerated(parser, tok, start, next, __LINE__3367,
3368 XML_ACCOUNT_DIRECT)) {
3369 accountingOnAbort(parser);
3370 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
3371 }
3372#endif /* XML_GE == 1 */
3373
3374 /* If we are at the end of the buffer, this would cause the next stage,
3375 i.e. externalEntityInitProcessor3, to pass control directly to
3376 doContent (by detecting XML_TOK_NONE) without processing any xml text
3377 declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
3378 */
3379 if (next == end && ! parser->m_parsingStatus.finalBuffer) {
3380 *endPtr = next;
3381 return XML_ERROR_NONE;
3382 }
3383 start = next;
3384 break;
3385 case XML_TOK_PARTIAL-1:
3386 if (! parser->m_parsingStatus.finalBuffer) {
3387 *endPtr = start;
3388 return XML_ERROR_NONE;
3389 }
3390 parser->m_eventPtr = start;
3391 return XML_ERROR_UNCLOSED_TOKEN;
3392 case XML_TOK_PARTIAL_CHAR-2:
3393 if (! parser->m_parsingStatus.finalBuffer) {
3394 *endPtr = start;
3395 return XML_ERROR_NONE;
3396 }
3397 parser->m_eventPtr = start;
3398 return XML_ERROR_PARTIAL_CHAR;
3399 }
3400 parser->m_processor = externalEntityInitProcessor3;
3401 return externalEntityInitProcessor3(parser, start, end, endPtr);
3402}
3403
3404static enum XML_Error PTRCALL
3405externalEntityInitProcessor3(XML_Parser parser, const char *start,
3406 const char *end, const char **endPtr) {
3407 int tok;
3408 const char *next = start; /* XmlContentTok doesn't always set the last arg */
3409 parser->m_eventPtr = start;
3410 tok = XmlContentTok(parser->m_encoding, start, end, &next)(((parser->m_encoding)->scanners[1])(parser->m_encoding
, start, end, &next))
;
3411 /* Note: These bytes are accounted later in:
3412 - processXmlDecl
3413 - externalEntityContentProcessor
3414 */
3415 parser->m_eventEndPtr = next;
3416
3417 switch (tok) {
3418 case XML_TOK_XML_DECL12: {
3419 enum XML_Error result;
3420 result = processXmlDecl(parser, 1, start, next);
3421 if (result != XML_ERROR_NONE)
3422 return result;
3423 switch (parser->m_parsingStatus.parsing) {
3424 case XML_SUSPENDED:
3425 *endPtr = next;
3426 return XML_ERROR_NONE;
3427 case XML_FINISHED:
3428 return XML_ERROR_ABORTED;
3429 case XML_PARSING:
3430 if (parser->m_reenter) {
3431 return XML_ERROR_UNEXPECTED_STATE; // LCOV_EXCL_LINE
3432 }
3433 EXPAT_FALLTHROUGH__attribute__((fallthrough));
3434 default:
3435 start = next;
3436 }
3437 } break;
3438 case XML_TOK_PARTIAL-1:
3439 if (! parser->m_parsingStatus.finalBuffer) {
3440 *endPtr = start;
3441 return XML_ERROR_NONE;
3442 }
3443 return XML_ERROR_UNCLOSED_TOKEN;
3444 case XML_TOK_PARTIAL_CHAR-2:
3445 if (! parser->m_parsingStatus.finalBuffer) {
3446 *endPtr = start;
3447 return XML_ERROR_NONE;
3448 }
3449 return XML_ERROR_PARTIAL_CHAR;
3450 }
3451 parser->m_processor = externalEntityContentProcessor;
3452 parser->m_tagLevel = 1;
3453 return externalEntityContentProcessor(parser, start, end, endPtr);
3454}
3455
3456static enum XML_Error PTRCALL
3457externalEntityContentProcessor(XML_Parser parser, const char *start,
3458 const char *end, const char **endPtr) {
3459 enum XML_Error result
3460 = doContent(parser, 1, parser->m_encoding, start, end, endPtr,
3461 (XML_Bool)! parser->m_parsingStatus.finalBuffer,
3462 XML_ACCOUNT_ENTITY_EXPANSION);
3463/* BEGIN MOZILLA CHANGE (Bug 1746996 - Ensure that storeRawNames is always called) */
3464#if 0
3465 if (result == XML_ERROR_NONE) {
3466 if (! storeRawNames(parser))
3467 return XML_ERROR_NO_MEMORY;
3468 }
3469#endif
3470/* END MOZILLA CHANGE */
3471 return result;
3472}
3473
3474static enum XML_Error
3475doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
3476 const char *s, const char *end, const char **nextPtr,
3477 XML_Bool haveMore, enum XML_Account account) {
3478/* BEGIN MOZILLA CHANGE (Bug 1746996 - Ensure that storeRawNames is always called) */
3479 enum XML_Error result = doContentInternal(parser, startTagLevel, enc, s, end,
3480 nextPtr, haveMore, account);
3481 if (result == XML_ERROR_NONE) {
3482 if (! storeRawNames(parser))
3483 return XML_ERROR_NO_MEMORY;
3484 }
3485 return result;
3486}
3487
3488static enum XML_Error
3489doContentInternal(XML_Parser parser, int startTagLevel, const ENCODING *enc,
3490 const char *s, const char *end, const char **nextPtr,
3491 XML_Bool haveMore, enum XML_Account account) {
3492/* END MOZILLA CHANGE */
3493 /* save one level of indirection */
3494 DTD *const dtd = parser->m_dtd;
3495
3496 const char **eventPP;
3497 const char **eventEndPP;
3498 if (enc == parser->m_encoding) {
3499 eventPP = &parser->m_eventPtr;
3500 eventEndPP = &parser->m_eventEndPtr;
3501 } else {
3502 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
3503 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
3504 }
3505 *eventPP = s;
3506
3507 for (;;) {
3508 const char *next = s; /* XmlContentTok doesn't always set the last arg */
3509 int tok = XmlContentTok(enc, s, end, &next)(((enc)->scanners[1])(enc, s, end, &next));
3510#if XML_GE1 == 1
3511 const char *accountAfter
3512 = ((tok == XML_TOK_TRAILING_RSQB-5) || (tok == XML_TOK_TRAILING_CR-3))
3513 ? (haveMore ? s /* i.e. 0 bytes */ : end)
3514 : next;
3515 if (! accountingDiffTolerated(parser, tok, s, accountAfter, __LINE__3515,
3516 account)) {
3517 accountingOnAbort(parser);
3518 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
3519 }
3520#endif
3521 *eventEndPP = next;
3522 switch (tok) {
3523 case XML_TOK_TRAILING_CR-3:
3524 if (haveMore) {
3525 *nextPtr = s;
3526 return XML_ERROR_NONE;
3527 }
3528 *eventEndPP = end;
3529 if (parser->m_characterDataHandler) {
3530 XML_Char c = 0xA;
3531 beforeHandler(parser);
3532 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
3533 afterHandler(parser);
3534 } else if (parser->m_defaultHandler)
3535 reportDefault(parser, enc, s, end);
3536 /* We are at the end of the final buffer, should we check for
3537 XML_SUSPENDED, XML_FINISHED?
3538 */
3539 if (startTagLevel == 0)
3540 return XML_ERROR_NO_ELEMENTS;
3541 if (parser->m_tagLevel != startTagLevel)
3542 return XML_ERROR_ASYNC_ENTITY;
3543 *nextPtr = end;
3544 return XML_ERROR_NONE;
3545 case XML_TOK_NONE-4:
3546 if (haveMore) {
3547 *nextPtr = s;
3548 return XML_ERROR_NONE;
3549 }
3550 if (startTagLevel > 0) {
3551 if (parser->m_tagLevel != startTagLevel)
3552 return XML_ERROR_ASYNC_ENTITY;
3553 *nextPtr = s;
3554 return XML_ERROR_NONE;
3555 }
3556 return XML_ERROR_NO_ELEMENTS;
3557 case XML_TOK_INVALID0:
3558 *eventPP = next;
3559 return XML_ERROR_INVALID_TOKEN;
3560 case XML_TOK_PARTIAL-1:
3561 if (haveMore) {
3562 *nextPtr = s;
3563 return XML_ERROR_NONE;
3564 }
3565 return XML_ERROR_UNCLOSED_TOKEN;
3566 case XML_TOK_PARTIAL_CHAR-2:
3567 if (haveMore) {
3568 *nextPtr = s;
3569 return XML_ERROR_NONE;
3570 }
3571 return XML_ERROR_PARTIAL_CHAR;
3572 case XML_TOK_ENTITY_REF9: {
3573 const XML_Char *name;
3574 ENTITY *entity;
3575 XML_Char ch = (XML_Char)XmlPredefinedEntityName((((enc)->predefinedEntityName)(enc, s + enc->minBytesPerChar
, next - enc->minBytesPerChar))
3576 enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar)(((enc)->predefinedEntityName)(enc, s + enc->minBytesPerChar
, next - enc->minBytesPerChar))
;
3577 if (ch) {
3578#if XML_GE1 == 1
3579 /* NOTE: We are replacing 4-6 characters original input for 1 character
3580 * so there is no amplification and hence recording without
3581 * protection. */
3582 accountingDiffTolerated(parser, tok, (char *)&ch,
3583 ((char *)&ch) + sizeof(XML_Char), __LINE__3583,
3584 XML_ACCOUNT_ENTITY_EXPANSION);
3585#endif /* XML_GE == 1 */
3586 if (parser->m_characterDataHandler) {
3587 beforeHandler(parser);
3588 parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
3589 afterHandler(parser);
3590 } else if (parser->m_defaultHandler)
3591 reportDefault(parser, enc, s, next);
3592 break;
3593 }
3594 name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
3595 next - enc->minBytesPerChar);
3596 if (! name)
3597 return XML_ERROR_NO_MEMORY;
3598 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
3599 poolDiscard(&dtd->pool)((&dtd->pool)->ptr = (&dtd->pool)->start);
3600 /* First, determine if a check for an existing declaration is needed;
3601 if yes, check that the entity exists, and that it is internal,
3602 otherwise call the skipped entity or default handler.
3603 */
3604 if (! dtd->hasParamEntityRefs || dtd->standalone) {
3605 if (! entity)
3606 return XML_ERROR_UNDEFINED_ENTITY;
3607 else if (! entity->is_internal)
3608 return XML_ERROR_ENTITY_DECLARED_IN_PE;
3609 } else if (! entity) {
3610 if (parser->m_skippedEntityHandler) {
3611 beforeHandler(parser);
3612 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
3613 afterHandler(parser);
3614/* BEGIN MOZILLA CHANGE (Bug 35984 - Undeclared entities are ignored when external DTD not found) */
3615#if 0
3616 } else if (parser->m_defaultHandler)
3617 reportDefault(parser, enc, s, next);
3618 break;
3619#else
3620 }
3621 return XML_ERROR_UNDEFINED_ENTITY;
3622#endif
3623/* END MOZILLA CHANGE */
3624 }
3625 if (entity->open)
3626 return XML_ERROR_RECURSIVE_ENTITY_REF;
3627 if (entity->notation)
3628 return XML_ERROR_BINARY_ENTITY_REF;
3629 if (entity->textPtr) {
3630 enum XML_Error result;
3631 if (! parser->m_defaultExpandInternalEntities) {
3632 if (parser->m_skippedEntityHandler) {
3633 beforeHandler(parser);
3634 parser->m_skippedEntityHandler(parser->m_handlerArg, entity->name,
3635 0);
3636 afterHandler(parser);
3637 } else if (parser->m_defaultHandler)
3638 reportDefault(parser, enc, s, next);
3639 break;
3640 }
3641 result = processEntity(parser, entity, XML_FALSE((XML_Bool)0), ENTITY_INTERNAL);
3642 if (result != XML_ERROR_NONE)
3643 return result;
3644 } else if (parser->m_externalEntityRefHandler) {
3645 const XML_Char *context;
3646 entity->open = true1;
3647 context = getContext(parser);
3648 entity->open = false0;
3649 if (! context)
3650 return XML_ERROR_NO_MEMORY;
3651 beforeHandler(parser);
3652 const int status = parser->m_externalEntityRefHandler(
3653 parser->m_externalEntityRefHandlerArg, context, entity->base,
3654 entity->systemId, entity->publicId);
3655 afterHandler(parser);
3656 if (! status)
3657 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
3658 poolDiscard(&parser->m_tempPool)((&parser->m_tempPool)->ptr = (&parser->m_tempPool
)->start)
;
3659 } else if (parser->m_defaultHandler)
3660 reportDefault(parser, enc, s, next);
3661 break;
3662 }
3663 case XML_TOK_START_TAG_NO_ATTS2:
3664 case XML_TOK_START_TAG_WITH_ATTS1: {
3665 TAG *tag;
3666 enum XML_Error result;
3667 XML_Char *toPtr;
3668 if (parser->m_freeTagList) {
3669 tag = parser->m_freeTagList;
3670 parser->m_freeTagList = parser->m_freeTagList->parent;
3671 } else {
3672 tag = MALLOC(parser, sizeof(TAG))(expat_malloc((parser), (sizeof(TAG)), 3672));
3673 if (! tag)
3674 return XML_ERROR_NO_MEMORY;
3675 tag->buf.raw = MALLOC(parser, INIT_TAG_BUF_SIZE)(expat_malloc((parser), (32), 3675));
3676 if (! tag->buf.raw) {
3677 FREE(parser, tag)(expat_free((parser), (tag), 3677));
3678 return XML_ERROR_NO_MEMORY;
3679 }
3680 tag->bufEnd = tag->buf.raw + INIT_TAG_BUF_SIZE32;
3681 }
3682 tag->bindings = NULL((void*)0);
3683 tag->parent = parser->m_tagStack;
3684 parser->m_tagStack = tag;
3685 tag->name.localPart = NULL((void*)0);
3686 tag->name.prefix = NULL((void*)0);
3687 tag->rawName = s + enc->minBytesPerChar;
3688 tag->rawNameLength = XmlNameLength(enc, tag->rawName)(((enc)->nameLength)(enc, tag->rawName));
3689 ++parser->m_tagLevel;
3690 {
3691 const char *rawNameEnd = tag->rawName + tag->rawNameLength;
3692 const char *fromPtr = tag->rawName;
3693 toPtr = tag->buf.str;
3694 for (;;) {
3695 const enum XML_Convert_Result convert_res
3696 = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr,(((enc)->utf16Convert)(enc, &fromPtr, rawNameEnd, (ICHAR
**)&toPtr, (ICHAR *)tag->bufEnd - 1))
3697 (ICHAR *)tag->bufEnd - 1)(((enc)->utf16Convert)(enc, &fromPtr, rawNameEnd, (ICHAR
**)&toPtr, (ICHAR *)tag->bufEnd - 1))
;
3698 const size_t convLen = (size_t)(toPtr - tag->buf.str);
3699 if ((fromPtr >= rawNameEnd)
3700 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
3701 tag->name.strLen = convLen;
3702 break;
3703 }
3704 if (SIZE_MAX(18446744073709551615UL) / 2 < (size_t)(tag->bufEnd - tag->buf.raw))
3705 return XML_ERROR_NO_MEMORY;
3706 const size_t bufSize = (size_t)(tag->bufEnd - tag->buf.raw) * 2;
3707 {
3708 char *temp = REALLOC(parser, tag->buf.raw, bufSize)(expat_realloc((parser), (tag->buf.raw), (bufSize), 3708));
3709 if (temp == NULL((void*)0))
3710 return XML_ERROR_NO_MEMORY;
3711 tag->buf.raw = temp;
3712 tag->bufEnd = temp + bufSize;
3713 toPtr = (XML_Char *)temp + convLen;
3714 }
3715 }
3716 }
3717 tag->name.str = tag->buf.str;
3718 *toPtr = XML_T('\0')(uint16_t)'\0';
3719 result
3720 = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings), account);
3721 if (result)
3722 return result;
3723 if (parser->m_startElementHandler) {
3724 beforeHandler(parser);
3725 parser->m_startElementHandler(parser->m_handlerArg, tag->name.str,
3726 (const XML_Char **)parser->m_atts);
3727 afterHandler(parser);
3728 } else if (parser->m_defaultHandler)
3729 reportDefault(parser, enc, s, next);
3730 poolClear(&parser->m_tempPool);
3731 break;
3732 }
3733 case XML_TOK_EMPTY_ELEMENT_NO_ATTS4:
3734 case XML_TOK_EMPTY_ELEMENT_WITH_ATTS3: {
3735 const char *rawName = s + enc->minBytesPerChar;
3736 enum XML_Error result;
3737 BINDING *bindings = NULL((void*)0);
3738 XML_Bool noElmHandlers = XML_TRUE((XML_Bool)1);
3739 TAG_NAME name;
3740 name.str = poolStoreString(&parser->m_tempPool, enc, rawName,
3741 rawName + XmlNameLength(enc, rawName)(((enc)->nameLength)(enc, rawName)));
3742 if (! name.str)
3743 return XML_ERROR_NO_MEMORY;
3744 poolFinish(&parser->m_tempPool)((&parser->m_tempPool)->start = (&parser->m_tempPool
)->ptr)
;
3745 result = storeAtts(parser, enc, s, &name, &bindings,
3746 XML_ACCOUNT_NONE /* token spans whole start tag */);
3747 if (result != XML_ERROR_NONE) {
3748 freeBindings(parser, bindings);
3749 return result;
3750 }
3751 poolFinish(&parser->m_tempPool)((&parser->m_tempPool)->start = (&parser->m_tempPool
)->ptr)
;
3752 if (parser->m_startElementHandler) {
3753 beforeHandler(parser);
3754 parser->m_startElementHandler(parser->m_handlerArg, name.str,
3755 (const XML_Char **)parser->m_atts);
3756 afterHandler(parser);
3757 noElmHandlers = XML_FALSE((XML_Bool)0);
3758 }
3759 if (parser->m_endElementHandler) {
3760 if (parser->m_startElementHandler)
3761 *eventPP = *eventEndPP;
3762 beforeHandler(parser);
3763 parser->m_endElementHandler(parser->m_handlerArg, name.str);
3764 afterHandler(parser);
3765 noElmHandlers = XML_FALSE((XML_Bool)0);
3766 }
3767 if (noElmHandlers && parser->m_defaultHandler)
3768 reportDefault(parser, enc, s, next);
3769 poolClear(&parser->m_tempPool);
3770 freeBindings(parser, bindings);
3771 }
3772 if ((parser->m_tagLevel == 0)
3773 && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
3774 if (parser->m_parsingStatus.parsing == XML_SUSPENDED
3775 || (parser->m_parsingStatus.parsing == XML_PARSING
3776 && parser->m_reenter))
3777 parser->m_processor = epilogProcessor;
3778 else
3779 return epilogProcessor(parser, next, end, nextPtr);
3780 }
3781 break;
3782 case XML_TOK_END_TAG5:
3783 if (parser->m_tagLevel == startTagLevel)
3784 return XML_ERROR_ASYNC_ENTITY;
3785 else {
3786 int len;
3787 const char *rawName;
3788 TAG *tag = parser->m_tagStack;
3789 rawName = s + enc->minBytesPerChar * 2;
3790 len = XmlNameLength(enc, rawName)(((enc)->nameLength)(enc, rawName));
3791 if (len != tag->rawNameLength
3792 || memcmp(tag->rawName, rawName, len) != 0) {
3793/* BEGIN MOZILLA CHANGE (Report opening tag of mismatched closing tag) */
3794 /* This code is copied from the |if (parser->m_endElementHandler)|
3795 block below
3796 */
3797 const XML_Char *localPart;
3798 const XML_Char *prefix;
3799 XML_Char *uri;
3800 localPart = tag->name.localPart;
3801 if (parser->m_ns && localPart) {
3802 /* localPart and prefix may have been overwritten in
3803 tag->name.str, since this points to the binding->uri
3804 buffer which gets reused; so we have to add them again
3805 */
3806 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
3807 /* don't need to check for space - already done in storeAtts() */
3808 while (*localPart)
3809 *uri++ = *localPart++;
3810 prefix = tag->name.prefix;
3811 if (parser->m_ns_triplets && prefix) {
3812 *uri++ = parser->m_namespaceSeparator;
3813 while (*prefix)
3814 *uri++ = *prefix++;
3815 }
3816 *uri = XML_T('\0')(uint16_t)'\0';
3817 }
3818 parser->m_mismatch = tag->name.str;
3819/* END MOZILLA CHANGE */
3820 *eventPP = rawName;
3821 return XML_ERROR_TAG_MISMATCH;
3822 }
3823 parser->m_tagStack = tag->parent;
3824 tag->parent = parser->m_freeTagList;
3825 parser->m_freeTagList = tag;
3826 --parser->m_tagLevel;
3827 if (parser->m_endElementHandler) {
3828 const XML_Char *localPart;
3829 const XML_Char *prefix;
3830 XML_Char *uri;
3831 localPart = tag->name.localPart;
3832 if (parser->m_ns && localPart) {
3833 /* localPart and prefix may have been overwritten in
3834 tag->name.str, since this points to the binding->uri
3835 buffer which gets reused; so we have to add them again
3836 */
3837 uri = (XML_Char *)tag->name.str + tag->name.uriLen;
3838 /* don't need to check for space - already done in storeAtts() */
3839 while (*localPart)
3840 *uri++ = *localPart++;
3841 prefix = tag->name.prefix;
3842 if (parser->m_ns_triplets && prefix) {
3843 *uri++ = parser->m_namespaceSeparator;
3844 while (*prefix)
3845 *uri++ = *prefix++;
3846 }
3847 *uri = XML_T('\0')(uint16_t)'\0';
3848 }
3849 beforeHandler(parser);
3850 parser->m_endElementHandler(parser->m_handlerArg, tag->name.str);
3851 afterHandler(parser);
3852 } else if (parser->m_defaultHandler)
3853 reportDefault(parser, enc, s, next);
3854 while (tag->bindings) {
3855 BINDING *b = tag->bindings;
3856 if (parser->m_endNamespaceDeclHandler) {
3857 beforeHandler(parser);
3858 parser->m_endNamespaceDeclHandler(parser->m_handlerArg,
3859 b->prefix->name);
3860 afterHandler(parser);
3861 }
3862 tag->bindings = tag->bindings->nextTagBinding;
3863 b->nextTagBinding = parser->m_freeBindingList;
3864 parser->m_freeBindingList = b;
3865 b->prefix->binding = b->prevPrefixBinding;
3866 }
3867 if ((parser->m_tagLevel == 0)
3868 && (parser->m_parsingStatus.parsing != XML_FINISHED)) {
3869 if (parser->m_parsingStatus.parsing == XML_SUSPENDED
3870 || (parser->m_parsingStatus.parsing == XML_PARSING
3871 && parser->m_reenter))
3872 parser->m_processor = epilogProcessor;
3873 else
3874 return epilogProcessor(parser, next, end, nextPtr);
3875 }
3876 }
3877 break;
3878 case XML_TOK_CHAR_REF10: {
3879 int n = XmlCharRefNumber(enc, s)(((enc)->charRefNumber)(enc, s));
3880 if (n < 0)
3881 return XML_ERROR_BAD_CHAR_REF;
3882 if (parser->m_characterDataHandler) {
3883 XML_Char buf[XML_ENCODE_MAX2];
3884 beforeHandler(parser);
3885 parser->m_characterDataHandler(parser->m_handlerArg, buf,
3886 XmlEncodeXmlUtf16Encode(n, (ICHAR *)buf));
3887 afterHandler(parser);
3888 } else if (parser->m_defaultHandler)
3889 reportDefault(parser, enc, s, next);
3890 } break;
3891 case XML_TOK_XML_DECL12:
3892 return XML_ERROR_MISPLACED_XML_PI;
3893 case XML_TOK_DATA_NEWLINE7:
3894 if (parser->m_characterDataHandler) {
3895 XML_Char c = 0xA;
3896 beforeHandler(parser);
3897 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
3898 afterHandler(parser);
3899 } else if (parser->m_defaultHandler)
3900 reportDefault(parser, enc, s, next);
3901 break;
3902 case XML_TOK_CDATA_SECT_OPEN8: {
3903 enum XML_Error result;
3904 if (parser->m_startCdataSectionHandler) {
3905 beforeHandler(parser);
3906 parser->m_startCdataSectionHandler(parser->m_handlerArg);
3907 afterHandler(parser);
3908 /* BEGIN disabled code */
3909 /* Suppose you doing a transformation on a document that involves
3910 changing only the character data. You set up a defaultHandler
3911 and a characterDataHandler. The defaultHandler simply copies
3912 characters through. The characterDataHandler does the
3913 transformation and writes the characters out escaping them as
3914 necessary. This case will fail to work if we leave out the
3915 following two lines (because & and < inside CDATA sections will
3916 be incorrectly escaped).
3917
3918 However, now we have a start/endCdataSectionHandler, so it seems
3919 easier to let the user deal with this.
3920 */
3921 } else if ((0) && parser->m_characterDataHandler) {
3922 beforeHandler(parser);
3923 parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3924 0);
3925 afterHandler(parser);
3926 /* END disabled code */
3927 } else if (parser->m_defaultHandler)
3928 reportDefault(parser, enc, s, next);
3929 result
3930 = doCdataSection(parser, enc, &next, end, nextPtr, haveMore, account);
3931 if (result != XML_ERROR_NONE)
3932 return result;
3933 else if (! next) {
3934 parser->m_processor = cdataSectionProcessor;
3935 return result;
3936 }
3937 } break;
3938 case XML_TOK_TRAILING_RSQB-5:
3939 if (haveMore) {
3940 *nextPtr = s;
3941 return XML_ERROR_NONE;
3942 }
3943 if (parser->m_characterDataHandler) {
3944 if (MUST_CONVERT(enc, s)(! (enc)->isUtf16 || (((uintptr_t)(s)) & 1))) {
3945 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
3946 XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd)(((enc)->utf16Convert)(enc, &s, end, &dataPtr, (ICHAR
*)parser->m_dataBufEnd))
;
3947 beforeHandler(parser);
3948 parser->m_characterDataHandler(
3949 parser->m_handlerArg, parser->m_dataBuf,
3950 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
3951 afterHandler(parser);
3952 } else {
3953 beforeHandler(parser);
3954 parser->m_characterDataHandler(
3955 parser->m_handlerArg, (const XML_Char *)s,
3956 (int)((const XML_Char *)end - (const XML_Char *)s));
3957 afterHandler(parser);
3958 }
3959 } else if (parser->m_defaultHandler)
3960 reportDefault(parser, enc, s, end);
3961 /* We are at the end of the final buffer, should we check for
3962 XML_SUSPENDED, XML_FINISHED?
3963 */
3964 if (startTagLevel == 0) {
3965 *eventPP = end;
3966 return XML_ERROR_NO_ELEMENTS;
3967 }
3968 if (parser->m_tagLevel != startTagLevel) {
3969 *eventPP = end;
3970 return XML_ERROR_ASYNC_ENTITY;
3971 }
3972 *nextPtr = end;
3973 return XML_ERROR_NONE;
3974 case XML_TOK_DATA_CHARS6: {
3975 XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
3976 if (charDataHandler) {
3977 if (MUST_CONVERT(enc, s)(! (enc)->isUtf16 || (((uintptr_t)(s)) & 1))) {
3978 for (;;) {
3979 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
3980 const enum XML_Convert_Result convert_res = XmlConvert((((enc)->utf16Convert)(enc, &s, next, &dataPtr, (ICHAR
*)parser->m_dataBufEnd))
3981 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd)(((enc)->utf16Convert)(enc, &s, next, &dataPtr, (ICHAR
*)parser->m_dataBufEnd))
;
3982 *eventEndPP = s;
3983 beforeHandler(parser);
3984 charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
3985 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
3986 afterHandler(parser);
3987 if ((convert_res == XML_CONVERT_COMPLETED)
3988 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
3989 break;
3990 *eventPP = s;
3991 }
3992 } else {
3993 beforeHandler(parser);
3994 charDataHandler(parser->m_handlerArg, (const XML_Char *)s,
3995 (int)((const XML_Char *)next - (const XML_Char *)s));
3996 afterHandler(parser);
3997 }
3998 } else if (parser->m_defaultHandler)
3999 reportDefault(parser, enc, s, next);
4000 } break;
4001 case XML_TOK_PI11:
4002 if (! reportProcessingInstruction(parser, enc, s, next))
4003 return XML_ERROR_NO_MEMORY;
4004 break;
4005 case XML_TOK_COMMENT13:
4006 if (! reportComment(parser, enc, s, next))
4007 return XML_ERROR_NO_MEMORY;
4008 break;
4009 default:
4010 /* All of the tokens produced by XmlContentTok() have their own
4011 * explicit cases, so this default is not strictly necessary.
4012 * However it is a useful safety net, so we retain the code and
4013 * simply exclude it from the coverage tests.
4014 *
4015 * LCOV_EXCL_START
4016 */
4017 if (parser->m_defaultHandler)
4018 reportDefault(parser, enc, s, next);
4019 break;
4020 /* LCOV_EXCL_STOP */
4021 }
4022 switch (parser->m_parsingStatus.parsing) {
4023 case XML_SUSPENDED:
4024 *eventPP = next;
4025 *nextPtr = next;
4026 return XML_ERROR_NONE;
4027 case XML_FINISHED:
4028 *eventPP = next;
4029 return XML_ERROR_ABORTED;
4030 case XML_PARSING:
4031 if (parser->m_reenter) {
4032 *nextPtr = next;
4033 return XML_ERROR_NONE;
4034 }
4035 EXPAT_FALLTHROUGH__attribute__((fallthrough));
4036 default:;
4037 *eventPP = s = next;
4038 }
4039 }
4040 /* not reached */
4041}
4042
4043/* This function does not call free() on the allocated memory, merely
4044 * moving it to the parser's m_freeBindingList where it can be freed or
4045 * reused as appropriate.
4046 */
4047static void
4048freeBindings(XML_Parser parser, BINDING *bindings) {
4049 while (bindings) {
4050 BINDING *b = bindings;
4051
4052 /* m_startNamespaceDeclHandler will have been called for this
4053 * binding in addBindings(), so call the end handler now.
4054 */
4055 if (parser->m_endNamespaceDeclHandler) {
4056 beforeHandler(parser);
4057 parser->m_endNamespaceDeclHandler(parser->m_handlerArg, b->prefix->name);
4058 afterHandler(parser);
4059 }
4060
4061 bindings = bindings->nextTagBinding;
4062 b->nextTagBinding = parser->m_freeBindingList;
4063 parser->m_freeBindingList = b;
4064 b->prefix->binding = b->prevPrefixBinding;
4065 }
4066}
4067
4068/* Precondition: all arguments must be non-NULL;
4069 Purpose:
4070 - normalize attributes
4071 - check attributes for well-formedness
4072 - generate namespace aware attribute names (URI, prefix)
4073 - build list of attributes for startElementHandler
4074 - default attributes
4075 - process namespace declarations (check and report them)
4076 - generate namespace aware element name (URI, prefix)
4077*/
4078static enum XML_Error
4079storeAtts(XML_Parser parser, const ENCODING *enc, const char *attStr,
4080 TAG_NAME *tagNamePtr, BINDING **bindingsPtr,
4081 enum XML_Account account) {
4082 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
4083 int attIndex = 0;
4084 XML_Char *uri;
4085 int nPrefixes = 0;
4086/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
4087 int nXMLNSDeclarations = 0;
4088/* END MOZILLA CHANGE */
4089 BINDING *binding;
4090 const XML_Char *localPart;
4091
4092 /* lookup the element type name */
4093 ELEMENT_TYPE *elementType
4094 = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str, 0);
4095 if (! elementType) {
4096 const XML_Char *name = poolCopyString(&dtd->pool, tagNamePtr->str);
4097 if (! name)
4098 return XML_ERROR_NO_MEMORY;
4099 elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
4100 sizeof(ELEMENT_TYPE));
4101 if (! elementType)
4102 return XML_ERROR_NO_MEMORY;
4103 if (! elementType->defaultAttForName.parser)
4104 hashTableInit(&(elementType->defaultAttForName), parser);
4105 if (parser->m_ns && ! setElementTypePrefix(parser, elementType))
4106 return XML_ERROR_NO_MEMORY;
4107 }
4108 const size_t nDefaultAtts = elementType->nDefaultAtts;
4109
4110 /* Detect and prevent integer overflow. */
4111 if (parser->m_attsSize > (size_t)INT_MAX2147483647)
4112 return XML_ERROR_NO_MEMORY;
4113
4114 /* get the attributes from the tokenizer */
4115 size_t n = (size_t)XmlGetAttributes(enc, attStr, (int)parser->m_attsSize,(((enc)->getAtts)(enc, attStr, (int)parser->m_attsSize,
parser->m_atts))
4116 parser->m_atts)(((enc)->getAtts)(enc, attStr, (int)parser->m_attsSize,
parser->m_atts))
;
4117
4118 /* Detect and prevent integer overflow */
4119 if (n > SIZE_MAX(18446744073709551615UL) - nDefaultAtts) {
4120 return XML_ERROR_NO_MEMORY;
4121 }
4122
4123 if (n + nDefaultAtts > parser->m_attsSize) {
4124 size_t oldAttsSize = parser->m_attsSize;
4125
4126 /* Detect and prevent integer overflow */
4127 if ((nDefaultAtts > SIZE_MAX(18446744073709551615UL) - INIT_ATTS_SIZE16)
4128 || (n > SIZE_MAX(18446744073709551615UL) - (nDefaultAtts + INIT_ATTS_SIZE16))) {
4129 return XML_ERROR_NO_MEMORY;
4130 }
4131
4132 parser->m_attsSize = n + nDefaultAtts + INIT_ATTS_SIZE16;
4133
4134 /* Detect and prevent integer overflow. */
4135 if (parser->m_attsSize > SIZE_MAX(18446744073709551615UL) / sizeof(ATTRIBUTE)) {
4136 parser->m_attsSize = oldAttsSize;
4137 return XML_ERROR_NO_MEMORY;
4138 }
4139
4140 ATTRIBUTE *const temp = REALLOC(parser, parser->m_atts,(expat_realloc((parser), (parser->m_atts), (parser->m_attsSize
* sizeof(ATTRIBUTE)), 4141))
4141 parser->m_attsSize * sizeof(ATTRIBUTE))(expat_realloc((parser), (parser->m_atts), (parser->m_attsSize
* sizeof(ATTRIBUTE)), 4141))
;
4142 if (temp == NULL((void*)0)) {
4143 parser->m_attsSize = oldAttsSize;
4144 return XML_ERROR_NO_MEMORY;
4145 }
4146 parser->m_atts = temp;
4147#ifdef XML_ATTR_INFO
4148 /* Detect and prevent integer overflow. */
4149 if (parser->m_attsSize > SIZE_MAX(18446744073709551615UL) / sizeof(XML_AttrInfo)) {
4150 parser->m_attsSize = oldAttsSize;
4151 return XML_ERROR_NO_MEMORY;
4152 }
4153
4154 XML_AttrInfo *const temp2 = REALLOC((expat_realloc((parser), (parser->m_attInfo), (parser->
m_attsSize * sizeof(XML_AttrInfo)), 4155))
4155 parser, parser->m_attInfo, parser->m_attsSize * sizeof(XML_AttrInfo))(expat_realloc((parser), (parser->m_attInfo), (parser->
m_attsSize * sizeof(XML_AttrInfo)), 4155))
;
4156 if (temp2 == NULL((void*)0)) {
4157 parser->m_attsSize = oldAttsSize;
4158 return XML_ERROR_NO_MEMORY;
4159 }
4160 parser->m_attInfo = temp2;
4161#endif
4162 if (n > oldAttsSize) {
4163 /* Detect and prevent integer overflow. */
4164 if (n > (size_t)INT_MAX2147483647)
4165 return XML_ERROR_NO_MEMORY;
4166 XmlGetAttributes(enc, attStr, (int)n, parser->m_atts)(((enc)->getAtts)(enc, attStr, (int)n, parser->m_atts));
4167 }
4168 }
4169
4170 /* the attribute list for the application */
4171 const XML_Char **const appAtts = (const XML_Char **)parser->m_atts;
4172 for (size_t i = 0; i < n; i++) {
4173 ATTRIBUTE *currAtt = &parser->m_atts[i];
4174#ifdef XML_ATTR_INFO
4175 XML_AttrInfo *currAttInfo = &parser->m_attInfo[i];
4176#endif
4177 /* add the name and value to the attribute list */
4178 ATTRIBUTE_ID *attId
4179 = getAttributeId(parser, enc, currAtt->name,
4180 currAtt->name + XmlNameLength(enc, currAtt->name)(((enc)->nameLength)(enc, currAtt->name)));
4181 if (! attId)
4182 return XML_ERROR_NO_MEMORY;
4183#ifdef XML_ATTR_INFO
4184 // NOTE: XML_Index is known to wrap around for >2 GiB content
4185 // on 32bit machines and 64bit Windows, unless (non-default and
4186 // uncommon) XML_LARGE_SIZE is defined.
4187 // That's a bug and it only lives on because we cannot break
4188 // ABI compatibility of public API.
4189 currAttInfo->nameStart
4190 = (XML_Index)(parser->m_parseEndByteIndex
4191 - (parser->m_parseEndPtr - currAtt->name));
4192 currAttInfo->nameEnd
4193 = currAttInfo->nameStart + XmlNameLength(enc, currAtt->name)(((enc)->nameLength)(enc, currAtt->name));
4194 currAttInfo->valueStart
4195 = (XML_Index)(parser->m_parseEndByteIndex
4196 - (parser->m_parseEndPtr - currAtt->valuePtr));
4197 currAttInfo->valueEnd
4198 = (XML_Index)(parser->m_parseEndByteIndex
4199 - (parser->m_parseEndPtr - currAtt->valueEnd));
4200#endif
4201 /* Detect duplicate attributes by their QNames. This does not work when
4202 namespace processing is turned on and different prefixes for the same
4203 namespace are used. For this case we have a check further down.
4204 */
4205 if ((attId->name)[-1]) {
4206 if (enc == parser->m_encoding)
4207 parser->m_eventPtr = parser->m_atts[i].name;
4208 return XML_ERROR_DUPLICATE_ATTRIBUTE;
4209 }
4210 (attId->name)[-1] = 1;
4211 appAtts[attIndex++] = attId->name;
4212 if (! parser->m_atts[i].normalized) {
4213 XML_Bool isCdata = XML_TRUE((XML_Bool)1);
4214
4215 /* figure out whether declared as other than CDATA */
4216 if (attId->maybeTokenized) {
4217 NAME_AND_DEFAULT_ATTRIBUTE *const nameAndDefaultAttribute
4218 = (NAME_AND_DEFAULT_ATTRIBUTE *)lookup(
4219 parser, &(elementType->defaultAttForName), attId->name, 0);
4220 if (nameAndDefaultAttribute != NULL((void*)0)) {
4221 assert(nameAndDefaultAttribute->attIndex < elementType->nDefaultAtts)((void) sizeof ((nameAndDefaultAttribute->attIndex < elementType
->nDefaultAtts) ? 1 : 0), __extension__ ({ if (nameAndDefaultAttribute
->attIndex < elementType->nDefaultAtts) ; else __assert_fail
("nameAndDefaultAttribute->attIndex < elementType->nDefaultAtts"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 4221
, __extension__ __PRETTY_FUNCTION__); }))
;
4222 const DEFAULT_ATTRIBUTE *const att
4223 = elementType->defaultAtts + nameAndDefaultAttribute->attIndex;
4224 isCdata = att->isCdata;
4225 }
4226 }
4227
4228 /* normalize the attribute value */
4229 const enum XML_Error result = storeAttributeValue(
4230 parser, enc, isCdata, parser->m_atts[i].valuePtr,
4231 parser->m_atts[i].valueEnd, &parser->m_tempPool, account);
4232 if (result)
4233 return result;
4234 appAtts[attIndex] = poolStart(&parser->m_tempPool)((&parser->m_tempPool)->start);
4235 poolFinish(&parser->m_tempPool)((&parser->m_tempPool)->start = (&parser->m_tempPool
)->ptr)
;
4236 } else {
4237 /* the value did not need normalizing */
4238 appAtts[attIndex] = poolStoreString(&parser->m_tempPool, enc,
4239 parser->m_atts[i].valuePtr,
4240 parser->m_atts[i].valueEnd);
4241 if (appAtts[attIndex] == 0)
4242 return XML_ERROR_NO_MEMORY;
4243 poolFinish(&parser->m_tempPool)((&parser->m_tempPool)->start = (&parser->m_tempPool
)->ptr)
;
4244 }
4245 /* handle prefixed attribute names */
4246 if (attId->prefix) {
4247 if (attId->xmlns) {
4248 /* deal with namespace declarations here */
4249 enum XML_Error result = addBinding(parser, attId->prefix, attId,
4250 appAtts[attIndex], bindingsPtr);
4251 if (result)
4252 return result;
4253/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
4254#if 0
4255 --attIndex;
4256#else
4257 attIndex++;
4258 nXMLNSDeclarations++;
4259 (attId->name)[-1] = 3;
4260#endif
4261/* END MOZILLA CHANGE */
4262 } else {
4263 /* deal with other prefixed names later */
4264 attIndex++;
4265 nPrefixes++;
4266 (attId->name)[-1] = 2;
4267 }
4268 } else
4269 attIndex++;
4270 }
4271
4272 /* set-up for XML_GetSpecifiedAttributeCount and XML_GetIdAttributeIndex */
4273 parser->m_nSpecifiedAtts = attIndex;
4274 if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
4275 for (int i = 0; i < attIndex; i += 2)
4276 if (appAtts[i] == elementType->idAtt->name) {
4277 parser->m_idAttIndex = i;
4278 break;
4279 }
4280 } else
4281 parser->m_idAttIndex = -1;
4282
4283 /* do attribute defaulting */
4284 for (size_t i = 0; i < nDefaultAtts; i++) {
4285 const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + i;
4286 if (! (da->id->name)[-1] && da->value) {
4287 if (da->id->prefix) {
4288 if (da->id->xmlns) {
4289 enum XML_Error result = addBinding(parser, da->id->prefix, da->id,
4290 da->value, bindingsPtr);
4291 if (result)
4292 return result;
4293/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
4294 (da->id->name)[-1] = 3;
4295 nXMLNSDeclarations++;
4296 appAtts[attIndex++] = da->id->name;
4297 appAtts[attIndex++] = da->value;
4298/* END MOZILLA CHANGE */
4299 } else {
4300 (da->id->name)[-1] = 2;
4301 nPrefixes++;
4302 appAtts[attIndex++] = da->id->name;
4303 appAtts[attIndex++] = da->value;
4304 }
4305 } else {
4306 (da->id->name)[-1] = 1;
4307 appAtts[attIndex++] = da->id->name;
4308 appAtts[attIndex++] = da->value;
4309 }
4310 }
4311 }
4312 appAtts[attIndex] = 0;
4313
4314 /* expand prefixed attribute names, check for duplicates,
4315 and clear flags that say whether attributes were specified */
4316 int i = 0;
4317/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
4318#if 0
4319 if (nPrefixes) {
4320#else
4321 if (nPrefixes || nXMLNSDeclarations) {
4322#endif
4323/* END MOZILLA CHANGE */
4324 unsigned int j; /* hash table index */
4325 unsigned long version = parser->m_nsAttsVersion;
4326
4327 /* Detect and prevent invalid shift */
4328 if (parser->m_nsAttsPower >= sizeof(unsigned int) * 8 /* bits per byte */) {
4329 return XML_ERROR_NO_MEMORY;
4330 }
4331
4332 unsigned int nsAttsSize = 1u << parser->m_nsAttsPower;
4333/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
4334 if (nPrefixes) {
4335/* END MOZILLA CHANGE */
4336 unsigned char oldNsAttsPower = parser->m_nsAttsPower;
4337 /* size of hash table must be at least 2 * (# of prefixed attributes) */
4338 if (parser->m_nsAttsPower == 0
4339 || (nPrefixes >> (parser->m_nsAttsPower - 1))) {
4340 /* hash table size must also be a power of 2 and >= 8 */
4341 while (nPrefixes >> parser->m_nsAttsPower++)
4342 ;
4343 if (parser->m_nsAttsPower < 3)
4344 parser->m_nsAttsPower = 3;
4345
4346 /* Detect and prevent invalid shift */
4347 if (parser->m_nsAttsPower >= sizeof(nsAttsSize) * 8 /* bits per byte */) {
4348 /* Restore actual size of memory in m_nsAtts */
4349 parser->m_nsAttsPower = oldNsAttsPower;
4350 return XML_ERROR_NO_MEMORY;
4351 }
4352
4353 nsAttsSize = 1u << parser->m_nsAttsPower;
4354
4355 /* Detect and prevent integer overflow.
4356 * The preprocessor guard addresses the "always false" warning
4357 * from -Wtype-limits on platforms where
4358 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
4359#if UINT_MAX(2147483647 *2U +1U) >= SIZE_MAX(18446744073709551615UL)
4360 if (nsAttsSize > SIZE_MAX(18446744073709551615UL) / sizeof(NS_ATT)) {
4361 /* Restore actual size of memory in m_nsAtts */
4362 parser->m_nsAttsPower = oldNsAttsPower;
4363 return XML_ERROR_NO_MEMORY;
4364 }
4365#endif
4366
4367 NS_ATT *const temp
4368 = REALLOC(parser, parser->m_nsAtts, nsAttsSize * sizeof(NS_ATT))(expat_realloc((parser), (parser->m_nsAtts), (nsAttsSize *
sizeof(NS_ATT)), 4368))
;
4369 if (! temp) {
4370 /* Restore actual size of memory in m_nsAtts */
4371 parser->m_nsAttsPower = oldNsAttsPower;
4372 return XML_ERROR_NO_MEMORY;
4373 }
4374 parser->m_nsAtts = temp;
4375 version = 0; /* force re-initialization of m_nsAtts hash table */
4376 }
4377 /* using a version flag saves us from initializing m_nsAtts every time */
4378 if (! version) { /* initialize version flags when version wraps around */
4379 version = INIT_ATTS_VERSION0xFFFFFFFF;
4380 for (j = nsAttsSize; j != 0;)
4381 parser->m_nsAtts[--j].version = version;
4382 }
4383 parser->m_nsAttsVersion = --version;
4384/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
4385 }
4386/* END MOZILLA CHANGE */
4387
4388 /* expand prefixed names and check for duplicates */
4389 for (; i < attIndex; i += 2) {
4390 const XML_Char *s = appAtts[i];
4391 if (s[-1] == 2) { /* prefixed */
4392 struct siphash sip_state;
4393 struct sipkey sip_key;
4394
4395 copy_salt_to_sipkey(parser, &sip_key);
4396 sip24_init(&sip_state, &sip_key);
4397
4398 ((XML_Char *)s)[-1] = 0; /* clear flag */
4399 ATTRIBUTE_ID *const id
4400 = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
4401 if (! id || ! id->prefix) {
4402 /* This code is walking through the appAtts array, dealing
4403 * with (in this case) a prefixed attribute name. To be in
4404 * the array, the attribute must have already been bound, so
4405 * has to have passed through the hash table lookup once
4406 * already. That implies that an entry for it already
4407 * exists, so the lookup above will return a pointer to
4408 * already allocated memory. There is no opportunity for
4409 * the allocator to fail, so the condition above cannot be
4410 * fulfilled.
4411 *
4412 * Since it is difficult to be certain that the above
4413 * analysis is complete, we retain the test and merely
4414 * remove the code from coverage tests.
4415 */
4416 return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
4417 }
4418 const BINDING *const b = id->prefix->binding;
4419 if (! b)
4420 return XML_ERROR_UNBOUND_PREFIX;
4421
4422 if (! poolAppendChars(&parser->m_tempPool, b->uri, b->uriLen))
4423 return XML_ERROR_NO_MEMORY;
4424
4425 sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
4426
4427 while (*s++ != XML_T(ASCII_COLON)(uint16_t)0x3A)
4428 ;
4429
4430 sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
4431
4432 {
4433 const size_t len = xcslen(s) + /*null terminator*/ 1;
4434 if (! poolAppendChars(&parser->m_tempPool, s, len))
4435 return XML_ERROR_NO_MEMORY;
4436 }
4437
4438 const unsigned long uriHash = (unsigned long)sip24_final(&sip_state);
4439
4440 { /* Check hash table for duplicate of expanded name (uriName).
4441 Derived from code in lookup(parser, HASH_TABLE *table, ...).
4442 */
4443 unsigned char step = 0;
4444 unsigned long mask = nsAttsSize - 1;
4445 j = uriHash & mask; /* index into hash table */
4446 while (parser->m_nsAtts[j].version == version) {
4447 /* for speed we compare stored hash values first */
4448 if (uriHash == parser->m_nsAtts[j].hash) {
4449 const XML_Char *s1 = poolStart(&parser->m_tempPool)((&parser->m_tempPool)->start);
4450 const XML_Char *s2 = parser->m_nsAtts[j].uriName;
4451 /* s1 is null terminated, but not s2 */
4452 for (; *s1 == *s2 && *s1 != 0; s1++, s2++)
4453 ;
4454 if (*s1 == 0)
4455 return XML_ERROR_DUPLICATE_ATTRIBUTE;
4456 }
4457 if (! step)
4458 step = PROBE_STEP(uriHash, mask, parser->m_nsAttsPower)((unsigned char)((((((uriHash) & ~(mask)) >> ((parser
->m_nsAttsPower) - 1)) & ((mask) >> 2))) | 1))
;
4459 j < step ? (j += nsAttsSize - step) : (j -= step);
4460 }
4461 }
4462
4463 if (parser->m_ns_triplets) { /* append namespace separator and prefix */
4464 parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator;
4465 s = b->prefix->name;
4466 const size_t len = xcslen(s) + /*null terminator*/ 1;
4467 if (! poolAppendChars(&parser->m_tempPool, s, len))
4468 return XML_ERROR_NO_MEMORY;
4469 }
4470
4471 /* store expanded name in attribute list */
4472 s = poolStart(&parser->m_tempPool)((&parser->m_tempPool)->start);
4473 poolFinish(&parser->m_tempPool)((&parser->m_tempPool)->start = (&parser->m_tempPool
)->ptr)
;
4474 appAtts[i] = s;
4475
4476 /* fill empty slot with new version, uriName and hash value */
4477 parser->m_nsAtts[j].version = version;
4478 parser->m_nsAtts[j].hash = uriHash;
4479 parser->m_nsAtts[j].uriName = s;
4480
4481/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
4482#if 0
4483 if (! --nPrefixes) {
4484#else
4485 if (! --nPrefixes && ! nXMLNSDeclarations) {
4486#endif
4487/* END MOZILLA CHANGE */
4488 i += 2;
4489 break;
4490 }
4491/* BEGIN MOZILLA CHANGE (Include xmlns attributes in attributes array) */
4492 } else if (s[-1] == 3) { /* xmlns attribute */
4493 static const XML_Char xmlnsNamespace[] = {
4494 ASCII_h0x68, ASCII_t0x74, ASCII_t0x74, ASCII_p0x70, ASCII_COLON0x3A, ASCII_SLASH0x2F, ASCII_SLASH0x2F,
4495 ASCII_w0x77, ASCII_w0x77, ASCII_w0x77, ASCII_PERIOD0x2E, ASCII_w0x77, ASCII_30x33, ASCII_PERIOD0x2E,
4496 ASCII_o0x6F, ASCII_r0x72, ASCII_g0x67, ASCII_SLASH0x2F, ASCII_20x32, ASCII_00x30, ASCII_00x30, ASCII_00x30,
4497 ASCII_SLASH0x2F, ASCII_x0x78, ASCII_m0x6D, ASCII_l0x6C, ASCII_n0x6E, ASCII_s0x73, ASCII_SLASH0x2F, '\0'
4498 };
4499 static const XML_Char xmlnsPrefix[] = {
4500 ASCII_x0x78, ASCII_m0x6D, ASCII_l0x6C, ASCII_n0x6E, ASCII_s0x73, '\0'
4501 };
4502
4503 ((XML_Char *)s)[-1] = 0; /* clear flag */
4504 if (! poolAppendString(&parser->m_tempPool, xmlnsNamespace)
4505 || ! poolAppendChar(&parser->m_tempPool, parser->m_namespaceSeparator))
4506 return XML_ERROR_NO_MEMORY;
4507 s += sizeof(xmlnsPrefix) / sizeof(xmlnsPrefix[0]) - 1;
4508 if (*s == XML_T(':')(uint16_t)':') {
4509 ++s;
4510 do { /* copies null terminator */
4511 if (! poolAppendChar(&parser->m_tempPool, *s))
4512 return XML_ERROR_NO_MEMORY;
4513 } while (*s++);
4514 if (parser->m_ns_triplets) { /* append namespace separator and prefix */
4515 parser->m_tempPool.ptr[-1] = parser->m_namespaceSeparator;
4516 if (! poolAppendString(&parser->m_tempPool, xmlnsPrefix)
4517 || ! poolAppendChar(&parser->m_tempPool, '\0'))
4518 return XML_ERROR_NO_MEMORY;
4519 }
4520 }
4521 else {
4522 /* xlmns attribute without a prefix. */
4523 if (! poolAppendString(&parser->m_tempPool, xmlnsPrefix)
4524 || ! poolAppendChar(&parser->m_tempPool, '\0'))
4525 return XML_ERROR_NO_MEMORY;
4526 }
4527
4528 /* store expanded name in attribute list */
4529 s = poolStart(&parser->m_tempPool)((&parser->m_tempPool)->start);
4530 poolFinish(&parser->m_tempPool)((&parser->m_tempPool)->start = (&parser->m_tempPool
)->ptr)
;
4531 appAtts[i] = s;
4532
4533 if (! --nXMLNSDeclarations && ! nPrefixes) {
4534 i += 2;
4535 break;
4536 }
4537/* END MOZILLA CHANGE */
4538 } else /* not prefixed */
4539 ((XML_Char *)s)[-1] = 0; /* clear flag */
4540 }
4541 }
4542 /* clear flags for the remaining attributes */
4543 for (; i < attIndex; i += 2)
4544 ((XML_Char *)(appAtts[i]))[-1] = 0;
4545 for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
4546 binding->attId->name[-1] = 0;
4547
4548 if (! parser->m_ns)
4549 return XML_ERROR_NONE;
4550
4551 /* expand the element type name */
4552 if (elementType->prefix) {
4553 binding = elementType->prefix->binding;
4554 if (! binding)
4555 return XML_ERROR_UNBOUND_PREFIX;
4556 localPart = tagNamePtr->str;
4557 while (*localPart++ != XML_T(ASCII_COLON)(uint16_t)0x3A)
4558 ;
4559 } else if (dtd->defaultPrefix.binding) {
4560 binding = dtd->defaultPrefix.binding;
4561 localPart = tagNamePtr->str;
4562 } else
4563 return XML_ERROR_NONE;
4564 size_t prefixLen = 0;
4565 if (parser->m_ns_triplets && binding->prefix->name)
4566 prefixLen = xcslen(binding->prefix->name) + /*null terminator*/ 1;
4567 tagNamePtr->localPart = localPart;
4568 tagNamePtr->uriLen = binding->uriLen;
4569 tagNamePtr->prefix = binding->prefix->name;
4570 tagNamePtr->prefixLen = prefixLen;
4571
4572 const size_t localPartLen = xcslen(localPart) + /*null terminator*/ 1;
4573
4574 /* Detect and prevent integer overflow */
4575 if (binding->uriLen > SIZE_MAX(18446744073709551615UL) - prefixLen
4576 || localPartLen > SIZE_MAX(18446744073709551615UL) - (binding->uriLen + prefixLen)) {
4577 return XML_ERROR_NO_MEMORY;
4578 }
4579
4580 const size_t totalLen = localPartLen + binding->uriLen + prefixLen;
4581 if (totalLen > binding->uriAlloc) {
4582 /* Detect and prevent integer overflow */
4583 if (totalLen > SIZE_MAX(18446744073709551615UL) - EXPAND_SPARE24
4584 || totalLen + EXPAND_SPARE24 > SIZE_MAX(18446744073709551615UL) / sizeof(XML_Char)) {
4585 return XML_ERROR_NO_MEMORY;
4586 }
4587
4588 uri = MALLOC(parser, (totalLen + EXPAND_SPARE) * sizeof(XML_Char))(expat_malloc((parser), ((totalLen + 24) * sizeof(XML_Char)),
4588))
;
4589 if (! uri)
4590 return XML_ERROR_NO_MEMORY;
4591 binding->uriAlloc = totalLen + EXPAND_SPARE24;
4592 memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
4593 for (TAG *p = parser->m_tagStack; p; p = p->parent)
4594 if (p->name.str == binding->uri)
4595 p->name.str = uri;
4596 FREE(parser, binding->uri)(expat_free((parser), (binding->uri), 4596));
4597 binding->uri = uri;
4598 }
4599 /* if m_namespaceSeparator != '\0' then uri includes it already */
4600 uri = binding->uri + binding->uriLen;
4601 /* Detect and prevent integer overflow */
4602 if (localPartLen > SIZE_MAX(18446744073709551615UL) / sizeof(XML_Char)) {
4603 return XML_ERROR_NO_MEMORY;
4604 }
4605 memcpy(uri, localPart, localPartLen * sizeof(XML_Char));
4606 /* we always have a namespace separator between localPart and prefix */
4607 if (prefixLen) {
4608 uri += localPartLen - 1;
4609 *uri = parser->m_namespaceSeparator; /* replace null terminator */
4610 memcpy(uri + 1, binding->prefix->name, prefixLen * sizeof(XML_Char));
4611 }
4612 tagNamePtr->str = binding->uri;
4613 return XML_ERROR_NONE;
4614}
4615
4616static XML_Bool
4617is_rfc3986_uri_char(XML_Char candidate) {
4618 // For the RFC 3986 ANBF grammar see
4619 // https://datatracker.ietf.org/doc/html/rfc3986#appendix-A
4620
4621 switch (candidate) {
4622 // From rule "ALPHA" (uppercase half)
4623 case 'A':
4624 case 'B':
4625 case 'C':
4626 case 'D':
4627 case 'E':
4628 case 'F':
4629 case 'G':
4630 case 'H':
4631 case 'I':
4632 case 'J':
4633 case 'K':
4634 case 'L':
4635 case 'M':
4636 case 'N':
4637 case 'O':
4638 case 'P':
4639 case 'Q':
4640 case 'R':
4641 case 'S':
4642 case 'T':
4643 case 'U':
4644 case 'V':
4645 case 'W':
4646 case 'X':
4647 case 'Y':
4648 case 'Z':
4649
4650 // From rule "ALPHA" (lowercase half)
4651 case 'a':
4652 case 'b':
4653 case 'c':
4654 case 'd':
4655 case 'e':
4656 case 'f':
4657 case 'g':
4658 case 'h':
4659 case 'i':
4660 case 'j':
4661 case 'k':
4662 case 'l':
4663 case 'm':
4664 case 'n':
4665 case 'o':
4666 case 'p':
4667 case 'q':
4668 case 'r':
4669 case 's':
4670 case 't':
4671 case 'u':
4672 case 'v':
4673 case 'w':
4674 case 'x':
4675 case 'y':
4676 case 'z':
4677
4678 // From rule "DIGIT"
4679 case '0':
4680 case '1':
4681 case '2':
4682 case '3':
4683 case '4':
4684 case '5':
4685 case '6':
4686 case '7':
4687 case '8':
4688 case '9':
4689
4690 // From rule "pct-encoded"
4691 case '%':
4692
4693 // From rule "unreserved"
4694 case '-':
4695 case '.':
4696 case '_':
4697 case '~':
4698
4699 // From rule "gen-delims"
4700 case ':':
4701 case '/':
4702 case '?':
4703 case '#':
4704 case '[':
4705 case ']':
4706 case '@':
4707
4708 // From rule "sub-delims"
4709 case '!':
4710 case '$':
4711 case '&':
4712 case '\'':
4713 case '(':
4714 case ')':
4715 case '*':
4716 case '+':
4717 case ',':
4718 case ';':
4719 case '=':
4720 return XML_TRUE((XML_Bool)1);
4721
4722 default:
4723 return XML_FALSE((XML_Bool)0);
4724 }
4725}
4726
4727/* addBinding() overwrites the value of prefix->binding without checking.
4728 Therefore one must keep track of the old value outside of addBinding().
4729*/
4730static enum XML_Error
4731addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
4732 const XML_Char *uri, BINDING **bindingsPtr) {
4733 // "http://www.w3.org/XML/1998/namespace"
4734 static const XML_Char xmlNamespace[]
4735 = {ASCII_h0x68, ASCII_t0x74, ASCII_t0x74, ASCII_p0x70, ASCII_COLON0x3A,
4736 ASCII_SLASH0x2F, ASCII_SLASH0x2F, ASCII_w0x77, ASCII_w0x77, ASCII_w0x77,
4737 ASCII_PERIOD0x2E, ASCII_w0x77, ASCII_30x33, ASCII_PERIOD0x2E, ASCII_o0x6F,
4738 ASCII_r0x72, ASCII_g0x67, ASCII_SLASH0x2F, ASCII_X0x58, ASCII_M0x4D,
4739 ASCII_L0x4C, ASCII_SLASH0x2F, ASCII_10x31, ASCII_90x39, ASCII_90x39,
4740 ASCII_80x38, ASCII_SLASH0x2F, ASCII_n0x6E, ASCII_a0x61, ASCII_m0x6D,
4741 ASCII_e0x65, ASCII_s0x73, ASCII_p0x70, ASCII_a0x61, ASCII_c0x63,
4742 ASCII_e0x65, '\0'};
4743 static const size_t xmlLen = sizeof(xmlNamespace) / sizeof(XML_Char) - 1;
4744 // "http://www.w3.org/2000/xmlns/"
4745 static const XML_Char xmlnsNamespace[]
4746 = {ASCII_h0x68, ASCII_t0x74, ASCII_t0x74, ASCII_p0x70, ASCII_COLON0x3A, ASCII_SLASH0x2F,
4747 ASCII_SLASH0x2F, ASCII_w0x77, ASCII_w0x77, ASCII_w0x77, ASCII_PERIOD0x2E, ASCII_w0x77,
4748 ASCII_30x33, ASCII_PERIOD0x2E, ASCII_o0x6F, ASCII_r0x72, ASCII_g0x67, ASCII_SLASH0x2F,
4749 ASCII_20x32, ASCII_00x30, ASCII_00x30, ASCII_00x30, ASCII_SLASH0x2F, ASCII_x0x78,
4750 ASCII_m0x6D, ASCII_l0x6C, ASCII_n0x6E, ASCII_s0x73, ASCII_SLASH0x2F, '\0'};
4751 static const size_t xmlnsLen = sizeof(xmlnsNamespace) / sizeof(XML_Char) - 1;
4752
4753 XML_Bool mustBeXML = XML_FALSE((XML_Bool)0);
4754 XML_Bool isXML = XML_TRUE((XML_Bool)1);
4755 XML_Bool isXMLNS = XML_TRUE((XML_Bool)1);
4756
4757 BINDING *b;
4758 size_t len;
4759
4760 /* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
4761 if (*uri == XML_T('\0')(uint16_t)'\0' && prefix->name)
4762 return XML_ERROR_UNDECLARING_PREFIX;
4763
4764 if (prefix->name && prefix->name[0] == XML_T(ASCII_x)(uint16_t)0x78
4765 && prefix->name[1] == XML_T(ASCII_m)(uint16_t)0x6D
4766 && prefix->name[2] == XML_T(ASCII_l)(uint16_t)0x6C) {
4767 /* Not allowed to bind xmlns */
4768 if (prefix->name[3] == XML_T(ASCII_n)(uint16_t)0x6E && prefix->name[4] == XML_T(ASCII_s)(uint16_t)0x73
4769 && prefix->name[5] == XML_T('\0')(uint16_t)'\0')
4770 return XML_ERROR_RESERVED_PREFIX_XMLNS;
4771
4772 if (prefix->name[3] == XML_T('\0')(uint16_t)'\0')
4773 mustBeXML = XML_TRUE((XML_Bool)1);
4774 }
4775
4776 for (len = 0; uri[len]; len++) {
4777 /* Detect and prevent integer overflow */
4778 if (len == SIZE_MAX(18446744073709551615UL)) {
4779 return XML_ERROR_NO_MEMORY;
4780 }
4781 if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
4782 isXML = XML_FALSE((XML_Bool)0);
4783
4784 if (! mustBeXML && isXMLNS
4785 && (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
4786 isXMLNS = XML_FALSE((XML_Bool)0);
4787
4788 // NOTE: While Expat does not validate namespace URIs against RFC 3986
4789 // today (and is not REQUIRED to do so with regard to the XML 1.0
4790 // namespaces specification) we have to at least make sure, that
4791 // the application on top of Expat (that is likely splitting expanded
4792 // element names ("qualified names") of form
4793 // "[uri sep] local [sep prefix] '\0'" back into 1, 2 or 3 pieces
4794 // in its element handler code) cannot be confused by an attacker
4795 // putting additional namespace separator characters into namespace
4796 // declarations. That would be ambiguous and not to be expected.
4797 //
4798 // While the HTML API docs of function XML_ParserCreateNS have been
4799 // advising against use of a namespace separator character that can
4800 // appear in a URI for >20 years now, some widespread applications
4801 // are using URI characters (':' (colon) in particular) for a
4802 // namespace separator, in practice. To keep these applications
4803 // functional, we only reject namespaces URIs containing the
4804 // application-chosen namespace separator if the chosen separator
4805 // is a non-URI character with regard to RFC 3986.
4806 if (parser->m_ns && (uri[len] == parser->m_namespaceSeparator)
4807 && ! is_rfc3986_uri_char(uri[len])) {
4808 return XML_ERROR_SYNTAX;
4809 }
4810 }
4811 isXML = isXML && len == xmlLen;
4812 isXMLNS = isXMLNS && len == xmlnsLen;
4813
4814 if (mustBeXML != isXML)
4815 return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
4816 : XML_ERROR_RESERVED_NAMESPACE_URI;
4817
4818 if (isXMLNS)
4819 return XML_ERROR_RESERVED_NAMESPACE_URI;
4820
4821 if (parser->m_namespaceSeparator) {
4822 /* Detect and prevent integer overflow */
4823 if (len == SIZE_MAX(18446744073709551615UL)) {
4824 return XML_ERROR_NO_MEMORY;
4825 }
4826 len++;
4827 }
4828 if (parser->m_freeBindingList) {
4829 b = parser->m_freeBindingList;
4830 if (len > b->uriAlloc) {
4831 /* Detect and prevent integer overflow */
4832 if (len > SIZE_MAX(18446744073709551615UL) - EXPAND_SPARE24
4833 || len + EXPAND_SPARE24 > SIZE_MAX(18446744073709551615UL) / sizeof(XML_Char)) {
4834 return XML_ERROR_NO_MEMORY;
4835 }
4836
4837 XML_Char *temp
4838 = REALLOC(parser, b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE))(expat_realloc((parser), (b->uri), (sizeof(XML_Char) * (len
+ 24)), 4838))
;
4839 if (temp == NULL((void*)0))
4840 return XML_ERROR_NO_MEMORY;
4841 b->uri = temp;
4842 b->uriAlloc = len + EXPAND_SPARE24;
4843 }
4844 parser->m_freeBindingList = b->nextTagBinding;
4845 } else {
4846 b = MALLOC(parser, sizeof(BINDING))(expat_malloc((parser), (sizeof(BINDING)), 4846));
4847 if (! b)
4848 return XML_ERROR_NO_MEMORY;
4849
4850 /* Detect and prevent integer overflow */
4851 if (len > SIZE_MAX(18446744073709551615UL) - EXPAND_SPARE24
4852 || len + EXPAND_SPARE24 > SIZE_MAX(18446744073709551615UL) / sizeof(XML_Char)) {
4853 return XML_ERROR_NO_MEMORY;
4854 }
4855
4856 b->uri = MALLOC(parser, sizeof(XML_Char) * (len + EXPAND_SPARE))(expat_malloc((parser), (sizeof(XML_Char) * (len + 24)), 4856
))
;
4857 if (! b->uri) {
4858 FREE(parser, b)(expat_free((parser), (b), 4858));
4859 return XML_ERROR_NO_MEMORY;
4860 }
4861 b->uriAlloc = len + EXPAND_SPARE24;
4862 }
4863 b->uriLen = len;
4864 memcpy(b->uri, uri, len * sizeof(XML_Char));
4865 if (parser->m_namespaceSeparator)
4866 b->uri[len - 1] = parser->m_namespaceSeparator;
4867 b->prefix = prefix;
4868 b->attId = attId;
4869 b->prevPrefixBinding = prefix->binding;
4870 /* NULL binding when default namespace undeclared */
4871 if (*uri == XML_T('\0')(uint16_t)'\0' && prefix == &parser->m_dtd->defaultPrefix)
4872 prefix->binding = NULL((void*)0);
4873 else
4874 prefix->binding = b;
4875 b->nextTagBinding = *bindingsPtr;
4876 *bindingsPtr = b;
4877 /* if attId == NULL then we are not starting a namespace scope */
4878 if (attId && parser->m_startNamespaceDeclHandler) {
4879 beforeHandler(parser);
4880 parser->m_startNamespaceDeclHandler(parser->m_handlerArg, prefix->name,
4881 prefix->binding ? uri : 0);
4882 afterHandler(parser);
4883 }
4884 return XML_ERROR_NONE;
4885}
4886
4887/* The idea here is to avoid using stack for each CDATA section when
4888 the whole file is parsed with one call.
4889*/
4890static enum XML_Error PTRCALL
4891cdataSectionProcessor(XML_Parser parser, const char *start, const char *end,
4892 const char **endPtr) {
4893 enum XML_Error result = doCdataSection(
4894 parser, parser->m_encoding, &start, end, endPtr,
4895 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_ACCOUNT_DIRECT);
4896 if (result != XML_ERROR_NONE)
4897 return result;
4898 if (start) {
4899 if (parser->m_parentParser) { /* we are parsing an external entity */
4900 parser->m_processor = externalEntityContentProcessor;
4901 return externalEntityContentProcessor(parser, start, end, endPtr);
4902 } else {
4903 parser->m_processor = contentProcessor;
4904 return contentProcessor(parser, start, end, endPtr);
4905 }
4906 }
4907 return result;
4908}
4909
4910/* startPtr gets set to non-null if the section is closed, and to null if
4911 the section is not yet closed.
4912*/
4913static enum XML_Error
4914doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
4915 const char *end, const char **nextPtr, XML_Bool haveMore,
4916 enum XML_Account account) {
4917 const char *s = *startPtr;
4918 const char **eventPP;
4919 const char **eventEndPP;
4920 if (enc == parser->m_encoding) {
4921 eventPP = &parser->m_eventPtr;
4922 *eventPP = s;
4923 eventEndPP = &parser->m_eventEndPtr;
4924 } else {
4925 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
4926 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
4927 }
4928 *eventPP = s;
4929 *startPtr = NULL((void*)0);
4930
4931 for (;;) {
4932 const char *next = s; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
4933 int tok = XmlCdataSectionTok(enc, s, end, &next)(((enc)->scanners[2])(enc, s, end, &next));
4934#if XML_GE1 == 1
4935 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__4935, account)) {
4936 accountingOnAbort(parser);
4937 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
4938 }
4939#else
4940 UNUSED_P(account)(void)account;
4941#endif
4942 *eventEndPP = next;
4943 switch (tok) {
4944 case XML_TOK_CDATA_SECT_CLOSE40:
4945 if (parser->m_endCdataSectionHandler) {
4946 beforeHandler(parser);
4947 parser->m_endCdataSectionHandler(parser->m_handlerArg);
4948 afterHandler(parser);
4949 }
4950 /* BEGIN disabled code */
4951 /* see comment under XML_TOK_CDATA_SECT_OPEN */
4952 else if ((0) && parser->m_characterDataHandler) {
4953 beforeHandler(parser);
4954 parser->m_characterDataHandler(parser->m_handlerArg, parser->m_dataBuf,
4955 0);
4956 afterHandler(parser);
4957 /* END disabled code */
4958 } else if (parser->m_defaultHandler)
4959 reportDefault(parser, enc, s, next);
4960 *startPtr = next;
4961 *nextPtr = next;
4962 if (parser->m_parsingStatus.parsing == XML_FINISHED)
4963 return XML_ERROR_ABORTED;
4964 else
4965 return XML_ERROR_NONE;
4966 case XML_TOK_DATA_NEWLINE7:
4967 if (parser->m_characterDataHandler) {
4968 XML_Char c = 0xA;
4969 beforeHandler(parser);
4970 parser->m_characterDataHandler(parser->m_handlerArg, &c, 1);
4971 afterHandler(parser);
4972 } else if (parser->m_defaultHandler)
4973 reportDefault(parser, enc, s, next);
4974 break;
4975 case XML_TOK_DATA_CHARS6: {
4976 XML_CharacterDataHandler charDataHandler = parser->m_characterDataHandler;
4977 if (charDataHandler) {
4978 if (MUST_CONVERT(enc, s)(! (enc)->isUtf16 || (((uintptr_t)(s)) & 1))) {
4979 for (;;) {
4980 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
4981 const enum XML_Convert_Result convert_res = XmlConvert((((enc)->utf16Convert)(enc, &s, next, &dataPtr, (ICHAR
*)parser->m_dataBufEnd))
4982 enc, &s, next, &dataPtr, (ICHAR *)parser->m_dataBufEnd)(((enc)->utf16Convert)(enc, &s, next, &dataPtr, (ICHAR
*)parser->m_dataBufEnd))
;
4983 *eventEndPP = next;
4984 beforeHandler(parser);
4985 charDataHandler(parser->m_handlerArg, parser->m_dataBuf,
4986 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
4987 afterHandler(parser);
4988 if ((convert_res == XML_CONVERT_COMPLETED)
4989 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
4990 break;
4991 *eventPP = s;
4992 }
4993 } else {
4994 beforeHandler(parser);
4995 charDataHandler(parser->m_handlerArg, (const XML_Char *)s,
4996 (int)((const XML_Char *)next - (const XML_Char *)s));
4997 afterHandler(parser);
4998 }
4999 } else if (parser->m_defaultHandler)
5000 reportDefault(parser, enc, s, next);
5001 } break;
5002 case XML_TOK_INVALID0:
5003 *eventPP = next;
5004 return XML_ERROR_INVALID_TOKEN;
5005 case XML_TOK_PARTIAL_CHAR-2:
5006 if (haveMore) {
5007 *nextPtr = s;
5008 return XML_ERROR_NONE;
5009 }
5010 return XML_ERROR_PARTIAL_CHAR;
5011 case XML_TOK_PARTIAL-1:
5012 case XML_TOK_NONE-4:
5013 if (haveMore) {
5014 *nextPtr = s;
5015 return XML_ERROR_NONE;
5016 }
5017 return XML_ERROR_UNCLOSED_CDATA_SECTION;
5018 default:
5019 /* Every token returned by XmlCdataSectionTok() has its own
5020 * explicit case, so this default case will never be executed.
5021 * We retain it as a safety net and exclude it from the coverage
5022 * statistics.
5023 *
5024 * LCOV_EXCL_START
5025 */
5026 *eventPP = next;
5027 return XML_ERROR_UNEXPECTED_STATE;
5028 /* LCOV_EXCL_STOP */
5029 }
5030
5031 switch (parser->m_parsingStatus.parsing) {
5032 case XML_SUSPENDED:
5033 *eventPP = next;
5034 *nextPtr = next;
5035 return XML_ERROR_NONE;
5036 case XML_FINISHED:
5037 *eventPP = next;
5038 return XML_ERROR_ABORTED;
5039 case XML_PARSING:
5040 if (parser->m_reenter) {
5041 return XML_ERROR_UNEXPECTED_STATE; // LCOV_EXCL_LINE
5042 }
5043 EXPAT_FALLTHROUGH__attribute__((fallthrough));
5044 default:;
5045 *eventPP = s = next;
5046 }
5047 }
5048 /* not reached */
5049}
5050
5051#ifdef XML_DTD
5052
5053/* The idea here is to avoid using stack for each IGNORE section when
5054 the whole file is parsed with one call.
5055*/
5056static enum XML_Error PTRCALL
5057ignoreSectionProcessor(XML_Parser parser, const char *start, const char *end,
5058 const char **endPtr) {
5059 enum XML_Error result
5060 = doIgnoreSection(parser, parser->m_encoding, &start, end, endPtr,
5061 (XML_Bool)! parser->m_parsingStatus.finalBuffer);
5062 if (result != XML_ERROR_NONE)
5063 return result;
5064 if (start) {
5065 parser->m_processor = prologProcessor;
5066 return prologProcessor(parser, start, end, endPtr);
5067 }
5068 return result;
5069}
5070
5071/* startPtr gets set to non-null is the section is closed, and to null
5072 if the section is not yet closed.
5073*/
5074static enum XML_Error
5075doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
5076 const char *end, const char **nextPtr, XML_Bool haveMore) {
5077 const char *next = *startPtr; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
5078 int tok;
5079 const char *s = *startPtr;
5080 const char **eventPP;
5081 const char **eventEndPP;
5082 if (enc == parser->m_encoding) {
5083 eventPP = &parser->m_eventPtr;
5084 *eventPP = s;
5085 eventEndPP = &parser->m_eventEndPtr;
5086 } else {
5087 /* It's not entirely clear, but it seems the following two lines
5088 * of code cannot be executed. The only occasions on which 'enc'
5089 * is not 'encoding' are when this function is called
5090 * from the internal entity processing, and IGNORE sections are an
5091 * error in internal entities.
5092 *
5093 * Since it really isn't clear that this is true, we keep the code
5094 * and just remove it from our coverage tests.
5095 *
5096 * LCOV_EXCL_START
5097 */
5098 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
5099 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
5100 /* LCOV_EXCL_STOP */
5101 }
5102 *eventPP = s;
5103 *startPtr = NULL((void*)0);
5104 tok = XmlIgnoreSectionTok(enc, s, end, &next)(((enc)->scanners[3])(enc, s, end, &next));
5105# if XML_GE1 == 1
5106 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__5106,
5107 XML_ACCOUNT_DIRECT)) {
5108 accountingOnAbort(parser);
5109 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
5110 }
5111# endif
5112 *eventEndPP = next;
5113 switch (tok) {
5114 case XML_TOK_IGNORE_SECT42:
5115 if (parser->m_defaultHandler)
5116 reportDefault(parser, enc, s, next);
5117 *startPtr = next;
5118 *nextPtr = next;
5119 if (parser->m_parsingStatus.parsing == XML_FINISHED)
5120 return XML_ERROR_ABORTED;
5121 else
5122 return XML_ERROR_NONE;
5123 case XML_TOK_INVALID0:
5124 *eventPP = next;
5125 return XML_ERROR_INVALID_TOKEN;
5126 case XML_TOK_PARTIAL_CHAR-2:
5127 if (haveMore) {
5128 *nextPtr = s;
5129 return XML_ERROR_NONE;
5130 }
5131 return XML_ERROR_PARTIAL_CHAR;
5132 case XML_TOK_PARTIAL-1:
5133 case XML_TOK_NONE-4:
5134 if (haveMore) {
5135 *nextPtr = s;
5136 return XML_ERROR_NONE;
5137 }
5138 return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
5139 default:
5140 /* All of the tokens that XmlIgnoreSectionTok() returns have
5141 * explicit cases to handle them, so this default case is never
5142 * executed. We keep it as a safety net anyway, and remove it
5143 * from our test coverage statistics.
5144 *
5145 * LCOV_EXCL_START
5146 */
5147 *eventPP = next;
5148 return XML_ERROR_UNEXPECTED_STATE;
5149 /* LCOV_EXCL_STOP */
5150 }
5151 /* not reached */
5152}
5153
5154#endif /* XML_DTD */
5155
5156static enum XML_Error
5157initializeEncoding(XML_Parser parser) {
5158 const char *s;
5159#ifdef XML_UNICODE
5160 char encodingBuf[128];
5161 /* See comments about `protocolEncodingName` in parserInit() */
5162 if (! parser->m_protocolEncodingName)
5163 s = NULL((void*)0);
5164 else {
5165 int i;
5166 for (i = 0; parser->m_protocolEncodingName[i]; i++) {
5167 if (i == sizeof(encodingBuf) - 1
5168 || (parser->m_protocolEncodingName[i] & ~0x7f) != 0) {
5169 encodingBuf[0] = '\0';
5170 break;
5171 }
5172 encodingBuf[i] = (char)parser->m_protocolEncodingName[i];
5173 }
5174 encodingBuf[i] = '\0';
5175 s = encodingBuf;
5176 }
5177#else
5178 s = parser->m_protocolEncodingName;
5179#endif
5180 if ((parser->m_ns ? XmlInitEncodingNS : XmlInitEncoding)(
5181 &parser->m_initEncoding, &parser->m_encoding, s))
5182 return XML_ERROR_NONE;
5183 return handleUnknownEncoding(parser, parser->m_protocolEncodingName);
5184}
5185
5186static enum XML_Error
5187processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s,
5188 const char *next) {
5189 const char *encodingName = NULL((void*)0);
5190 const XML_Char *storedEncName = NULL((void*)0);
5191 const ENCODING *newEncoding = NULL((void*)0);
5192 const char *version = NULL((void*)0);
5193 const char *versionend = NULL((void*)0);
5194 const XML_Char *storedversion = NULL((void*)0);
5195 int standalone = -1;
5196
5197#if XML_GE1 == 1
5198 if (! accountingDiffTolerated(parser, XML_TOK_XML_DECL12, s, next, __LINE__5198,
5199 XML_ACCOUNT_DIRECT)) {
5200 accountingOnAbort(parser);
5201 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
5202 }
5203#endif
5204
5205 if (! (parser->m_ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)(
5206 isGeneralTextEntity, parser->m_encoding, s, next, &parser->m_eventPtr,
5207 &version, &versionend, &encodingName, &newEncoding, &standalone)) {
5208 if (isGeneralTextEntity)
5209 return XML_ERROR_TEXT_DECL;
5210 else
5211 return XML_ERROR_XML_DECL;
5212 }
5213 if (! isGeneralTextEntity && standalone == 1) {
5214 parser->m_dtd->standalone = XML_TRUE((XML_Bool)1);
5215#ifdef XML_DTD
5216 if (parser->m_paramEntityParsing
5217 == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
5218 parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
5219#endif /* XML_DTD */
5220 }
5221 if (parser->m_xmlDeclHandler) {
5222 if (encodingName != NULL((void*)0)) {
5223 storedEncName = poolStoreString(
5224 &parser->m_temp2Pool, parser->m_encoding, encodingName,
5225 encodingName + XmlNameLength(parser->m_encoding, encodingName)(((parser->m_encoding)->nameLength)(parser->m_encoding
, encodingName))
);
5226 if (! storedEncName)
5227 return XML_ERROR_NO_MEMORY;
5228 poolFinish(&parser->m_temp2Pool)((&parser->m_temp2Pool)->start = (&parser->m_temp2Pool
)->ptr)
;
5229 }
5230 if (version) {
5231 storedversion
5232 = poolStoreString(&parser->m_temp2Pool, parser->m_encoding, version,
5233 versionend - parser->m_encoding->minBytesPerChar);
5234 if (! storedversion)
5235 return XML_ERROR_NO_MEMORY;
5236 }
5237 beforeHandler(parser);
5238 parser->m_xmlDeclHandler(parser->m_handlerArg, storedversion, storedEncName,
5239 standalone);
5240 afterHandler(parser);
5241 } else if (parser->m_defaultHandler)
5242 reportDefault(parser, parser->m_encoding, s, next);
5243 if (parser->m_protocolEncodingName == NULL((void*)0)) {
5244 if (newEncoding) {
5245 /* Check that the specified encoding does not conflict with what
5246 * the parser has already deduced. Do we have the same number
5247 * of bytes in the smallest representation of a character? If
5248 * this is UTF-16, is it the same endianness?
5249 */
5250 if (newEncoding->minBytesPerChar != parser->m_encoding->minBytesPerChar
5251 || (newEncoding->minBytesPerChar == 2
5252 && newEncoding != parser->m_encoding)) {
5253 parser->m_eventPtr = encodingName;
5254 return XML_ERROR_INCORRECT_ENCODING;
5255 }
5256 parser->m_encoding = newEncoding;
5257 } else if (encodingName) {
5258 enum XML_Error result;
5259 if (! storedEncName) {
5260 storedEncName = poolStoreString(
5261 &parser->m_temp2Pool, parser->m_encoding, encodingName,
5262 encodingName + XmlNameLength(parser->m_encoding, encodingName)(((parser->m_encoding)->nameLength)(parser->m_encoding
, encodingName))
);
5263 if (! storedEncName)
5264 return XML_ERROR_NO_MEMORY;
5265 }
5266 result = handleUnknownEncoding(parser, storedEncName);
5267 poolClear(&parser->m_temp2Pool);
5268 if (result == XML_ERROR_UNKNOWN_ENCODING)
5269 parser->m_eventPtr = encodingName;
5270 return result;
5271 }
5272 }
5273
5274 if (storedEncName || storedversion)
5275 poolClear(&parser->m_temp2Pool);
5276
5277 return XML_ERROR_NONE;
5278}
5279
5280static enum XML_Error
5281handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) {
5282 if (parser->m_unknownEncodingHandler) {
5283 XML_Encoding info;
5284 int i;
5285 for (i = 0; i < 256; i++)
5286 info.map[i] = -1;
5287 info.convert = NULL((void*)0);
5288 info.data = NULL((void*)0);
5289 info.release = NULL((void*)0);
5290 beforeHandler(parser);
5291 const int status = parser->m_unknownEncodingHandler(
5292 parser->m_unknownEncodingHandlerData, encodingName, &info);
5293 afterHandler(parser);
5294
5295 parser->m_unknownEncodingRelease = info.release;
5296 parser->m_unknownEncodingData = info.data;
5297
5298 if (status) {
5299 ENCODING *enc;
5300 parser->m_unknownEncodingMem = MALLOC(parser, XmlSizeOfUnknownEncoding())(expat_malloc((parser), (XmlSizeOfUnknownEncoding()), 5300));
5301 if (! parser->m_unknownEncodingMem) {
5302 if (parser->m_unknownEncodingRelease)
5303 callUnknownEncodingRelease(parser);
5304 else
5305 parser->m_unknownEncodingData = NULL((void*)0);
5306 return XML_ERROR_NO_MEMORY;
5307 }
5308 parser->m_unknownEncodingConvert = info.convert;
5309 enc = (parser->m_ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)(
5310 parser->m_unknownEncodingMem, info.map,
5311 info.convert ? callUnknownEncodingConvert : NULL((void*)0), parser);
5312 if (enc) {
5313 parser->m_encoding = enc;
5314 return XML_ERROR_NONE;
5315 }
5316 parser->m_unknownEncodingConvert = NULL((void*)0);
5317 }
5318 if (parser->m_unknownEncodingRelease != NULL((void*)0))
5319 callUnknownEncodingRelease(parser);
5320 else
5321 parser->m_unknownEncodingData = NULL((void*)0);
5322 }
5323 return XML_ERROR_UNKNOWN_ENCODING;
5324}
5325
5326static enum XML_Error PTRCALL
5327prologInitProcessor(XML_Parser parser, const char *s, const char *end,
5328 const char **nextPtr) {
5329 enum XML_Error result = initializeEncoding(parser);
5330 if (result != XML_ERROR_NONE)
5331 return result;
5332 parser->m_processor = prologProcessor;
5333 return prologProcessor(parser, s, end, nextPtr);
5334}
5335
5336#ifdef XML_DTD
5337
5338static enum XML_Error PTRCALL
5339externalParEntInitProcessor(XML_Parser parser, const char *s, const char *end,
5340 const char **nextPtr) {
5341 enum XML_Error result = initializeEncoding(parser);
5342 if (result != XML_ERROR_NONE)
5343 return result;
5344
5345 /* we know now that XML_Parse(Buffer) has been called,
5346 so we consider the external parameter entity read */
5347 parser->m_dtd->paramEntityRead = XML_TRUE((XML_Bool)1);
5348
5349 if (parser->m_prologState.inEntityValue) {
5350 parser->m_processor = entityValueInitProcessor;
5351 return entityValueInitProcessor(parser, s, end, nextPtr);
5352 } else {
5353 parser->m_processor = externalParEntProcessor;
5354 return externalParEntProcessor(parser, s, end, nextPtr);
5355 }
5356}
5357
5358static enum XML_Error PTRCALL
5359entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
5360 const char **nextPtr) {
5361 int tok;
5362 const char *start = s;
5363 const char *next = start;
5364 parser->m_eventPtr = start;
5365
5366 for (;;) {
5367 tok = XmlPrologTok(parser->m_encoding, start, end, &next)(((parser->m_encoding)->scanners[0])(parser->m_encoding
, start, end, &next))
;
5368 /* Note: Except for XML_TOK_BOM below, these bytes are accounted later in:
5369 - storeEntityValue
5370 - processXmlDecl
5371 */
5372 parser->m_eventEndPtr = next;
5373 if (tok <= 0) {
5374 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID0) {
5375 *nextPtr = s;
5376 return XML_ERROR_NONE;
5377 }
5378 switch (tok) {
5379 case XML_TOK_INVALID0:
5380 return XML_ERROR_INVALID_TOKEN;
5381 case XML_TOK_PARTIAL-1:
5382 return XML_ERROR_UNCLOSED_TOKEN;
5383 case XML_TOK_PARTIAL_CHAR-2:
5384 return XML_ERROR_PARTIAL_CHAR;
5385 case XML_TOK_NONE-4: /* start == end */
5386 default:
5387 break;
5388 }
5389 /* found end of entity value - can store it now */
5390 return storeEntityValue(parser, parser->m_encoding, s, end,
5391 XML_ACCOUNT_DIRECT, NULL((void*)0));
5392 } else if (tok == XML_TOK_XML_DECL12) {
5393 enum XML_Error result;
5394 result = processXmlDecl(parser, 0, start, next);
5395 if (result != XML_ERROR_NONE)
5396 return result;
5397 /* At this point, m_parsingStatus.parsing cannot be XML_SUSPENDED. For
5398 * that to happen, a parameter entity parsing handler must have attempted
5399 * to suspend the parser, which fails and raises an error. The parser can
5400 * be aborted, but can't be suspended.
5401 */
5402 if (parser->m_parsingStatus.parsing == XML_FINISHED)
5403 return XML_ERROR_ABORTED;
5404 *nextPtr = next;
5405 /* stop scanning for text declaration - we found one */
5406 parser->m_processor = entityValueProcessor;
5407 return entityValueProcessor(parser, next, end, nextPtr);
5408 }
5409 /* XmlPrologTok has now set the encoding based on the BOM it found, and we
5410 must move s and nextPtr forward to consume the BOM.
5411
5412 If we didn't, and got XML_TOK_NONE from the next XmlPrologTok call, we
5413 would leave the BOM in the buffer and return. On the next call to this
5414 function, our XmlPrologTok call would return XML_TOK_INVALID, since it
5415 is not valid to have multiple BOMs.
5416 */
5417 else if (tok == XML_TOK_BOM14) {
5418# if XML_GE1 == 1
5419 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__5419,
5420 XML_ACCOUNT_DIRECT)) {
5421 accountingOnAbort(parser);
5422 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
5423 }
5424# endif
5425
5426 *nextPtr = next;
5427 s = next;
5428 }
5429 /* If we get this token, we have the start of what might be a
5430 normal tag, but not a declaration (i.e. it doesn't begin with
5431 "<!" or "<?"). In a DTD context, that isn't legal.
5432 */
5433 else if (tok == XML_TOK_INSTANCE_START29) {
5434 *nextPtr = next;
5435 return XML_ERROR_SYNTAX;
5436 }
5437 start = next;
5438 parser->m_eventPtr = start;
5439 }
5440}
5441
5442static enum XML_Error PTRCALL
5443externalParEntProcessor(XML_Parser parser, const char *s, const char *end,
5444 const char **nextPtr) {
5445 const char *next = s;
5446 int tok;
5447
5448 tok = XmlPrologTok(parser->m_encoding, s, end, &next)(((parser->m_encoding)->scanners[0])(parser->m_encoding
, s, end, &next))
;
5449 if (tok <= 0) {
5450 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID0) {
5451 *nextPtr = s;
5452 return XML_ERROR_NONE;
5453 }
5454 switch (tok) {
5455 case XML_TOK_INVALID0:
5456 return XML_ERROR_INVALID_TOKEN;
5457 case XML_TOK_PARTIAL-1:
5458 return XML_ERROR_UNCLOSED_TOKEN;
5459 case XML_TOK_PARTIAL_CHAR-2:
5460 return XML_ERROR_PARTIAL_CHAR;
5461 case XML_TOK_NONE-4: /* start == end */
5462 default:
5463 break;
5464 }
5465 }
5466 /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
5467 However, when parsing an external subset, doProlog will not accept a BOM
5468 as valid, and report a syntax error, so we have to skip the BOM, and
5469 account for the BOM bytes.
5470 */
5471 else if (tok == XML_TOK_BOM14) {
5472 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__5472,
5473 XML_ACCOUNT_DIRECT)) {
5474 accountingOnAbort(parser);
5475 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
5476 }
5477
5478 s = next;
5479 tok = XmlPrologTok(parser->m_encoding, s, end, &next)(((parser->m_encoding)->scanners[0])(parser->m_encoding
, s, end, &next))
;
5480 }
5481
5482 parser->m_processor = prologProcessor;
5483 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
5484 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE((XML_Bool)1),
5485 XML_ACCOUNT_DIRECT);
5486}
5487
5488static enum XML_Error PTRCALL
5489entityValueProcessor(XML_Parser parser, const char *s, const char *end,
5490 const char **nextPtr) {
5491 const char *start = s;
5492 const char *next = s;
5493 const ENCODING *enc = parser->m_encoding;
5494 int tok;
5495
5496 for (;;) {
5497 tok = XmlPrologTok(enc, start, end, &next)(((enc)->scanners[0])(enc, start, end, &next));
5498 /* Note: These bytes are accounted later in:
5499 - storeEntityValue
5500 */
5501 if (tok <= 0) {
5502 if (! parser->m_parsingStatus.finalBuffer && tok != XML_TOK_INVALID0) {
5503 *nextPtr = s;
5504 return XML_ERROR_NONE;
5505 }
5506 switch (tok) {
5507 case XML_TOK_INVALID0:
5508 return XML_ERROR_INVALID_TOKEN;
5509 case XML_TOK_PARTIAL-1:
5510 return XML_ERROR_UNCLOSED_TOKEN;
5511 case XML_TOK_PARTIAL_CHAR-2:
5512 return XML_ERROR_PARTIAL_CHAR;
5513 case XML_TOK_NONE-4: /* start == end */
5514 default:
5515 break;
5516 }
5517 /* found end of entity value - can store it now */
5518 return storeEntityValue(parser, enc, s, end, XML_ACCOUNT_DIRECT, NULL((void*)0));
5519 }
5520 /* If we get this token, we have the start of what might be a
5521 normal tag, but not a declaration (i.e. it doesn't begin with
5522 "<!" or "<?"). In a DTD context, that isn't legal.
5523 */
5524 else if (tok == XML_TOK_INSTANCE_START29) {
5525 *nextPtr = next;
5526 return XML_ERROR_SYNTAX;
5527 }
5528
5529 start = next;
5530 }
5531}
5532
5533#endif /* XML_DTD */
5534
5535static enum XML_Error PTRCALL
5536prologProcessor(XML_Parser parser, const char *s, const char *end,
5537 const char **nextPtr) {
5538 const char *next = s;
5539 int tok = XmlPrologTok(parser->m_encoding, s, end, &next)(((parser->m_encoding)->scanners[0])(parser->m_encoding
, s, end, &next))
;
5540 return doProlog(parser, parser->m_encoding, s, end, tok, next, nextPtr,
5541 (XML_Bool)! parser->m_parsingStatus.finalBuffer, XML_TRUE((XML_Bool)1),
5542 XML_ACCOUNT_DIRECT);
5543}
5544
5545static enum XML_Error
5546doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
5547 int tok, const char *next, const char **nextPtr, XML_Bool haveMore,
5548 XML_Bool allowClosingDoctype, enum XML_Account account) {
5549#ifdef XML_DTD
5550 static const XML_Char externalSubsetName[] = {ASCII_HASH0x23, '\0'};
5551#endif /* XML_DTD */
5552 static const XML_Char atypeCDATA[]
5553 = {ASCII_C0x43, ASCII_D0x44, ASCII_A0x41, ASCII_T0x54, ASCII_A0x41, '\0'};
5554 static const XML_Char atypeID[] = {ASCII_I0x49, ASCII_D0x44, '\0'};
5555 static const XML_Char atypeIDREF[]
5556 = {ASCII_I0x49, ASCII_D0x44, ASCII_R0x52, ASCII_E0x45, ASCII_F0x46, '\0'};
5557 static const XML_Char atypeIDREFS[]
5558 = {ASCII_I0x49, ASCII_D0x44, ASCII_R0x52, ASCII_E0x45, ASCII_F0x46, ASCII_S0x53, '\0'};
5559 static const XML_Char atypeENTITY[]
5560 = {ASCII_E0x45, ASCII_N0x4E, ASCII_T0x54, ASCII_I0x49, ASCII_T0x54, ASCII_Y0x59, '\0'};
5561 static const XML_Char atypeENTITIES[]
5562 = {ASCII_E0x45, ASCII_N0x4E, ASCII_T0x54, ASCII_I0x49, ASCII_T0x54,
5563 ASCII_I0x49, ASCII_E0x45, ASCII_S0x53, '\0'};
5564 static const XML_Char atypeNMTOKEN[]
5565 = {ASCII_N0x4E, ASCII_M0x4D, ASCII_T0x54, ASCII_O0x4F, ASCII_K0x4B, ASCII_E0x45, ASCII_N0x4E, '\0'};
5566 static const XML_Char atypeNMTOKENS[]
5567 = {ASCII_N0x4E, ASCII_M0x4D, ASCII_T0x54, ASCII_O0x4F, ASCII_K0x4B,
5568 ASCII_E0x45, ASCII_N0x4E, ASCII_S0x53, '\0'};
5569 static const XML_Char notationPrefix[]
5570 = {ASCII_N0x4E, ASCII_O0x4F, ASCII_T0x54, ASCII_A0x41, ASCII_T0x54,
5571 ASCII_I0x49, ASCII_O0x4F, ASCII_N0x4E, ASCII_LPAREN0x28, '\0'};
5572 static const XML_Char enumValueSep[] = {ASCII_PIPE0x7C, '\0'};
5573 static const XML_Char enumValueStart[] = {ASCII_LPAREN0x28, '\0'};
5574
5575#ifndef XML_DTD
5576 UNUSED_P(account)(void)account;
5577#endif
5578
5579 /* save one level of indirection */
5580 DTD *const dtd = parser->m_dtd;
5581
5582 const char **eventPP;
5583 const char **eventEndPP;
5584 enum XML_Content_Quant quant;
5585
5586 if (enc == parser->m_encoding) {
5587 eventPP = &parser->m_eventPtr;
5588 eventEndPP = &parser->m_eventEndPtr;
5589 } else {
5590 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
5591 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
5592 }
5593
5594 for (;;) {
5595 int role;
5596 XML_Bool handleDefault = XML_TRUE((XML_Bool)1);
5597 *eventPP = s;
5598 *eventEndPP = next;
5599 if (tok <= 0) {
5600 if (haveMore && tok != XML_TOK_INVALID0) {
5601 *nextPtr = s;
5602 return XML_ERROR_NONE;
5603 }
5604 switch (tok) {
5605 case XML_TOK_INVALID0:
5606 *eventPP = next;
5607 return XML_ERROR_INVALID_TOKEN;
5608 case XML_TOK_PARTIAL-1:
5609 return XML_ERROR_UNCLOSED_TOKEN;
5610 case XML_TOK_PARTIAL_CHAR-2:
5611 return XML_ERROR_PARTIAL_CHAR;
5612 case -XML_TOK_PROLOG_S15:
5613 tok = -tok;
5614 break;
5615 case XML_TOK_NONE-4:
5616#ifdef XML_DTD
5617 /* for internal PE NOT referenced between declarations */
5618 if (enc != parser->m_encoding
5619 && ! parser->m_openInternalEntities->betweenDecl) {
5620 *nextPtr = s;
5621 return XML_ERROR_NONE;
5622 }
5623 /* WFC: PE Between Declarations - must check that PE contains
5624 complete markup, not only for external PEs, but also for
5625 internal PEs if the reference occurs between declarations.
5626 */
5627 if (parser->m_isParamEntity || enc != parser->m_encoding) {
5628 if (XmlTokenRole(&parser->m_prologState, XML_TOK_NONE, end, end, enc)(((&parser->m_prologState)->handler)(&parser->
m_prologState, -4, end, end, enc))
5629 == XML_ROLE_ERROR)
5630 return XML_ERROR_INCOMPLETE_PE;
5631 *nextPtr = s;
5632 return XML_ERROR_NONE;
5633 }
5634#endif /* XML_DTD */
5635 return XML_ERROR_NO_ELEMENTS;
5636 default:
5637 tok = -tok;
5638 next = end;
5639 break;
5640 }
5641 }
5642 role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc)(((&parser->m_prologState)->handler)(&parser->
m_prologState, tok, s, next, enc))
;
5643#if XML_GE1 == 1
5644 switch (role) {
5645 case XML_ROLE_INSTANCE_START: // bytes accounted in contentProcessor
5646 case XML_ROLE_XML_DECL: // bytes accounted in processXmlDecl
5647# ifdef XML_DTD
5648 case XML_ROLE_TEXT_DECL: // bytes accounted in processXmlDecl
5649# endif
5650 break;
5651 default:
5652 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__5652, account)) {
5653 accountingOnAbort(parser);
5654 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
5655 }
5656 }
5657#endif
5658 switch (role) {
5659 case XML_ROLE_XML_DECL: {
5660 enum XML_Error result = processXmlDecl(parser, 0, s, next);
5661 if (result != XML_ERROR_NONE)
5662 return result;
5663 enc = parser->m_encoding;
5664 handleDefault = XML_FALSE((XML_Bool)0);
5665 } break;
5666 case XML_ROLE_DOCTYPE_NAME:
5667 if (parser->m_startDoctypeDeclHandler) {
5668 parser->m_doctypeName
5669 = poolStoreString(&parser->m_tempPool, enc, s, next);
5670 if (! parser->m_doctypeName)
5671 return XML_ERROR_NO_MEMORY;
5672 poolFinish(&parser->m_tempPool)((&parser->m_tempPool)->start = (&parser->m_tempPool
)->ptr)
;
5673 parser->m_doctypePubid = NULL((void*)0);
5674 handleDefault = XML_FALSE((XML_Bool)0);
5675 }
5676 parser->m_doctypeSysid = NULL((void*)0); /* always initialize to NULL */
5677 break;
5678 case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
5679 if (parser->m_startDoctypeDeclHandler) {
5680 beforeHandler(parser);
5681 parser->m_startDoctypeDeclHandler(
5682 parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
5683 parser->m_doctypePubid, 1);
5684 afterHandler(parser);
5685 parser->m_doctypeName = NULL((void*)0);
5686 poolClear(&parser->m_tempPool);
5687 handleDefault = XML_FALSE((XML_Bool)0);
5688 }
5689 break;
5690#ifdef XML_DTD
5691 case XML_ROLE_TEXT_DECL: {
5692 enum XML_Error result = processXmlDecl(parser, 1, s, next);
5693 if (result != XML_ERROR_NONE)
5694 return result;
5695 enc = parser->m_encoding;
5696 handleDefault = XML_FALSE((XML_Bool)0);
5697 } break;
5698#endif /* XML_DTD */
5699 case XML_ROLE_DOCTYPE_PUBLIC_ID:
5700#ifdef XML_DTD
5701 parser->m_useForeignDTD = XML_FALSE((XML_Bool)0);
5702 parser->m_declEntity = (ENTITY *)lookup(
5703 parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
5704 if (! parser->m_declEntity)
5705 return XML_ERROR_NO_MEMORY;
5706#endif /* XML_DTD */
5707 dtd->hasParamEntityRefs = XML_TRUE((XML_Bool)1);
5708 if (parser->m_startDoctypeDeclHandler) {
5709 XML_Char *pubId;
5710 if (! XmlIsPublicId(enc, s, next, eventPP)(((enc)->isPublicId)(enc, s, next, eventPP)))
5711 return XML_ERROR_PUBLICID;
5712 pubId = poolStoreString(&parser->m_tempPool, enc,
5713 s + enc->minBytesPerChar,
5714 next - enc->minBytesPerChar);
5715 if (! pubId)
5716 return XML_ERROR_NO_MEMORY;
5717 normalizePublicId(pubId);
5718 poolFinish(&parser->m_tempPool)((&parser->m_tempPool)->start = (&parser->m_tempPool
)->ptr)
;
5719 parser->m_doctypePubid = pubId;
5720 handleDefault = XML_FALSE((XML_Bool)0);
5721 goto alreadyChecked;
5722 }
5723 EXPAT_FALLTHROUGH__attribute__((fallthrough));
5724 case XML_ROLE_ENTITY_PUBLIC_ID:
5725 if (! XmlIsPublicId(enc, s, next, eventPP)(((enc)->isPublicId)(enc, s, next, eventPP)))
5726 return XML_ERROR_PUBLICID;
5727 alreadyChecked:
5728 if (dtd->keepProcessing && parser->m_declEntity) {
5729 XML_Char *tem
5730 = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
5731 next - enc->minBytesPerChar);
5732 if (! tem)
5733 return XML_ERROR_NO_MEMORY;
5734 normalizePublicId(tem);
5735 parser->m_declEntity->publicId = tem;
5736 poolFinish(&dtd->pool)((&dtd->pool)->start = (&dtd->pool)->ptr);
5737 /* Don't suppress the default handler if we fell through from
5738 * the XML_ROLE_DOCTYPE_PUBLIC_ID case.
5739 */
5740 if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_PUBLIC_ID)
5741 handleDefault = XML_FALSE((XML_Bool)0);
5742 }
5743 break;
5744 case XML_ROLE_DOCTYPE_CLOSE:
5745 if (allowClosingDoctype != XML_TRUE((XML_Bool)1)) {
5746 /* Must not close doctype from within expanded parameter entities */
5747 return XML_ERROR_INVALID_TOKEN;
5748 }
5749
5750 if (parser->m_doctypeName) {
5751 beforeHandler(parser);
5752 parser->m_startDoctypeDeclHandler(
5753 parser->m_handlerArg, parser->m_doctypeName, parser->m_doctypeSysid,
5754 parser->m_doctypePubid, 0);
5755 afterHandler(parser);
5756 poolClear(&parser->m_tempPool);
5757 handleDefault = XML_FALSE((XML_Bool)0);
5758 }
5759 /* parser->m_doctypeSysid will be non-NULL in the case of a previous
5760 XML_ROLE_DOCTYPE_SYSTEM_ID, even if parser->m_startDoctypeDeclHandler
5761 was not set, indicating an external subset
5762 */
5763#ifdef XML_DTD
5764 if (parser->m_doctypeSysid || parser->m_useForeignDTD) {
5765 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
5766 dtd->hasParamEntityRefs = XML_TRUE((XML_Bool)1);
5767 if (parser->m_paramEntityParsing
5768 && parser->m_externalEntityRefHandler) {
5769 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
5770 externalSubsetName, sizeof(ENTITY));
5771 if (! entity) {
5772 /* The external subset name "#" will have already been
5773 * inserted into the hash table at the start of the
5774 * external entity parsing, so no allocation will happen
5775 * and lookup() cannot fail.
5776 */
5777 return XML_ERROR_NO_MEMORY; /* LCOV_EXCL_LINE */
5778 }
5779 if (parser->m_useForeignDTD)
5780 entity->base = parser->m_curBase;
5781 dtd->paramEntityRead = XML_FALSE((XML_Bool)0);
5782 beforeHandler(parser);
5783 const int status = parser->m_externalEntityRefHandler(
5784 parser->m_externalEntityRefHandlerArg, 0, entity->base,
5785 entity->systemId, entity->publicId);
5786 afterHandler(parser);
5787 if (! status)
5788 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5789 if (dtd->paramEntityRead) {
5790 if (! dtd->standalone && parser->m_notStandaloneHandler) {
5791 beforeHandler(parser);
5792 const int handlerStatus
5793 = parser->m_notStandaloneHandler(parser->m_handlerArg);
5794 afterHandler(parser);
5795 if (! handlerStatus)
5796 return XML_ERROR_NOT_STANDALONE;
5797 }
5798 }
5799 /* if we didn't read the foreign DTD then this means that there
5800 is no external subset and we must reset dtd->hasParamEntityRefs
5801 */
5802 else if (! parser->m_doctypeSysid)
5803 dtd->hasParamEntityRefs = hadParamEntityRefs;
5804 /* end of DTD - no need to update dtd->keepProcessing */
5805 }
5806 parser->m_useForeignDTD = XML_FALSE((XML_Bool)0);
5807 }
5808#endif /* XML_DTD */
5809 if (parser->m_endDoctypeDeclHandler) {
5810 beforeHandler(parser);
5811 parser->m_endDoctypeDeclHandler(parser->m_handlerArg);
5812 afterHandler(parser);
5813 handleDefault = XML_FALSE((XML_Bool)0);
5814 }
5815 break;
5816 case XML_ROLE_INSTANCE_START:
5817#ifdef XML_DTD
5818 /* if there is no DOCTYPE declaration then now is the
5819 last chance to read the foreign DTD
5820 */
5821 if (parser->m_useForeignDTD) {
5822 XML_Bool hadParamEntityRefs = dtd->hasParamEntityRefs;
5823 dtd->hasParamEntityRefs = XML_TRUE((XML_Bool)1);
5824 if (parser->m_paramEntityParsing
5825 && parser->m_externalEntityRefHandler) {
5826 ENTITY *entity = (ENTITY *)lookup(parser, &dtd->paramEntities,
5827 externalSubsetName, sizeof(ENTITY));
5828 if (! entity)
5829 return XML_ERROR_NO_MEMORY;
5830 entity->base = parser->m_curBase;
5831 dtd->paramEntityRead = XML_FALSE((XML_Bool)0);
5832 beforeHandler(parser);
5833 const int status = parser->m_externalEntityRefHandler(
5834 parser->m_externalEntityRefHandlerArg, 0, entity->base,
5835 entity->systemId, entity->publicId);
5836 afterHandler(parser);
5837 if (! status)
5838 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
5839 if (dtd->paramEntityRead) {
5840 if (! dtd->standalone && parser->m_notStandaloneHandler) {
5841 beforeHandler(parser);
5842 const int handlerStatus
5843 = parser->m_notStandaloneHandler(parser->m_handlerArg);
5844 afterHandler(parser);
5845 if (! handlerStatus)
5846 return XML_ERROR_NOT_STANDALONE;
5847 }
5848 }
5849 /* if we didn't read the foreign DTD then this means that there
5850 is no external subset and we must reset dtd->hasParamEntityRefs
5851 */
5852 else
5853 dtd->hasParamEntityRefs = hadParamEntityRefs;
5854 /* end of DTD - no need to update dtd->keepProcessing */
5855 }
5856 }
5857#endif /* XML_DTD */
5858 parser->m_processor = contentProcessor;
5859 return contentProcessor(parser, s, end, nextPtr);
5860 case XML_ROLE_ATTLIST_ELEMENT_NAME:
5861 parser->m_declElementType = getElementType(parser, enc, s, next);
5862 if (! parser->m_declElementType)
5863 return XML_ERROR_NO_MEMORY;
5864 goto checkAttListDeclHandler;
5865 case XML_ROLE_ATTRIBUTE_NAME:
5866 parser->m_declAttributeId = getAttributeId(parser, enc, s, next);
5867 if (! parser->m_declAttributeId)
5868 return XML_ERROR_NO_MEMORY;
5869 parser->m_declAttributeIsCdata = XML_FALSE((XML_Bool)0);
5870 parser->m_declAttributeType = NULL((void*)0);
5871 parser->m_declAttributeIsId = XML_FALSE((XML_Bool)0);
5872 goto checkAttListDeclHandler;
5873 case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
5874 parser->m_declAttributeIsCdata = XML_TRUE((XML_Bool)1);
5875 parser->m_declAttributeType = atypeCDATA;
5876 goto checkAttListDeclHandler;
5877 case XML_ROLE_ATTRIBUTE_TYPE_ID:
5878 parser->m_declAttributeIsId = XML_TRUE((XML_Bool)1);
5879 parser->m_declAttributeType = atypeID;
5880 goto checkAttListDeclHandler;
5881 case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
5882 parser->m_declAttributeType = atypeIDREF;
5883 goto checkAttListDeclHandler;
5884 case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
5885 parser->m_declAttributeType = atypeIDREFS;
5886 goto checkAttListDeclHandler;
5887 case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
5888 parser->m_declAttributeType = atypeENTITY;
5889 goto checkAttListDeclHandler;
5890 case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
5891 parser->m_declAttributeType = atypeENTITIES;
5892 goto checkAttListDeclHandler;
5893 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
5894 parser->m_declAttributeType = atypeNMTOKEN;
5895 goto checkAttListDeclHandler;
5896 case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
5897 parser->m_declAttributeType = atypeNMTOKENS;
5898 checkAttListDeclHandler:
5899 if (dtd->keepProcessing && parser->m_attlistDeclHandler)
5900 handleDefault = XML_FALSE((XML_Bool)0);
5901 break;
5902 case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
5903 case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
5904 if (dtd->keepProcessing && parser->m_attlistDeclHandler) {
5905 const XML_Char *prefix;
5906 if (parser->m_declAttributeType) {
5907 prefix = enumValueSep;
5908 } else {
5909 prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE ? notationPrefix
5910 : enumValueStart);
5911 }
5912 if (! poolAppendString(&parser->m_tempPool, prefix))
5913 return XML_ERROR_NO_MEMORY;
5914 if (! poolAppend(&parser->m_tempPool, enc, s, next))
5915 return XML_ERROR_NO_MEMORY;
5916 parser->m_declAttributeType = parser->m_tempPool.start;
5917 handleDefault = XML_FALSE((XML_Bool)0);
5918 }
5919 break;
5920 case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
5921 case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
5922 if (dtd->keepProcessing) {
5923 if (! defineAttribute(parser->m_declElementType,
5924 parser->m_declAttributeId,
5925 parser->m_declAttributeIsCdata,
5926 parser->m_declAttributeIsId, 0, parser))
5927 return XML_ERROR_NO_MEMORY;
5928 if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
5929 if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)(uint16_t)0x28
5930 || (*parser->m_declAttributeType == XML_T(ASCII_N)(uint16_t)0x4E
5931 && parser->m_declAttributeType[1] == XML_T(ASCII_O)(uint16_t)0x4F)) {
5932 /* Enumerated or Notation type */
5933 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)(uint16_t)0x29)
5934 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')(uint16_t)'\0'))
5935 return XML_ERROR_NO_MEMORY;
5936 parser->m_declAttributeType = parser->m_tempPool.start;
5937 poolFinish(&parser->m_tempPool)((&parser->m_tempPool)->start = (&parser->m_tempPool
)->ptr)
;
5938 }
5939 *eventEndPP = s;
5940 beforeHandler(parser);
5941 parser->m_attlistDeclHandler(
5942 parser->m_handlerArg, parser->m_declElementType->name,
5943 parser->m_declAttributeId->name, parser->m_declAttributeType, 0,
5944 role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
5945 afterHandler(parser);
5946 handleDefault = XML_FALSE((XML_Bool)0);
5947 }
5948 }
5949 poolClear(&parser->m_tempPool);
5950 break;
5951 case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
5952 case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
5953 if (dtd->keepProcessing) {
5954 const XML_Char *attVal;
5955 enum XML_Error result = storeAttributeValue(
5956 parser, enc, parser->m_declAttributeIsCdata,
5957 s + enc->minBytesPerChar, next - enc->minBytesPerChar, &dtd->pool,
5958 XML_ACCOUNT_NONE);
5959 if (result)
5960 return result;
5961 attVal = poolStart(&dtd->pool)((&dtd->pool)->start);
5962 poolFinish(&dtd->pool)((&dtd->pool)->start = (&dtd->pool)->ptr);
5963 /* ID attributes aren't allowed to have a default */
5964 if (! defineAttribute(
5965 parser->m_declElementType, parser->m_declAttributeId,
5966 parser->m_declAttributeIsCdata, XML_FALSE((XML_Bool)0), attVal, parser))
5967 return XML_ERROR_NO_MEMORY;
5968 if (parser->m_attlistDeclHandler && parser->m_declAttributeType) {
5969 if (*parser->m_declAttributeType == XML_T(ASCII_LPAREN)(uint16_t)0x28
5970 || (*parser->m_declAttributeType == XML_T(ASCII_N)(uint16_t)0x4E
5971 && parser->m_declAttributeType[1] == XML_T(ASCII_O)(uint16_t)0x4F)) {
5972 /* Enumerated or Notation type */
5973 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_RPAREN)(uint16_t)0x29)
5974 || ! poolAppendChar(&parser->m_tempPool, XML_T('\0')(uint16_t)'\0'))
5975 return XML_ERROR_NO_MEMORY;
5976 parser->m_declAttributeType = parser->m_tempPool.start;
5977 poolFinish(&parser->m_tempPool)((&parser->m_tempPool)->start = (&parser->m_tempPool
)->ptr)
;
5978 }
5979 *eventEndPP = s;
5980 beforeHandler(parser);
5981 parser->m_attlistDeclHandler(
5982 parser->m_handlerArg, parser->m_declElementType->name,
5983 parser->m_declAttributeId->name, parser->m_declAttributeType,
5984 attVal, role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
5985 afterHandler(parser);
5986 poolClear(&parser->m_tempPool);
5987 handleDefault = XML_FALSE((XML_Bool)0);
5988 }
5989 }
5990 break;
5991 case XML_ROLE_ENTITY_VALUE:
5992 if (dtd->keepProcessing) {
5993#if XML_GE1 == 1
5994 // This will store the given replacement text in
5995 // parser->m_declEntity->textPtr.
5996 enum XML_Error result = callStoreEntityValue(
5997 parser, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar,
5998 XML_ACCOUNT_NONE);
5999 if (parser->m_declEntity) {
6000 /* Detect and prevent signed integer overflow */
6001 if ((size_t)poolLength(&dtd->entityValuePool)((&dtd->entityValuePool)->ptr - (&dtd->entityValuePool
)->start)
> (size_t)INT_MAX2147483647) {
6002 return XML_ERROR_NO_MEMORY;
6003 }
6004 parser->m_declEntity->textPtr = poolStart(&dtd->entityValuePool)((&dtd->entityValuePool)->start);
6005 parser->m_declEntity->textLen
6006 = (int)(poolLength(&dtd->entityValuePool)((&dtd->entityValuePool)->ptr - (&dtd->entityValuePool
)->start)
);
6007 poolFinish(&dtd->entityValuePool)((&dtd->entityValuePool)->start = (&dtd->entityValuePool
)->ptr)
;
6008 if (parser->m_entityDeclHandler) {
6009 *eventEndPP = s;
6010 beforeHandler(parser);
6011 parser->m_entityDeclHandler(
6012 parser->m_handlerArg, parser->m_declEntity->name,
6013 parser->m_declEntity->is_param, parser->m_declEntity->textPtr,
6014 parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0);
6015 afterHandler(parser);
6016 handleDefault = XML_FALSE((XML_Bool)0);
6017 }
6018 } else
6019 poolDiscard(&dtd->entityValuePool)((&dtd->entityValuePool)->ptr = (&dtd->entityValuePool
)->start)
;
6020 if (result != XML_ERROR_NONE)
6021 return result;
6022#else
6023 // This will store "&amp;entity123;" in parser->m_declEntity->textPtr
6024 // to end up as "&entity123;" in the handler.
6025 if (parser->m_declEntity != NULL((void*)0)) {
6026 const enum XML_Error result
6027 = storeSelfEntityValue(parser, parser->m_declEntity);
6028 if (result != XML_ERROR_NONE)
6029 return result;
6030
6031 if (parser->m_entityDeclHandler) {
6032 *eventEndPP = s;
6033 beforeHandler(parser);
6034 parser->m_entityDeclHandler(
6035 parser->m_handlerArg, parser->m_declEntity->name,
6036 parser->m_declEntity->is_param, parser->m_declEntity->textPtr,
6037 parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0);
6038 afterHandler(parser);
6039 handleDefault = XML_FALSE((XML_Bool)0);
6040 }
6041 }
6042#endif
6043 }
6044 break;
6045 case XML_ROLE_DOCTYPE_SYSTEM_ID:
6046#ifdef XML_DTD
6047 parser->m_useForeignDTD = XML_FALSE((XML_Bool)0);
6048#endif /* XML_DTD */
6049 dtd->hasParamEntityRefs = XML_TRUE((XML_Bool)1);
6050 if (parser->m_startDoctypeDeclHandler) {
6051 parser->m_doctypeSysid = poolStoreString(&parser->m_tempPool, enc,
6052 s + enc->minBytesPerChar,
6053 next - enc->minBytesPerChar);
6054 if (parser->m_doctypeSysid == NULL((void*)0))
6055 return XML_ERROR_NO_MEMORY;
6056 poolFinish(&parser->m_tempPool)((&parser->m_tempPool)->start = (&parser->m_tempPool
)->ptr)
;
6057 handleDefault = XML_FALSE((XML_Bool)0);
6058 }
6059#ifdef XML_DTD
6060 else
6061 /* use externalSubsetName to make parser->m_doctypeSysid non-NULL
6062 for the case where no parser->m_startDoctypeDeclHandler is set */
6063 parser->m_doctypeSysid = externalSubsetName;
6064#endif /* XML_DTD */
6065 if (! dtd->standalone
6066#ifdef XML_DTD
6067 && ! parser->m_paramEntityParsing
6068#endif /* XML_DTD */
6069 && parser->m_notStandaloneHandler) {
6070 beforeHandler(parser);
6071 const int status = parser->m_notStandaloneHandler(parser->m_handlerArg);
6072 afterHandler(parser);
6073 if (! status)
6074 return XML_ERROR_NOT_STANDALONE;
6075 }
6076#ifndef XML_DTD
6077 break;
6078#else /* XML_DTD */
6079 if (! parser->m_declEntity) {
6080 parser->m_declEntity = (ENTITY *)lookup(
6081 parser, &dtd->paramEntities, externalSubsetName, sizeof(ENTITY));
6082 if (! parser->m_declEntity)
6083 return XML_ERROR_NO_MEMORY;
6084 parser->m_declEntity->publicId = NULL((void*)0);
6085 }
6086#endif /* XML_DTD */
6087 EXPAT_FALLTHROUGH__attribute__((fallthrough));
6088 case XML_ROLE_ENTITY_SYSTEM_ID:
6089 if (dtd->keepProcessing && parser->m_declEntity) {
6090 parser->m_declEntity->systemId
6091 = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
6092 next - enc->minBytesPerChar);
6093 if (! parser->m_declEntity->systemId)
6094 return XML_ERROR_NO_MEMORY;
6095 parser->m_declEntity->base = parser->m_curBase;
6096 poolFinish(&dtd->pool)((&dtd->pool)->start = (&dtd->pool)->ptr);
6097 /* Don't suppress the default handler if we fell through from
6098 * the XML_ROLE_DOCTYPE_SYSTEM_ID case.
6099 */
6100 if (parser->m_entityDeclHandler && role == XML_ROLE_ENTITY_SYSTEM_ID)
6101 handleDefault = XML_FALSE((XML_Bool)0);
6102 }
6103 break;
6104 case XML_ROLE_ENTITY_COMPLETE:
6105#if XML_GE1 == 0
6106 // This will store "&amp;entity123;" in entity->textPtr
6107 // to end up as "&entity123;" in the handler.
6108 if (parser->m_declEntity != NULL((void*)0)) {
6109 const enum XML_Error result
6110 = storeSelfEntityValue(parser, parser->m_declEntity);
6111 if (result != XML_ERROR_NONE)
6112 return result;
6113 }
6114#endif
6115 if (dtd->keepProcessing && parser->m_declEntity
6116 && parser->m_entityDeclHandler) {
6117 *eventEndPP = s;
6118 beforeHandler(parser);
6119 parser->m_entityDeclHandler(
6120 parser->m_handlerArg, parser->m_declEntity->name,
6121 parser->m_declEntity->is_param, 0, 0, parser->m_declEntity->base,
6122 parser->m_declEntity->systemId, parser->m_declEntity->publicId, 0);
6123 afterHandler(parser);
6124 handleDefault = XML_FALSE((XML_Bool)0);
6125 }
6126 break;
6127 case XML_ROLE_ENTITY_NOTATION_NAME:
6128 if (dtd->keepProcessing && parser->m_declEntity) {
6129 parser->m_declEntity->notation
6130 = poolStoreString(&dtd->pool, enc, s, next);
6131 if (! parser->m_declEntity->notation)
6132 return XML_ERROR_NO_MEMORY;
6133 poolFinish(&dtd->pool)((&dtd->pool)->start = (&dtd->pool)->ptr);
6134 if (parser->m_unparsedEntityDeclHandler) {
6135 *eventEndPP = s;
6136 beforeHandler(parser);
6137 parser->m_unparsedEntityDeclHandler(
6138 parser->m_handlerArg, parser->m_declEntity->name,
6139 parser->m_declEntity->base, parser->m_declEntity->systemId,
6140 parser->m_declEntity->publicId, parser->m_declEntity->notation);
6141 afterHandler(parser);
6142 handleDefault = XML_FALSE((XML_Bool)0);
6143 } else if (parser->m_entityDeclHandler) {
6144 *eventEndPP = s;
6145 beforeHandler(parser);
6146 parser->m_entityDeclHandler(
6147 parser->m_handlerArg, parser->m_declEntity->name, 0, 0, 0,
6148 parser->m_declEntity->base, parser->m_declEntity->systemId,
6149 parser->m_declEntity->publicId, parser->m_declEntity->notation);
6150 afterHandler(parser);
6151 handleDefault = XML_FALSE((XML_Bool)0);
6152 }
6153 }
6154 break;
6155 case XML_ROLE_GENERAL_ENTITY_NAME: {
6156 if (XmlPredefinedEntityName(enc, s, next)(((enc)->predefinedEntityName)(enc, s, next))) {
6157 parser->m_declEntity = NULL((void*)0);
6158 break;
6159 }
6160 if (dtd->keepProcessing) {
6161 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
6162 if (! name)
6163 return XML_ERROR_NO_MEMORY;
6164 parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->generalEntities,
6165 name, sizeof(ENTITY));
6166 if (! parser->m_declEntity)
6167 return XML_ERROR_NO_MEMORY;
6168 if (parser->m_declEntity->name != name) {
6169 poolDiscard(&dtd->pool)((&dtd->pool)->ptr = (&dtd->pool)->start);
6170 parser->m_declEntity = NULL((void*)0);
6171 } else {
6172 poolFinish(&dtd->pool)((&dtd->pool)->start = (&dtd->pool)->ptr);
6173 parser->m_declEntity->publicId = NULL((void*)0);
6174 parser->m_declEntity->is_param = XML_FALSE((XML_Bool)0);
6175 /* if we have a parent parser or are reading an internal parameter
6176 entity, then the entity declaration is not considered "internal"
6177 */
6178 parser->m_declEntity->is_internal
6179 = ! (parser->m_parentParser || parser->m_openInternalEntities);
6180 if (parser->m_entityDeclHandler)
6181 handleDefault = XML_FALSE((XML_Bool)0);
6182 }
6183 } else {
6184 poolDiscard(&dtd->pool)((&dtd->pool)->ptr = (&dtd->pool)->start);
6185 parser->m_declEntity = NULL((void*)0);
6186 }
6187 } break;
6188 case XML_ROLE_PARAM_ENTITY_NAME:
6189#ifdef XML_DTD
6190 if (dtd->keepProcessing) {
6191 const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
6192 if (! name)
6193 return XML_ERROR_NO_MEMORY;
6194 parser->m_declEntity = (ENTITY *)lookup(parser, &dtd->paramEntities,
6195 name, sizeof(ENTITY));
6196 if (! parser->m_declEntity)
6197 return XML_ERROR_NO_MEMORY;
6198 if (parser->m_declEntity->name != name) {
6199 poolDiscard(&dtd->pool)((&dtd->pool)->ptr = (&dtd->pool)->start);
6200 parser->m_declEntity = NULL((void*)0);
6201 } else {
6202 poolFinish(&dtd->pool)((&dtd->pool)->start = (&dtd->pool)->ptr);
6203 parser->m_declEntity->publicId = NULL((void*)0);
6204 parser->m_declEntity->is_param = XML_TRUE((XML_Bool)1);
6205 /* if we have a parent parser or are reading an internal parameter
6206 entity, then the entity declaration is not considered "internal"
6207 */
6208 parser->m_declEntity->is_internal
6209 = ! (parser->m_parentParser || parser->m_openInternalEntities);
6210 if (parser->m_entityDeclHandler)
6211 handleDefault = XML_FALSE((XML_Bool)0);
6212 }
6213 } else {
6214 poolDiscard(&dtd->pool)((&dtd->pool)->ptr = (&dtd->pool)->start);
6215 parser->m_declEntity = NULL((void*)0);
6216 }
6217#else /* not XML_DTD */
6218 parser->m_declEntity = NULL((void*)0);
6219#endif /* XML_DTD */
6220 break;
6221 case XML_ROLE_NOTATION_NAME:
6222 parser->m_declNotationPublicId = NULL((void*)0);
6223 parser->m_declNotationName = NULL((void*)0);
6224 if (parser->m_notationDeclHandler) {
6225 parser->m_declNotationName
6226 = poolStoreString(&parser->m_tempPool, enc, s, next);
6227 if (! parser->m_declNotationName)
6228 return XML_ERROR_NO_MEMORY;
6229 poolFinish(&parser->m_tempPool)((&parser->m_tempPool)->start = (&parser->m_tempPool
)->ptr)
;
6230 handleDefault = XML_FALSE((XML_Bool)0);
6231 }
6232 break;
6233 case XML_ROLE_NOTATION_PUBLIC_ID:
6234 if (! XmlIsPublicId(enc, s, next, eventPP)(((enc)->isPublicId)(enc, s, next, eventPP)))
6235 return XML_ERROR_PUBLICID;
6236 if (parser
6237 ->m_declNotationName) { /* means m_notationDeclHandler != NULL */
6238 XML_Char *tem = poolStoreString(&parser->m_tempPool, enc,
6239 s + enc->minBytesPerChar,
6240 next - enc->minBytesPerChar);
6241 if (! tem)
6242 return XML_ERROR_NO_MEMORY;
6243 normalizePublicId(tem);
6244 parser->m_declNotationPublicId = tem;
6245 poolFinish(&parser->m_tempPool)((&parser->m_tempPool)->start = (&parser->m_tempPool
)->ptr)
;
6246 handleDefault = XML_FALSE((XML_Bool)0);
6247 }
6248 break;
6249 case XML_ROLE_NOTATION_SYSTEM_ID:
6250 if (parser->m_declNotationName && parser->m_notationDeclHandler) {
6251 const XML_Char *systemId = poolStoreString(&parser->m_tempPool, enc,
6252 s + enc->minBytesPerChar,
6253 next - enc->minBytesPerChar);
6254 if (! systemId)
6255 return XML_ERROR_NO_MEMORY;
6256 *eventEndPP = s;
6257 beforeHandler(parser);
6258 parser->m_notationDeclHandler(
6259 parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
6260 systemId, parser->m_declNotationPublicId);
6261 afterHandler(parser);
6262 handleDefault = XML_FALSE((XML_Bool)0);
6263 }
6264 poolClear(&parser->m_tempPool);
6265 break;
6266 case XML_ROLE_NOTATION_NO_SYSTEM_ID:
6267 if (parser->m_declNotationPublicId && parser->m_notationDeclHandler) {
6268 *eventEndPP = s;
6269 beforeHandler(parser);
6270 parser->m_notationDeclHandler(
6271 parser->m_handlerArg, parser->m_declNotationName, parser->m_curBase,
6272 0, parser->m_declNotationPublicId);
6273 afterHandler(parser);
6274 handleDefault = XML_FALSE((XML_Bool)0);
6275 }
6276 poolClear(&parser->m_tempPool);
6277 break;
6278 case XML_ROLE_ERROR:
6279 switch (tok) {
6280 case XML_TOK_PARAM_ENTITY_REF28:
6281 /* PE references in internal subset are
6282 not allowed within declarations. */
6283 return XML_ERROR_PARAM_ENTITY_REF;
6284 case XML_TOK_XML_DECL12:
6285 return XML_ERROR_MISPLACED_XML_PI;
6286 default:
6287 return XML_ERROR_SYNTAX;
6288 }
6289#ifdef XML_DTD
6290 case XML_ROLE_IGNORE_SECT: {
6291 enum XML_Error result;
6292 if (parser->m_defaultHandler)
6293 reportDefault(parser, enc, s, next);
6294 handleDefault = XML_FALSE((XML_Bool)0);
6295 result = doIgnoreSection(parser, enc, &next, end, nextPtr, haveMore);
6296 if (result != XML_ERROR_NONE)
6297 return result;
6298 else if (! next) {
6299 parser->m_processor = ignoreSectionProcessor;
6300 return result;
6301 }
6302 } break;
6303#endif /* XML_DTD */
6304 case XML_ROLE_GROUP_OPEN:
6305 if (parser->m_prologState.level >= parser->m_groupSize) {
6306 if (parser->m_groupSize) {
6307 /* Detect and prevent integer overflow */
6308 if (parser->m_groupSize > SIZE_MAX(18446744073709551615UL) / 2) {
6309 return XML_ERROR_NO_MEMORY;
6310 }
6311
6312 char *const new_connector = REALLOC(parser, parser->m_groupConnector,(expat_realloc((parser), (parser->m_groupConnector), (parser
->m_groupSize *= 2), 6313))
6313 parser->m_groupSize *= 2)(expat_realloc((parser), (parser->m_groupConnector), (parser
->m_groupSize *= 2), 6313))
;
6314 if (new_connector == NULL((void*)0)) {
6315 parser->m_groupSize /= 2;
6316 return XML_ERROR_NO_MEMORY;
6317 }
6318 parser->m_groupConnector = new_connector;
6319 } else {
6320 parser->m_groupConnector = MALLOC(parser, parser->m_groupSize = 32)(expat_malloc((parser), (parser->m_groupSize = 32), 6320));
6321 if (! parser->m_groupConnector) {
6322 parser->m_groupSize = 0;
6323 return XML_ERROR_NO_MEMORY;
6324 }
6325 }
6326 }
6327 parser->m_groupConnector[parser->m_prologState.level] = 0;
6328 if (dtd->in_eldecl) {
6329 int myindex = nextScaffoldPart(parser);
6330 if (myindex < 0)
6331 return XML_ERROR_NO_MEMORY;
6332 assert(dtd->scaffIndex != NULL)((void) sizeof ((dtd->scaffIndex != ((void*)0)) ? 1 : 0), __extension__
({ if (dtd->scaffIndex != ((void*)0)) ; else __assert_fail
("dtd->scaffIndex != NULL", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 6332, __extension__ __PRETTY_FUNCTION__); }))
;
6333 if ((size_t)dtd->scaffLevel >= dtd->scaffIndexSize) {
6334 /* Detect and prevent integer overflow */
6335 if (dtd->scaffIndexSize > SIZE_MAX(18446744073709551615UL) / 2 / sizeof(int)) {
6336 return XML_ERROR_NO_MEMORY;
6337 }
6338 assert(dtd->scaffIndexSize > 0)((void) sizeof ((dtd->scaffIndexSize > 0) ? 1 : 0), __extension__
({ if (dtd->scaffIndexSize > 0) ; else __assert_fail (
"dtd->scaffIndexSize > 0", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 6338, __extension__ __PRETTY_FUNCTION__); }))
;
6339 const size_t new_size = dtd->scaffIndexSize * 2;
6340 int *const new_scaff_index
6341 = REALLOC(parser, dtd->scaffIndex, new_size * sizeof(int))(expat_realloc((parser), (dtd->scaffIndex), (new_size * sizeof
(int)), 6341))
;
6342 if (new_scaff_index == NULL((void*)0)) {
6343 return XML_ERROR_NO_MEMORY;
6344 }
6345 dtd->scaffIndex = new_scaff_index;
6346 dtd->scaffIndexSize = new_size;
6347 }
6348 dtd->scaffIndex[dtd->scaffLevel] = myindex;
6349 dtd->scaffLevel++;
6350 dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
6351 if (parser->m_elementDeclHandler)
6352 handleDefault = XML_FALSE((XML_Bool)0);
6353 }
6354 break;
6355 case XML_ROLE_GROUP_SEQUENCE:
6356 if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_PIPE0x7C)
6357 return XML_ERROR_SYNTAX;
6358 parser->m_groupConnector[parser->m_prologState.level] = ASCII_COMMA0x2C;
6359 if (dtd->in_eldecl && parser->m_elementDeclHandler)
6360 handleDefault = XML_FALSE((XML_Bool)0);
6361 break;
6362 case XML_ROLE_GROUP_CHOICE:
6363 if (parser->m_groupConnector[parser->m_prologState.level] == ASCII_COMMA0x2C)
6364 return XML_ERROR_SYNTAX;
6365 if (dtd->in_eldecl
6366 && ! parser->m_groupConnector[parser->m_prologState.level]
6367 && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
6368 != XML_CTYPE_MIXED)) {
6369 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
6370 = XML_CTYPE_CHOICE;
6371 if (parser->m_elementDeclHandler)
6372 handleDefault = XML_FALSE((XML_Bool)0);
6373 }
6374 parser->m_groupConnector[parser->m_prologState.level] = ASCII_PIPE0x7C;
6375 break;
6376 case XML_ROLE_PARAM_ENTITY_REF:
6377#ifdef XML_DTD
6378 case XML_ROLE_INNER_PARAM_ENTITY_REF:
6379 dtd->hasParamEntityRefs = XML_TRUE((XML_Bool)1);
6380 if (! parser->m_paramEntityParsing)
6381 dtd->keepProcessing = dtd->standalone;
6382 else {
6383 const XML_Char *name;
6384 ENTITY *entity;
6385 name = poolStoreString(&dtd->pool, enc, s + enc->minBytesPerChar,
6386 next - enc->minBytesPerChar);
6387 if (! name)
6388 return XML_ERROR_NO_MEMORY;
6389 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
6390 poolDiscard(&dtd->pool)((&dtd->pool)->ptr = (&dtd->pool)->start);
6391 /* first, determine if a check for an existing declaration is needed;
6392 if yes, check that the entity exists, and that it is internal,
6393 otherwise call the skipped entity handler
6394 */
6395 if (parser->m_prologState.documentEntity
6396 && (dtd->standalone ? ! parser->m_openInternalEntities
6397 : ! dtd->hasParamEntityRefs)) {
6398 if (! entity)
6399 return XML_ERROR_UNDEFINED_ENTITY;
6400 else if (! entity->is_internal) {
6401 /* It's hard to exhaustively search the code to be sure,
6402 * but there doesn't seem to be a way of executing the
6403 * following line. There are two cases:
6404 *
6405 * If 'standalone' is false, the DTD must have no
6406 * parameter entities or we wouldn't have passed the outer
6407 * 'if' statement. That means the only entity in the hash
6408 * table is the external subset name "#" which cannot be
6409 * given as a parameter entity name in XML syntax, so the
6410 * lookup must have returned NULL and we don't even reach
6411 * the test for an internal entity.
6412 *
6413 * If 'standalone' is true, it does not seem to be
6414 * possible to create entities taking this code path that
6415 * are not internal entities, so fail the test above.
6416 *
6417 * Because this analysis is very uncertain, the code is
6418 * being left in place and merely removed from the
6419 * coverage test statistics.
6420 */
6421 return XML_ERROR_ENTITY_DECLARED_IN_PE; /* LCOV_EXCL_LINE */
6422 }
6423 } else if (! entity) {
6424 dtd->keepProcessing = dtd->standalone;
6425 /* cannot report skipped entities in declarations */
6426 if ((role == XML_ROLE_PARAM_ENTITY_REF)
6427 && parser->m_skippedEntityHandler) {
6428 beforeHandler(parser);
6429 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 1);
6430 afterHandler(parser);
6431 handleDefault = XML_FALSE((XML_Bool)0);
6432 }
6433 break;
6434 }
6435 if (entity->open)
6436 return XML_ERROR_RECURSIVE_ENTITY_REF;
6437 if (entity->textPtr) {
6438 enum XML_Error result;
6439 XML_Bool betweenDecl
6440 = (role == XML_ROLE_PARAM_ENTITY_REF ? XML_TRUE((XML_Bool)1) : XML_FALSE((XML_Bool)0));
6441 result = processEntity(parser, entity, betweenDecl, ENTITY_INTERNAL);
6442 if (result != XML_ERROR_NONE)
6443 return result;
6444 handleDefault = XML_FALSE((XML_Bool)0);
6445 break;
6446 }
6447 if (parser->m_externalEntityRefHandler) {
6448 dtd->paramEntityRead = XML_FALSE((XML_Bool)0);
6449 entity->open = true1;
6450 entityTrackingOnOpen(parser, entity, __LINE__6450);
6451 beforeHandler(parser);
6452 const int status = parser->m_externalEntityRefHandler(
6453/* BEGIN MOZILLA CHANGE (Bug 191482 - Add external entity inclusions to internalSubset) */
6454#if 0
6455 parser->m_externalEntityRefHandlerArg, 0, entity->base,
6456#else
6457 parser->m_externalEntityRefHandlerArg, entity->name, entity->base,
6458#endif
6459/* END MOZILLA CHANGE */
6460 entity->systemId, entity->publicId);
6461 afterHandler(parser);
6462 if (! status) {
6463 entityTrackingOnClose(parser, entity, __LINE__6463);
6464 entity->open = false0;
6465 return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
6466 }
6467 entityTrackingOnClose(parser, entity, __LINE__6467);
6468 entity->open = false0;
6469 handleDefault = XML_FALSE((XML_Bool)0);
6470 if (! dtd->paramEntityRead) {
6471 dtd->keepProcessing = dtd->standalone;
6472 break;
6473 }
6474 } else {
6475 dtd->keepProcessing = dtd->standalone;
6476 break;
6477 }
6478 }
6479#endif /* XML_DTD */
6480 if (! dtd->standalone && parser->m_notStandaloneHandler) {
6481 beforeHandler(parser);
6482 const int status = parser->m_notStandaloneHandler(parser->m_handlerArg);
6483 afterHandler(parser);
6484 if (! status)
6485 return XML_ERROR_NOT_STANDALONE;
6486 }
6487 break;
6488
6489 /* Element declaration stuff */
6490
6491 case XML_ROLE_ELEMENT_NAME:
6492 if (parser->m_elementDeclHandler) {
6493 parser->m_declElementType = getElementType(parser, enc, s, next);
6494 if (! parser->m_declElementType)
6495 return XML_ERROR_NO_MEMORY;
6496 dtd->scaffLevel = 0;
6497 dtd->scaffCount = 0;
6498 dtd->in_eldecl = XML_TRUE((XML_Bool)1);
6499 handleDefault = XML_FALSE((XML_Bool)0);
6500 }
6501 break;
6502
6503 case XML_ROLE_CONTENT_ANY:
6504 case XML_ROLE_CONTENT_EMPTY:
6505 if (dtd->in_eldecl) {
6506 if (parser->m_elementDeclHandler) {
6507 // NOTE: We are avoiding MALLOC(..) here to so that
6508 // applications that are not using XML_FreeContentModel but
6509 // plain free(..) or .free_fcn() to free the content model's
6510 // memory are safe.
6511 XML_Content *content = parser->m_mem.malloc_fcn(sizeof(XML_Content));
6512 if (! content)
6513 return XML_ERROR_NO_MEMORY;
6514 content->quant = XML_CQUANT_NONE;
6515 content->name = NULL((void*)0);
6516 content->numchildren = 0;
6517 content->children = NULL((void*)0);
6518 content->type = ((role == XML_ROLE_CONTENT_ANY) ? XML_CTYPE_ANY
6519 : XML_CTYPE_EMPTY);
6520 *eventEndPP = s;
6521 beforeHandler(parser);
6522 parser->m_elementDeclHandler(
6523 parser->m_handlerArg, parser->m_declElementType->name, content);
6524 afterHandler(parser);
6525 handleDefault = XML_FALSE((XML_Bool)0);
6526 }
6527 dtd->in_eldecl = XML_FALSE((XML_Bool)0);
6528 }
6529 break;
6530
6531 case XML_ROLE_CONTENT_PCDATA:
6532 if (dtd->in_eldecl) {
6533 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
6534 = XML_CTYPE_MIXED;
6535 if (parser->m_elementDeclHandler)
6536 handleDefault = XML_FALSE((XML_Bool)0);
6537 }
6538 break;
6539
6540 case XML_ROLE_CONTENT_ELEMENT:
6541 quant = XML_CQUANT_NONE;
6542 goto elementContent;
6543 case XML_ROLE_CONTENT_ELEMENT_OPT:
6544 quant = XML_CQUANT_OPT;
6545 goto elementContent;
6546 case XML_ROLE_CONTENT_ELEMENT_REP:
6547 quant = XML_CQUANT_REP;
6548 goto elementContent;
6549 case XML_ROLE_CONTENT_ELEMENT_PLUS:
6550 quant = XML_CQUANT_PLUS;
6551 elementContent:
6552 if (dtd->in_eldecl) {
6553 ELEMENT_TYPE *el;
6554 const XML_Char *name;
6555 size_t nameLen;
6556 const char *nxt
6557 = (quant == XML_CQUANT_NONE ? next : next - enc->minBytesPerChar);
6558 int myindex = nextScaffoldPart(parser);
6559 if (myindex < 0)
6560 return XML_ERROR_NO_MEMORY;
6561 dtd->scaffold[myindex].type = XML_CTYPE_NAME;
6562 dtd->scaffold[myindex].quant = quant;
6563 el = getElementType(parser, enc, s, nxt);
6564 if (! el)
6565 return XML_ERROR_NO_MEMORY;
6566 name = el->name;
6567 dtd->scaffold[myindex].name = name;
6568 nameLen = xcslen(name) + /*null terminator*/ 1;
6569
6570 /* Detect and prevent integer overflow */
6571 if (nameLen > UINT_MAX(2147483647 *2U +1U) - dtd->contentStringLen) {
6572 return XML_ERROR_NO_MEMORY;
6573 }
6574
6575 dtd->contentStringLen += (unsigned)nameLen;
6576 if (parser->m_elementDeclHandler)
6577 handleDefault = XML_FALSE((XML_Bool)0);
6578 }
6579 break;
6580
6581 case XML_ROLE_GROUP_CLOSE:
6582 quant = XML_CQUANT_NONE;
6583 goto closeGroup;
6584 case XML_ROLE_GROUP_CLOSE_OPT:
6585 quant = XML_CQUANT_OPT;
6586 goto closeGroup;
6587 case XML_ROLE_GROUP_CLOSE_REP:
6588 quant = XML_CQUANT_REP;
6589 goto closeGroup;
6590 case XML_ROLE_GROUP_CLOSE_PLUS:
6591 quant = XML_CQUANT_PLUS;
6592 closeGroup:
6593 if (dtd->in_eldecl) {
6594 if (parser->m_elementDeclHandler)
6595 handleDefault = XML_FALSE((XML_Bool)0);
6596 dtd->scaffLevel--;
6597 dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
6598 if (dtd->scaffLevel == 0) {
6599 if (! handleDefault) {
6600 XML_Content *model = build_model(parser);
6601 if (! model)
6602 return XML_ERROR_NO_MEMORY;
6603 *eventEndPP = s;
6604 beforeHandler(parser);
6605 parser->m_elementDeclHandler(
6606 parser->m_handlerArg, parser->m_declElementType->name, model);
6607 afterHandler(parser);
6608 }
6609 dtd->in_eldecl = XML_FALSE((XML_Bool)0);
6610 dtd->contentStringLen = 0;
6611 }
6612 }
6613 break;
6614 /* End element declaration stuff */
6615
6616 case XML_ROLE_PI:
6617 if (! reportProcessingInstruction(parser, enc, s, next))
6618 return XML_ERROR_NO_MEMORY;
6619 handleDefault = XML_FALSE((XML_Bool)0);
6620 break;
6621 case XML_ROLE_COMMENT:
6622 if (! reportComment(parser, enc, s, next))
6623 return XML_ERROR_NO_MEMORY;
6624 handleDefault = XML_FALSE((XML_Bool)0);
6625 break;
6626 case XML_ROLE_NONE:
6627 switch (tok) {
6628 case XML_TOK_BOM14:
6629 handleDefault = XML_FALSE((XML_Bool)0);
6630 break;
6631 }
6632 break;
6633 case XML_ROLE_DOCTYPE_NONE:
6634 if (parser->m_startDoctypeDeclHandler)
6635 handleDefault = XML_FALSE((XML_Bool)0);
6636 break;
6637 case XML_ROLE_ENTITY_NONE:
6638 if (dtd->keepProcessing && parser->m_entityDeclHandler)
6639 handleDefault = XML_FALSE((XML_Bool)0);
6640 break;
6641 case XML_ROLE_NOTATION_NONE:
6642 if (parser->m_notationDeclHandler)
6643 handleDefault = XML_FALSE((XML_Bool)0);
6644 break;
6645 case XML_ROLE_ATTLIST_NONE:
6646 if (dtd->keepProcessing && parser->m_attlistDeclHandler)
6647 handleDefault = XML_FALSE((XML_Bool)0);
6648 break;
6649 case XML_ROLE_ELEMENT_NONE:
6650 if (parser->m_elementDeclHandler)
6651 handleDefault = XML_FALSE((XML_Bool)0);
6652 break;
6653 } /* end of big switch */
6654
6655 if (handleDefault && parser->m_defaultHandler)
6656 reportDefault(parser, enc, s, next);
6657
6658 switch (parser->m_parsingStatus.parsing) {
6659 case XML_SUSPENDED:
6660 *nextPtr = next;
6661 return XML_ERROR_NONE;
6662 case XML_FINISHED:
6663 return XML_ERROR_ABORTED;
6664 case XML_PARSING:
6665 if (parser->m_reenter) {
6666 *nextPtr = next;
6667 return XML_ERROR_NONE;
6668 }
6669 EXPAT_FALLTHROUGH__attribute__((fallthrough));
6670 default:
6671 s = next;
6672 tok = XmlPrologTok(enc, s, end, &next)(((enc)->scanners[0])(enc, s, end, &next));
6673 }
6674 }
6675 /* not reached */
6676}
6677
6678static enum XML_Error PTRCALL
6679epilogProcessor(XML_Parser parser, const char *s, const char *end,
6680 const char **nextPtr) {
6681 parser->m_processor = epilogProcessor;
6682 parser->m_eventPtr = s;
6683 for (;;) {
6684 const char *next = NULL((void*)0);
6685 int tok = XmlPrologTok(parser->m_encoding, s, end, &next)(((parser->m_encoding)->scanners[0])(parser->m_encoding
, s, end, &next))
;
6686#if XML_GE1 == 1
6687 if (! accountingDiffTolerated(parser, tok, s, next, __LINE__6687,
6688 XML_ACCOUNT_DIRECT)) {
6689 accountingOnAbort(parser);
6690 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
6691 }
6692#endif
6693 parser->m_eventEndPtr = next;
6694 switch (tok) {
6695 /* report partial linebreak - it might be the last token */
6696 case -XML_TOK_PROLOG_S15:
6697 if (parser->m_defaultHandler) {
6698 reportDefault(parser, parser->m_encoding, s, next);
6699 if (parser->m_parsingStatus.parsing == XML_FINISHED)
6700 return XML_ERROR_ABORTED;
6701 }
6702 *nextPtr = next;
6703 return XML_ERROR_NONE;
6704 case XML_TOK_NONE-4:
6705 *nextPtr = s;
6706 return XML_ERROR_NONE;
6707 case XML_TOK_PROLOG_S15:
6708 if (parser->m_defaultHandler)
6709 reportDefault(parser, parser->m_encoding, s, next);
6710 break;
6711 case XML_TOK_PI11:
6712 if (! reportProcessingInstruction(parser, parser->m_encoding, s, next))
6713 return XML_ERROR_NO_MEMORY;
6714 break;
6715 case XML_TOK_COMMENT13:
6716 if (! reportComment(parser, parser->m_encoding, s, next))
6717 return XML_ERROR_NO_MEMORY;
6718 break;
6719 case XML_TOK_INVALID0:
6720 parser->m_eventPtr = next;
6721 return XML_ERROR_INVALID_TOKEN;
6722 case XML_TOK_PARTIAL-1:
6723 if (! parser->m_parsingStatus.finalBuffer) {
6724 *nextPtr = s;
6725 return XML_ERROR_NONE;
6726 }
6727 return XML_ERROR_UNCLOSED_TOKEN;
6728 case XML_TOK_PARTIAL_CHAR-2:
6729 if (! parser->m_parsingStatus.finalBuffer) {
6730 *nextPtr = s;
6731 return XML_ERROR_NONE;
6732 }
6733 return XML_ERROR_PARTIAL_CHAR;
6734 default:
6735 return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
6736 }
6737 switch (parser->m_parsingStatus.parsing) {
6738 case XML_SUSPENDED:
6739 parser->m_eventPtr = next;
6740 *nextPtr = next;
6741 return XML_ERROR_NONE;
6742 case XML_FINISHED:
6743 parser->m_eventPtr = next;
6744 return XML_ERROR_ABORTED;
6745 case XML_PARSING:
6746 if (parser->m_reenter) {
6747 return XML_ERROR_UNEXPECTED_STATE; // LCOV_EXCL_LINE
6748 }
6749 EXPAT_FALLTHROUGH__attribute__((fallthrough));
6750 default:;
6751 parser->m_eventPtr = s = next;
6752 }
6753 }
6754}
6755
6756static enum XML_Error
6757processEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl,
6758 enum EntityType type) {
6759 OPEN_INTERNAL_ENTITY *openEntity, **openEntityList;
6760 OPEN_INTERNAL_ENTITY **const freeEntityList = &parser->m_freeEntities;
6761 switch (type) {
6762 case ENTITY_INTERNAL:
6763 parser->m_processor = internalEntityProcessor;
6764 openEntityList = &parser->m_openInternalEntities;
6765 break;
6766 case ENTITY_ATTRIBUTE:
6767 openEntityList = &parser->m_openAttributeEntities;
6768 break;
6769 case ENTITY_VALUE:
6770 openEntityList = &parser->m_openValueEntities;
6771 break;
6772 /* default case serves merely as a safety net in case of a
6773 * wrong entityType. Therefore we exclude the following lines
6774 * from the test coverage.
6775 *
6776 * LCOV_EXCL_START
6777 */
6778 default:
6779 // Should not reach here
6780 assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 6780, __extension__ __PRETTY_FUNCTION__); }))
;
6781 /* LCOV_EXCL_STOP */
6782 }
6783
6784 if (*freeEntityList) {
6785 openEntity = *freeEntityList;
6786 *freeEntityList = openEntity->next;
6787 } else {
6788 openEntity = MALLOC(parser, sizeof(OPEN_INTERNAL_ENTITY))(expat_malloc((parser), (sizeof(OPEN_INTERNAL_ENTITY)), 6788)
)
;
6789 if (! openEntity)
6790 return XML_ERROR_NO_MEMORY;
6791 }
6792 entity->open = true1;
6793 entity->hasMore = XML_TRUE((XML_Bool)1);
6794#if XML_GE1 == 1
6795 entityTrackingOnOpen(parser, entity, __LINE__6795);
6796#endif
6797 entity->processed = 0;
6798 openEntity->next = *openEntityList;
6799 *openEntityList = openEntity;
6800 openEntity->entity = entity;
6801 openEntity->type = type;
6802 openEntity->startTagLevel = parser->m_tagLevel;
6803 openEntity->betweenDecl = betweenDecl;
6804 openEntity->internalEventPtr = NULL((void*)0);
6805 openEntity->internalEventEndPtr = NULL((void*)0);
6806
6807 // Only internal entities make use of the reenter flag
6808 // therefore no need to set it for other entity types
6809 if (type == ENTITY_INTERNAL) {
6810 triggerReenter(parser);
6811 }
6812 return XML_ERROR_NONE;
6813}
6814
6815static enum XML_Error PTRCALL
6816internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
6817 const char **nextPtr) {
6818 UNUSED_P(s)(void)s;
6819 UNUSED_P(end)(void)end;
6820 UNUSED_P(nextPtr)(void)nextPtr;
6821 ENTITY *entity;
6822 const char *textStart, *textEnd;
6823 const char *next;
6824 enum XML_Error result;
6825 OPEN_INTERNAL_ENTITY *openEntity = parser->m_openInternalEntities;
6826 if (! openEntity)
6827 return XML_ERROR_UNEXPECTED_STATE;
6828
6829 entity = openEntity->entity;
6830
6831 // This will return early
6832 if (entity->hasMore) {
6833 textStart = ((const char *)entity->textPtr) + entity->processed;
6834 textEnd = (const char *)(entity->textPtr + entity->textLen);
6835 /* Set a safe default value in case 'next' does not get set */
6836 next = textStart;
6837
6838 if (entity->is_param) {
6839 int tok
6840 = XmlPrologTok(parser->m_internalEncoding, textStart, textEnd, &next)(((parser->m_internalEncoding)->scanners[0])(parser->
m_internalEncoding, textStart, textEnd, &next))
;
6841 result = doProlog(parser, parser->m_internalEncoding, textStart, textEnd,
6842 tok, next, &next, XML_FALSE((XML_Bool)0), XML_FALSE((XML_Bool)0),
6843 XML_ACCOUNT_ENTITY_EXPANSION);
6844 } else {
6845 result = doContent(parser, openEntity->startTagLevel,
6846 parser->m_internalEncoding, textStart, textEnd, &next,
6847 XML_FALSE((XML_Bool)0), XML_ACCOUNT_ENTITY_EXPANSION);
6848 }
6849
6850 if (result != XML_ERROR_NONE)
6851 return result;
6852 // Check if entity is complete, if not, mark down how much of it is
6853 // processed
6854 if (textEnd != next
6855 && (parser->m_parsingStatus.parsing == XML_SUSPENDED
6856 || (parser->m_parsingStatus.parsing == XML_PARSING
6857 && parser->m_reenter))) {
6858 entity->processed = (int)(next - (const char *)entity->textPtr);
6859 return result;
6860 }
6861
6862 // Entity is complete. We cannot close it here since we need to first
6863 // process its possible inner entities (which are added to the
6864 // m_openInternalEntities during doProlog or doContent calls above)
6865 entity->hasMore = XML_FALSE((XML_Bool)0);
6866 if (! entity->is_param
6867 && (openEntity->startTagLevel != parser->m_tagLevel)) {
6868 return XML_ERROR_ASYNC_ENTITY;
6869 }
6870 triggerReenter(parser);
6871 return result;
6872 } // End of entity processing, "if" block will return here
6873
6874 // Remove fully processed openEntity from open entity list.
6875#if XML_GE1 == 1
6876 entityTrackingOnClose(parser, entity, __LINE__6876);
6877#endif
6878 // openEntity is m_openInternalEntities' head, as we set it at the start of
6879 // this function and we skipped doProlog and doContent calls with hasMore set
6880 // to false. This means we can directly remove the head of
6881 // m_openInternalEntities
6882 assert(parser->m_openInternalEntities == openEntity)((void) sizeof ((parser->m_openInternalEntities == openEntity
) ? 1 : 0), __extension__ ({ if (parser->m_openInternalEntities
== openEntity) ; else __assert_fail ("parser->m_openInternalEntities == openEntity"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 6882
, __extension__ __PRETTY_FUNCTION__); }))
;
6883 entity->open = false0;
6884 parser->m_openInternalEntities = parser->m_openInternalEntities->next;
6885
6886 /* put openEntity back in list of free instances */
6887 openEntity->next = parser->m_freeEntities;
6888 parser->m_freeEntities = openEntity;
6889
6890 if (parser->m_openInternalEntities == NULL((void*)0)) {
6891 parser->m_processor = entity->is_param ? prologProcessor : contentProcessor;
6892 }
6893 triggerReenter(parser);
6894 return XML_ERROR_NONE;
6895}
6896
6897static enum XML_Error PTRCALL
6898errorProcessor(XML_Parser parser, const char *s, const char *end,
6899 const char **nextPtr) {
6900 UNUSED_P(s)(void)s;
6901 UNUSED_P(end)(void)end;
6902 UNUSED_P(nextPtr)(void)nextPtr;
6903 return parser->m_errorCode;
6904}
6905
6906static enum XML_Error
6907storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
6908 const char *ptr, const char *end, STRING_POOL *pool,
6909 enum XML_Account account) {
6910 const char *next = ptr;
6911 enum XML_Error result = XML_ERROR_NONE;
6912
6913 while (1) {
6914 if (! parser->m_openAttributeEntities) {
6915 result = appendAttributeValue(parser, enc, isCdata, next, end, pool,
6916 account, &next);
6917 } else {
6918 OPEN_INTERNAL_ENTITY *const openEntity = parser->m_openAttributeEntities;
6919 if (! openEntity)
6920 return XML_ERROR_UNEXPECTED_STATE;
6921
6922 ENTITY *const entity = openEntity->entity;
6923 const char *const textStart
6924 = ((const char *)entity->textPtr) + entity->processed;
6925 const char *const textEnd
6926 = (const char *)(entity->textPtr + entity->textLen);
6927 /* Set a safe default value in case 'next' does not get set */
6928 const char *nextInEntity = textStart;
6929 if (entity->hasMore) {
6930 result = appendAttributeValue(
6931 parser, parser->m_internalEncoding, isCdata, textStart, textEnd,
6932 pool, XML_ACCOUNT_ENTITY_EXPANSION, &nextInEntity);
6933 if (result != XML_ERROR_NONE)
6934 break;
6935 // Check if entity is complete, if not, mark down how much of it is
6936 // processed. A XML_SUSPENDED check here is not required as
6937 // appendAttributeValue will never suspend the parser.
6938 if (nextInEntity < textEnd) {
6939 entity->processed
6940 = (int)(nextInEntity - (const char *)entity->textPtr);
6941 continue;
6942 }
6943 assert(nextInEntity == textEnd)((void) sizeof ((nextInEntity == textEnd) ? 1 : 0), __extension__
({ if (nextInEntity == textEnd) ; else __assert_fail ("nextInEntity == textEnd"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 6943
, __extension__ __PRETTY_FUNCTION__); }))
;
6944
6945 // Entity is complete. We cannot close it here since we need to first
6946 // process its possible inner entities (which are added to the
6947 // m_openAttributeEntities during appendAttributeValue)
6948 entity->hasMore = XML_FALSE((XML_Bool)0);
6949 continue;
6950 } // End of entity processing, "if" block skips the rest
6951
6952 // Remove fully processed openEntity from open entity list.
6953#if XML_GE1 == 1
6954 entityTrackingOnClose(parser, entity, __LINE__6954);
6955#endif
6956 // openEntity is m_openAttributeEntities' head, since we set it at the
6957 // start of this function and because we skipped appendAttributeValue call
6958 // with hasMore set to false. This means we can directly remove the head
6959 // of m_openAttributeEntities
6960 assert(parser->m_openAttributeEntities == openEntity)((void) sizeof ((parser->m_openAttributeEntities == openEntity
) ? 1 : 0), __extension__ ({ if (parser->m_openAttributeEntities
== openEntity) ; else __assert_fail ("parser->m_openAttributeEntities == openEntity"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 6960
, __extension__ __PRETTY_FUNCTION__); }))
;
6961 entity->open = false0;
6962 parser->m_openAttributeEntities = parser->m_openAttributeEntities->next;
6963
6964 /* put openEntity back in list of free instances */
6965 openEntity->next = parser->m_freeEntities;
6966 parser->m_freeEntities = openEntity;
6967 }
6968
6969 // Break if an error occurred or there is nothing left to process
6970 if (result || (parser->m_openAttributeEntities == NULL((void*)0) && end == next)) {
6971 break;
6972 }
6973 }
6974
6975 if (result)
6976 return result;
6977 if (! isCdata && poolLength(pool)((pool)->ptr - (pool)->start) && poolLastChar(pool)(((pool)->ptr)[-1]) == 0x20)
6978 poolChop(pool)((void)--(pool->ptr));
6979 if (! poolAppendChar(pool, XML_T('\0')(uint16_t)'\0'))
6980 return XML_ERROR_NO_MEMORY;
6981 return XML_ERROR_NONE;
6982}
6983
6984static enum XML_Error
6985appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
6986 const char *ptr, const char *end, STRING_POOL *pool,
6987 enum XML_Account account, const char **nextPtr) {
6988 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
6989#ifndef XML_DTD
6990 UNUSED_P(account)(void)account;
6991#endif
6992
6993 for (;;) {
6994 const char *next
6995 = ptr; /* XmlAttributeValueTok doesn't always set the last arg */
6996 int tok = XmlAttributeValueTok(enc, ptr, end, &next)(((enc)->literalScanners[0])(enc, ptr, end, &next));
6997#if XML_GE1 == 1
6998 if (! accountingDiffTolerated(parser, tok, ptr, next, __LINE__6998, account)) {
6999 accountingOnAbort(parser);
7000 return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
7001 }
7002#endif
7003 switch (tok) {
7004 case XML_TOK_NONE-4:
7005 if (nextPtr) {
7006 *nextPtr = next;
7007 }
7008 return XML_ERROR_NONE;
7009 case XML_TOK_INVALID0:
7010 if (enc == parser->m_encoding)
7011 parser->m_eventPtr = next;
7012 return XML_ERROR_INVALID_TOKEN;
7013 case XML_TOK_PARTIAL-1:
7014 if (enc == parser->m_encoding)
7015 parser->m_eventPtr = ptr;
7016 return XML_ERROR_INVALID_TOKEN;
7017 case XML_TOK_CHAR_REF10: {
7018 XML_Char buf[XML_ENCODE_MAX2];
7019 int n = XmlCharRefNumber(enc, ptr)(((enc)->charRefNumber)(enc, ptr));
7020 if (n < 0) {
7021 if (enc == parser->m_encoding)
7022 parser->m_eventPtr = ptr;
7023 return XML_ERROR_BAD_CHAR_REF;
7024 }
7025 if (! isCdata && n == 0x20 /* space */
7026 && (poolLength(pool)((pool)->ptr - (pool)->start) == 0 || poolLastChar(pool)(((pool)->ptr)[-1]) == 0x20))
7027 break;
7028 n = XmlEncodeXmlUtf16Encode(n, (ICHAR *)buf);
7029 /* The XmlEncode() functions can never return 0 here. That
7030 * error return happens if the code point passed in is either
7031 * negative or greater than or equal to 0x110000. The
7032 * XmlCharRefNumber() functions will all return a number
7033 * strictly less than 0x110000 or a negative value if an error
7034 * occurred. The negative value is intercepted above, so
7035 * XmlEncode() is never passed a value it might return an
7036 * error for.
7037 */
7038
7039 if (! poolAppendChars(pool, buf, n))
7040 return XML_ERROR_NO_MEMORY;
7041 } break;
7042 case XML_TOK_DATA_CHARS6:
7043 if (! poolAppend(pool, enc, ptr, next))
7044 return XML_ERROR_NO_MEMORY;
7045 break;
7046 case XML_TOK_TRAILING_CR-3:
7047 next = ptr + enc->minBytesPerChar;
7048 EXPAT_FALLTHROUGH__attribute__((fallthrough));
7049 case XML_TOK_ATTRIBUTE_VALUE_S39:
7050 case XML_TOK_DATA_NEWLINE7:
7051 if (! isCdata && (poolLength(pool)((pool)->ptr - (pool)->start) == 0 || poolLastChar(pool)(((pool)->ptr)[-1]) == 0x20))
7052 break;
7053 if (! poolAppendChar(pool, 0x20))
7054 return XML_ERROR_NO_MEMORY;
7055 break;
7056 case XML_TOK_ENTITY_REF9: {
7057 const XML_Char *name;
7058 ENTITY *entity;
7059 bool_Bool checkEntityDecl;
7060 XML_Char ch = (XML_Char)XmlPredefinedEntityName((((enc)->predefinedEntityName)(enc, ptr + enc->minBytesPerChar
, next - enc->minBytesPerChar))
7061 enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar)(((enc)->predefinedEntityName)(enc, ptr + enc->minBytesPerChar
, next - enc->minBytesPerChar))
;
7062 if (ch) {
7063#if XML_GE1 == 1
7064 /* NOTE: We are replacing 4-6 characters original input for 1 character
7065 * so there is no amplification and hence recording without
7066 * protection. */
7067 accountingDiffTolerated(parser, tok, (char *)&ch,
7068 ((char *)&ch) + sizeof(XML_Char), __LINE__7068,
7069 XML_ACCOUNT_ENTITY_EXPANSION);
7070#endif /* XML_GE == 1 */
7071 if (! poolAppendChar(pool, ch))
7072 return XML_ERROR_NO_MEMORY;
7073 break;
7074 }
7075 name = poolStoreString(&parser->m_temp2Pool, enc,
7076 ptr + enc->minBytesPerChar,
7077 next - enc->minBytesPerChar);
7078 if (! name)
7079 return XML_ERROR_NO_MEMORY;
7080 entity = (ENTITY *)lookup(parser, &dtd->generalEntities, name, 0);
7081 poolDiscard(&parser->m_temp2Pool)((&parser->m_temp2Pool)->ptr = (&parser->m_temp2Pool
)->start)
;
7082 /* First, determine if a check for an existing declaration is needed;
7083 if yes, check that the entity exists, and that it is internal.
7084 */
7085 if (pool == &dtd->pool) /* are we called from prolog? */
7086 checkEntityDecl =
7087#ifdef XML_DTD
7088 parser->m_prologState.documentEntity &&
7089#endif /* XML_DTD */
7090 (dtd->standalone ? ! parser->m_openInternalEntities
7091 : ! dtd->hasParamEntityRefs);
7092 else /* if (pool == &parser->m_tempPool): we are called from content */
7093 checkEntityDecl = ! dtd->hasParamEntityRefs || dtd->standalone;
7094 if (checkEntityDecl) {
7095 if (! entity)
7096 return XML_ERROR_UNDEFINED_ENTITY;
7097 else if (! entity->is_internal)
7098 return XML_ERROR_ENTITY_DECLARED_IN_PE;
7099 } else if (! entity) {
7100 /* Cannot report skipped entity here - see comments on
7101 parser->m_skippedEntityHandler.
7102 if (parser->m_skippedEntityHandler) {
7103 beforeHandler(parser);
7104 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
7105 afterHandler(parser);
7106 }
7107 */
7108 /* Cannot call the default handler because this would be
7109 out of sync with the call to the startElementHandler.
7110 if ((pool == &parser->m_tempPool) && parser->m_defaultHandler)
7111 reportDefault(parser, enc, ptr, next);
7112 */
7113/* BEGIN MOZILLA CHANGE (Bug 35984 - Undeclared entities are ignored when external DTD not found) */
7114#if 0
7115 break;
7116#else
7117 return XML_ERROR_UNDEFINED_ENTITY;
7118#endif
7119/* END MOZILLA CHANGE */
7120 }
7121 if (entity->open) {
7122 if (enc == parser->m_encoding) {
7123 /* It does not appear that this line can be executed.
7124 *
7125 * The "if (entity->open)" check catches recursive entity
7126 * definitions. In order to be called with an open
7127 * entity, it must have gone through this code before and
7128 * been through the recursive call to
7129 * appendAttributeValue() some lines below. That call
7130 * sets the local encoding ("enc") to the parser's
7131 * internal encoding (internal_utf8 or internal_utf16),
7132 * which can never be the same as the principle encoding.
7133 * It doesn't appear there is another code path that gets
7134 * here with entity->open being TRUE.
7135 *
7136 * Since it is not certain that this logic is watertight,
7137 * we keep the line and merely exclude it from coverage
7138 * tests.
7139 */
7140 parser->m_eventPtr = ptr; /* LCOV_EXCL_LINE */
7141 }
7142 return XML_ERROR_RECURSIVE_ENTITY_REF;
7143 }
7144 if (entity->notation) {
7145 if (enc == parser->m_encoding)
7146 parser->m_eventPtr = ptr;
7147 return XML_ERROR_BINARY_ENTITY_REF;
7148 }
7149 if (! entity->textPtr) {
7150 if (enc == parser->m_encoding)
7151 parser->m_eventPtr = ptr;
7152 return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
7153 } else {
7154 enum XML_Error result;
7155 result = processEntity(parser, entity, XML_FALSE((XML_Bool)0), ENTITY_ATTRIBUTE);
7156 if ((result == XML_ERROR_NONE) && (nextPtr != NULL((void*)0))) {
7157 *nextPtr = next;
7158 }
7159 return result;
7160 }
7161 } break;
7162 default:
7163 /* The only token returned by XmlAttributeValueTok() that does
7164 * not have an explicit case here is XML_TOK_PARTIAL_CHAR.
7165 * Getting that would require an entity name to contain an
7166 * incomplete XML character (e.g. \xE2\x82); however previous
7167 * tokenisers will have already recognised and rejected such
7168 * names before XmlAttributeValueTok() gets a look-in. This
7169 * default case should be retained as a safety net, but the code
7170 * excluded from coverage tests.
7171 *
7172 * LCOV_EXCL_START
7173 */
7174 if (enc == parser->m_encoding)
7175 parser->m_eventPtr = ptr;
7176 return XML_ERROR_UNEXPECTED_STATE;
7177 /* LCOV_EXCL_STOP */
7178 }
7179 ptr = next;
7180 }
7181 /* not reached */
7182}
7183
7184#if XML_GE1 == 1
7185static enum XML_Error
7186storeEntityValue(XML_Parser parser, const ENCODING *enc,
7187 const char *entityTextPtr, const char *entityTextEnd,
7188 enum XML_Account account, const char **nextPtr) {
7189 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
7190 STRING_POOL *pool = &(dtd->entityValuePool);
7191 enum XML_Error result = XML_ERROR_NONE;
7192# ifdef XML_DTD
7193 int oldInEntityValue = parser->m_prologState.inEntityValue;
7194 parser->m_prologState.inEntityValue = 1;
7195# else
7196 UNUSED_P(account)(void)account;
7197# endif /* XML_DTD */
7198 /* never return Null for the value argument in EntityDeclHandler,
7199 since this would indicate an external entity; therefore we
7200 have to make sure that entityValuePool.start is not null */
7201 if (! pool->blocks) {
7202 if (! poolGrow(pool))
7203 return XML_ERROR_NO_MEMORY;
7204 }
7205
7206 const char *next = entityTextPtr;
7207
7208 /* Nothing to tokenize. */
7209 if (entityTextPtr >= entityTextEnd) {
7210 result = XML_ERROR_NONE;
7211 goto endEntityValue;
7212 }
7213
7214 for (;;) {
7215 next
7216 = entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */
7217 int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next)(((enc)->literalScanners[1])(enc, entityTextPtr, entityTextEnd
, &next))
;
7218
7219 if (! accountingDiffTolerated(parser, tok, entityTextPtr, next, __LINE__7219,
7220 account)) {
7221 accountingOnAbort(parser);
7222 result = XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
7223 goto endEntityValue;
7224 }
7225
7226 switch (tok) {
7227 case XML_TOK_PARAM_ENTITY_REF28:
7228# ifdef XML_DTD
7229 if (parser->m_isParamEntity || enc != parser->m_encoding) {
7230 const XML_Char *name;
7231 ENTITY *entity;
7232 name = poolStoreString(&parser->m_tempPool, enc,
7233 entityTextPtr + enc->minBytesPerChar,
7234 next - enc->minBytesPerChar);
7235 if (! name) {
7236 result = XML_ERROR_NO_MEMORY;
7237 goto endEntityValue;
7238 }
7239 entity = (ENTITY *)lookup(parser, &dtd->paramEntities, name, 0);
7240 poolDiscard(&parser->m_tempPool)((&parser->m_tempPool)->ptr = (&parser->m_tempPool
)->start)
;
7241 if (! entity) {
7242 /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
7243 /* cannot report skipped entity here - see comments on
7244 parser->m_skippedEntityHandler
7245 if (parser->m_skippedEntityHandler) {
7246 beforeHandler(parser);
7247 parser->m_skippedEntityHandler(parser->m_handlerArg, name, 0);
7248 afterHandler(parser);
7249 }
7250 */
7251 dtd->keepProcessing = dtd->standalone;
7252 goto endEntityValue;
7253 }
7254 if (entity->open || (entity == parser->m_declEntity)) {
7255 if (enc == parser->m_encoding)
7256 parser->m_eventPtr = entityTextPtr;
7257 result = XML_ERROR_RECURSIVE_ENTITY_REF;
7258 goto endEntityValue;
7259 }
7260 if (entity->systemId) {
7261 if (parser->m_externalEntityRefHandler) {
7262 dtd->paramEntityRead = XML_FALSE((XML_Bool)0);
7263 entity->open = true1;
7264 entityTrackingOnOpen(parser, entity, __LINE__7264);
7265 beforeHandler(parser);
7266 const int status = parser->m_externalEntityRefHandler(
7267 parser->m_externalEntityRefHandlerArg, 0, entity->base,
7268 entity->systemId, entity->publicId);
7269 afterHandler(parser);
7270 if (! status) {
7271 entityTrackingOnClose(parser, entity, __LINE__7271);
7272 entity->open = false0;
7273 result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
7274 goto endEntityValue;
7275 }
7276 entityTrackingOnClose(parser, entity, __LINE__7276);
7277 entity->open = false0;
7278 if (! dtd->paramEntityRead)
7279 dtd->keepProcessing = dtd->standalone;
7280 } else
7281 dtd->keepProcessing = dtd->standalone;
7282 } else {
7283 result = processEntity(parser, entity, XML_FALSE((XML_Bool)0), ENTITY_VALUE);
7284 goto endEntityValue;
7285 }
7286 break;
7287 }
7288# endif /* XML_DTD */
7289 /* In the internal subset, PE references are not legal
7290 within markup declarations, e.g entity values in this case. */
7291 parser->m_eventPtr = entityTextPtr;
7292 result = XML_ERROR_PARAM_ENTITY_REF;
7293 goto endEntityValue;
7294 case XML_TOK_NONE-4:
7295 result = XML_ERROR_NONE;
7296 goto endEntityValue;
7297 case XML_TOK_ENTITY_REF9:
7298 case XML_TOK_DATA_CHARS6:
7299 if (! poolAppend(pool, enc, entityTextPtr, next)) {
7300 result = XML_ERROR_NO_MEMORY;
7301 goto endEntityValue;
7302 }
7303 break;
7304 case XML_TOK_TRAILING_CR-3:
7305 next = entityTextPtr + enc->minBytesPerChar;
7306 EXPAT_FALLTHROUGH__attribute__((fallthrough));
7307 case XML_TOK_DATA_NEWLINE7:
7308 if (! poolAppendChar(pool, 0xA)) {
7309 result = XML_ERROR_NO_MEMORY;
7310 goto endEntityValue;
7311 }
7312 break;
7313 case XML_TOK_CHAR_REF10: {
7314 XML_Char buf[XML_ENCODE_MAX2];
7315 int n = XmlCharRefNumber(enc, entityTextPtr)(((enc)->charRefNumber)(enc, entityTextPtr));
7316 if (n < 0) {
7317 if (enc == parser->m_encoding)
7318 parser->m_eventPtr = entityTextPtr;
7319 result = XML_ERROR_BAD_CHAR_REF;
7320 goto endEntityValue;
7321 }
7322 n = XmlEncodeXmlUtf16Encode(n, (ICHAR *)buf);
7323 /* The XmlEncode() functions can never return 0 here. That
7324 * error return happens if the code point passed in is either
7325 * negative or greater than or equal to 0x110000. The
7326 * XmlCharRefNumber() functions will all return a number
7327 * strictly less than 0x110000 or a negative value if an error
7328 * occurred. The negative value is intercepted above, so
7329 * XmlEncode() is never passed a value it might return an
7330 * error for.
7331 */
7332 if (! poolAppendChars(pool, buf, n)) {
7333 result = XML_ERROR_NO_MEMORY;
7334 goto endEntityValue;
7335 }
7336 } break;
7337 case XML_TOK_PARTIAL-1:
7338 if (enc == parser->m_encoding)
7339 parser->m_eventPtr = entityTextPtr;
7340 result = XML_ERROR_INVALID_TOKEN;
7341 goto endEntityValue;
7342 case XML_TOK_INVALID0:
7343 if (enc == parser->m_encoding)
7344 parser->m_eventPtr = next;
7345 result = XML_ERROR_INVALID_TOKEN;
7346 goto endEntityValue;
7347 default:
7348 /* This default case should be unnecessary -- all the tokens
7349 * that XmlEntityValueTok() can return have their own explicit
7350 * cases -- but should be retained for safety. We do however
7351 * exclude it from the coverage statistics.
7352 *
7353 * LCOV_EXCL_START
7354 */
7355 if (enc == parser->m_encoding)
7356 parser->m_eventPtr = entityTextPtr;
7357 result = XML_ERROR_UNEXPECTED_STATE;
7358 goto endEntityValue;
7359 /* LCOV_EXCL_STOP */
7360 }
7361 entityTextPtr = next;
7362 }
7363endEntityValue:
7364# ifdef XML_DTD
7365 parser->m_prologState.inEntityValue = oldInEntityValue;
7366# endif /* XML_DTD */
7367 // If 'nextPtr' is given, it should be updated during the processing
7368 if (nextPtr != NULL((void*)0)) {
7369 *nextPtr = next;
7370 }
7371 return result;
7372}
7373
7374static enum XML_Error
7375callStoreEntityValue(XML_Parser parser, const ENCODING *enc,
7376 const char *entityTextPtr, const char *entityTextEnd,
7377 enum XML_Account account) {
7378 const char *next = entityTextPtr;
7379 enum XML_Error result = XML_ERROR_NONE;
7380 while (1) {
7381 if (! parser->m_openValueEntities) {
7382 result
7383 = storeEntityValue(parser, enc, next, entityTextEnd, account, &next);
7384 } else {
7385 OPEN_INTERNAL_ENTITY *const openEntity = parser->m_openValueEntities;
7386 if (! openEntity)
7387 return XML_ERROR_UNEXPECTED_STATE;
7388
7389 ENTITY *const entity = openEntity->entity;
7390 const char *const textStart
7391 = ((const char *)entity->textPtr) + entity->processed;
7392 const char *const textEnd
7393 = (const char *)(entity->textPtr + entity->textLen);
7394 /* Set a safe default value in case 'next' does not get set */
7395 const char *nextInEntity = textStart;
7396 if (entity->hasMore) {
7397 result = storeEntityValue(parser, parser->m_internalEncoding, textStart,
7398 textEnd, XML_ACCOUNT_ENTITY_EXPANSION,
7399 &nextInEntity);
7400 if (result != XML_ERROR_NONE)
7401 break;
7402 // Check if entity is complete, if not, mark down how much of it is
7403 // processed. A XML_SUSPENDED check here is not required as
7404 // appendAttributeValue will never suspend the parser.
7405 if (textEnd != nextInEntity) {
7406 entity->processed
7407 = (int)(nextInEntity - (const char *)entity->textPtr);
7408 continue;
7409 }
7410
7411 // Entity is complete. We cannot close it here since we need to first
7412 // process its possible inner entities (which are added to the
7413 // m_openValueEntities during storeEntityValue)
7414 entity->hasMore = XML_FALSE((XML_Bool)0);
7415 continue;
7416 } // End of entity processing, "if" block skips the rest
7417
7418 // Remove fully processed openEntity from open entity list.
7419# if XML_GE1 == 1
7420 entityTrackingOnClose(parser, entity, __LINE__7420);
7421# endif
7422 // openEntity is m_openValueEntities' head, since we set it at the
7423 // start of this function and because we skipped storeEntityValue call
7424 // with hasMore set to false. This means we can directly remove the head
7425 // of m_openValueEntities
7426 assert(parser->m_openValueEntities == openEntity)((void) sizeof ((parser->m_openValueEntities == openEntity
) ? 1 : 0), __extension__ ({ if (parser->m_openValueEntities
== openEntity) ; else __assert_fail ("parser->m_openValueEntities == openEntity"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 7426
, __extension__ __PRETTY_FUNCTION__); }))
;
7427 entity->open = false0;
7428 parser->m_openValueEntities = parser->m_openValueEntities->next;
7429
7430 /* put openEntity back in list of free instances */
7431 openEntity->next = parser->m_freeEntities;
7432 parser->m_freeEntities = openEntity;
7433 }
7434
7435 // Break if an error occurred or there is nothing left to process
7436 if (result
7437 || (parser->m_openValueEntities == NULL((void*)0) && entityTextEnd == next)) {
7438 break;
7439 }
7440 }
7441
7442 return result;
7443}
7444
7445#else /* XML_GE == 0 */
7446
7447static enum XML_Error
7448storeSelfEntityValue(XML_Parser parser, ENTITY *entity) {
7449 // This will store "&amp;entity123;" in entity->textPtr
7450 // to end up as "&entity123;" in the handler.
7451 const char *const entity_start = "&amp;";
7452 const char *const entity_end = ";";
7453
7454 STRING_POOL *const pool = &(parser->m_dtd->entityValuePool);
7455 if (! poolAppendString(pool, entity_start)
7456 || ! poolAppendString(pool, entity->name)
7457 || ! poolAppendString(pool, entity_end)) {
7458 poolDiscard(pool)((pool)->ptr = (pool)->start);
7459 return XML_ERROR_NO_MEMORY;
7460 }
7461
7462 /* Detect and prevent signed integer overflow */
7463 if ((size_t)poolLength(pool)((pool)->ptr - (pool)->start) > (size_t)INT_MAX2147483647) {
7464 poolDiscard(pool)((pool)->ptr = (pool)->start);
7465 return XML_ERROR_NO_MEMORY;
7466 }
7467 entity->textPtr = poolStart(pool)((pool)->start);
7468 entity->textLen = (int)(poolLength(pool)((pool)->ptr - (pool)->start));
7469 poolFinish(pool)((pool)->start = (pool)->ptr);
7470
7471 return XML_ERROR_NONE;
7472}
7473
7474#endif /* XML_GE == 0 */
7475
7476static void FASTCALL
7477normalizeLines(XML_Char *s) {
7478 XML_Char *p;
7479 for (;; s++) {
7480 if (*s == XML_T('\0')(uint16_t)'\0')
7481 return;
7482 if (*s == 0xD)
7483 break;
7484 }
7485 p = s;
7486 do {
7487 if (*s == 0xD) {
7488 *p++ = 0xA;
7489 if (*++s == 0xA)
7490 s++;
7491 } else
7492 *p++ = *s++;
7493 } while (*s);
7494 *p = XML_T('\0')(uint16_t)'\0';
7495}
7496
7497static int
7498reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
7499 const char *start, const char *end) {
7500 const XML_Char *target;
7501 XML_Char *data;
7502 const char *tem;
7503 if (! parser->m_processingInstructionHandler) {
7504 if (parser->m_defaultHandler)
7505 reportDefault(parser, enc, start, end);
7506 return 1;
7507 }
7508 start += enc->minBytesPerChar * 2;
7509 tem = start + XmlNameLength(enc, start)(((enc)->nameLength)(enc, start));
7510 target = poolStoreString(&parser->m_tempPool, enc, start, tem);
7511 if (! target)
7512 return 0;
7513 poolFinish(&parser->m_tempPool)((&parser->m_tempPool)->start = (&parser->m_tempPool
)->ptr)
;
7514 data = poolStoreString(&parser->m_tempPool, enc, XmlSkipS(enc, tem)(((enc)->skipS)(enc, tem)),
7515 end - enc->minBytesPerChar * 2);
7516 if (! data)
7517 return 0;
7518 normalizeLines(data);
7519 beforeHandler(parser);
7520 parser->m_processingInstructionHandler(parser->m_handlerArg, target, data);
7521 afterHandler(parser);
7522 poolClear(&parser->m_tempPool);
7523 return 1;
7524}
7525
7526static int
7527reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
7528 const char *end) {
7529 XML_Char *data;
7530 if (! parser->m_commentHandler) {
7531 if (parser->m_defaultHandler)
7532 reportDefault(parser, enc, start, end);
7533 return 1;
7534 }
7535 data = poolStoreString(&parser->m_tempPool, enc,
7536 start + enc->minBytesPerChar * 4,
7537 end - enc->minBytesPerChar * 3);
7538 if (! data)
7539 return 0;
7540 normalizeLines(data);
7541 beforeHandler(parser);
7542 parser->m_commentHandler(parser->m_handlerArg, data);
7543 afterHandler(parser);
7544 poolClear(&parser->m_tempPool);
7545 return 1;
7546}
7547
7548static void
7549reportDefault(XML_Parser parser, const ENCODING *enc, const char *s,
7550 const char *end) {
7551 if (MUST_CONVERT(enc, s)(! (enc)->isUtf16 || (((uintptr_t)(s)) & 1))) {
7552 enum XML_Convert_Result convert_res;
7553 const char **eventPP;
7554 const char **eventEndPP;
7555 if (enc == parser->m_encoding) {
7556 eventPP = &parser->m_eventPtr;
7557 eventEndPP = &parser->m_eventEndPtr;
7558 } else {
7559 /* To get here, two things must be true; the parser must be
7560 * using a character encoding that is not the same as the
7561 * encoding passed in, and the encoding passed in must need
7562 * conversion to the internal format (UTF-8 unless XML_UNICODE
7563 * is defined). The only occasions on which the encoding passed
7564 * in is not the same as the parser's encoding are when it is
7565 * the internal encoding (e.g. a previously defined parameter
7566 * entity, already converted to internal format). This by
7567 * definition doesn't need conversion, so the whole branch never
7568 * gets executed.
7569 *
7570 * For safety's sake we don't delete these lines and merely
7571 * exclude them from coverage statistics.
7572 *
7573 * LCOV_EXCL_START
7574 */
7575 eventPP = &(parser->m_openInternalEntities->internalEventPtr);
7576 eventEndPP = &(parser->m_openInternalEntities->internalEventEndPtr);
7577 /* LCOV_EXCL_STOP */
7578 }
7579 do {
7580 ICHAR *dataPtr = (ICHAR *)parser->m_dataBuf;
7581 convert_res
7582 = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)parser->m_dataBufEnd)(((enc)->utf16Convert)(enc, &s, end, &dataPtr, (ICHAR
*)parser->m_dataBufEnd))
;
7583 *eventEndPP = s;
7584 beforeHandler(parser);
7585 parser->m_defaultHandler(parser->m_handlerArg, parser->m_dataBuf,
7586 (int)(dataPtr - (ICHAR *)parser->m_dataBuf));
7587 afterHandler(parser);
7588 *eventPP = s;
7589 } while ((convert_res != XML_CONVERT_COMPLETED)
7590 && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
7591 } else {
7592 beforeHandler(parser);
7593 parser->m_defaultHandler(
7594 parser->m_handlerArg, (const XML_Char *)s,
7595 (int)((const XML_Char *)end - (const XML_Char *)s));
7596 afterHandler(parser);
7597 }
7598}
7599
7600static int
7601defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
7602 XML_Bool isId, const XML_Char *value, XML_Parser parser) {
7603 DEFAULT_ATTRIBUTE *att;
7604 if (value || isId) {
7605 /* The handling of default attributes gets messed up if we have
7606 a default which duplicates a non-default. */
7607 NAMED *const nameFound
7608 = lookup(parser, &(type->defaultAttForName), attId->name, 0);
7609 if (nameFound)
7610 return 1;
7611 if (isId && ! type->idAtt && ! attId->xmlns)
7612 type->idAtt = attId;
7613 }
7614 if (type->nDefaultAtts == type->allocDefaultAtts) {
7615 /* Detect and prevent integer overflow */
7616 if (type->allocDefaultAtts > SIZE_MAX(18446744073709551615UL) / 2) {
7617 return 0;
7618 }
7619
7620 size_t count = type->allocDefaultAtts * 2;
7621 if (count == 0) {
7622 count = 8;
7623 }
7624
7625 /* Detect and prevent integer overflow. */
7626 if (count > SIZE_MAX(18446744073709551615UL) / sizeof(DEFAULT_ATTRIBUTE)) {
7627 return 0;
7628 }
7629
7630 DEFAULT_ATTRIBUTE *const temp = REALLOC((expat_realloc((parser), (type->defaultAtts), ((count * sizeof
(DEFAULT_ATTRIBUTE))), 7631))
7631 parser, type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)))(expat_realloc((parser), (type->defaultAtts), ((count * sizeof
(DEFAULT_ATTRIBUTE))), 7631))
;
7632 if (temp == NULL((void*)0))
7633 return 0;
7634 type->allocDefaultAtts = count;
7635 type->defaultAtts = temp;
7636 }
7637 att = type->defaultAtts + type->nDefaultAtts;
7638 att->id = attId;
7639 att->value = value;
7640 att->isCdata = isCdata;
7641 if (! isCdata)
7642 attId->maybeTokenized = XML_TRUE((XML_Bool)1);
7643
7644 NAME_AND_DEFAULT_ATTRIBUTE *const nameAndDefaultAttribute
7645 = (NAME_AND_DEFAULT_ATTRIBUTE *)lookup(
7646 parser, &(type->defaultAttForName), attId->name,
7647 sizeof(NAME_AND_DEFAULT_ATTRIBUTE));
7648 if (! nameAndDefaultAttribute)
7649 return 0;
7650
7651 assert(nameAndDefaultAttribute->name == attId->name)((void) sizeof ((nameAndDefaultAttribute->name == attId->
name) ? 1 : 0), __extension__ ({ if (nameAndDefaultAttribute->
name == attId->name) ; else __assert_fail ("nameAndDefaultAttribute->name == attId->name"
, "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c", 7651
, __extension__ __PRETTY_FUNCTION__); }))
;
7652
7653 // NOTE: The XML 1.0r4 spec says:
7654 // "When more than one definition is provided for the same attribute of a
7655 // given element type, the first declaration is binding and later
7656 // declarations are ignored."
7657 if (! nameAndDefaultAttribute->initialized) {
7658 nameAndDefaultAttribute->attIndex = type->nDefaultAtts;
7659 nameAndDefaultAttribute->initialized = true1;
7660 }
7661
7662 type->nDefaultAtts += 1;
7663 return 1;
7664}
7665
7666static int
7667setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) {
7668 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
7669 const XML_Char *name;
7670 for (name = elementType->name; *name; name++) {
7671 if (*name == XML_T(ASCII_COLON)(uint16_t)0x3A) {
7672 PREFIX *prefix;
7673 const XML_Char *s;
7674 for (s = elementType->name; s != name; s++) {
7675 if (! poolAppendChar(&dtd->pool, *s))
7676 return 0;
7677 }
7678 if (! poolAppendChar(&dtd->pool, XML_T('\0')(uint16_t)'\0'))
7679 return 0;
7680 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool)((&dtd->pool)->start),
7681 sizeof(PREFIX));
7682 if (! prefix)
7683 return 0;
7684 if (prefix->name == poolStart(&dtd->pool)((&dtd->pool)->start))
7685 poolFinish(&dtd->pool)((&dtd->pool)->start = (&dtd->pool)->ptr);
7686 else
7687 poolDiscard(&dtd->pool)((&dtd->pool)->ptr = (&dtd->pool)->start);
7688 elementType->prefix = prefix;
7689 break;
7690 }
7691 }
7692 return 1;
7693}
7694
7695static ATTRIBUTE_ID *
7696getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
7697 const char *end) {
7698 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
7699 ATTRIBUTE_ID *id;
7700 const XML_Char *name;
7701 if (! poolAppendChar(&dtd->pool, XML_T('\0')(uint16_t)'\0'))
7702 return NULL((void*)0);
7703 name = poolStoreString(&dtd->pool, enc, start, end);
7704 if (! name)
7705 return NULL((void*)0);
7706 /* skip quotation mark - its storage will be reused (like in name[-1]) */
7707 ++name;
7708 id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, name,
7709 sizeof(ATTRIBUTE_ID));
7710 if (! id)
7711 return NULL((void*)0);
7712 if (id->name != name)
7713 poolDiscard(&dtd->pool)((&dtd->pool)->ptr = (&dtd->pool)->start);
7714 else {
7715 poolFinish(&dtd->pool)((&dtd->pool)->start = (&dtd->pool)->ptr);
7716 if (! parser->m_ns)
7717 ;
7718 else if (name[0] == XML_T(ASCII_x)(uint16_t)0x78 && name[1] == XML_T(ASCII_m)(uint16_t)0x6D
7719 && name[2] == XML_T(ASCII_l)(uint16_t)0x6C && name[3] == XML_T(ASCII_n)(uint16_t)0x6E
7720 && name[4] == XML_T(ASCII_s)(uint16_t)0x73
7721 && (name[5] == XML_T('\0')(uint16_t)'\0' || name[5] == XML_T(ASCII_COLON)(uint16_t)0x3A)) {
7722 if (name[5] == XML_T('\0')(uint16_t)'\0')
7723 id->prefix = &dtd->defaultPrefix;
7724 else
7725 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6,
7726 sizeof(PREFIX));
7727 id->xmlns = XML_TRUE((XML_Bool)1);
7728 } else {
7729 int i;
7730 for (i = 0; name[i]; i++) {
7731 /* Detect and prevent signed integer overflow */
7732 if (i == INT_MAX2147483647) {
7733 return NULL((void*)0);
7734 }
7735 /* attributes without prefix are *not* in the default namespace */
7736 if (name[i] == XML_T(ASCII_COLON)(uint16_t)0x3A) {
7737 if (! poolAppendChars(&dtd->pool, name, i))
7738 return NULL((void*)0);
7739 if (! poolAppendChar(&dtd->pool, XML_T('\0')(uint16_t)'\0'))
7740 return NULL((void*)0);
7741 id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes,
7742 poolStart(&dtd->pool)((&dtd->pool)->start), sizeof(PREFIX));
7743 if (! id->prefix)
7744 return NULL((void*)0);
7745 if (id->prefix->name == poolStart(&dtd->pool)((&dtd->pool)->start))
7746 poolFinish(&dtd->pool)((&dtd->pool)->start = (&dtd->pool)->ptr);
7747 else
7748 poolDiscard(&dtd->pool)((&dtd->pool)->ptr = (&dtd->pool)->start);
7749 break;
7750 }
7751 }
7752 }
7753 }
7754 return id;
7755}
7756
7757#define CONTEXT_SEP(uint16_t)0x0C XML_T(ASCII_FF)(uint16_t)0x0C
7758
7759static const XML_Char *
7760getContext(XML_Parser parser) {
7761 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
7762 HASH_TABLE_ITER iter;
7763 XML_Bool needSep = XML_FALSE((XML_Bool)0);
7764
7765 if (dtd->defaultPrefix.binding) {
7766 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)(uint16_t)0x3D))
7767 return NULL((void*)0);
7768 size_t len = dtd->defaultPrefix.binding->uriLen;
7769 if (parser->m_namespaceSeparator)
7770 len--;
7771 if (! poolAppendChars(&parser->m_tempPool, dtd->defaultPrefix.binding->uri,
7772 len)) {
7773 /* Because of memory caching, I don't believe this line can be
7774 * executed.
7775 *
7776 * This is part of a loop copying the default prefix binding
7777 * URI into the parser's temporary string pool. Previously,
7778 * that URI was copied into the same string pool, with a
7779 * terminating NUL character, as part of setContext(). When
7780 * the pool was cleared, that leaves a block definitely big
7781 * enough to hold the URI on the free block list of the pool.
7782 * The URI copy in getContext() therefore cannot run out of
7783 * memory.
7784 *
7785 * If the pool is used between the setContext() and
7786 * getContext() calls, the worst it can do is leave a bigger
7787 * block on the front of the free list. Given that this is
7788 * all somewhat inobvious and program logic can be changed, we
7789 * don't delete the line but we do exclude it from the test
7790 * coverage statistics.
7791 */
7792 return NULL((void*)0); /* LCOV_EXCL_LINE */
7793 }
7794 needSep = XML_TRUE((XML_Bool)1);
7795 }
7796
7797 hashTableIterInit(&iter, &(dtd->prefixes));
7798 for (;;) {
7799 PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
7800 if (! prefix)
7801 break;
7802 if (! prefix->binding) {
7803 /* This test appears to be (justifiable) paranoia. There does
7804 * not seem to be a way of injecting a prefix without a binding
7805 * that doesn't get errored long before this function is called.
7806 * The test should remain for safety's sake, so we instead
7807 * exclude the following line from the coverage statistics.
7808 */
7809 continue; /* LCOV_EXCL_LINE */
7810 }
7811 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP(uint16_t)0x0C))
7812 return NULL((void*)0);
7813 if (! poolAppendChars(&parser->m_tempPool, prefix->name,
7814 xcslen(prefix->name)))
7815 return NULL((void*)0);
7816 if (! poolAppendChar(&parser->m_tempPool, XML_T(ASCII_EQUALS)(uint16_t)0x3D))
7817 return NULL((void*)0);
7818 size_t len = prefix->binding->uriLen;
7819 if (parser->m_namespaceSeparator)
7820 len--;
7821 if (! poolAppendChars(&parser->m_tempPool, prefix->binding->uri, len))
7822 return NULL((void*)0);
7823 needSep = XML_TRUE((XML_Bool)1);
7824 }
7825
7826 hashTableIterInit(&iter, &(dtd->generalEntities));
7827 for (;;) {
7828 ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
7829 if (! e)
7830 break;
7831 if (! e->open)
7832 continue;
7833 if (needSep && ! poolAppendChar(&parser->m_tempPool, CONTEXT_SEP(uint16_t)0x0C))
7834 return NULL((void*)0);
7835 if (! poolAppendChars(&parser->m_tempPool, e->name, xcslen(e->name)))
7836 return NULL((void*)0);
7837 needSep = XML_TRUE((XML_Bool)1);
7838 }
7839
7840 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')(uint16_t)'\0'))
7841 return NULL((void*)0);
7842 return parser->m_tempPool.start;
7843}
7844
7845static XML_Bool
7846setContext(XML_Parser parser, const XML_Char *context) {
7847 if (context == NULL((void*)0)) {
7848 return XML_FALSE((XML_Bool)0);
7849 }
7850
7851 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
7852 const XML_Char *s = context;
7853
7854 while (*context != XML_T('\0')(uint16_t)'\0') {
7855 if (*s == CONTEXT_SEP(uint16_t)0x0C || *s == XML_T('\0')(uint16_t)'\0') {
7856 ENTITY *e;
7857 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')(uint16_t)'\0'))
7858 return XML_FALSE((XML_Bool)0);
7859 e = (ENTITY *)lookup(parser, &dtd->generalEntities,
7860 poolStart(&parser->m_tempPool)((&parser->m_tempPool)->start), 0);
7861 if (e)
7862 e->open = true1;
7863 if (*s != XML_T('\0')(uint16_t)'\0')
7864 s++;
7865 context = s;
7866 poolDiscard(&parser->m_tempPool)((&parser->m_tempPool)->ptr = (&parser->m_tempPool
)->start)
;
7867 } else if (*s == XML_T(ASCII_EQUALS)(uint16_t)0x3D) {
7868 PREFIX *prefix;
7869 if (poolLength(&parser->m_tempPool)((&parser->m_tempPool)->ptr - (&parser->m_tempPool
)->start)
== 0)
7870 prefix = &dtd->defaultPrefix;
7871 else {
7872 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')(uint16_t)'\0'))
7873 return XML_FALSE((XML_Bool)0);
7874 const XML_Char *const prefixName = poolCopyStringNoFinish(
7875 &dtd->pool, poolStart(&parser->m_tempPool)((&parser->m_tempPool)->start));
7876 if (! prefixName) {
7877 return XML_FALSE((XML_Bool)0);
7878 }
7879
7880 prefix = (PREFIX *)lookup(parser, &dtd->prefixes, prefixName,
7881 sizeof(PREFIX));
7882
7883 const bool_Bool prefixNameUsed = prefix && prefix->name == prefixName;
7884 if (prefixNameUsed)
7885 poolFinish(&dtd->pool)((&dtd->pool)->start = (&dtd->pool)->ptr);
7886 else
7887 poolDiscard(&dtd->pool)((&dtd->pool)->ptr = (&dtd->pool)->start);
7888
7889 if (! prefix)
7890 return XML_FALSE((XML_Bool)0);
7891
7892 poolDiscard(&parser->m_tempPool)((&parser->m_tempPool)->ptr = (&parser->m_tempPool
)->start)
;
7893 }
7894 for (context = s + 1; *context != CONTEXT_SEP(uint16_t)0x0C && *context != XML_T('\0')(uint16_t)'\0';
7895 context++)
7896 if (! poolAppendChar(&parser->m_tempPool, *context))
7897 return XML_FALSE((XML_Bool)0);
7898 if (! poolAppendChar(&parser->m_tempPool, XML_T('\0')(uint16_t)'\0'))
7899 return XML_FALSE((XML_Bool)0);
7900 if (addBinding(parser, prefix, NULL((void*)0), poolStart(&parser->m_tempPool)((&parser->m_tempPool)->start),
7901 &parser->m_inheritedBindings)
7902 != XML_ERROR_NONE)
7903 return XML_FALSE((XML_Bool)0);
7904 poolDiscard(&parser->m_tempPool)((&parser->m_tempPool)->ptr = (&parser->m_tempPool
)->start)
;
7905 if (*context != XML_T('\0')(uint16_t)'\0')
7906 ++context;
7907 s = context;
7908 } else {
7909 if (! poolAppendChar(&parser->m_tempPool, *s))
7910 return XML_FALSE((XML_Bool)0);
7911 s++;
7912 }
7913 }
7914 return XML_TRUE((XML_Bool)1);
7915}
7916
7917static void FASTCALL
7918normalizePublicId(XML_Char *publicId) {
7919 XML_Char *p = publicId;
7920 XML_Char *s;
7921 for (s = publicId; *s; s++) {
7922 switch (*s) {
7923 case 0x20:
7924 case 0xD:
7925 case 0xA:
7926 if (p != publicId && p[-1] != 0x20)
7927 *p++ = 0x20;
7928 break;
7929 default:
7930 *p++ = *s;
7931 }
7932 }
7933 if (p != publicId && p[-1] == 0x20)
7934 --p;
7935 *p = XML_T('\0')(uint16_t)'\0';
7936}
7937
7938static DTD *
7939dtdCreate(XML_Parser parser) {
7940 DTD *p = MALLOC(parser, sizeof(DTD))(expat_malloc((parser), (sizeof(DTD)), 7940));
7941 if (p == NULL((void*)0))
7942 return p;
7943 poolInit(&(p->pool), parser);
7944 poolInit(&(p->entityValuePool), parser);
7945 hashTableInit(&(p->generalEntities), parser);
7946 hashTableInit(&(p->elementTypes), parser);
7947 hashTableInit(&(p->attributeIds), parser);
7948 hashTableInit(&(p->prefixes), parser);
7949#ifdef XML_DTD
7950 p->paramEntityRead = XML_FALSE((XML_Bool)0);
7951 hashTableInit(&(p->paramEntities), parser);
7952#endif /* XML_DTD */
7953 p->defaultPrefix.name = NULL((void*)0);
7954 p->defaultPrefix.binding = NULL((void*)0);
7955
7956 p->in_eldecl = XML_FALSE((XML_Bool)0);
7957 p->scaffIndex = NULL((void*)0);
7958 p->scaffIndexSize = 0;
7959 p->scaffold = NULL((void*)0);
7960 p->scaffLevel = 0;
7961 p->scaffSize = 0;
7962 p->scaffCount = 0;
7963 p->contentStringLen = 0;
7964
7965 p->keepProcessing = XML_TRUE((XML_Bool)1);
7966 p->hasParamEntityRefs = XML_FALSE((XML_Bool)0);
7967 p->standalone = XML_FALSE((XML_Bool)0);
7968 return p;
7969}
7970
7971/* BEGIN MOZILLA CHANGE (unused API) */
7972#if 0
7973static void
7974dtdReset(DTD *p, XML_Parser parser) {
7975 HASH_TABLE_ITER iter;
7976 hashTableIterInit(&iter, &(p->elementTypes));
7977 for (;;) {
7978 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
7979 if (! e)
7980 break;
7981 hashTableDestroy(&(e->defaultAttForName));
7982 FREE(parser, e->defaultAtts)(expat_free((parser), (e->defaultAtts), 7982));
7983 }
7984 hashTableClear(&(p->generalEntities));
7985#ifdef XML_DTD
7986 p->paramEntityRead = XML_FALSE((XML_Bool)0);
7987 hashTableClear(&(p->paramEntities));
7988#endif /* XML_DTD */
7989 hashTableClear(&(p->elementTypes));
7990 hashTableClear(&(p->attributeIds));
7991 hashTableClear(&(p->prefixes));
7992 poolClear(&(p->pool));
7993 poolClear(&(p->entityValuePool));
7994 p->defaultPrefix.name = NULL((void*)0);
7995 p->defaultPrefix.binding = NULL((void*)0);
7996
7997 p->in_eldecl = XML_FALSE((XML_Bool)0);
7998
7999 FREE(parser, p->scaffIndex)(expat_free((parser), (p->scaffIndex), 7999));
8000 p->scaffIndex = NULL((void*)0);
8001 p->scaffIndexSize = 0;
8002 FREE(parser, p->scaffold)(expat_free((parser), (p->scaffold), 8002));
8003 p->scaffold = NULL((void*)0);
8004
8005 p->scaffLevel = 0;
8006 p->scaffSize = 0;
8007 p->scaffCount = 0;
8008 p->contentStringLen = 0;
8009
8010 p->keepProcessing = XML_TRUE((XML_Bool)1);
8011 p->hasParamEntityRefs = XML_FALSE((XML_Bool)0);
8012 p->standalone = XML_FALSE((XML_Bool)0);
8013}
8014#endif
8015/* END MOZILLA CHANGE */
8016
8017static void
8018dtdDestroy(DTD *p, XML_Bool isDocEntity, XML_Parser parser) {
8019 HASH_TABLE_ITER iter;
8020 hashTableIterInit(&iter, &(p->elementTypes));
8021 for (;;) {
8022 ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
8023 if (! e)
8024 break;
8025 hashTableDestroy(&(e->defaultAttForName));
8026 FREE(parser, e->defaultAtts)(expat_free((parser), (e->defaultAtts), 8026));
8027 }
8028 hashTableDestroy(&(p->generalEntities));
8029#ifdef XML_DTD
8030 hashTableDestroy(&(p->paramEntities));
8031#endif /* XML_DTD */
8032 hashTableDestroy(&(p->elementTypes));
8033 hashTableDestroy(&(p->attributeIds));
8034 hashTableDestroy(&(p->prefixes));
8035 poolDestroy(&(p->pool));
8036 poolDestroy(&(p->entityValuePool));
8037 if (isDocEntity) {
8038 FREE(parser, p->scaffIndex)(expat_free((parser), (p->scaffIndex), 8038));
8039 FREE(parser, p->scaffold)(expat_free((parser), (p->scaffold), 8039));
8040 }
8041 FREE(parser, p)(expat_free((parser), (p), 8041));
8042}
8043
8044/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
8045 The new DTD has already been initialized.
8046*/
8047static int
8048dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
8049 XML_Parser parser) {
8050 HASH_TABLE_ITER iter;
8051
8052 /* Copy the prefix table. */
8053
8054 hashTableIterInit(&iter, &(oldDtd->prefixes));
8055 for (;;) {
8056 const XML_Char *name;
8057 const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
8058 if (! oldP)
8059 break;
8060 name = poolCopyString(&(newDtd->pool), oldP->name);
8061 if (! name)
8062 return 0;
8063 if (! lookup(oldParser, &(newDtd->prefixes), name, sizeof(PREFIX)))
8064 return 0;
8065 }
8066
8067 hashTableIterInit(&iter, &(oldDtd->attributeIds));
8068
8069 /* Copy the attribute id table. */
8070
8071 for (;;) {
8072 ATTRIBUTE_ID *newA;
8073 const XML_Char *name;
8074 const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
8075
8076 if (! oldA)
8077 break;
8078 /* Remember to allocate the scratch byte before the name. */
8079 if (! poolAppendChar(&(newDtd->pool), XML_T('\0')(uint16_t)'\0'))
8080 return 0;
8081 name = poolCopyString(&(newDtd->pool), oldA->name);
8082 if (! name)
8083 return 0;
8084 ++name;
8085 newA = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds), name,
8086 sizeof(ATTRIBUTE_ID));
8087 if (! newA)
8088 return 0;
8089 newA->maybeTokenized = oldA->maybeTokenized;
8090 if (oldA->prefix) {
8091 newA->xmlns = oldA->xmlns;
8092 if (oldA->prefix == &oldDtd->defaultPrefix)
8093 newA->prefix = &newDtd->defaultPrefix;
8094 else
8095 newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
8096 oldA->prefix->name, 0);
8097 }
8098 }
8099
8100 /* Copy the element type table. */
8101
8102 hashTableIterInit(&iter, &(oldDtd->elementTypes));
8103
8104 for (;;) {
8105 ELEMENT_TYPE *newE;
8106 const XML_Char *name;
8107 const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
8108 if (! oldE)
8109 break;
8110 name = poolCopyString(&(newDtd->pool), oldE->name);
8111 if (! name)
8112 return 0;
8113 newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
8114 sizeof(ELEMENT_TYPE));
8115 if (! newE)
8116 return 0;
8117
8118 if (! newE->defaultAttForName.parser)
8119 hashTableInit(&(newE->defaultAttForName), parser);
8120
8121 if (oldE->nDefaultAtts) {
8122 /* Detect and prevent integer overflow. */
8123 if (oldE->nDefaultAtts > SIZE_MAX(18446744073709551615UL) / sizeof(DEFAULT_ATTRIBUTE)) {
8124 return 0;
8125 }
8126 newE->defaultAtts
8127 = MALLOC(parser, oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE))(expat_malloc((parser), (oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE
)), 8127))
;
8128 if (! newE->defaultAtts) {
8129 return 0;
8130 }
8131 }
8132 if (oldE->idAtt)
8133 newE->idAtt = (ATTRIBUTE_ID *)lookup(oldParser, &(newDtd->attributeIds),
8134 oldE->idAtt->name, 0);
8135 newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
8136 if (oldE->prefix)
8137 newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
8138 oldE->prefix->name, 0);
8139 for (size_t i = 0; i < newE->nDefaultAtts; i++) {
8140 const XML_Char *const attributeName = oldE->defaultAtts[i].id->name;
8141 newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(
8142 oldParser, &(newDtd->attributeIds), attributeName, 0);
8143 newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
8144 if (oldE->defaultAtts[i].value) {
8145 newE->defaultAtts[i].value
8146 = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
8147 if (! newE->defaultAtts[i].value)
8148 return 0;
8149 } else
8150 newE->defaultAtts[i].value = NULL((void*)0);
8151
8152 NAME_AND_DEFAULT_ATTRIBUTE *const nameAndDefaultAttribute
8153 = (NAME_AND_DEFAULT_ATTRIBUTE *)lookup(
8154 parser, &(newE->defaultAttForName), attributeName,
8155 sizeof(NAME_AND_DEFAULT_ATTRIBUTE));
8156 if (! nameAndDefaultAttribute) {
8157 return 0;
8158 }
8159
8160 // NOTE: The XML 1.0r4 spec says:
8161 // "When more than one definition is provided for the same attribute of a
8162 // given element type, the first declaration is binding and later
8163 // declarations are ignored."
8164 if (! nameAndDefaultAttribute->initialized) {
8165 nameAndDefaultAttribute->attIndex = i;
8166 nameAndDefaultAttribute->initialized = true1;
8167 }
8168 }
8169 }
8170
8171 /* Copy the entity tables. */
8172 if (! copyEntityTable(oldParser, &(newDtd->generalEntities), &(newDtd->pool),
8173 &(oldDtd->generalEntities)))
8174 return 0;
8175
8176#ifdef XML_DTD
8177 if (! copyEntityTable(oldParser, &(newDtd->paramEntities), &(newDtd->pool),
8178 &(oldDtd->paramEntities)))
8179 return 0;
8180 newDtd->paramEntityRead = oldDtd->paramEntityRead;
8181#endif /* XML_DTD */
8182
8183 newDtd->keepProcessing = oldDtd->keepProcessing;
8184 newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
8185 newDtd->standalone = oldDtd->standalone;
8186
8187 /* Don't want deep copying for scaffolding */
8188 newDtd->in_eldecl = oldDtd->in_eldecl;
8189 newDtd->scaffold = oldDtd->scaffold;
8190 newDtd->contentStringLen = oldDtd->contentStringLen;
8191 newDtd->scaffSize = oldDtd->scaffSize;
8192 newDtd->scaffLevel = oldDtd->scaffLevel;
8193 newDtd->scaffIndex = oldDtd->scaffIndex;
8194 newDtd->scaffIndexSize = oldDtd->scaffIndexSize;
8195
8196 return 1;
8197} /* End dtdCopy */
8198
8199static int
8200copyEntityTable(XML_Parser oldParser, HASH_TABLE *newTable,
8201 STRING_POOL *newPool, const HASH_TABLE *oldTable) {
8202 HASH_TABLE_ITER iter;
8203 const XML_Char *cachedOldBase = NULL((void*)0);
8204 const XML_Char *cachedNewBase = NULL((void*)0);
8205
8206 hashTableIterInit(&iter, oldTable);
8207
8208 for (;;) {
8209 ENTITY *newE;
8210 const XML_Char *name;
8211 const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
8212 if (! oldE)
8213 break;
8214 name = poolCopyString(newPool, oldE->name);
8215 if (! name)
8216 return 0;
8217 newE = (ENTITY *)lookup(oldParser, newTable, name, sizeof(ENTITY));
8218 if (! newE)
8219 return 0;
8220 if (oldE->systemId) {
8221 const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
8222 if (! tem)
8223 return 0;
8224 newE->systemId = tem;
8225 if (oldE->base) {
8226 if (oldE->base == cachedOldBase)
8227 newE->base = cachedNewBase;
8228 else {
8229 cachedOldBase = oldE->base;
8230 tem = poolCopyString(newPool, cachedOldBase);
8231 if (! tem)
8232 return 0;
8233 cachedNewBase = newE->base = tem;
8234 }
8235 }
8236 if (oldE->publicId) {
8237 tem = poolCopyString(newPool, oldE->publicId);
8238 if (! tem)
8239 return 0;
8240 newE->publicId = tem;
8241 }
8242 } else {
8243 const XML_Char *tem
8244 = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
8245 if (! tem)
8246 return 0;
8247 newE->textPtr = tem;
8248 newE->textLen = oldE->textLen;
8249 }
8250 if (oldE->notation) {
8251 const XML_Char *tem = poolCopyString(newPool, oldE->notation);
8252 if (! tem)
8253 return 0;
8254 newE->notation = tem;
8255 }
8256 newE->is_param = oldE->is_param;
8257 newE->is_internal = oldE->is_internal;
8258 }
8259 return 1;
8260}
8261
8262#define INIT_POWER6 6
8263
8264// Compares two strings `s1` and `s2` whereas:
8265// - `s2` is zero-terminated but
8266// - `s1` is made up of exactly (not just up to) `s1len` non-zero characters.
8267static XML_Bool FASTCALL
8268keyeq(KEY s1, size_t s1len, KEY s2) {
8269#ifdef XML_UNICODE
8270# ifdef XML_UNICODE_WCHAR_T
8271 return (wcsncmp(s1, s2, s1len) == 0 && s2[s1len] == L'\0') ? XML_TRUE((XML_Bool)1)
8272 : XML_FALSE((XML_Bool)0);
8273# else
8274 for (; s1len > 0 && *s1 == *s2; s1len--, s1++, s2++)
8275 ; /* no loop body! */
8276 return ((s1len == 0) && (*s2 == 0)) ? XML_TRUE((XML_Bool)1) : XML_FALSE((XML_Bool)0);
8277# endif
8278#else
8279 return (strncmp(s1, s2, s1len) == 0 && s2[s1len] == '\0') ? XML_TRUE((XML_Bool)1)
8280 : XML_FALSE((XML_Bool)0);
8281#endif
8282}
8283
8284static size_t
8285keylen(KEY s) {
8286 return xcslen(s);
8287}
8288
8289static void
8290copy_salt_to_sipkey(XML_Parser parser, struct sipkey *key) {
8291 const XML_Parser rootParser = getRootParserOf(parser, NULL((void*)0));
8292 assert(! rootParser->m_parentParser)((void) sizeof ((! rootParser->m_parentParser) ? 1 : 0), __extension__
({ if (! rootParser->m_parentParser) ; else __assert_fail
("! rootParser->m_parentParser", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 8292, __extension__ __PRETTY_FUNCTION__); }))
;
8293
8294 *key = rootParser->m_hash_secret_salt_128;
8295}
8296
8297static unsigned long FASTCALL
8298hash(XML_Parser parser, KEY s, size_t keyLen) {
8299 struct siphash state;
8300 struct sipkey key;
8301 (void)sip24_valid;
8302 copy_salt_to_sipkey(parser, &key);
8303 sip24_init(&state, &key);
8304 sip24_update(&state, s, keyLen * sizeof(XML_Char));
8305 return (unsigned long)sip24_final(&state);
8306}
8307
8308// Function `lookupWithLength` can be used to either…
8309//
8310// a) check whether an element with key `name` exists in the given hash table
8311// (read-only mode where `createSize == 0`) or
8312//
8313// b) check whether an element with key `name` exists in the given hash table
8314// *and* insert it if missing (i.e. read-write mode where `createSize != 0`.
8315//
8316// When inserting, a block of `createSize` number of bytes will be allocated
8317// and set to zero, and the resulting block of memory will be considered
8318// to start with a `NAMED` structure, and `->name = name;` is performed.
8319// The fact that all other bytes in the structure are initially zero can
8320// be used to tell cases "existed and found" and "newly inserted" apart
8321// with the structure returned.
8322//
8323// NOTE: Read-only lookup does not need zero-terminated keys but
8324// read-write mode does, because keys can be re-hashed later and the
8325// hash table does not store key length information.
8326//
8327static NAMED *
8328lookupWithLength(XML_Parser parser, HASH_TABLE *table, KEY name, size_t nameLen,
8329 size_t createSize) {
8330 size_t i;
8331 if (table->size == 0) {
8332 size_t tsize;
8333 if (! createSize)
8334 return NULL((void*)0);
8335 table->power = INIT_POWER6;
8336 /* table->size is a power of 2 */
8337 table->size = (size_t)1 << INIT_POWER6;
8338 tsize = table->size * sizeof(NAMED *);
8339 table->v = MALLOC(table->parser, tsize)(expat_malloc((table->parser), (tsize), 8339));
8340 if (! table->v) {
8341 table->size = 0;
8342 return NULL((void*)0);
8343 }
8344 memset(table->v, 0, tsize);
8345 i = hash(parser, name, nameLen) & ((unsigned long)table->size - 1);
8346 } else {
8347 unsigned long h = hash(parser, name, nameLen);
8348 unsigned long mask = (unsigned long)table->size - 1;
8349 unsigned char step = 0;
8350 i = h & mask;
8351 while (table->v[i]) {
8352 if (keyeq(name, nameLen, table->v[i]->name))
8353 return table->v[i];
8354 if (! step)
8355 step = PROBE_STEP(h, mask, table->power)((unsigned char)((((((h) & ~(mask)) >> ((table->
power) - 1)) & ((mask) >> 2))) | 1))
;
8356 i < step ? (i += table->size - step) : (i -= step);
8357 }
8358 if (! createSize)
8359 return NULL((void*)0);
8360
8361 /* check for overflow (table is half full) */
8362 if (table->used >> (table->power - 1)) {
8363 unsigned char newPower = table->power + 1;
8364
8365 /* Detect and prevent invalid shift */
8366 if (newPower >= sizeof(unsigned long) * 8 /* bits per byte */) {
8367 return NULL((void*)0);
8368 }
8369
8370 size_t newSize = (size_t)1 << newPower;
8371 unsigned long newMask = (unsigned long)newSize - 1;
8372
8373 /* Detect and prevent integer overflow */
8374 if (newSize > SIZE_MAX(18446744073709551615UL) / sizeof(NAMED *)) {
8375 return NULL((void*)0);
8376 }
8377
8378 size_t tsize = newSize * sizeof(NAMED *);
8379 NAMED **newV = MALLOC(table->parser, tsize)(expat_malloc((table->parser), (tsize), 8379));
8380 if (! newV)
8381 return NULL((void*)0);
8382 memset(newV, 0, tsize);
8383 for (i = 0; i < table->size; i++)
8384 if (table->v[i]) {
8385 KEY const key = table->v[i]->name;
8386 unsigned long newHash = hash(parser, key, keylen(key));
8387 size_t j = newHash & newMask;
8388 step = 0;
8389 while (newV[j]) {
8390 if (! step)
8391 step = PROBE_STEP(newHash, newMask, newPower)((unsigned char)((((((newHash) & ~(newMask)) >> ((newPower
) - 1)) & ((newMask) >> 2))) | 1))
;
8392 j < step ? (j += newSize - step) : (j -= step);
8393 }
8394 newV[j] = table->v[i];
8395 }
8396 FREE(table->parser, table->v)(expat_free((table->parser), (table->v), 8396));
8397 table->v = newV;
8398 table->power = newPower;
8399 table->size = newSize;
8400 i = h & newMask;
8401 step = 0;
8402 while (table->v[i]) {
8403 if (! step)
8404 step = PROBE_STEP(h, newMask, newPower)((unsigned char)((((((h) & ~(newMask)) >> ((newPower
) - 1)) & ((newMask) >> 2))) | 1))
;
8405 i < step ? (i += newSize - step) : (i -= step);
8406 }
8407 }
8408 }
8409 assert(createSize >= sizeof(NAMED))((void) sizeof ((createSize >= sizeof(NAMED)) ? 1 : 0), __extension__
({ if (createSize >= sizeof(NAMED)) ; else __assert_fail (
"createSize >= sizeof(NAMED)", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 8409, __extension__ __PRETTY_FUNCTION__); }))
;
8410 table->v[i] = MALLOC(table->parser, createSize)(expat_malloc((table->parser), (createSize), 8410));
8411 if (! table->v[i])
8412 return NULL((void*)0);
8413 memset(table->v[i], 0, createSize);
8414 table->v[i]->name = name; // NOTE: This requires and assumes zero termination!
8415 (table->used)++;
8416 return table->v[i];
8417}
8418
8419// Function `lookup` can be used to either…
8420//
8421// a) check whether an element with key `name` exists in the given hash table
8422// (read-only mode where `createSize == 0`) or
8423//
8424// b) check whether an element with key `name` exists in the given hash table
8425// *and* insert it if missing (i.e. read-write mode where `createSize != 0`.
8426//
8427// When inserting, a block of `createSize` number of bytes will be allocated
8428// and set to zero, and the resulting block of memory will be considered
8429// to start with a `NAMED` structure, and `->name = name;` is performed.
8430// The fact that all other bytes in the structure are initially zero can
8431// be used to tell cases "existed and found" and "newly inserted" apart
8432// with the structure returned.
8433//
8434static NAMED *
8435lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
8436 return lookupWithLength(parser, table, name, keylen(name), createSize);
8437}
8438
8439/* BEGIN MOZILLA CHANGE (unused API) */
8440#if 0
8441static void FASTCALL
8442hashTableClear(HASH_TABLE *table) {
8443 size_t i;
8444 for (i = 0; i < table->size; i++) {
8445 FREE(table->parser, table->v[i])(expat_free((table->parser), (table->v[i]), 8445));
8446 table->v[i] = NULL((void*)0);
8447 }
8448 table->used = 0;
8449}
8450#endif
8451/* END MOZILLA CHANGE */
8452
8453static void FASTCALL
8454hashTableDestroy(HASH_TABLE *table) {
8455 size_t i;
8456 for (i = 0; i < table->size; i++)
8457 FREE(table->parser, table->v[i])(expat_free((table->parser), (table->v[i]), 8457));
8458 FREE(table->parser, table->v)(expat_free((table->parser), (table->v), 8458));
8459}
8460
8461static void FASTCALL
8462hashTableInit(HASH_TABLE *p, XML_Parser parser) {
8463 p->power = 0;
8464 p->size = 0;
8465 p->used = 0;
8466 p->v = NULL((void*)0);
8467 p->parser = parser;
8468}
8469
8470static void FASTCALL
8471hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) {
8472 iter->p = table->v;
8473 iter->end = iter->p ? iter->p + table->size : NULL((void*)0);
8474}
8475
8476static NAMED *FASTCALL
8477hashTableIterNext(HASH_TABLE_ITER *iter) {
8478 while (iter->p != iter->end) {
8479 NAMED *tem = *(iter->p)++;
8480 if (tem)
8481 return tem;
8482 }
8483 return NULL((void*)0);
8484}
8485
8486static void FASTCALL
8487poolInit(STRING_POOL *pool, XML_Parser parser) {
8488 pool->blocks = NULL((void*)0);
8489 pool->freeBlocks = NULL((void*)0);
8490 pool->start = NULL((void*)0);
8491 pool->ptr = NULL((void*)0);
8492 pool->end = NULL((void*)0);
8493 pool->parser = parser;
8494}
8495
8496static void FASTCALL
8497poolClear(STRING_POOL *pool) {
8498 if (! pool->freeBlocks)
8499 pool->freeBlocks = pool->blocks;
8500 else {
8501 BLOCK *p = pool->blocks;
8502 while (p) {
8503 BLOCK *tem = p->next;
8504 p->next = pool->freeBlocks;
8505 pool->freeBlocks = p;
8506 p = tem;
8507 }
8508 }
8509 pool->blocks = NULL((void*)0);
8510 pool->start = NULL((void*)0);
8511 pool->ptr = NULL((void*)0);
8512 pool->end = NULL((void*)0);
8513}
8514
8515static void FASTCALL
8516poolDestroy(STRING_POOL *pool) {
8517 BLOCK *p = pool->blocks;
8518 while (p) {
8519 BLOCK *tem = p->next;
8520 FREE(pool->parser, p)(expat_free((pool->parser), (p), 8520));
8521 p = tem;
8522 }
8523 p = pool->freeBlocks;
8524 while (p) {
8525 BLOCK *tem = p->next;
8526 FREE(pool->parser, p)(expat_free((pool->parser), (p), 8526));
8527 p = tem;
8528 }
8529}
8530
8531static XML_Char *
8532poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
8533 const char *end) {
8534 if (! pool->ptr && ! poolGrow(pool))
8535 return NULL((void*)0);
8536 for (;;) {
8537 const enum XML_Convert_Result convert_res = XmlConvert((((enc)->utf16Convert)(enc, &ptr, end, (ICHAR **)&
(pool->ptr), (const ICHAR *)pool->end))
8538 enc, &ptr, end, (ICHAR **)&(pool->ptr), (const ICHAR *)pool->end)(((enc)->utf16Convert)(enc, &ptr, end, (ICHAR **)&
(pool->ptr), (const ICHAR *)pool->end))
;
8539 if ((convert_res == XML_CONVERT_COMPLETED)
8540 || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
8541 break;
8542 if (! poolGrow(pool))
8543 return NULL((void*)0);
8544 }
8545 return pool->start;
8546}
8547
8548static const XML_Char *FASTCALL
8549poolCopyString(STRING_POOL *pool, const XML_Char *s) {
8550 if (! poolAppendChars(pool, s, xcslen(s) + /*null terminator*/ 1))
8551 return NULL((void*)0);
8552 s = pool->start;
8553 poolFinish(pool)((pool)->start = (pool)->ptr);
8554 return s;
8555}
8556
8557// A version of `poolCopyString` that does not call `poolFinish`
8558// and reverts any partial advancement upon failure.
8559static const XML_Char *FASTCALL
8560poolCopyStringNoFinish(STRING_POOL *pool, const XML_Char *s) {
8561 const XML_Char *const original = s;
8562 do {
8563 if (! poolAppendChar(pool, *s)) {
8564 // Revert any previously successful advancement
8565 const ptrdiff_t advancedBy = s - original;
8566 if (advancedBy > 0)
8567 pool->ptr -= advancedBy;
8568 return NULL((void*)0);
8569 }
8570 } while (*s++);
8571 return pool->start;
8572}
8573
8574static const XML_Char *
8575poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) {
8576 if (! pool->ptr && ! poolGrow(pool)) {
8577 /* The following line is unreachable given the current usage of
8578 * poolCopyStringN(). Currently it is called from exactly one
8579 * place to copy the text of a simple general entity. By that
8580 * point, the name of the entity is already stored in the pool, so
8581 * pool->ptr cannot be NULL.
8582 *
8583 * If poolCopyStringN() is used elsewhere as it well might be,
8584 * this line may well become executable again. Regardless, this
8585 * sort of check shouldn't be removed lightly, so we just exclude
8586 * it from the coverage statistics.
8587 */
8588 return NULL((void*)0); /* LCOV_EXCL_LINE */
8589 }
8590 if (n > 0 && ! poolAppendChars(pool, s, n))
8591 return NULL((void*)0);
8592 s = pool->start;
8593 poolFinish(pool)((pool)->start = (pool)->ptr);
8594 return s;
8595}
8596
8597static const XML_Char *FASTCALL
8598poolAppendString(STRING_POOL *pool, const XML_Char *s) {
8599 if (! poolAppendChars(pool, s, xcslen(s)))
8600 return NULL((void*)0);
8601 return pool->start;
8602}
8603
8604static XML_Char *
8605poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr,
8606 const char *end) {
8607 if (! poolAppend(pool, enc, ptr, end))
8608 return NULL((void*)0);
8609 if (! poolAppendChar(pool, 0))
8610 return NULL((void*)0);
8611 return pool->start;
8612}
8613
8614static size_t
8615poolBytesToAllocateFor(int blockSize) {
8616 /* Unprotected math would be:
8617 ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
8618 **
8619 ** Detect overflow, avoiding _signed_ overflow undefined behavior
8620 ** For a + b * c we check b * c in isolation first, so that addition of a
8621 ** on top has no chance of making us accept a small non-negative number
8622 */
8623 const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */
8624
8625 if (blockSize <= 0)
8626 return 0;
8627
8628 if (blockSize > (int)(INT_MAX2147483647 / stretch))
8629 return 0;
8630
8631 {
8632 const int stretchedBlockSize = blockSize * (int)stretch;
8633 const int bytesToAllocate
8634 = (int)(offsetof(BLOCK, s)__builtin_offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
8635 if (bytesToAllocate < 0)
8636 return 0;
8637
8638 return (size_t)bytesToAllocate;
8639 }
8640}
8641
8642static XML_Bool FASTCALL
8643poolGrow(STRING_POOL *pool) {
8644 if (pool->freeBlocks) {
8645 if (pool->start == NULL((void*)0)) {
8646 pool->blocks = pool->freeBlocks;
8647 pool->freeBlocks = pool->freeBlocks->next;
8648 pool->blocks->next = NULL((void*)0);
8649 pool->start = pool->blocks->s;
8650 pool->end = pool->start + pool->blocks->size;
8651 pool->ptr = pool->start;
8652 return XML_TRUE((XML_Bool)1);
8653 }
8654 if (pool->end - pool->start < pool->freeBlocks->size) {
8655 BLOCK *tem = pool->freeBlocks->next;
8656 pool->freeBlocks->next = pool->blocks;
8657 pool->blocks = pool->freeBlocks;
8658 pool->freeBlocks = tem;
8659 memcpy(pool->blocks->s, pool->start,
8660 (pool->end - pool->start) * sizeof(XML_Char));
8661 pool->ptr = pool->blocks->s + EXPAT_SAFE_PTR_DIFF(pool->ptr, pool->start)(((pool->ptr) && (pool->start)) ? ((pool->ptr
) - (pool->start)) : 0)
;
8662 pool->start = pool->blocks->s;
8663 pool->end = pool->start + pool->blocks->size;
8664 return XML_TRUE((XML_Bool)1);
8665 }
8666 }
8667 if (pool->blocks && pool->start == pool->blocks->s) {
8668 BLOCK *temp;
8669 int blockSize = (int)((unsigned)(pool->end - pool->start) * 2U);
8670 size_t bytesToAllocate;
8671
8672 /* NOTE: Needs to be calculated prior to calling `realloc`
8673 to avoid dangling pointers: */
8674 const ptrdiff_t offsetInsideBlock
8675 = EXPAT_SAFE_PTR_DIFF(pool->ptr, pool->start)(((pool->ptr) && (pool->start)) ? ((pool->ptr
) - (pool->start)) : 0)
;
8676
8677 if (blockSize < 0) {
8678 /* This condition traps a situation where either more than
8679 * INT_MAX/2 bytes have already been allocated. This isn't
8680 * readily testable, since it is unlikely that an average
8681 * machine will have that much memory, so we exclude it from the
8682 * coverage statistics.
8683 */
8684 return XML_FALSE((XML_Bool)0); /* LCOV_EXCL_LINE */
8685 }
8686
8687 bytesToAllocate = poolBytesToAllocateFor(blockSize);
8688 if (bytesToAllocate == 0)
8689 return XML_FALSE((XML_Bool)0);
8690
8691 temp = REALLOC(pool->parser, pool->blocks, bytesToAllocate)(expat_realloc((pool->parser), (pool->blocks), (bytesToAllocate
), 8691))
;
8692 if (temp == NULL((void*)0))
8693 return XML_FALSE((XML_Bool)0);
8694 pool->blocks = temp;
8695 pool->blocks->size = blockSize;
8696 pool->ptr = pool->blocks->s + offsetInsideBlock;
8697 pool->start = pool->blocks->s;
8698 pool->end = pool->start + blockSize;
8699 } else {
8700 BLOCK *tem;
8701 int blockSize = (int)(pool->end - pool->start);
8702 size_t bytesToAllocate;
8703
8704 if (blockSize < 0) {
8705 /* This condition traps a situation where either more than
8706 * INT_MAX bytes have already been allocated (which is prevented
8707 * by various pieces of program logic, not least this one, never
8708 * mind the unlikelihood of actually having that much memory) or
8709 * the pool control fields have been corrupted (which could
8710 * conceivably happen in an extremely buggy user handler
8711 * function). Either way it isn't readily testable, so we
8712 * exclude it from the coverage statistics.
8713 */
8714 return XML_FALSE((XML_Bool)0); /* LCOV_EXCL_LINE */
8715 }
8716
8717 if (blockSize < INIT_BLOCK_SIZE1024)
8718 blockSize = INIT_BLOCK_SIZE1024;
8719 else {
8720 /* Detect overflow, avoiding _signed_ overflow undefined behavior */
8721 if ((int)((unsigned)blockSize * 2U) < 0) {
8722 return XML_FALSE((XML_Bool)0);
8723 }
8724 blockSize *= 2;
8725 }
8726
8727 bytesToAllocate = poolBytesToAllocateFor(blockSize);
8728 if (bytesToAllocate == 0)
8729 return XML_FALSE((XML_Bool)0);
8730
8731 tem = MALLOC(pool->parser, bytesToAllocate)(expat_malloc((pool->parser), (bytesToAllocate), 8731));
8732 if (! tem)
8733 return XML_FALSE((XML_Bool)0);
8734 tem->size = blockSize;
8735 tem->next = pool->blocks;
8736 pool->blocks = tem;
8737 if (pool->ptr != pool->start)
8738 memcpy(tem->s, pool->start,
8739 EXPAT_SAFE_PTR_DIFF(pool->ptr, pool->start)(((pool->ptr) && (pool->start)) ? ((pool->ptr
) - (pool->start)) : 0)
* sizeof(XML_Char));
8740 pool->ptr = tem->s + EXPAT_SAFE_PTR_DIFF(pool->ptr, pool->start)(((pool->ptr) && (pool->start)) ? ((pool->ptr
) - (pool->start)) : 0)
;
8741 pool->start = tem->s;
8742 pool->end = tem->s + blockSize;
8743 }
8744 return XML_TRUE((XML_Bool)1);
8745}
8746
8747static bool_Bool FASTCALL
8748poolGrowUntil(STRING_POOL *pool, size_t needed) {
8749 for (;;) {
8750 const size_t available = pool->end - pool->ptr;
8751 if (available >= needed) {
8752 return true1;
8753 }
8754 if (! poolGrow(pool)) {
8755 return false0;
8756 }
8757 }
8758}
8759
8760static int FASTCALL
8761nextScaffoldPart(XML_Parser parser) {
8762 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
8763 CONTENT_SCAFFOLD *me;
8764 int next;
8765
8766 if (! dtd->scaffIndex) {
8767 /* Detect and prevent integer overflow. */
8768 if (parser->m_groupSize > SIZE_MAX(18446744073709551615UL) / sizeof(int)) {
8769 return -1;
8770 }
8771 dtd->scaffIndex = MALLOC(parser, parser->m_groupSize * sizeof(int))(expat_malloc((parser), (parser->m_groupSize * sizeof(int)
), 8771))
;
8772 if (! dtd->scaffIndex)
8773 return -1;
8774 dtd->scaffIndexSize = parser->m_groupSize;
8775 dtd->scaffIndex[0] = 0;
8776 }
8777
8778 // Will casting to int be safe further down?
8779 if (dtd->scaffCount > INT_MAX2147483647) {
8780 return -1;
8781 }
8782
8783 if (dtd->scaffCount >= dtd->scaffSize) {
8784 CONTENT_SCAFFOLD *temp;
8785 if (dtd->scaffold) {
8786 /* Detect and prevent integer overflow */
8787 if (dtd->scaffSize > UINT_MAX(2147483647 *2U +1U) / 2u) {
8788 return -1;
8789 }
8790 /* Detect and prevent integer overflow.
8791 * The preprocessor guard addresses the "always false" warning
8792 * from -Wtype-limits on platforms where
8793 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
8794#if UINT_MAX(2147483647 *2U +1U) >= SIZE_MAX(18446744073709551615UL)
8795 if (dtd->scaffSize > SIZE_MAX(18446744073709551615UL) / 2u / sizeof(CONTENT_SCAFFOLD)) {
8796 return -1;
8797 }
8798#endif
8799
8800 temp = REALLOC(parser, dtd->scaffold,(expat_realloc((parser), (dtd->scaffold), (dtd->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD)), 8801))
8801 dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD))(expat_realloc((parser), (dtd->scaffold), (dtd->scaffSize
* 2 * sizeof(CONTENT_SCAFFOLD)), 8801))
;
8802 if (temp == NULL((void*)0))
8803 return -1;
8804 dtd->scaffSize *= 2;
8805 } else {
8806 temp = MALLOC(parser, INIT_SCAFFOLD_ELEMENTS * sizeof(CONTENT_SCAFFOLD))(expat_malloc((parser), (32 * sizeof(CONTENT_SCAFFOLD)), 8806
))
;
8807 if (temp == NULL((void*)0))
8808 return -1;
8809 dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS32;
8810 }
8811 dtd->scaffold = temp;
8812 }
8813 next = (int)dtd->scaffCount++;
8814 me = &dtd->scaffold[next];
8815 if (dtd->scaffLevel) {
8816 CONTENT_SCAFFOLD *parent
8817 = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]];
8818 if (parent->lastchild) {
8819 dtd->scaffold[parent->lastchild].nextsib = next;
8820 }
8821 if (! parent->childcnt)
8822 parent->firstchild = next;
8823 parent->lastchild = next;
8824 parent->childcnt++;
8825 }
8826 me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
8827 return next;
8828}
8829
8830static XML_Content *
8831build_model(XML_Parser parser) {
8832 /* Function build_model transforms the existing parser->m_dtd->scaffold
8833 * array of CONTENT_SCAFFOLD tree nodes into a new array of
8834 * XML_Content tree nodes followed by a gapless list of zero-terminated
8835 * strings. */
8836 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
8837 XML_Content *ret;
8838 XML_Char *str; /* the current string writing location */
8839
8840 /* Detect and prevent integer overflow.
8841 * The preprocessor guard addresses the "always false" warning
8842 * from -Wtype-limits on platforms where
8843 * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
8844#if UINT_MAX(2147483647 *2U +1U) >= SIZE_MAX(18446744073709551615UL)
8845 if (dtd->scaffCount > SIZE_MAX(18446744073709551615UL) / sizeof(XML_Content)) {
8846 return NULL((void*)0);
8847 }
8848 if (dtd->contentStringLen > SIZE_MAX(18446744073709551615UL) / sizeof(XML_Char)) {
8849 return NULL((void*)0);
8850 }
8851#endif
8852 if (dtd->scaffCount * sizeof(XML_Content)
8853 > SIZE_MAX(18446744073709551615UL) - dtd->contentStringLen * sizeof(XML_Char)) {
8854 return NULL((void*)0);
8855 }
8856
8857 const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content)
8858 + (dtd->contentStringLen * sizeof(XML_Char)));
8859
8860 // NOTE: We are avoiding MALLOC(..) here to so that
8861 // applications that are not using XML_FreeContentModel but plain
8862 // free(..) or .free_fcn() to free the content model's memory are safe.
8863 ret = parser->m_mem.malloc_fcn(allocsize);
8864 if (! ret)
8865 return NULL((void*)0);
8866
8867 /* What follows is an iterative implementation (of what was previously done
8868 * recursively in a dedicated function called "build_node". The old recursive
8869 * build_node could be forced into stack exhaustion from input as small as a
8870 * few megabyte, and so that was a security issue. Hence, a function call
8871 * stack is avoided now by resolving recursion.)
8872 *
8873 * The iterative approach works as follows:
8874 *
8875 * - We have two writing pointers, both walking up the result array; one does
8876 * the work, the other creates "jobs" for its colleague to do, and leads
8877 * the way:
8878 *
8879 * - The faster one, pointer jobDest, always leads and writes "what job
8880 * to do" by the other, once they reach that place in the
8881 * array: leader "jobDest" stores the source node array index (relative
8882 * to array dtd->scaffold) in field "numchildren".
8883 *
8884 * - The slower one, pointer dest, looks at the value stored in the
8885 * "numchildren" field (which actually holds a source node array index
8886 * at that time) and puts the real data from dtd->scaffold in.
8887 *
8888 * - Before the loop starts, jobDest writes source array index 0
8889 * (where the root node is located) so that dest will have something to do
8890 * when it starts operation.
8891 *
8892 * - Whenever nodes with children are encountered, jobDest appends
8893 * them as new jobs, in order. As a result, tree node siblings are
8894 * adjacent in the resulting array, for example:
8895 *
8896 * [0] root, has two children
8897 * [1] first child of 0, has three children
8898 * [3] first child of 1, does not have children
8899 * [4] second child of 1, does not have children
8900 * [5] third child of 1, does not have children
8901 * [2] second child of 0, does not have children
8902 *
8903 * Or (the same data) presented in flat array view:
8904 *
8905 * [0] root, has two children
8906 *
8907 * [1] first child of 0, has three children
8908 * [2] second child of 0, does not have children
8909 *
8910 * [3] first child of 1, does not have children
8911 * [4] second child of 1, does not have children
8912 * [5] third child of 1, does not have children
8913 *
8914 * - The algorithm repeats until all target array indices have been processed.
8915 */
8916 XML_Content *dest = ret; /* tree node writing location, moves upwards */
8917 XML_Content *const destLimit = &ret[dtd->scaffCount];
8918 XML_Content *jobDest = ret; /* next free writing location in target array */
8919 str = (XML_Char *)&ret[dtd->scaffCount];
8920
8921 /* Add the starting job, the root node (index 0) of the source tree */
8922 (jobDest++)->numchildren = 0;
8923
8924 for (; dest < destLimit; dest++) {
8925 /* Retrieve source tree array index from job storage */
8926 const int src_node = (int)dest->numchildren;
8927
8928 /* Convert item */
8929 dest->type = dtd->scaffold[src_node].type;
8930 dest->quant = dtd->scaffold[src_node].quant;
8931 if (dest->type == XML_CTYPE_NAME) {
8932 const XML_Char *src;
8933 dest->name = str;
8934 src = dtd->scaffold[src_node].name;
8935
8936 const size_t nameLen = xcslen(src) + /* null terminator*/ 1;
8937
8938 // Detect and prevent integer overflow
8939 if (nameLen > SIZE_MAX(18446744073709551615UL) / sizeof(XML_Char)) {
8940 // NOTE: We are avoiding FREE(..) here because the model
8941 // is not being allocated with MALLOC(..) but with plain
8942 // .malloc_fcn(..).
8943 parser->m_mem.free_fcn(ret);
8944 return NULL((void*)0);
8945 }
8946
8947 memcpy(str, src, nameLen * sizeof(XML_Char));
8948 str += nameLen;
8949
8950 dest->numchildren = 0;
8951 dest->children = NULL((void*)0);
8952 } else {
8953 unsigned int i;
8954 int cn;
8955 dest->name = NULL((void*)0);
8956 dest->numchildren = dtd->scaffold[src_node].childcnt;
8957 dest->children = jobDest;
8958
8959 /* Append scaffold indices of children to array */
8960 for (i = 0, cn = dtd->scaffold[src_node].firstchild;
8961 i < dest->numchildren; i++, cn = dtd->scaffold[cn].nextsib)
8962 (jobDest++)->numchildren = (unsigned int)cn;
8963 }
8964 }
8965
8966 return ret;
8967}
8968
8969static ELEMENT_TYPE *
8970getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr,
8971 const char *end) {
8972 DTD *const dtd = parser->m_dtd; /* save one level of indirection */
8973 const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
8974 ELEMENT_TYPE *ret;
8975
8976 if (! name)
8977 return NULL((void*)0);
8978 ret = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, name,
8979 sizeof(ELEMENT_TYPE));
8980 if (! ret)
8981 return NULL((void*)0);
8982 if (! ret->defaultAttForName.parser)
8983 hashTableInit(&(ret->defaultAttForName), getRootParserOf(parser, NULL((void*)0)));
8984 if (ret->name != name)
8985 poolDiscard(&dtd->pool)((&dtd->pool)->ptr = (&dtd->pool)->start);
8986 else {
8987 poolFinish(&dtd->pool)((&dtd->pool)->start = (&dtd->pool)->ptr);
8988 if (! setElementTypePrefix(parser, ret))
8989 return NULL((void*)0);
8990 }
8991 return ret;
8992}
8993
8994static XML_Char *
8995copyString(const XML_Char *s, XML_Parser parser) {
8996 /* First determine how long the string is */
8997 const size_t charsRequired = xcslen(s) + /*null terminator*/ 1;
8998
8999 /* Detect and prevent integer overflow */
9000 if (charsRequired > SIZE_MAX(18446744073709551615UL) / sizeof(XML_Char))
9001 return NULL((void*)0);
9002
9003 const size_t bytesRequired = charsRequired * sizeof(XML_Char);
9004
9005 /* Now allocate space for the copy */
9006 XML_Char *const result = MALLOC(parser, bytesRequired)(expat_malloc((parser), (bytesRequired), 9006));
9007
9008 if (result == NULL((void*)0))
9009 return NULL((void*)0);
9010
9011 /* Copy the original into place */
9012 memcpy(result, s, bytesRequired);
9013
9014 return result;
9015}
9016
9017#if XML_GE1 == 1
9018
9019static float
9020accountingGetCurrentAmplification(XML_Parser rootParser) {
9021 // 1.........1.........12 => 22
9022 const size_t lenOfShortestInclude = sizeof("<!ENTITY a SYSTEM 'b'>") - 1;
9023 const XmlBigCount countBytesOutput
9024 = rootParser->m_accounting.countBytesDirect
9025 + rootParser->m_accounting.countBytesIndirect;
9026 const float amplificationFactor
9027 = rootParser->m_accounting.countBytesDirect
9028 ? ((float)countBytesOutput
9029 / (float)(rootParser->m_accounting.countBytesDirect))
9030 : ((float)(lenOfShortestInclude
9031 + rootParser->m_accounting.countBytesIndirect)
9032 / (float)lenOfShortestInclude);
9033 assert(! rootParser->m_parentParser)((void) sizeof ((! rootParser->m_parentParser) ? 1 : 0), __extension__
({ if (! rootParser->m_parentParser) ; else __assert_fail
("! rootParser->m_parentParser", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 9033, __extension__ __PRETTY_FUNCTION__); }))
;
9034 return amplificationFactor;
9035}
9036
9037static void
9038accountingReportStats(XML_Parser originParser, const char *epilog) {
9039/* BEGIN MOZILLA CHANGE (don't report debug information) */
9040#if 0
9041 const XML_Parser rootParser = getRootParserOf(originParser, NULL((void*)0));
9042 assert(! rootParser->m_parentParser)((void) sizeof ((! rootParser->m_parentParser) ? 1 : 0), __extension__
({ if (! rootParser->m_parentParser) ; else __assert_fail
("! rootParser->m_parentParser", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 9042, __extension__ __PRETTY_FUNCTION__); }))
;
9043
9044 if (rootParser->m_accounting.debugLevel == 0u) {
9045 return;
9046 }
9047
9048 const float amplificationFactor
9049 = accountingGetCurrentAmplification(rootParser);
9050 fprintf(stderrstderr,
9051 "expat: Accounting(%p): Direct " EXPAT_FMT_ULL("%" "10" "llu"
9052 "10")"%" "10" "llu" ", indirect " EXPAT_FMT_ULL("10")"%" "10" "llu" ", amplification %8.2f%s",
9053 (void *)rootParser, rootParser->m_accounting.countBytesDirect,
9054 rootParser->m_accounting.countBytesIndirect,
9055 (double)amplificationFactor, epilog);
9056#endif
9057/* END MOZILLA CHANGE */
9058}
9059
9060static void
9061accountingOnAbort(XML_Parser originParser) {
9062 accountingReportStats(originParser, " ABORTING\n");
9063}
9064
9065/* BEGIN MOZILLA CHANGE (don't report debug information) */
9066#if 0
9067static void
9068accountingReportDiff(XML_Parser rootParser,
9069 unsigned int levelsAwayFromRootParser, const char *before,
9070 const char *after, ptrdiff_t bytesMore, int source_line,
9071 enum XML_Account account) {
9072 assert(! rootParser->m_parentParser)((void) sizeof ((! rootParser->m_parentParser) ? 1 : 0), __extension__
({ if (! rootParser->m_parentParser) ; else __assert_fail
("! rootParser->m_parentParser", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 9072, __extension__ __PRETTY_FUNCTION__); }))
;
9073
9074 fprintf(stderrstderr,
9075 " (+" EXPAT_FMT_PTRDIFF_T("6")"%" "6" "l" "d" " bytes %s|%u, xmlparse.c:%d) %*s\"",
9076 bytesMore, (account == XML_ACCOUNT_DIRECT) ? "DIR" : "EXP",
9077 levelsAwayFromRootParser, source_line, 10, "");
9078
9079 const char ellipis[] = "[..]";
9080 const size_t ellipsisLength = sizeof(ellipis) /* because compile-time */ - 1;
9081 const unsigned int contextLength = 10;
9082
9083 /* Note: Performance is of no concern here */
9084 const char *walker = before;
9085 if ((rootParser->m_accounting.debugLevel >= 3u)
9086 || (after - before)
9087 <= (ptrdiff_t)(contextLength + ellipsisLength + contextLength)) {
9088 for (; walker < after; walker++) {
9089 fprintf(stderrstderr, "%s", unsignedCharToPrintable(walker[0]));
9090 }
9091 } else {
9092 for (; walker < before + contextLength; walker++) {
9093 fprintf(stderrstderr, "%s", unsignedCharToPrintable(walker[0]));
9094 }
9095 fprintf(stderrstderr, ellipis);
9096 walker = after - contextLength;
9097 for (; walker < after; walker++) {
9098 fprintf(stderrstderr, "%s", unsignedCharToPrintable(walker[0]));
9099 }
9100 }
9101 fprintf(stderrstderr, "\"\n");
9102}
9103#endif
9104/* END MOZILLA CHANGE */
9105
9106static XML_Bool
9107accountingDiffTolerated(XML_Parser originParser, int tok, const char *before,
9108 const char *after, int source_line,
9109 enum XML_Account account) {
9110 /* Note: We need to check the token type *first* to be sure that
9111 * we can even access variable <after>, safely.
9112 * E.g. for XML_TOK_NONE <after> may hold an invalid pointer. */
9113 switch (tok) {
9114 case XML_TOK_INVALID0:
9115 case XML_TOK_PARTIAL-1:
9116 case XML_TOK_PARTIAL_CHAR-2:
9117 case XML_TOK_NONE-4:
9118 return XML_TRUE((XML_Bool)1);
9119 }
9120
9121 if (account == XML_ACCOUNT_NONE)
9122 return XML_TRUE((XML_Bool)1); /* because these bytes have been accounted for, already */
9123
9124 unsigned int levelsAwayFromRootParser;
9125 const XML_Parser rootParser
9126 = getRootParserOf(originParser, &levelsAwayFromRootParser);
9127 assert(! rootParser->m_parentParser)((void) sizeof ((! rootParser->m_parentParser) ? 1 : 0), __extension__
({ if (! rootParser->m_parentParser) ; else __assert_fail
("! rootParser->m_parentParser", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 9127, __extension__ __PRETTY_FUNCTION__); }))
;
9128
9129 const int isDirect
9130 = (account == XML_ACCOUNT_DIRECT) && (originParser == rootParser);
9131 const ptrdiff_t bytesMore = after - before;
9132
9133 XmlBigCount *const additionTarget
9134 = isDirect ? &rootParser->m_accounting.countBytesDirect
9135 : &rootParser->m_accounting.countBytesIndirect;
9136
9137 /* Detect and avoid integer overflow */
9138 if (*additionTarget > (XmlBigCount)(-1) - (XmlBigCount)bytesMore)
9139 return XML_FALSE((XML_Bool)0);
9140 *additionTarget += bytesMore;
9141
9142 const XmlBigCount countBytesOutput
9143 = rootParser->m_accounting.countBytesDirect
9144 + rootParser->m_accounting.countBytesIndirect;
9145 const float amplificationFactor
9146 = accountingGetCurrentAmplification(rootParser);
9147 const XML_Bool tolerated
9148 = (countBytesOutput < rootParser->m_accounting.activationThresholdBytes)
9149 || (amplificationFactor
9150 <= rootParser->m_accounting.maximumAmplificationFactor);
9151
9152/* BEGIN MOZILLA CHANGE (don't report debug information) */
9153#if 0
9154 if (rootParser->m_accounting.debugLevel >= 2u) {
9155 accountingReportStats(rootParser, "");
9156 accountingReportDiff(rootParser, levelsAwayFromRootParser, before, after,
9157 bytesMore, source_line, account);
9158 }
9159#endif
9160/* END MOZILLA CHANGE */
9161
9162 return tolerated;
9163}
9164
9165/* BEGIN MOZILLA CHANGE (unused API) */
9166#if 0
9167unsigned long long
9168testingAccountingGetCountBytesDirect(XML_Parser parser) {
9169 if (! parser)
9170 return 0;
9171 return parser->m_accounting.countBytesDirect;
9172}
9173
9174unsigned long long
9175testingAccountingGetCountBytesIndirect(XML_Parser parser) {
9176 if (! parser)
9177 return 0;
9178 return parser->m_accounting.countBytesIndirect;
9179}
9180#endif
9181/* END MOZILLA CHANGE */
9182
9183/* BEGIN MOZILLA CHANGE (don't report debug information) */
9184#if 0
9185static void
9186entityTrackingReportStats(XML_Parser rootParser, ENTITY *entity,
9187 const char *action, int sourceLine) {
9188 assert(! rootParser->m_parentParser)((void) sizeof ((! rootParser->m_parentParser) ? 1 : 0), __extension__
({ if (! rootParser->m_parentParser) ; else __assert_fail
("! rootParser->m_parentParser", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 9188, __extension__ __PRETTY_FUNCTION__); }))
;
9189 if (rootParser->m_entity_stats.debugLevel == 0u)
9190 return;
9191
9192# if defined(XML_UNICODE)
9193 const char *const entityName = "[..]";
9194# else
9195 const char *const entityName = entity->name;
9196# endif
9197
9198 const bool_Bool limitingWanted = rootParser->m_entity_stats.debugLevel < 2;
9199 const int maxLimitedDepth = 10; // somewhat arbitrary
9200 const int candidateIndentDepth
9201 = (int)rootParser->m_entity_stats.currentDepth - 1;
9202 const bool_Bool limitingNeeded
9203 = limitingWanted && (candidateIndentDepth > maxLimitedDepth);
9204 const char *const ellipisOrEmpty = limitingNeeded ? " [..] " : "";
9205 const int indentDepth
9206 = limitingNeeded ? (maxLimitedDepth - /* make space for ellipis */ 2)
9207 : candidateIndentDepth;
9208
9209 fprintf(
9210 stderrstderr,
9211 "expat: Entities(%p): Count %9u, depth %2u/%2u %*s%s%s%s; %s length %d (xmlparse.c:%d)\n",
9212 (void *)rootParser, rootParser->m_entity_stats.countEverOpened,
9213 rootParser->m_entity_stats.currentDepth,
9214 rootParser->m_entity_stats.maximumDepthSeen, indentDepth * 2, "",
9215 ellipisOrEmpty, entity->is_param ? "%" : "&", entityName, action,
9216 entity->textLen, sourceLine);
9217}
9218#endif
9219/* END MOZILLA CHANGE */
9220
9221static void
9222entityTrackingOnOpen(XML_Parser originParser, ENTITY *entity, int sourceLine) {
9223/* BEGIN MOZILLA CHANGE (don't report debug information) */
9224#if 0
9225 const XML_Parser rootParser = getRootParserOf(originParser, NULL((void*)0));
9226 assert(! rootParser->m_parentParser)((void) sizeof ((! rootParser->m_parentParser) ? 1 : 0), __extension__
({ if (! rootParser->m_parentParser) ; else __assert_fail
("! rootParser->m_parentParser", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 9226, __extension__ __PRETTY_FUNCTION__); }))
;
9227
9228 rootParser->m_entity_stats.countEverOpened++;
9229 rootParser->m_entity_stats.currentDepth++;
9230 if (rootParser->m_entity_stats.currentDepth
9231 > rootParser->m_entity_stats.maximumDepthSeen) {
9232 rootParser->m_entity_stats.maximumDepthSeen++;
9233 }
9234
9235 entityTrackingReportStats(rootParser, entity, "OPEN ", sourceLine);
9236#endif
9237/* END MOZILLA CHANGE */
9238}
9239
9240static void
9241entityTrackingOnClose(XML_Parser originParser, ENTITY *entity, int sourceLine) {
9242/* BEGIN MOZILLA CHANGE (don't report debug information) */
9243#if 0
9244 const XML_Parser rootParser = getRootParserOf(originParser, NULL((void*)0));
9245 assert(! rootParser->m_parentParser)((void) sizeof ((! rootParser->m_parentParser) ? 1 : 0), __extension__
({ if (! rootParser->m_parentParser) ; else __assert_fail
("! rootParser->m_parentParser", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 9245, __extension__ __PRETTY_FUNCTION__); }))
;
9246
9247 entityTrackingReportStats(rootParser, entity, "CLOSE", sourceLine);
9248 rootParser->m_entity_stats.currentDepth--;
9249#endif
9250/* END MOZILLA CHANGE */
9251}
9252
9253#endif /* XML_GE == 1 */
9254
9255static XML_Parser
9256getRootParserOf(XML_Parser parser, unsigned int *outLevelDiff) {
9257 XML_Parser rootParser = parser;
9258 unsigned int stepsTakenUpwards = 0;
9259 while (rootParser->m_parentParser) {
9260 rootParser = rootParser->m_parentParser;
9261 stepsTakenUpwards++;
9262 }
9263 assert(! rootParser->m_parentParser)((void) sizeof ((! rootParser->m_parentParser) ? 1 : 0), __extension__
({ if (! rootParser->m_parentParser) ; else __assert_fail
("! rootParser->m_parentParser", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 9263, __extension__ __PRETTY_FUNCTION__); }))
;
9264 if (outLevelDiff != NULL((void*)0)) {
9265 *outLevelDiff = stepsTakenUpwards;
9266 }
9267 return rootParser;
9268}
9269
9270#if XML_GE1 == 1
9271
9272/* BEGIN MOZILLA CHANGE (don't report debug information) */
9273#if 0
9274const char *
9275unsignedCharToPrintable(unsigned char c) {
9276 switch (c) {
9277 case 0:
9278 return "\\0";
9279 case 1:
9280 return "\\x1";
9281 case 2:
9282 return "\\x2";
9283 case 3:
9284 return "\\x3";
9285 case 4:
9286 return "\\x4";
9287 case 5:
9288 return "\\x5";
9289 case 6:
9290 return "\\x6";
9291 case 7:
9292 return "\\x7";
9293 case 8:
9294 return "\\x8";
9295 case 9:
9296 return "\\t";
9297 case 10:
9298 return "\\n";
9299 case 11:
9300 return "\\xB";
9301 case 12:
9302 return "\\xC";
9303 case 13:
9304 return "\\r";
9305 case 14:
9306 return "\\xE";
9307 case 15:
9308 return "\\xF";
9309 case 16:
9310 return "\\x10";
9311 case 17:
9312 return "\\x11";
9313 case 18:
9314 return "\\x12";
9315 case 19:
9316 return "\\x13";
9317 case 20:
9318 return "\\x14";
9319 case 21:
9320 return "\\x15";
9321 case 22:
9322 return "\\x16";
9323 case 23:
9324 return "\\x17";
9325 case 24:
9326 return "\\x18";
9327 case 25:
9328 return "\\x19";
9329 case 26:
9330 return "\\x1A";
9331 case 27:
9332 return "\\x1B";
9333 case 28:
9334 return "\\x1C";
9335 case 29:
9336 return "\\x1D";
9337 case 30:
9338 return "\\x1E";
9339 case 31:
9340 return "\\x1F";
9341 case 32:
9342 return " ";
9343 case 33:
9344 return "!";
9345 case 34:
9346 return "\\\"";
9347 case 35:
9348 return "#";
9349 case 36:
9350 return "$";
9351 case 37:
9352 return "%";
9353 case 38:
9354 return "&";
9355 case 39:
9356 return "'";
9357 case 40:
9358 return "(";
9359 case 41:
9360 return ")";
9361 case 42:
9362 return "*";
9363 case 43:
9364 return "+";
9365 case 44:
9366 return ",";
9367 case 45:
9368 return "-";
9369 case 46:
9370 return ".";
9371 case 47:
9372 return "/";
9373 case 48:
9374 return "0";
9375 case 49:
9376 return "1";
9377 case 50:
9378 return "2";
9379 case 51:
9380 return "3";
9381 case 52:
9382 return "4";
9383 case 53:
9384 return "5";
9385 case 54:
9386 return "6";
9387 case 55:
9388 return "7";
9389 case 56:
9390 return "8";
9391 case 57:
9392 return "9";
9393 case 58:
9394 return ":";
9395 case 59:
9396 return ";";
9397 case 60:
9398 return "<";
9399 case 61:
9400 return "=";
9401 case 62:
9402 return ">";
9403 case 63:
9404 return "?";
9405 case 64:
9406 return "@";
9407 case 65:
9408 return "A";
9409 case 66:
9410 return "B";
9411 case 67:
9412 return "C";
9413 case 68:
9414 return "D";
9415 case 69:
9416 return "E";
9417 case 70:
9418 return "F";
9419 case 71:
9420 return "G";
9421 case 72:
9422 return "H";
9423 case 73:
9424 return "I";
9425 case 74:
9426 return "J";
9427 case 75:
9428 return "K";
9429 case 76:
9430 return "L";
9431 case 77:
9432 return "M";
9433 case 78:
9434 return "N";
9435 case 79:
9436 return "O";
9437 case 80:
9438 return "P";
9439 case 81:
9440 return "Q";
9441 case 82:
9442 return "R";
9443 case 83:
9444 return "S";
9445 case 84:
9446 return "T";
9447 case 85:
9448 return "U";
9449 case 86:
9450 return "V";
9451 case 87:
9452 return "W";
9453 case 88:
9454 return "X";
9455 case 89:
9456 return "Y";
9457 case 90:
9458 return "Z";
9459 case 91:
9460 return "[";
9461 case 92:
9462 return "\\\\";
9463 case 93:
9464 return "]";
9465 case 94:
9466 return "^";
9467 case 95:
9468 return "_";
9469 case 96:
9470 return "`";
9471 case 97:
9472 return "a";
9473 case 98:
9474 return "b";
9475 case 99:
9476 return "c";
9477 case 100:
9478 return "d";
9479 case 101:
9480 return "e";
9481 case 102:
9482 return "f";
9483 case 103:
9484 return "g";
9485 case 104:
9486 return "h";
9487 case 105:
9488 return "i";
9489 case 106:
9490 return "j";
9491 case 107:
9492 return "k";
9493 case 108:
9494 return "l";
9495 case 109:
9496 return "m";
9497 case 110:
9498 return "n";
9499 case 111:
9500 return "o";
9501 case 112:
9502 return "p";
9503 case 113:
9504 return "q";
9505 case 114:
9506 return "r";
9507 case 115:
9508 return "s";
9509 case 116:
9510 return "t";
9511 case 117:
9512 return "u";
9513 case 118:
9514 return "v";
9515 case 119:
9516 return "w";
9517 case 120:
9518 return "x";
9519 case 121:
9520 return "y";
9521 case 122:
9522 return "z";
9523 case 123:
9524 return "{";
9525 case 124:
9526 return "|";
9527 case 125:
9528 return "}";
9529 case 126:
9530 return "~";
9531 case 127:
9532 return "\\x7F";
9533 case 128:
9534 return "\\x80";
9535 case 129:
9536 return "\\x81";
9537 case 130:
9538 return "\\x82";
9539 case 131:
9540 return "\\x83";
9541 case 132:
9542 return "\\x84";
9543 case 133:
9544 return "\\x85";
9545 case 134:
9546 return "\\x86";
9547 case 135:
9548 return "\\x87";
9549 case 136:
9550 return "\\x88";
9551 case 137:
9552 return "\\x89";
9553 case 138:
9554 return "\\x8A";
9555 case 139:
9556 return "\\x8B";
9557 case 140:
9558 return "\\x8C";
9559 case 141:
9560 return "\\x8D";
9561 case 142:
9562 return "\\x8E";
9563 case 143:
9564 return "\\x8F";
9565 case 144:
9566 return "\\x90";
9567 case 145:
9568 return "\\x91";
9569 case 146:
9570 return "\\x92";
9571 case 147:
9572 return "\\x93";
9573 case 148:
9574 return "\\x94";
9575 case 149:
9576 return "\\x95";
9577 case 150:
9578 return "\\x96";
9579 case 151:
9580 return "\\x97";
9581 case 152:
9582 return "\\x98";
9583 case 153:
9584 return "\\x99";
9585 case 154:
9586 return "\\x9A";
9587 case 155:
9588 return "\\x9B";
9589 case 156:
9590 return "\\x9C";
9591 case 157:
9592 return "\\x9D";
9593 case 158:
9594 return "\\x9E";
9595 case 159:
9596 return "\\x9F";
9597 case 160:
9598 return "\\xA0";
9599 case 161:
9600 return "\\xA1";
9601 case 162:
9602 return "\\xA2";
9603 case 163:
9604 return "\\xA3";
9605 case 164:
9606 return "\\xA4";
9607 case 165:
9608 return "\\xA5";
9609 case 166:
9610 return "\\xA6";
9611 case 167:
9612 return "\\xA7";
9613 case 168:
9614 return "\\xA8";
9615 case 169:
9616 return "\\xA9";
9617 case 170:
9618 return "\\xAA";
9619 case 171:
9620 return "\\xAB";
9621 case 172:
9622 return "\\xAC";
9623 case 173:
9624 return "\\xAD";
9625 case 174:
9626 return "\\xAE";
9627 case 175:
9628 return "\\xAF";
9629 case 176:
9630 return "\\xB0";
9631 case 177:
9632 return "\\xB1";
9633 case 178:
9634 return "\\xB2";
9635 case 179:
9636 return "\\xB3";
9637 case 180:
9638 return "\\xB4";
9639 case 181:
9640 return "\\xB5";
9641 case 182:
9642 return "\\xB6";
9643 case 183:
9644 return "\\xB7";
9645 case 184:
9646 return "\\xB8";
9647 case 185:
9648 return "\\xB9";
9649 case 186:
9650 return "\\xBA";
9651 case 187:
9652 return "\\xBB";
9653 case 188:
9654 return "\\xBC";
9655 case 189:
9656 return "\\xBD";
9657 case 190:
9658 return "\\xBE";
9659 case 191:
9660 return "\\xBF";
9661 case 192:
9662 return "\\xC0";
9663 case 193:
9664 return "\\xC1";
9665 case 194:
9666 return "\\xC2";
9667 case 195:
9668 return "\\xC3";
9669 case 196:
9670 return "\\xC4";
9671 case 197:
9672 return "\\xC5";
9673 case 198:
9674 return "\\xC6";
9675 case 199:
9676 return "\\xC7";
9677 case 200:
9678 return "\\xC8";
9679 case 201:
9680 return "\\xC9";
9681 case 202:
9682 return "\\xCA";
9683 case 203:
9684 return "\\xCB";
9685 case 204:
9686 return "\\xCC";
9687 case 205:
9688 return "\\xCD";
9689 case 206:
9690 return "\\xCE";
9691 case 207:
9692 return "\\xCF";
9693 case 208:
9694 return "\\xD0";
9695 case 209:
9696 return "\\xD1";
9697 case 210:
9698 return "\\xD2";
9699 case 211:
9700 return "\\xD3";
9701 case 212:
9702 return "\\xD4";
9703 case 213:
9704 return "\\xD5";
9705 case 214:
9706 return "\\xD6";
9707 case 215:
9708 return "\\xD7";
9709 case 216:
9710 return "\\xD8";
9711 case 217:
9712 return "\\xD9";
9713 case 218:
9714 return "\\xDA";
9715 case 219:
9716 return "\\xDB";
9717 case 220:
9718 return "\\xDC";
9719 case 221:
9720 return "\\xDD";
9721 case 222:
9722 return "\\xDE";
9723 case 223:
9724 return "\\xDF";
9725 case 224:
9726 return "\\xE0";
9727 case 225:
9728 return "\\xE1";
9729 case 226:
9730 return "\\xE2";
9731 case 227:
9732 return "\\xE3";
9733 case 228:
9734 return "\\xE4";
9735 case 229:
9736 return "\\xE5";
9737 case 230:
9738 return "\\xE6";
9739 case 231:
9740 return "\\xE7";
9741 case 232:
9742 return "\\xE8";
9743 case 233:
9744 return "\\xE9";
9745 case 234:
9746 return "\\xEA";
9747 case 235:
9748 return "\\xEB";
9749 case 236:
9750 return "\\xEC";
9751 case 237:
9752 return "\\xED";
9753 case 238:
9754 return "\\xEE";
9755 case 239:
9756 return "\\xEF";
9757 case 240:
9758 return "\\xF0";
9759 case 241:
9760 return "\\xF1";
9761 case 242:
9762 return "\\xF2";
9763 case 243:
9764 return "\\xF3";
9765 case 244:
9766 return "\\xF4";
9767 case 245:
9768 return "\\xF5";
9769 case 246:
9770 return "\\xF6";
9771 case 247:
9772 return "\\xF7";
9773 case 248:
9774 return "\\xF8";
9775 case 249:
9776 return "\\xF9";
9777 case 250:
9778 return "\\xFA";
9779 case 251:
9780 return "\\xFB";
9781 case 252:
9782 return "\\xFC";
9783 case 253:
9784 return "\\xFD";
9785 case 254:
9786 return "\\xFE";
9787 case 255:
9788 return "\\xFF";
9789 // LCOV_EXCL_START
9790 default:
9791 assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 9791, __extension__ __PRETTY_FUNCTION__); }))
; /* never gets here */
9792 return "dead code";
9793 }
9794 assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "/root/firefox-clang/parser/expat/expat/lib/xmlparse.c"
, 9794, __extension__ __PRETTY_FUNCTION__); }))
; /* never gets here */
9795 // LCOV_EXCL_STOP
9796}
9797#endif
9798/* END MOZILLA CHANGE */
9799
9800#endif /* XML_GE == 1 */
9801
9802/* BEGIN MOZILLA CHANGE (don't report debug information) */
9803#if 0
9804static unsigned long
9805getDebugLevel(const char *variableName, unsigned long defaultDebugLevel) {
9806 const char *const valueOrNull = getenv(variableName);
9807 if (valueOrNull == NULL((void*)0)) {
9808 return defaultDebugLevel;
9809 }
9810 const char *const value = valueOrNull;
9811
9812 errno(*__errno_location ()) = 0;
9813 char *afterValue = NULL((void*)0);
9814 unsigned long debugLevel = strtoul(value, &afterValue, 10);
9815 if ((errno(*__errno_location ()) != 0) || (afterValue == value) || (afterValue[0] != '\0')) {
9816 errno(*__errno_location ()) = 0;
9817 return defaultDebugLevel;
9818 }
9819
9820 return debugLevel;
9821}
9822#endif
9823/* END MOZILLA CHANGE */