summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty')
-rw-r--r--3rdParty/Expat/src/COPYING5
-rw-r--r--3rdParty/Expat/src/Changes389
-rw-r--r--3rdParty/Expat/src/expat.h35
-rw-r--r--3rdParty/Expat/src/expat_external.h19
-rw-r--r--3rdParty/Expat/src/internal.h22
-rw-r--r--3rdParty/Expat/src/siphash.h344
-rw-r--r--3rdParty/Expat/src/winconfig.h40
-rw-r--r--3rdParty/Expat/src/xmlparse.c734
-rw-r--r--3rdParty/Expat/src/xmlrole.c230
-rw-r--r--3rdParty/Expat/src/xmltok.c244
-rw-r--r--3rdParty/Expat/src/xmltok.h10
-rw-r--r--3rdParty/Expat/src/xmltok_impl.c226
12 files changed, 1818 insertions, 480 deletions
diff --git a/3rdParty/Expat/src/COPYING b/3rdParty/Expat/src/COPYING
index dcb4506..8d288f0 100644
--- a/3rdParty/Expat/src/COPYING
+++ b/3rdParty/Expat/src/COPYING
@@ -1,22 +1,21 @@
-Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
- and Clark Cooper
-Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers.
+Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper
+Copyright (c) 2001-2017 Expat maintainers
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/3rdParty/Expat/src/Changes b/3rdParty/Expat/src/Changes
new file mode 100644
index 0000000..3054c32
--- /dev/null
+++ b/3rdParty/Expat/src/Changes
@@ -0,0 +1,389 @@
+NOTE: We are looking for help with a few things:
+ https://github.com/libexpat/libexpat/labels/help%20wanted
+ If you can help, please get in touch. Thanks!
+
+Release 2.2.1 Sat June 17 2017
+ Security fixes:
+ CVE-2017-9233 -- External entity infinite loop DoS
+ Details: https://libexpat.github.io/doc/cve-2017-9233/
+ Commit c4bf96bb51dd2a1b0e185374362ee136fe2c9d7f
+ [MOX-002] CVE-2016-9063 -- Detect integer overflow; commit
+ d4f735b88d9932bd5039df2335eefdd0723dbe20
+ (Fixed version of existing downstream patches!)
+ (SF.net) #539 Fix regression from fix to CVE-2016-0718 cutting off
+ longer tag names; commits
+ * 896b6c1fd3b842f377d1b62135dccf0a579cf65d
+ * af507cef2c93cb8d40062a0abe43a4f4e9158fb2
+ #16 * 0dbbf43fdb20f593ddf4fa1ff67288000dd4a7fd
+ #25 More integer overflow detection (function poolGrow); commits
+ * 810b74e4703dcfdd8f404e3cb177d44684775143
+ * 44178553f3539ce69d34abee77a05e879a7982ac
+ [MOX-002] Detect overflow from len=INT_MAX call to XML_Parse; commits
+ * 4be2cb5afcc018d996f34bbbce6374b7befad47f
+ * 7e5b71b748491b6e459e5c9a1d090820f94544d8
+ [MOX-005] #30 Use high quality entropy for hash initialization:
+ * arc4random_buf on BSD, systems with libbsd
+ (when configured with --with-libbsd), CloudABI
+ * RtlGenRandom on Windows XP / Server 2003 and later
+ * getrandom on Linux 3.17+
+ In a way, that's still part of CVE-2016-5300.
+ https://github.com/libexpat/libexpat/pull/30/commits
+ [MOX-005] For the low quality entropy extraction fallback code,
+ the parser instance address can no longer leak, commit
+ 04ad658bd3079dd15cb60fc67087900f0ff4b083
+ [MOX-003] Prevent use of uninitialised variable; commit
+ [MOX-004] a4dc944f37b664a3ca7199c624a98ee37babdb4b
+ Add missing parameter validation to public API functions
+ and dedicated error code XML_ERROR_INVALID_ARGUMENT:
+ [MOX-006] * NULL checks; commits
+ * d37f74b2b7149a3a95a680c4c4cd2a451a51d60a (merge/many)
+ * 9ed727064b675b7180c98cb3d4f75efba6966681
+ * 6a747c837c50114dfa413994e07c0ba477be4534
+ * Negative length (XML_Parse); commit
+ [MOX-002] 70db8d2538a10f4c022655d6895e4c3e78692e7f
+ [MOX-001] #35 Change hash algorithm to William Ahern's version of SipHash
+ to go further with fixing CVE-2012-0876.
+ https://github.com/libexpat/libexpat/pull/39/commits
+
+ Bug fixes:
+ #32 Fix sharing of hash salt across parsers;
+ relevant where XML_ExternalEntityParserCreate is called
+ prior to XML_Parse, in particular (e.g. FBReader)
+ #28 xmlwf: Auto-disable use of memory-mapping (and parsing
+ as a single chunk) for files larger than ~1 GB (2^30 bytes)
+ rather than failing with error "out of memory"
+ #3 Fix double free after malloc failure in DTD code; commit
+ 7ae9c3d3af433cd4defe95234eae7dc8ed15637f
+ #17 Fix memory leak on parser error for unbound XML attribute
+ prefix with new namespaces defined in the same tag;
+ found by Google's OSS-Fuzz; commits
+ * 16f87daae5a16132e479e4f71862128c7a915c73
+ * b47dbc9745932c160893d433220e462bd605f8cd
+ xmlwf on Windows: Add missing calls to CloseHandle
+
+ New features:
+ #30 Introduced environment switch EXPAT_ENTROPY_DEBUG=1
+ for runtime debugging of entropy extraction
+
+ Other changes:
+ Increase code coverage
+ #33 Reject use of XML_UNICODE_WCHAR_T with sizeof(wchar_t) != 2;
+ XML_UNICODE_WCHAR_T was never meant to be used outside
+ of Windows; 4-byte wchar_t is common on Linux
+ (SF.net) #538 Start using -fno-strict-aliasing
+ (SF.net) #540 Support compilation against cloudlibc of CloudABI
+ Allow MinGW cross-compilation
+ (SF.net) #534 CMake: Introduce option "BUILD_doc" (enabled by default)
+ to bypass compilation of the xmlwf.1 man page
+ (SF.net) pr2 CMake: Introduce option "INSTALL" (enabled by default)
+ to bypass installation of expat files
+ CMake: Fix ninja support
+ Autotools: Add parameters --enable-xml-context [COUNT]
+ and --disable-xml-context; default of context of 1024
+ bytes enabled unchanged
+ #14 Drop AmigaOS 4.x code and includes
+ #14 Drop ancient build systems:
+ * Borland C++ Builder
+ * OpenVMS
+ * Open Watcom
+ * Visual Studio 6.0
+ * Pre-X Mac OS (MPW Makefile)
+ If you happen to rely on some of these, please get in
+ touch for joining with maintenance.
+ #10 Move from WIN32 to _WIN32
+ #13 Fix "make run-xmltest" order instability
+ Address compile warnings
+ Bump version info from 7:2:6 to 7:3:6
+ Add AUTHORS file
+
+ Infrastructure:
+ #1 Migrate from SourceForge to GitHub (except downloads):
+ https://github.com/libexpat/
+ #1 Re-create http://libexpat.org/ project website
+ Start utilizing Travis CI
+
+ Special thanks to:
+ Andy Wang
+ Don Lewis
+ Ed Schouten
+ Karl Waclawek
+ Pascal Cuoq
+ Rhodri James
+ Sergei Nikulov
+ Tobias Taschner
+ Viktor Szakats
+ and
+ Core Infrastructure Initiative
+ Mozilla Foundation (MOSS Track 3: Secure Open Source)
+ Radically Open Security
+
+Release 2.2.0 Tue June 21 2016
+ Security fixes:
+ #537 CVE-2016-0718 -- Fix crash on malformed input
+ CVE-2016-4472 -- Improve insufficient fix to CVE-2015-1283 /
+ CVE-2015-2716 introduced with Expat 2.1.1
+ #499 CVE-2016-5300 -- Use more entropy for hash initialization
+ than the original fix to CVE-2012-0876
+ #519 CVE-2012-6702 -- Resolve troublesome internal call to srand
+ that was introduced with Expat 2.1.0
+ when addressing CVE-2012-0876 (issue #496)
+
+ Bug fixes:
+ Fix uninitialized reads of size 1
+ (e.g. in little2_updatePosition)
+ Fix detection of UTF-8 character boundaries
+
+ Other changes:
+ #532 Fix compilation for Visual Studio 2010 (keyword "C99")
+ Autotools: Resolve use of "$<" to better support bmake
+ Autotools: Add QA script "qa.sh" (and make target "qa")
+ Autotools: Respect CXXFLAGS if given
+ Autotools: Fix "make run-xmltest"
+ Autotools: Have "make run-xmltest" check for expected output
+ p90 CMake: Fix static build (BUILD_shared=OFF) on Windows
+ #536 CMake: Add soversion, support -DNO_SONAME=yes to bypass
+ #323 CMake: Add suffix "d" to differentiate debug from release
+ CMake: Define WIN32 with CMake on Windows
+ Annotate memory allocators for GCC
+ Address all currently known compile warnings
+ Make sure that API symbols remain visible despite
+ -fvisibility=hidden
+ Remove executable flag from source files
+ Resolve COMPILED_FROM_DSP in favor of WIN32
+
+ Special thanks to:
+ Björn Lindahl
+ Christian Heimes
+ Cristian Rodríguez
+ Daniel Krügler
+ Gustavo Grieco
+ Karl Waclawek
+ László Böszörményi
+ Marco Grassi
+ Pascal Cuoq
+ Sergei Nikulov
+ Thomas Beutlich
+ Warren Young
+ Yann Droneaud
+
+Release 2.1.1 Sat March 12 2016
+ Security fixes:
+ #582: CVE-2015-1283 - Multiple integer overflows in XML_GetBuffer
+
+ Bug fixes:
+ #502: Fix potential null pointer dereference
+ #520: Symbol XML_SetHashSalt was not exported
+ Output of "xmlwf -h" was incomplete
+
+ Other changes:
+ #503: Document behavior of calling XML_SetHashSalt with salt 0
+ Minor improvements to man page xmlwf(1)
+ Improvements to the experimental CMake build system
+ libtool now invoked with --verbose
+
+Release 2.1.0 Sat March 24 2012
+ - Security fixes:
+ #2958794: CVE-2012-1148 - Memory leak in poolGrow.
+ #2895533: CVE-2012-1147 - Resource leak in readfilemap.c.
+ #3496608: CVE-2012-0876 - Hash DOS attack.
+ #2894085: CVE-2009-3560 - Buffer over-read and crash in big2_toUtf8().
+ #1990430: CVE-2009-3720 - Parser crash with special UTF-8 sequences.
+ - Bug Fixes:
+ #1742315: Harmful XML_ParserCreateNS suggestion.
+ #1785430: Expat build fails on linux-amd64 with gcc version>=4.1 -O3.
+ #1983953, 2517952, 2517962, 2649838:
+ Build modifications using autoreconf instead of buildconf.sh.
+ #2815947, #2884086: OBJEXT and EXEEXT support while building.
+ #2517938: xmlwf should return non-zero exit status if not well-formed.
+ #2517946: Wrong statement about XMLDecl in xmlwf.1 and xmlwf.sgml.
+ #2855609: Dangling positionPtr after error.
+ #2990652: CMake support.
+ #3010819: UNEXPECTED_STATE with a trailing "%" in entity value.
+ #3206497: Unitialized memory returned from XML_Parse.
+ #3287849: make check fails on mingw-w64.
+ - Patches:
+ #1749198: pkg-config support.
+ #3010222: Fix for bug #3010819.
+ #3312568: CMake support.
+ #3446384: Report byte offsets for attr names and values.
+ - New Features / API changes:
+ Added new API member XML_SetHashSalt() that allows setting an initial
+ value (salt) for hash calculations. This is part of the fix for
+ bug #3496608 to randomize hash parameters.
+ When compiled with XML_ATTR_INFO defined, adds new API member
+ XML_GetAttributeInfo() that allows retrieving the byte
+ offsets for attribute names and values (patch #3446384).
+ Added CMake build system.
+ See bug #2990652 and patch #3312568.
+ Added run-benchmark target to Makefile.in - relies on testdata module
+ present in the same relative location as in the repository.
+
+Release 2.0.1 Tue June 5 2007
+ - Fixed bugs #1515266, #1515600: The character data handler's calling
+ of XML_StopParser() was not handled properly; if the parser was
+ stopped and the handler set to NULL, the parser would segfault.
+ - Fixed bug #1690883: Expat failed on EBCDIC systems as it assumed
+ some character constants to be ASCII encoded.
+ - Minor cleanups of the test harness.
+ - Fixed xmlwf bug #1513566: "out of memory" error on file size zero.
+ - Fixed outline.c bug #1543233: missing a final XML_ParserFree() call.
+ - Fixes and improvements for Windows platform:
+ bugs #1409451, #1476160, #1548182, #1602769, #1717322.
+ - Build fixes for various platforms:
+ HP-UX, Tru64, Solaris 9: patch #1437840, bug #1196180.
+ All Unix: #1554618 (refreshed config.sub/config.guess).
+ #1490371, #1613457: support both, DESTDIR and INSTALL_ROOT,
+ without relying on GNU-Make specific features.
+ #1647805: Patched configure.in to work better with Intel compiler.
+ - Fixes to Makefile.in to have make check work correctly:
+ bugs #1408143, #1535603, #1536684.
+ - Added Open Watcom support: patch #1523242.
+
+Release 2.0.0 Wed Jan 11 2006
+ - We no longer use the "check" library for C unit testing; we
+ always use the (partial) internal implementation of the API.
+ - Report XML_NS setting via XML_GetFeatureList().
+ - Fixed headers for use from C++.
+ - XML_GetCurrentLineNumber() and XML_GetCurrentColumnNumber()
+ now return unsigned integers.
+ - Added XML_LARGE_SIZE switch to enable 64-bit integers for
+ byte indexes and line/column numbers.
+ - Updated to use libtool 1.5.22 (the most recent).
+ - Added support for AmigaOS.
+ - Some mostly minor bug fixes. SF issues include: #1006708,
+ #1021776, #1023646, #1114960, #1156398, #1221160, #1271642.
+
+Release 1.95.8 Fri Jul 23 2004
+ - Major new feature: suspend/resume. Handlers can now request
+ that a parse be suspended for later resumption or aborted
+ altogether. See "Temporarily Stopping Parsing" in the
+ documentation for more details.
+ - Some mostly minor bug fixes, but compilation should no
+ longer generate warnings on most platforms. SF issues
+ include: #827319, #840173, #846309, #888329, #896188, #923913,
+ #928113, #961698, #985192.
+
+Release 1.95.7 Mon Oct 20 2003
+ - Fixed enum XML_Status issue (reported on SourceForge many
+ times), so compilers that are properly picky will be happy.
+ - Introduced an XMLCALL macro to control the calling
+ convention used by the Expat API; this macro should be used
+ to annotate prototypes and definitions of callback
+ implementations in code compiled with a calling convention
+ other than the default convention for the host platform.
+ - Improved ability to build without the configure-generated
+ expat_config.h header. This is useful for applications
+ which embed Expat rather than linking in the library.
+ - Fixed a variety of bugs: see SF issues #458907, #609603,
+ #676844, #679754, #692878, #692964, #695401, #699323, #699487,
+ #820946.
+ - Improved hash table lookups.
+ - Added more regression tests and improved documentation.
+
+Release 1.95.6 Tue Jan 28 2003
+ - Added XML_FreeContentModel().
+ - Added XML_MemMalloc(), XML_MemRealloc(), XML_MemFree().
+ - Fixed a variety of bugs: see SF issues #615606, #616863,
+ #618199, #653180, #673791.
+ - Enhanced the regression test suite.
+ - Man page improvements: includes SF issue #632146.
+
+Release 1.95.5 Fri Sep 6 2002
+ - Added XML_UseForeignDTD() for improved SAX2 support.
+ - Added XML_GetFeatureList().
+ - Defined XML_Bool type and the values XML_TRUE and XML_FALSE.
+ - Use an incomplete struct instead of a void* for the parser
+ (may not retain).
+ - Fixed UTF-8 decoding bug that caused legal UTF-8 to be rejected.
+ - Finally fixed bug where default handler would report DTD
+ events that were already handled by another handler.
+ Initial patch contributed by Darryl Miles.
+ - Removed unnecessary DllMain() function that caused static
+ linking into a DLL to be difficult.
+ - Added VC++ projects for building static libraries.
+ - Reduced line-length for all source code and headers to be
+ no longer than 80 characters, to help with AS/400 support.
+ - Reduced memory copying during parsing (SF patch #600964).
+ - Fixed a variety of bugs: see SF issues #580793, #434664,
+ #483514, #580503, #581069, #584041, #584183, #584832, #585537,
+ #596555, #596678, #598352, #598944, #599715, #600479, #600971.
+
+Release 1.95.4 Fri Jul 12 2002
+ - Added support for VMS, contributed by Craig Berry. See
+ vms/README.vms for more information.
+ - Added Mac OS (classic) support, with a makefile for MPW,
+ contributed by Thomas Wegner and Daryle Walker.
+ - Added Borland C++ Builder 5 / BCC 5.5 support, contributed
+ by Patrick McConnell (SF patch #538032).
+ - Fixed a variety of bugs: see SF issues #441449, #563184,
+ #564342, #566334, #566901, #569461, #570263, #575168, #579196.
+ - Made skippedEntityHandler conform to SAX2 (see source comment)
+ - Re-implemented WFC: Entity Declared from XML 1.0 spec and
+ added a new error "entity declared in parameter entity":
+ see SF bug report #569461 and SF patch #578161
+ - Re-implemented section 5.1 from XML 1.0 spec:
+ see SF bug report #570263 and SF patch #578161
+
+Release 1.95.3 Mon Jun 3 2002
+ - Added a project to the MSVC workspace to create a wchar_t
+ version of the library; the DLLs are named libexpatw.dll.
+ - Changed the name of the Windows DLLs from expat.dll to
+ libexpat.dll; this fixes SF bug #432456.
+ - Added the XML_ParserReset() API function.
+ - Fixed XML_SetReturnNSTriplet() to work for element names.
+ - Made the XML_UNICODE builds usable (thanks, Karl!).
+ - Allow xmlwf to read from standard input.
+ - Install a man page for xmlwf on Unix systems.
+ - Fixed many bugs; see SF bug reports #231864, #461380, #464837,
+ #466885, #469226, #477667, #484419, #487840, #494749, #496505,
+ #547350. Other bugs which we can't test as easily may also
+ have been fixed, especially in the area of build support.
+
+Release 1.95.2 Fri Jul 27 2001
+ - More changes to make MSVC happy with the build; add a single
+ workspace to support both the library and xmlwf application.
+ - Added a Windows installer for Windows users; includes
+ xmlwf.exe.
+ - Added compile-time constants that can be used to determine the
+ Expat version
+ - Removed a lot of GNU-specific dependencies to aide portability
+ among the various Unix flavors.
+ - Fix the UTF-8 BOM bug.
+ - Cleaned up warning messages for several compilers.
+ - Added the -Wall, -Wstrict-prototypes options for GCC.
+
+Release 1.95.1 Sun Oct 22 15:11:36 EDT 2000
+ - Changes to get expat to build under Microsoft compiler
+ - Removed all aborts and instead return an UNEXPECTED_STATE error.
+ - Fixed a bug where a stray '%' in an entity value would cause an
+ abort.
+ - Defined XML_SetEndNamespaceDeclHandler. Thanks to Darryl Miles for
+ finding this oversight.
+ - Changed default patterns in lib/Makefile.in to fit non-GNU makes
+ Thanks to robin@unrated.net for reporting and providing an
+ account to test on.
+ - The reference had the wrong label for XML_SetStartNamespaceDecl.
+ Reported by an anonymous user.
+
+Release 1.95.0 Fri Sep 29 2000
+ - XML_ParserCreate_MM
+ Allows you to set a memory management suite to replace the
+ standard malloc,realloc, and free.
+ - XML_SetReturnNSTriplet
+ If you turn this feature on when namespace processing is in
+ effect, then qualified, prefixed element and attribute names
+ are returned as "uri|name|prefix" where '|' is whatever
+ separator character is used in namespace processing.
+ - Merged in features from perl-expat
+ o XML_SetElementDeclHandler
+ o XML_SetAttlistDeclHandler
+ o XML_SetXmlDeclHandler
+ o XML_SetEntityDeclHandler
+ o StartDoctypeDeclHandler takes 3 additional parameters:
+ sysid, pubid, has_internal_subset
+ o Many paired handler setters (like XML_SetElementHandler)
+ now have corresponding individual handler setters
+ o XML_GetInputContext for getting the input context of
+ the current parse position.
+ - Added reference material
+ - Packaged into a distribution that builds a sharable library
diff --git a/3rdParty/Expat/src/expat.h b/3rdParty/Expat/src/expat.h
index 9a21680..28b0f95 100644
--- a/3rdParty/Expat/src/expat.h
+++ b/3rdParty/Expat/src/expat.h
@@ -68,61 +68,63 @@ enum XML_Error {
XML_ERROR_ASYNC_ENTITY,
XML_ERROR_BAD_CHAR_REF,
XML_ERROR_BINARY_ENTITY_REF,
XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
XML_ERROR_MISPLACED_XML_PI,
XML_ERROR_UNKNOWN_ENCODING,
XML_ERROR_INCORRECT_ENCODING,
XML_ERROR_UNCLOSED_CDATA_SECTION,
XML_ERROR_EXTERNAL_ENTITY_HANDLING,
XML_ERROR_NOT_STANDALONE,
XML_ERROR_UNEXPECTED_STATE,
XML_ERROR_ENTITY_DECLARED_IN_PE,
XML_ERROR_FEATURE_REQUIRES_XML_DTD,
XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING,
/* Added in 1.95.7. */
XML_ERROR_UNBOUND_PREFIX,
/* Added in 1.95.8. */
XML_ERROR_UNDECLARING_PREFIX,
XML_ERROR_INCOMPLETE_PE,
XML_ERROR_XML_DECL,
XML_ERROR_TEXT_DECL,
XML_ERROR_PUBLICID,
XML_ERROR_SUSPENDED,
XML_ERROR_NOT_SUSPENDED,
XML_ERROR_ABORTED,
XML_ERROR_FINISHED,
XML_ERROR_SUSPEND_PE,
/* Added in 2.0. */
XML_ERROR_RESERVED_PREFIX_XML,
XML_ERROR_RESERVED_PREFIX_XMLNS,
- XML_ERROR_RESERVED_NAMESPACE_URI
+ XML_ERROR_RESERVED_NAMESPACE_URI,
+ /* Added in 2.2.1. */
+ XML_ERROR_INVALID_ARGUMENT
};
enum XML_Content_Type {
XML_CTYPE_EMPTY = 1,
XML_CTYPE_ANY,
XML_CTYPE_MIXED,
XML_CTYPE_NAME,
XML_CTYPE_CHOICE,
XML_CTYPE_SEQ
};
enum XML_Content_Quant {
XML_CQUANT_NONE,
XML_CQUANT_OPT,
XML_CQUANT_REP,
XML_CQUANT_PLUS
};
/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be
XML_CQUANT_NONE, and the other fields will be zero or NULL.
If type == XML_CTYPE_MIXED, then quant will be NONE or REP and
numchildren will contain number of elements that may be mixed in
and children point to an array of XML_Content cells that will be
all of XML_CTYPE_NAME type with no quantification.
If type == XML_CTYPE_NAME, then the name points to the name, and
the numchildren field will be zero and children will be NULL. The
quant fields indicates any quantifiers placed on the name.
CHOICE and SEQ will have name NULL, the number of children in
@@ -315,61 +317,61 @@ typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData);
For internal entities (<!ENTITY foo "bar">), value will
be non-NULL and systemId, publicID, and notationName will be NULL.
The value string is NOT nul-terminated; the length is provided in
the value_length argument. Since it is legal to have zero-length
values, do not use this argument to test for internal entities.
For external entities, value will be NULL and systemId will be
non-NULL. The publicId argument will be NULL unless a public
identifier was provided. The notationName argument will have a
non-NULL value only for unparsed entity declarations.
Note that is_parameter_entity can't be changed to XML_Bool, since
that would break binary compatibility.
*/
typedef void (XMLCALL *XML_EntityDeclHandler) (
void *userData,
const XML_Char *entityName,
int is_parameter_entity,
const XML_Char *value,
int value_length,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId,
const XML_Char *notationName);
XMLPARSEAPI(void)
XML_SetEntityDeclHandler(XML_Parser parser,
XML_EntityDeclHandler handler);
/* OBSOLETE -- OBSOLETE -- OBSOLETE
- This handler has been superceded by the EntityDeclHandler above.
+ This handler has been superseded by the EntityDeclHandler above.
It is provided here for backward compatibility.
This is called for a declaration of an unparsed (NDATA) entity.
The base argument is whatever was set by XML_SetBase. The
entityName, systemId and notationName arguments will never be
NULL. The other arguments may be.
*/
typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) (
void *userData,
const XML_Char *entityName,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId,
const XML_Char *notationName);
/* This is called for a declaration of notation. The base argument is
whatever was set by XML_SetBase. The notationName will never be
NULL. The other arguments can be.
*/
typedef void (XMLCALL *XML_NotationDeclHandler) (
void *userData,
const XML_Char *notationName,
const XML_Char *base,
const XML_Char *systemId,
const XML_Char *publicId);
/* When namespace processing is enabled, these are called once for
each namespace declaration. The call to the start and end element
handlers occur between the calls to the start and end namespace
declaration handlers. For an xmlns attribute, prefix will be
@@ -679,92 +681,94 @@ XML_SetUserData(XML_Parser parser, void *userData);
Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer
has no effect and returns XML_STATUS_ERROR.
*/
XMLPARSEAPI(enum XML_Status)
XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
/* If this function is called, then the parser will be passed as the
first argument to callbacks instead of userData. The userData will
still be accessible using XML_GetUserData.
*/
XMLPARSEAPI(void)
XML_UseParserAsHandlerArg(XML_Parser parser);
/* If useDTD == XML_TRUE is passed to this function, then the parser
will assume that there is an external subset, even if none is
specified in the document. In such a case the parser will call the
externalEntityRefHandler with a value of NULL for the systemId
argument (the publicId and context arguments will be NULL as well).
Note: For the purpose of checking WFC: Entity Declared, passing
useDTD == XML_TRUE will make the parser behave as if the document
had a DTD with an external subset.
Note: If this function is called, then this must be done before
the first call to XML_Parse or XML_ParseBuffer, since it will
have no effect after that. Returns
XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING.
Note: If the document does not have a DOCTYPE declaration at all,
then startDoctypeDeclHandler and endDoctypeDeclHandler will not
be called, despite an external subset being parsed.
Note: If XML_DTD is not defined when Expat is compiled, returns
XML_ERROR_FEATURE_REQUIRES_XML_DTD.
+ Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT.
*/
XMLPARSEAPI(enum XML_Error)
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
/* Sets the base to be used for resolving relative URIs in system
identifiers in declarations. Resolving relative identifiers is
left to the application: this value will be passed through as the
base argument to the XML_ExternalEntityRefHandler,
XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base
argument will be copied. Returns XML_STATUS_ERROR if out of memory,
XML_STATUS_OK otherwise.
*/
XMLPARSEAPI(enum XML_Status)
XML_SetBase(XML_Parser parser, const XML_Char *base);
XMLPARSEAPI(const XML_Char *)
XML_GetBase(XML_Parser parser);
/* Returns the number of the attribute/value pairs passed in last call
to the XML_StartElementHandler that were specified in the start-tag
rather than defaulted. Each attribute/value pair counts as 2; thus
this correspondds to an index into the atts array passed to the
- XML_StartElementHandler.
+ XML_StartElementHandler. Returns -1 if parser == NULL.
*/
XMLPARSEAPI(int)
XML_GetSpecifiedAttributeCount(XML_Parser parser);
/* Returns the index of the ID attribute passed in the last call to
- XML_StartElementHandler, or -1 if there is no ID attribute. Each
- attribute/value pair counts as 2; thus this correspondds to an
- index into the atts array passed to the XML_StartElementHandler.
+ XML_StartElementHandler, or -1 if there is no ID attribute or
+ parser == NULL. Each attribute/value pair counts as 2; thus this
+ correspondds to an index into the atts array passed to the
+ XML_StartElementHandler.
*/
XMLPARSEAPI(int)
XML_GetIdAttributeIndex(XML_Parser parser);
#ifdef XML_ATTR_INFO
/* Source file byte offsets for the start and end of attribute names and values.
The value indices are exclusive of surrounding quotes; thus in a UTF-8 source
file an attribute value of "blah" will yield:
info->valueEnd - info->valueStart = 4 bytes.
*/
typedef struct {
XML_Index nameStart; /* Offset to beginning of the attribute name. */
XML_Index nameEnd; /* Offset after the attribute name's last byte. */
XML_Index valueStart; /* Offset to beginning of the attribute value. */
XML_Index valueEnd; /* Offset after the attribute value's last byte. */
} XML_AttrInfo;
/* Returns an array of XML_AttrInfo structures for the attribute/value pairs
passed in last call to the XML_StartElementHandler that were specified
in the start-tag rather than defaulted. Each attribute/value pair counts
as 1; thus the number of entries in the array is
XML_GetSpecifiedAttributeCount(parser) / 2.
*/
XMLPARSEAPI(const XML_AttrInfo *)
XML_GetAttributeInfo(XML_Parser parser);
#endif
/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is
detected. The last call to XML_Parse must have isFinal true; len
may be zero for this call (or any other).
@@ -874,174 +878,181 @@ XML_ExternalEntityParserCreate(XML_Parser parser,
const XML_Char *encoding);
enum XML_ParamEntityParsing {
XML_PARAM_ENTITY_PARSING_NEVER,
XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
XML_PARAM_ENTITY_PARSING_ALWAYS
};
/* Controls parsing of parameter entities (including the external DTD
subset). If parsing of parameter entities is enabled, then
references to external parameter entities (including the external
DTD subset) will be passed to the handler set with
XML_SetExternalEntityRefHandler. The context passed will be 0.
Unlike external general entities, external parameter entities can
only be parsed synchronously. If the external parameter entity is
to be parsed, it must be parsed during the call to the external
entity ref handler: the complete sequence of
XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and
XML_ParserFree calls must be made during this call. After
XML_ExternalEntityParserCreate has been called to create the parser
for the external parameter entity (context must be 0 for this
call), it is illegal to make any calls on the old parser until
XML_ParserFree has been called on the newly created parser.
If the library has been compiled without support for parameter
entity parsing (ie without XML_DTD being defined), then
XML_SetParamEntityParsing will return 0 if parsing of parameter
entities is requested; otherwise it will return non-zero.
Note: If XML_SetParamEntityParsing is called after XML_Parse or
XML_ParseBuffer, then it has no effect and will always return 0.
+ Note: If parser == NULL, the function will do nothing and return 0.
*/
XMLPARSEAPI(int)
XML_SetParamEntityParsing(XML_Parser parser,
enum XML_ParamEntityParsing parsing);
/* Sets the hash salt to use for internal hash calculations.
Helps in preventing DoS attacks based on predicting hash
function behavior. This must be called before parsing is started.
Returns 1 if successful, 0 when called after parsing has started.
+ Note: If parser == NULL, the function will do nothing and return 0.
*/
XMLPARSEAPI(int)
XML_SetHashSalt(XML_Parser parser,
unsigned long hash_salt);
/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then
XML_GetErrorCode returns information about the error.
*/
XMLPARSEAPI(enum XML_Error)
XML_GetErrorCode(XML_Parser parser);
/* These functions return information about the current parse
location. They may be called from any callback called to report
some parse event; in this case the location is the location of the
first of the sequence of characters that generated the event. When
called from callbacks generated by declarations in the document
prologue, the location identified isn't as neatly defined, but will
be within the relevant markup. When called outside of the callback
functions, the position indicated will be just past the last parse
event (regardless of whether there was an associated callback).
They may also be called after returning from a call to XML_Parse
or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then
the location is the location of the character at which the error
was detected; otherwise the location is the location of the last
parse event, as described above.
+
+ Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber
+ return 0 to indicate an error.
+ Note: XML_GetCurrentByteIndex returns -1 to indicate an error.
*/
XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
XMLPARSEAPI(XML_Index) XML_GetCurrentByteIndex(XML_Parser parser);
/* Return the number of bytes in the current event.
Returns 0 if the event is in an internal entity.
*/
XMLPARSEAPI(int)
XML_GetCurrentByteCount(XML_Parser parser);
/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets
the integer pointed to by offset to the offset within this buffer
of the current parse position, and sets the integer pointed to by size
to the size of this buffer (the number of input bytes). Otherwise
returns a NULL pointer. Also returns a NULL pointer if a parse isn't
active.
NOTE: The character pointer returned should not be used outside
the handler that makes the call.
*/
XMLPARSEAPI(const char *)
XML_GetInputContext(XML_Parser parser,
int *offset,
int *size);
/* For backwards compatibility with previous versions. */
#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
/* Frees the content model passed to the element declaration handler */
XMLPARSEAPI(void)
XML_FreeContentModel(XML_Parser parser, XML_Content *model);
/* Exposing the memory handling functions used in Expat */
XMLPARSEAPI(void *)
+XML_ATTR_MALLOC
+XML_ATTR_ALLOC_SIZE(2)
XML_MemMalloc(XML_Parser parser, size_t size);
XMLPARSEAPI(void *)
+XML_ATTR_ALLOC_SIZE(3)
XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);
XMLPARSEAPI(void)
XML_MemFree(XML_Parser parser, void *ptr);
/* Frees memory used by the parser. */
XMLPARSEAPI(void)
XML_ParserFree(XML_Parser parser);
/* Returns a string describing the error. */
XMLPARSEAPI(const XML_LChar *)
XML_ErrorString(enum XML_Error code);
/* Return a string containing the version number of this expat */
XMLPARSEAPI(const XML_LChar *)
XML_ExpatVersion(void);
typedef struct {
int major;
int minor;
int micro;
} XML_Expat_Version;
/* Return an XML_Expat_Version structure containing numeric version
number information for this version of expat.
*/
XMLPARSEAPI(XML_Expat_Version)
XML_ExpatVersionInfo(void);
/* Added in Expat 1.95.5. */
enum XML_FeatureEnum {
XML_FEATURE_END = 0,
XML_FEATURE_UNICODE,
XML_FEATURE_UNICODE_WCHAR_T,
XML_FEATURE_DTD,
XML_FEATURE_CONTEXT_BYTES,
XML_FEATURE_MIN_SIZE,
XML_FEATURE_SIZEOF_XML_CHAR,
XML_FEATURE_SIZEOF_XML_LCHAR,
XML_FEATURE_NS,
XML_FEATURE_LARGE_SIZE,
XML_FEATURE_ATTR_INFO
/* Additional features must be added to the end of this enum. */
};
typedef struct {
enum XML_FeatureEnum feature;
const XML_LChar *name;
long int value;
} XML_Feature;
XMLPARSEAPI(const XML_Feature *)
XML_GetFeatureList(void);
-/* Expat follows the GNU/Linux convention of odd number minor version for
- beta/development releases and even number minor version for stable
- releases. Micro is bumped with each release, and set to 0 with each
- change to major or minor version.
+/* Expat follows the semantic versioning convention.
+ See http://semver.org.
*/
#define XML_MAJOR_VERSION 2
-#define XML_MINOR_VERSION 1
-#define XML_MICRO_VERSION 0
+#define XML_MINOR_VERSION 2
+#define XML_MICRO_VERSION 1
#ifdef __cplusplus
}
#endif
#endif /* not Expat_INCLUDED */
diff --git a/3rdParty/Expat/src/expat_external.h b/3rdParty/Expat/src/expat_external.h
index 2c03284..892eb4b 100644
--- a/3rdParty/Expat/src/expat_external.h
+++ b/3rdParty/Expat/src/expat_external.h
@@ -38,75 +38,92 @@
#define XMLCALL __cdecl
#elif defined(__GNUC__) && defined(__i386) && !defined(__INTEL_COMPILER)
#define XMLCALL __attribute__((cdecl))
#else
/* For any platform which uses this definition and supports more than
one calling convention, we need to extend this definition to
declare the convention used on that platform, if it's possible to
do so.
If this is the case for your platform, please file a bug report
with information on how to identify your platform via the C
pre-processor and how to specify the same calling convention as the
platform's malloc() implementation.
*/
#define XMLCALL
#endif
#endif /* not defined XMLCALL */
#if !defined(XML_STATIC) && !defined(XMLIMPORT)
#ifndef XML_BUILDING_EXPAT
/* using Expat from an application */
#ifdef XML_USE_MSC_EXTENSIONS
#define XMLIMPORT __declspec(dllimport)
#endif
#endif
#endif /* not defined XML_STATIC */
+#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4)
+#define XMLIMPORT __attribute__ ((visibility ("default")))
+#endif
/* If we didn't define it above, define it away: */
#ifndef XMLIMPORT
#define XMLIMPORT
#endif
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
+#define XML_ATTR_MALLOC __attribute__((__malloc__))
+#else
+#define XML_ATTR_MALLOC
+#endif
+
+#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+#define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
+#else
+#define XML_ATTR_ALLOC_SIZE(x)
+#endif
#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
#ifdef __cplusplus
extern "C" {
#endif
#ifdef XML_UNICODE_WCHAR_T
-#define XML_UNICODE
+# define XML_UNICODE
+# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)
+# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"
+# endif
#endif
#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
#ifdef XML_UNICODE_WCHAR_T
typedef wchar_t XML_Char;
typedef wchar_t XML_LChar;
#else
typedef unsigned short XML_Char;
typedef char XML_LChar;
#endif /* XML_UNICODE_WCHAR_T */
#else /* Information is UTF-8 encoded. */
typedef char XML_Char;
typedef char XML_LChar;
#endif /* XML_UNICODE */
#ifdef XML_LARGE_SIZE /* Use large integers for file/stream positions. */
#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
typedef __int64 XML_Index;
typedef unsigned __int64 XML_Size;
#else
typedef long long XML_Index;
typedef unsigned long long XML_Size;
#endif
#else
typedef long XML_Index;
typedef unsigned long XML_Size;
#endif /* XML_LARGE_SIZE */
#ifdef __cplusplus
}
diff --git a/3rdParty/Expat/src/internal.h b/3rdParty/Expat/src/internal.h
index dd54548..94cb98e 100644
--- a/3rdParty/Expat/src/internal.h
+++ b/3rdParty/Expat/src/internal.h
@@ -44,30 +44,52 @@
/* Make sure all of these are defined if they aren't already. */
#ifndef FASTCALL
#define FASTCALL
#endif
#ifndef PTRCALL
#define PTRCALL
#endif
#ifndef PTRFASTCALL
#define PTRFASTCALL
#endif
#ifndef XML_MIN_SIZE
#if !defined(__cplusplus) && !defined(inline)
#ifdef __GNUC__
#define inline __inline
#endif /* __GNUC__ */
#endif
#endif /* XML_MIN_SIZE */
#ifdef __cplusplus
#define inline inline
#else
#ifndef inline
#define inline
#endif
#endif
+
+#ifndef UNUSED_P
+# ifdef __GNUC__
+# define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__))
+# else
+# define UNUSED_P(p) UNUSED_ ## p
+# endif
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void
+align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/3rdParty/Expat/src/siphash.h b/3rdParty/Expat/src/siphash.h
new file mode 100644
index 0000000..23b56d2
--- /dev/null
+++ b/3rdParty/Expat/src/siphash.h
@@ -0,0 +1,344 @@
+/* ==========================================================================
+ * siphash.h - SipHash-2-4 in a single header file
+ * --------------------------------------------------------------------------
+ * Derived by William Ahern from the reference implementation[1] published[2]
+ * by Jean-Philippe Aumasson and Daniel J. Berstein. Licensed in kind.
+ * by Jean-Philippe Aumasson and Daniel J. Berstein.
+ * Minimal changes by Sebastian Pipping on top, details below.
+ * Licensed under the CC0 Public Domain Dedication license.
+ *
+ * 1. https://www.131002.net/siphash/siphash24.c
+ * 2. https://www.131002.net/siphash/
+ * --------------------------------------------------------------------------
+ * HISTORY:
+ *
+ * 2017-06-10 (Sebastian Pipping)
+ * - Clarify license note in the header
+ * - Address C89 issues:
+ * - Stop using inline keyword (and let compiler decide)
+ * - Turn integer suffix ULL to UL
+ * - Replace _Bool by int
+ * - Turn macro siphash24 into a function
+ * - Address invalid conversion (void pointer) by explicit cast
+ * - Always expose sip24_valid (for self-tests)
+ *
+ * 2012-11-04 - Born. (William Ahern)
+ * --------------------------------------------------------------------------
+ * USAGE:
+ *
+ * SipHash-2-4 takes as input two 64-bit words as the key, some number of
+ * message bytes, and outputs a 64-bit word as the message digest. This
+ * implementation employs two data structures: a struct sipkey for
+ * representing the key, and a struct siphash for representing the hash
+ * state.
+ *
+ * For converting a 16-byte unsigned char array to a key, use either the
+ * macro sip_keyof or the routine sip_tokey. The former instantiates a
+ * compound literal key, while the latter requires a key object as a
+ * parameter.
+ *
+ * unsigned char secret[16];
+ * arc4random_buf(secret, sizeof secret);
+ * struct sipkey *key = sip_keyof(secret);
+ *
+ * For hashing a message, use either the convenience macro siphash24 or the
+ * routines sip24_init, sip24_update, and sip24_final.
+ *
+ * struct siphash state;
+ * void *msg;
+ * size_t len;
+ * uint64_t hash;
+ *
+ * sip24_init(&state, key);
+ * sip24_update(&state, msg, len);
+ * hash = sip24_final(&state);
+ *
+ * or
+ *
+ * hash = siphash24(msg, len, key);
+ *
+ * To convert the 64-bit hash value to a canonical 8-byte little-endian
+ * binary representation, use either the macro sip_binof or the routine
+ * sip_tobin. The former instantiates and returns a compound literal array,
+ * while the latter requires an array object as a parameter.
+ * --------------------------------------------------------------------------
+ * NOTES:
+ *
+ * o Neither sip_keyof, sip_binof, nor siphash24 will work with compilers
+ * lacking compound literal support. Instead, you must use the lower-level
+ * interfaces which take as parameters the temporary state objects.
+ *
+ * o Uppercase macros may evaluate parameters more than once. Lowercase
+ * macros should not exhibit any such side effects.
+ * ==========================================================================
+ */
+#ifndef SIPHASH_H
+#define SIPHASH_H
+
+#include <stddef.h> /* size_t */
+#include <stdint.h> /* uint64_t uint32_t uint8_t */
+
+
+#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ( (x) >> (64 - (b))))
+
+#define SIP_U32TO8_LE(p, v) \
+ (p)[0] = (uint8_t)((v) >> 0); (p)[1] = (uint8_t)((v) >> 8); \
+ (p)[2] = (uint8_t)((v) >> 16); (p)[3] = (uint8_t)((v) >> 24);
+
+#define SIP_U64TO8_LE(p, v) \
+ SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >> 0)); \
+ SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
+
+#define SIP_U8TO64_LE(p) \
+ (((uint64_t)((p)[0]) << 0) | \
+ ((uint64_t)((p)[1]) << 8) | \
+ ((uint64_t)((p)[2]) << 16) | \
+ ((uint64_t)((p)[3]) << 24) | \
+ ((uint64_t)((p)[4]) << 32) | \
+ ((uint64_t)((p)[5]) << 40) | \
+ ((uint64_t)((p)[6]) << 48) | \
+ ((uint64_t)((p)[7]) << 56))
+
+
+#define SIPHASH_INITIALIZER { 0, 0, 0, 0, { 0 }, 0, 0 }
+
+struct siphash {
+ uint64_t v0, v1, v2, v3;
+
+ unsigned char buf[8], *p;
+ uint64_t c;
+}; /* struct siphash */
+
+
+#define SIP_KEYLEN 16
+
+struct sipkey {
+ uint64_t k[2];
+}; /* struct sipkey */
+
+#define sip_keyof(k) sip_tokey(&(struct sipkey){ { 0 } }, (k))
+
+static struct sipkey *sip_tokey(struct sipkey *key, const void *src) {
+ key->k[0] = SIP_U8TO64_LE((const unsigned char *)src);
+ key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8);
+ return key;
+} /* sip_tokey() */
+
+
+#define sip_binof(v) sip_tobin((unsigned char[8]){ 0 }, (v))
+
+static void *sip_tobin(void *dst, uint64_t u64) {
+ SIP_U64TO8_LE((unsigned char *)dst, u64);
+ return dst;
+} /* sip_tobin() */
+
+
+static void sip_round(struct siphash *H, const int rounds) {
+ int i;
+
+ for (i = 0; i < rounds; i++) {
+ H->v0 += H->v1;
+ H->v1 = SIP_ROTL(H->v1, 13);
+ H->v1 ^= H->v0;
+ H->v0 = SIP_ROTL(H->v0, 32);
+
+ H->v2 += H->v3;
+ H->v3 = SIP_ROTL(H->v3, 16);
+ H->v3 ^= H->v2;
+
+ H->v0 += H->v3;
+ H->v3 = SIP_ROTL(H->v3, 21);
+ H->v3 ^= H->v0;
+
+ H->v2 += H->v1;
+ H->v1 = SIP_ROTL(H->v1, 17);
+ H->v1 ^= H->v2;
+ H->v2 = SIP_ROTL(H->v2, 32);
+ }
+} /* sip_round() */
+
+
+static struct siphash *sip24_init(struct siphash *H, const struct sipkey *key) {
+ H->v0 = 0x736f6d6570736575UL ^ key->k[0];
+ H->v1 = 0x646f72616e646f6dUL ^ key->k[1];
+ H->v2 = 0x6c7967656e657261UL ^ key->k[0];
+ H->v3 = 0x7465646279746573UL ^ key->k[1];
+
+ H->p = H->buf;
+ H->c = 0;
+
+ return H;
+} /* sip24_init() */
+
+
+#define sip_endof(a) (&(a)[sizeof (a) / sizeof *(a)])
+
+static struct siphash *sip24_update(struct siphash *H, const void *src, size_t len) {
+ const unsigned char *p = (const unsigned char *)src, *pe = p + len;
+ uint64_t m;
+
+ do {
+ while (p < pe && H->p < sip_endof(H->buf))
+ *H->p++ = *p++;
+
+ if (H->p < sip_endof(H->buf))
+ break;
+
+ m = SIP_U8TO64_LE(H->buf);
+ H->v3 ^= m;
+ sip_round(H, 2);
+ H->v0 ^= m;
+
+ H->p = H->buf;
+ H->c += 8;
+ } while (p < pe);
+
+ return H;
+} /* sip24_update() */
+
+
+static uint64_t sip24_final(struct siphash *H) {
+ char left = H->p - H->buf;
+ uint64_t b = (H->c + left) << 56;
+
+ switch (left) {
+ case 7: b |= (uint64_t)H->buf[6] << 48;
+ case 6: b |= (uint64_t)H->buf[5] << 40;
+ case 5: b |= (uint64_t)H->buf[4] << 32;
+ case 4: b |= (uint64_t)H->buf[3] << 24;
+ case 3: b |= (uint64_t)H->buf[2] << 16;
+ case 2: b |= (uint64_t)H->buf[1] << 8;
+ case 1: b |= (uint64_t)H->buf[0] << 0;
+ case 0: break;
+ }
+
+ H->v3 ^= b;
+ sip_round(H, 2);
+ H->v0 ^= b;
+ H->v2 ^= 0xff;
+ sip_round(H, 4);
+
+ return H->v0 ^ H->v1 ^ H->v2 ^ H->v3;
+} /* sip24_final() */
+
+
+static uint64_t siphash24(const void *src, size_t len, const struct sipkey *key) {
+ struct siphash state = SIPHASH_INITIALIZER;
+ return sip24_final(sip24_update(sip24_init(&state, key), src, len));
+} /* siphash24() */
+
+
+/*
+ * SipHash-2-4 output with
+ * k = 00 01 02 ...
+ * and
+ * in = (empty string)
+ * in = 00 (1 byte)
+ * in = 00 01 (2 bytes)
+ * in = 00 01 02 (3 bytes)
+ * ...
+ * in = 00 01 02 ... 3e (63 bytes)
+ */
+static int sip24_valid(void) {
+ static const unsigned char vectors[64][8] = {
+ { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, },
+ { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, },
+ { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, },
+ { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, },
+ { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, },
+ { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, },
+ { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, },
+ { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, },
+ { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, },
+ { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, },
+ { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, },
+ { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, },
+ { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, },
+ { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, },
+ { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, },
+ { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, },
+ { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, },
+ { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, },
+ { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, },
+ { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, },
+ { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, },
+ { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, },
+ { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, },
+ { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, },
+ { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, },
+ { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, },
+ { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, },
+ { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, },
+ { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, },
+ { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, },
+ { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, },
+ { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, },
+ { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, },
+ { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, },
+ { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, },
+ { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, },
+ { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, },
+ { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, },
+ { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, },
+ { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, },
+ { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, },
+ { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, },
+ { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, },
+ { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, },
+ { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, },
+ { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, },
+ { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, },
+ { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, },
+ { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, },
+ { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, },
+ { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, },
+ { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, },
+ { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, },
+ { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, },
+ { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, },
+ { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, },
+ { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, },
+ { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, },
+ { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, },
+ { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, },
+ { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, },
+ { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, },
+ { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, },
+ { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, }
+ };
+ unsigned char in[64];
+ struct sipkey k;
+ size_t i;
+
+ sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017");
+
+ for (i = 0; i < sizeof in; ++i) {
+ in[i] = i;
+
+ if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i]))
+ return 0;
+ }
+
+ return 1;
+} /* sip24_valid() */
+
+
+#if SIPHASH_MAIN
+
+#include <stdio.h>
+
+int main(void) {
+ int ok = sip24_valid();
+
+ if (ok)
+ puts("OK");
+ else
+ puts("FAIL");
+
+ return !ok;
+} /* main() */
+
+#endif /* SIPHASH_MAIN */
+
+
+#endif /* SIPHASH_H */
diff --git a/3rdParty/Expat/src/winconfig.h b/3rdParty/Expat/src/winconfig.h
new file mode 100644
index 0000000..9bf014d
--- /dev/null
+++ b/3rdParty/Expat/src/winconfig.h
@@ -0,0 +1,40 @@
+/*================================================================
+** Copyright 2000, Clark Cooper
+** All rights reserved.
+**
+** This is free software. You are permitted to copy, distribute, or modify
+** it under the terms of the MIT/X license (contained in the COPYING file
+** with this distribution.)
+*/
+
+#ifndef WINCONFIG_H
+#define WINCONFIG_H
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef WIN32_LEAN_AND_MEAN
+
+#include <memory.h>
+#include <string.h>
+
+
+#if defined(HAVE_EXPAT_CONFIG_H) /* e.g. MinGW */
+# include <expat_config.h>
+#else /* !defined(HAVE_EXPAT_CONFIG_H) */
+
+
+#define XML_NS 1
+#define XML_DTD 1
+#define XML_CONTEXT_BYTES 1024
+
+/* we will assume all Windows platforms are little endian */
+#define BYTEORDER 1234
+
+/* Windows has memmove() available. */
+#define HAVE_MEMMOVE
+
+
+#endif /* !defined(HAVE_EXPAT_CONFIG_H) */
+
+
+#endif /* ndef WINCONFIG_H */
diff --git a/3rdParty/Expat/src/xmlparse.c b/3rdParty/Expat/src/xmlparse.c
index 9b8bd69..76f078e 100644
--- a/3rdParty/Expat/src/xmlparse.c
+++ b/3rdParty/Expat/src/xmlparse.c
@@ -1,56 +1,64 @@
/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
See the file COPYING for copying permission.
+
+ 77fea421d361dca90041d0040ecf1dca651167fadf2af79e990e35168d70d933 (2.2.1+)
*/
+#define _GNU_SOURCE /* syscall prototype */
+
#include <stddef.h>
#include <string.h> /* memset(), memcpy() */
#include <assert.h>
#include <limits.h> /* UINT_MAX */
-#include <time.h> /* time() */
+#include <stdio.h> /* fprintf */
+#include <stdlib.h> /* getenv */
+
+#ifdef _WIN32
+#define getpid GetCurrentProcessId
+#else
+#include <sys/time.h> /* gettimeofday() */
+#include <sys/types.h> /* getpid() */
+#include <unistd.h> /* getpid() */
+#endif
#define XML_BUILDING_EXPAT 1
-#ifdef COMPILED_FROM_DSP
+#ifdef _WIN32
#include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-#elif defined(__amigaos__)
-#include "amigaconfig.h"
-#elif defined(__WATCOMC__)
-#include "watcomconfig.h"
#elif defined(HAVE_EXPAT_CONFIG_H)
#include <expat_config.h>
-#endif /* ndef COMPILED_FROM_DSP */
+#endif /* ndef _WIN32 */
#include "ascii.h"
#include "expat.h"
+#include "siphash.h"
#ifdef XML_UNICODE
#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
#define XmlConvert XmlUtf16Convert
#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
#define XmlEncode XmlUtf16Encode
/* Using pointer subtraction to convert to integer type. */
#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((char *)(s) - (char *)NULL) & 1))
typedef unsigned short ICHAR;
#else
#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
#define XmlConvert XmlUtf8Convert
#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
#define XmlEncode XmlUtf8Encode
#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
typedef char ICHAR;
#endif
#ifndef XML_NS
#define XmlInitEncodingNS XmlInitEncoding
#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
#undef XmlGetInternalEncodingNS
#define XmlGetInternalEncodingNS XmlGetInternalEncoding
#define XmlParseXmlDeclNS XmlParseXmlDecl
#endif
@@ -75,71 +83,65 @@ typedef char ICHAR;
/* Round up n to be a multiple of sz, where sz is a power of 2. */
#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
/* Handle the case where memmove() doesn't exist. */
#ifndef HAVE_MEMMOVE
#ifdef HAVE_BCOPY
#define memmove(d,s,l) bcopy((s),(d),(l))
#else
#error memmove does not exist on this platform, nor is a substitute available
#endif /* HAVE_BCOPY */
#endif /* HAVE_MEMMOVE */
#include "internal.h"
#include "xmltok.h"
#include "xmlrole.h"
typedef const XML_Char *KEY;
typedef struct {
KEY name;
} NAMED;
typedef struct {
NAMED **v;
unsigned char power;
size_t size;
size_t used;
const XML_Memory_Handling_Suite *mem;
} HASH_TABLE;
-/* Basic character hash algorithm, taken from Python's string hash:
- h = h * 1000003 ^ character, the constant being a prime number.
+static size_t
+keylen(KEY s);
-*/
-#ifdef XML_UNICODE
-#define CHAR_HASH(h, c) \
- (((h) * 0xF4243) ^ (unsigned short)(c))
-#else
-#define CHAR_HASH(h, c) \
- (((h) * 0xF4243) ^ (unsigned char)(c))
-#endif
+static void
+copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key);
/* For probing (after a collision) we need a step size relative prime
to the hash table size, which is a power of 2. We use double-hashing,
since we can calculate a second hash value cheaply by taking those bits
of the first hash value that were discarded (masked out) when the table
index was calculated: index = hash & mask, where mask = table->size - 1.
We limit the maximum step size to table->size / 4 (mask >> 2) and make
it odd, since odd numbers are always relative prime to a power of 2.
*/
#define SECOND_HASH(hash, mask, power) \
((((hash) & ~(mask)) >> ((power) - 1)) & ((mask) >> 2))
#define PROBE_STEP(hash, mask, power) \
((unsigned char)((SECOND_HASH(hash, mask, power)) | 1))
typedef struct {
NAMED **p;
NAMED **end;
} HASH_TABLE_ITER;
#define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */
#define INIT_DATA_BUF_SIZE 1024
#define INIT_ATTS_SIZE 16
#define INIT_ATTS_VERSION 0xFFFFFFFF
#define INIT_BLOCK_SIZE 1024
#define INIT_BUFFER_SIZE 1024
#define EXPAND_SPARE 24
typedef struct binding {
struct prefix *prefix;
@@ -321,60 +323,62 @@ static Processor externalEntityInitProcessor3;
static Processor externalEntityContentProcessor;
static Processor internalEntityProcessor;
static enum XML_Error
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
static enum XML_Error
processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
const char *s, const char *next);
static enum XML_Error
initializeEncoding(XML_Parser parser);
static enum XML_Error
doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
const char *end, int tok, const char *next, const char **nextPtr,
XML_Bool haveMore);
static enum XML_Error
processInternalEntity(XML_Parser parser, ENTITY *entity,
XML_Bool betweenDecl);
static enum XML_Error
doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
const char *start, const char *end, const char **endPtr,
XML_Bool haveMore);
static enum XML_Error
doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr,
const char *end, const char **nextPtr, XML_Bool haveMore);
#ifdef XML_DTD
static enum XML_Error
doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr,
const char *end, const char **nextPtr, XML_Bool haveMore);
#endif /* XML_DTD */
+static void
+freeBindings(XML_Parser parser, BINDING *bindings);
static enum XML_Error
storeAtts(XML_Parser parser, const ENCODING *, const char *s,
TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
static enum XML_Error
addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
const XML_Char *uri, BINDING **bindingsPtr);
static int
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, XML_Bool isCdata,
XML_Bool isId, const XML_Char *dfltValue, XML_Parser parser);
static enum XML_Error
storeAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
const char *, const char *, STRING_POOL *);
static enum XML_Error
appendAttributeValue(XML_Parser parser, const ENCODING *, XML_Bool isCdata,
const char *, const char *, STRING_POOL *);
static ATTRIBUTE_ID *
getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start,
const char *end);
static int
setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
static enum XML_Error
storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start,
const char *end);
static int
reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
const char *start, const char *end);
static int
reportComment(XML_Parser parser, const ENCODING *enc, const char *start,
const char *end);
static void
@@ -405,61 +409,61 @@ hashTableInit(HASH_TABLE *, const XML_Memory_Handling_Suite *ms);
static void FASTCALL hashTableClear(HASH_TABLE *);
static void FASTCALL hashTableDestroy(HASH_TABLE *);
static void FASTCALL
hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
static NAMED * FASTCALL hashTableIterNext(HASH_TABLE_ITER *);
static void FASTCALL
poolInit(STRING_POOL *, const XML_Memory_Handling_Suite *ms);
static void FASTCALL poolClear(STRING_POOL *);
static void FASTCALL poolDestroy(STRING_POOL *);
static XML_Char *
poolAppend(STRING_POOL *pool, const ENCODING *enc,
const char *ptr, const char *end);
static XML_Char *
poolStoreString(STRING_POOL *pool, const ENCODING *enc,
const char *ptr, const char *end);
static XML_Bool FASTCALL poolGrow(STRING_POOL *pool);
static const XML_Char * FASTCALL
poolCopyString(STRING_POOL *pool, const XML_Char *s);
static const XML_Char *
poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
static const XML_Char * FASTCALL
poolAppendString(STRING_POOL *pool, const XML_Char *s);
static int FASTCALL nextScaffoldPart(XML_Parser parser);
static XML_Content * build_model(XML_Parser parser);
static ELEMENT_TYPE *
getElementType(XML_Parser parser, const ENCODING *enc,
const char *ptr, const char *end);
-static unsigned long generate_hash_secret_salt(void);
+static unsigned long generate_hash_secret_salt(XML_Parser parser);
static XML_Bool startParsing(XML_Parser parser);
static XML_Parser
parserCreate(const XML_Char *encodingName,
const XML_Memory_Handling_Suite *memsuite,
const XML_Char *nameSep,
DTD *dtd);
static void
parserInit(XML_Parser parser, const XML_Char *encodingName);
#define poolStart(pool) ((pool)->start)
#define poolEnd(pool) ((pool)->ptr)
#define poolLength(pool) ((pool)->ptr - (pool)->start)
#define poolChop(pool) ((void)--(pool->ptr))
#define poolLastChar(pool) (((pool)->ptr)[-1])
#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
#define poolFinish(pool) ((pool)->start = (pool)->ptr)
#define poolAppendChar(pool, c) \
(((pool)->ptr == (pool)->end && !poolGrow(pool)) \
? 0 \
: ((*((pool)->ptr)++ = c), 1))
struct XML_ParserStruct {
/* The first member must be userData so that the XML_GetUserData
macro works. */
void *m_userData;
void *m_handlerArg;
char *m_buffer;
const XML_Memory_Handling_Suite m_mem;
@@ -663,74 +667,217 @@ struct XML_ParserStruct {
#ifdef XML_DTD
#define isParamEntity (parser->m_isParamEntity)
#define useForeignDTD (parser->m_useForeignDTD)
#define paramEntityParsing (parser->m_paramEntityParsing)
#endif /* XML_DTD */
#define hash_secret_salt (parser->m_hash_secret_salt)
XML_Parser XMLCALL
XML_ParserCreate(const XML_Char *encodingName)
{
return XML_ParserCreate_MM(encodingName, NULL, NULL);
}
XML_Parser XMLCALL
XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
{
XML_Char tmp[2];
*tmp = nsSep;
return XML_ParserCreate_MM(encodingName, NULL, tmp);
}
static const XML_Char implicitContext[] = {
ASCII_x, ASCII_m, ASCII_l, ASCII_EQUALS, ASCII_h, ASCII_t, ASCII_t, ASCII_p,
ASCII_COLON, ASCII_SLASH, ASCII_SLASH, ASCII_w, ASCII_w, ASCII_w,
ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD, ASCII_o, ASCII_r, ASCII_g,
ASCII_SLASH, ASCII_X, ASCII_M, ASCII_L, ASCII_SLASH, ASCII_1, ASCII_9,
ASCII_9, ASCII_8, ASCII_SLASH, ASCII_n, ASCII_a, ASCII_m, ASCII_e,
ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0'
};
+
+#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
+# include <errno.h>
+
+# if defined(HAVE_GETRANDOM)
+# include <sys/random.h> /* getrandom */
+# else
+# include <unistd.h> /* syscall */
+# include <sys/syscall.h> /* SYS_getrandom */
+# endif
+
+/* Obtain entropy on Linux 3.17+ */
+static int
+writeRandomBytes_getrandom(void * target, size_t count) {
+ int success = 0; /* full count bytes written? */
+ size_t bytesWrittenTotal = 0;
+ const unsigned int getrandomFlags = 0;
+
+ do {
+ void * const currentTarget = (void*)((char*)target + bytesWrittenTotal);
+ const size_t bytesToWrite = count - bytesWrittenTotal;
+
+ const int bytesWrittenMore =
+#if defined(HAVE_GETRANDOM)
+ getrandom(currentTarget, bytesToWrite, getrandomFlags);
+#else
+ syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags);
+#endif
+
+ if (bytesWrittenMore > 0) {
+ bytesWrittenTotal += bytesWrittenMore;
+ if (bytesWrittenTotal >= count)
+ success = 1;
+ }
+ } while (! success && (errno == EINTR || errno == EAGAIN));
+
+ return success;
+}
+
+#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */
+
+
+#ifdef _WIN32
+
+typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG);
+
+/* Obtain entropy on Windows XP / Windows Server 2003 and later.
+ * Hint on RtlGenRandom and the following article from libsodioum.
+ *
+ * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI
+ * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/
+ */
+static int
+writeRandomBytes_RtlGenRandom(void * target, size_t count) {
+ int success = 0; /* full count bytes written? */
+ const HMODULE advapi32 = LoadLibrary("ADVAPI32.DLL");
+
+ if (advapi32) {
+ const RTLGENRANDOM_FUNC RtlGenRandom
+ = (RTLGENRANDOM_FUNC)GetProcAddress(advapi32, "SystemFunction036");
+ if (RtlGenRandom) {
+ if (RtlGenRandom((PVOID)target, (ULONG)count) == TRUE) {
+ success = 1;
+ }
+ }
+ FreeLibrary(advapi32);
+ }
+
+ return success;
+}
+
+#endif /* _WIN32 */
+
+
static unsigned long
-generate_hash_secret_salt(void)
+gather_time_entropy(void)
{
- unsigned int seed = time(NULL) % UINT_MAX;
- srand(seed);
- return rand();
+#ifdef _WIN32
+ FILETIME ft;
+ GetSystemTimeAsFileTime(&ft); /* never fails */
+ return ft.dwHighDateTime ^ ft.dwLowDateTime;
+#else
+ struct timeval tv;
+ int gettimeofday_res;
+
+ gettimeofday_res = gettimeofday(&tv, NULL);
+ assert (gettimeofday_res == 0);
+
+ /* Microseconds time is <20 bits entropy */
+ return tv.tv_usec;
+#endif
+}
+
+#if defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_LIBBSD)
+# include <bsd/stdlib.h>
+#endif
+
+static unsigned long
+ENTROPY_DEBUG(const char * label, unsigned long entropy) {
+ const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG");
+ if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) {
+ fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n",
+ label,
+ (int)sizeof(entropy) * 2, entropy,
+ (unsigned long)sizeof(entropy));
+ }
+ return entropy;
+}
+
+static unsigned long
+generate_hash_secret_salt(XML_Parser parser)
+{
+ unsigned long entropy;
+ (void)parser;
+#if defined(HAVE_ARC4RANDOM_BUF) || defined(__CloudABI__)
+ (void)gather_time_entropy;
+ arc4random_buf(&entropy, sizeof(entropy));
+ return ENTROPY_DEBUG("arc4random_buf", entropy);
+#else
+ /* Try high quality providers first .. */
+#ifdef _WIN32
+ if (writeRandomBytes_RtlGenRandom((void *)&entropy, sizeof(entropy))) {
+ return ENTROPY_DEBUG("RtlGenRandom", entropy);
+ }
+#elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM)
+ if (writeRandomBytes_getrandom((void *)&entropy, sizeof(entropy))) {
+ return ENTROPY_DEBUG("getrandom", entropy);
+ }
+#endif
+ /* .. and self-made low quality for backup: */
+
+ /* Process ID is 0 bits entropy if attacker has local access */
+ entropy = gather_time_entropy() ^ getpid();
+
+ /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */
+ if (sizeof(unsigned long) == 4) {
+ return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647);
+ } else {
+ return ENTROPY_DEBUG("fallback(8)",
+ entropy * (unsigned long)2305843009213693951);
+ }
+#endif
+}
+
+static unsigned long
+get_hash_secret_salt(XML_Parser parser) {
+ if (parser->m_parentParser != NULL)
+ return get_hash_secret_salt(parser->m_parentParser);
+ return parser->m_hash_secret_salt;
}
static XML_Bool /* only valid for root parser */
startParsing(XML_Parser parser)
{
/* hash functions must be initialized before setContext() is called */
if (hash_secret_salt == 0)
- hash_secret_salt = generate_hash_secret_salt();
+ hash_secret_salt = generate_hash_secret_salt(parser);
if (ns) {
/* implicit context only set for root parser, since child
parsers (i.e. external entity parsers) will inherit it
*/
return setContext(parser, implicitContext);
}
return XML_TRUE;
}
XML_Parser XMLCALL
XML_ParserCreate_MM(const XML_Char *encodingName,
const XML_Memory_Handling_Suite *memsuite,
const XML_Char *nameSep)
{
return parserCreate(encodingName, memsuite, nameSep, NULL);
}
static XML_Parser
parserCreate(const XML_Char *encodingName,
const XML_Memory_Handling_Suite *memsuite,
const XML_Char *nameSep,
DTD *dtd)
{
XML_Parser parser;
if (memsuite) {
XML_Memory_Handling_Suite *mtemp;
parser = (XML_Parser)
memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
if (parser != NULL) {
@@ -899,163 +1046,205 @@ parserInit(XML_Parser parser, const XML_Char *encodingName)
unknownEncodingMem = NULL;
unknownEncodingRelease = NULL;
unknownEncodingData = NULL;
parentParser = NULL;
ps_parsing = XML_INITIALIZED;
#ifdef XML_DTD
isParamEntity = XML_FALSE;
useForeignDTD = XML_FALSE;
paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
#endif
hash_secret_salt = 0;
}
/* moves list of bindings to freeBindingList */
static void FASTCALL
moveToFreeBindingList(XML_Parser parser, BINDING *bindings)
{
while (bindings) {
BINDING *b = bindings;
bindings = bindings->nextTagBinding;
b->nextTagBinding = freeBindingList;
freeBindingList = b;
}
}
XML_Bool XMLCALL
XML_ParserReset(XML_Parser parser, const XML_Char *encodingName)
{
TAG *tStk;
OPEN_INTERNAL_ENTITY *openEntityList;
+
+ if (parser == NULL)
+ return XML_FALSE;
+
if (parentParser)
return XML_FALSE;
/* move tagStack to freeTagList */
tStk = tagStack;
while (tStk) {
TAG *tag = tStk;
tStk = tStk->parent;
tag->parent = freeTagList;
moveToFreeBindingList(parser, tag->bindings);
tag->bindings = NULL;
freeTagList = tag;
}
/* move openInternalEntities to freeInternalEntities */
openEntityList = openInternalEntities;
while (openEntityList) {
OPEN_INTERNAL_ENTITY *openEntity = openEntityList;
openEntityList = openEntity->next;
openEntity->next = freeInternalEntities;
freeInternalEntities = openEntity;
}
moveToFreeBindingList(parser, inheritedBindings);
FREE(unknownEncodingMem);
if (unknownEncodingRelease)
unknownEncodingRelease(unknownEncodingData);
poolClear(&tempPool);
poolClear(&temp2Pool);
parserInit(parser, encodingName);
dtdReset(_dtd, &parser->m_mem);
return XML_TRUE;
}
enum XML_Status XMLCALL
XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
{
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
/* Block after XML_Parse()/XML_ParseBuffer() has been called.
XXX There's no way for the caller to determine which of the
XXX possible error cases caused the XML_STATUS_ERROR return.
*/
if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
return XML_STATUS_ERROR;
if (encodingName == NULL)
protocolEncodingName = NULL;
else {
protocolEncodingName = poolCopyString(&tempPool, encodingName);
if (!protocolEncodingName)
return XML_STATUS_ERROR;
}
return XML_STATUS_OK;
}
XML_Parser XMLCALL
XML_ExternalEntityParserCreate(XML_Parser oldParser,
const XML_Char *context,
const XML_Char *encodingName)
{
XML_Parser parser = oldParser;
DTD *newDtd = NULL;
- DTD *oldDtd = _dtd;
- XML_StartElementHandler oldStartElementHandler = startElementHandler;
- XML_EndElementHandler oldEndElementHandler = endElementHandler;
- XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
- XML_ProcessingInstructionHandler oldProcessingInstructionHandler
- = processingInstructionHandler;
- XML_CommentHandler oldCommentHandler = commentHandler;
- XML_StartCdataSectionHandler oldStartCdataSectionHandler
- = startCdataSectionHandler;
- XML_EndCdataSectionHandler oldEndCdataSectionHandler
- = endCdataSectionHandler;
- XML_DefaultHandler oldDefaultHandler = defaultHandler;
- XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
- = unparsedEntityDeclHandler;
- XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
- XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
- = startNamespaceDeclHandler;
- XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
- = endNamespaceDeclHandler;
- XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
- XML_ExternalEntityRefHandler oldExternalEntityRefHandler
- = externalEntityRefHandler;
- XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
- XML_UnknownEncodingHandler oldUnknownEncodingHandler
- = unknownEncodingHandler;
- XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
- XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
- XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
- XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
- ELEMENT_TYPE * oldDeclElementType = declElementType;
-
- void *oldUserData = userData;
- void *oldHandlerArg = handlerArg;
- XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
- XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+ DTD *oldDtd;
+ XML_StartElementHandler oldStartElementHandler;
+ XML_EndElementHandler oldEndElementHandler;
+ XML_CharacterDataHandler oldCharacterDataHandler;
+ XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
+ XML_CommentHandler oldCommentHandler;
+ XML_StartCdataSectionHandler oldStartCdataSectionHandler;
+ XML_EndCdataSectionHandler oldEndCdataSectionHandler;
+ XML_DefaultHandler oldDefaultHandler;
+ XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
+ XML_NotationDeclHandler oldNotationDeclHandler;
+ XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
+ XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
+ XML_NotStandaloneHandler oldNotStandaloneHandler;
+ XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
+ XML_SkippedEntityHandler oldSkippedEntityHandler;
+ XML_UnknownEncodingHandler oldUnknownEncodingHandler;
+ XML_ElementDeclHandler oldElementDeclHandler;
+ XML_AttlistDeclHandler oldAttlistDeclHandler;
+ XML_EntityDeclHandler oldEntityDeclHandler;
+ XML_XmlDeclHandler oldXmlDeclHandler;
+ ELEMENT_TYPE * oldDeclElementType;
+
+ void *oldUserData;
+ void *oldHandlerArg;
+ XML_Bool oldDefaultExpandInternalEntities;
+ XML_Parser oldExternalEntityRefHandlerArg;
#ifdef XML_DTD
- enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
- int oldInEntityValue = prologState.inEntityValue;
+ enum XML_ParamEntityParsing oldParamEntityParsing;
+ int oldInEntityValue;
#endif
- XML_Bool oldns_triplets = ns_triplets;
+ XML_Bool oldns_triplets;
/* Note that the new parser shares the same hash secret as the old
parser, so that dtdCopy and copyEntityTable can lookup values
from hash tables associated with either parser without us having
to worry which hash secrets each table has.
*/
- unsigned long oldhash_secret_salt = hash_secret_salt;
+ unsigned long oldhash_secret_salt;
+
+ /* Validate the oldParser parameter before we pull everything out of it */
+ if (oldParser == NULL)
+ return NULL;
+
+ /* Stash the original parser contents on the stack */
+ oldDtd = _dtd;
+ oldStartElementHandler = startElementHandler;
+ oldEndElementHandler = endElementHandler;
+ oldCharacterDataHandler = characterDataHandler;
+ oldProcessingInstructionHandler = processingInstructionHandler;
+ oldCommentHandler = commentHandler;
+ oldStartCdataSectionHandler = startCdataSectionHandler;
+ oldEndCdataSectionHandler = endCdataSectionHandler;
+ oldDefaultHandler = defaultHandler;
+ oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
+ oldNotationDeclHandler = notationDeclHandler;
+ oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
+ oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
+ oldNotStandaloneHandler = notStandaloneHandler;
+ oldExternalEntityRefHandler = externalEntityRefHandler;
+ oldSkippedEntityHandler = skippedEntityHandler;
+ oldUnknownEncodingHandler = unknownEncodingHandler;
+ oldElementDeclHandler = elementDeclHandler;
+ oldAttlistDeclHandler = attlistDeclHandler;
+ oldEntityDeclHandler = entityDeclHandler;
+ oldXmlDeclHandler = xmlDeclHandler;
+ oldDeclElementType = declElementType;
+
+ oldUserData = userData;
+ oldHandlerArg = handlerArg;
+ oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
+ oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+#ifdef XML_DTD
+ oldParamEntityParsing = paramEntityParsing;
+ oldInEntityValue = prologState.inEntityValue;
+#endif
+ oldns_triplets = ns_triplets;
+ /* Note that the new parser shares the same hash secret as the old
+ parser, so that dtdCopy and copyEntityTable can lookup values
+ from hash tables associated with either parser without us having
+ to worry which hash secrets each table has.
+ */
+ oldhash_secret_salt = hash_secret_salt;
#ifdef XML_DTD
if (!context)
newDtd = oldDtd;
#endif /* XML_DTD */
/* Note that the magical uses of the pre-processor to make field
access look more like C++ require that `parser' be overwritten
here. This makes this function more painful to follow than it
would be otherwise.
*/
if (ns) {
XML_Char tmp[2];
*tmp = namespaceSeparator;
parser = parserCreate(encodingName, &parser->m_mem, tmp, newDtd);
}
else {
parser = parserCreate(encodingName, &parser->m_mem, NULL, newDtd);
}
if (!parser)
return NULL;
startElementHandler = oldStartElementHandler;
endElementHandler = oldEndElementHandler;
characterDataHandler = oldCharacterDataHandler;
processingInstructionHandler = oldProcessingInstructionHandler;
commentHandler = oldCommentHandler;
startCdataSectionHandler = oldStartCdataSectionHandler;
endCdataSectionHandler = oldEndCdataSectionHandler;
@@ -1167,779 +1356,903 @@ XML_ParserFree(XML_Parser parser)
destroyBindings(freeBindingList, parser);
destroyBindings(inheritedBindings, parser);
poolDestroy(&tempPool);
poolDestroy(&temp2Pool);
#ifdef XML_DTD
/* external parameter entity parsers share the DTD structure
parser->m_dtd with the root parser, so we must not destroy it
*/
if (!isParamEntity && _dtd)
#else
if (_dtd)
#endif /* XML_DTD */
dtdDestroy(_dtd, (XML_Bool)!parentParser, &parser->m_mem);
FREE((void *)atts);
#ifdef XML_ATTR_INFO
FREE((void *)attInfo);
#endif
FREE(groupConnector);
FREE(buffer);
FREE(dataBuf);
FREE(nsAtts);
FREE(unknownEncodingMem);
if (unknownEncodingRelease)
unknownEncodingRelease(unknownEncodingData);
FREE(parser);
}
void XMLCALL
XML_UseParserAsHandlerArg(XML_Parser parser)
{
- handlerArg = parser;
+ if (parser != NULL)
+ handlerArg = parser;
}
enum XML_Error XMLCALL
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
{
+ if (parser == NULL)
+ return XML_ERROR_INVALID_ARGUMENT;
#ifdef XML_DTD
/* block after XML_Parse()/XML_ParseBuffer() has been called */
if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
return XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING;
useForeignDTD = useDTD;
return XML_ERROR_NONE;
#else
return XML_ERROR_FEATURE_REQUIRES_XML_DTD;
#endif
}
void XMLCALL
XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
{
+ if (parser == NULL)
+ return;
/* block after XML_Parse()/XML_ParseBuffer() has been called */
if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
return;
ns_triplets = do_nst ? XML_TRUE : XML_FALSE;
}
void XMLCALL
XML_SetUserData(XML_Parser parser, void *p)
{
+ if (parser == NULL)
+ return;
if (handlerArg == userData)
handlerArg = userData = p;
else
userData = p;
}
enum XML_Status XMLCALL
XML_SetBase(XML_Parser parser, const XML_Char *p)
{
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
if (p) {
p = poolCopyString(&_dtd->pool, p);
if (!p)
return XML_STATUS_ERROR;
curBase = p;
}
else
curBase = NULL;
return XML_STATUS_OK;
}
const XML_Char * XMLCALL
XML_GetBase(XML_Parser parser)
{
+ if (parser == NULL)
+ return NULL;
return curBase;
}
int XMLCALL
XML_GetSpecifiedAttributeCount(XML_Parser parser)
{
+ if (parser == NULL)
+ return -1;
return nSpecifiedAtts;
}
int XMLCALL
XML_GetIdAttributeIndex(XML_Parser parser)
{
+ if (parser == NULL)
+ return -1;
return idAttIndex;
}
#ifdef XML_ATTR_INFO
const XML_AttrInfo * XMLCALL
XML_GetAttributeInfo(XML_Parser parser)
{
+ if (parser == NULL)
+ return NULL;
return attInfo;
}
#endif
void XMLCALL
XML_SetElementHandler(XML_Parser parser,
XML_StartElementHandler start,
XML_EndElementHandler end)
{
+ if (parser == NULL)
+ return;
startElementHandler = start;
endElementHandler = end;
}
void XMLCALL
XML_SetStartElementHandler(XML_Parser parser,
XML_StartElementHandler start) {
- startElementHandler = start;
+ if (parser != NULL)
+ startElementHandler = start;
}
void XMLCALL
XML_SetEndElementHandler(XML_Parser parser,
XML_EndElementHandler end) {
- endElementHandler = end;
+ if (parser != NULL)
+ endElementHandler = end;
}
void XMLCALL
XML_SetCharacterDataHandler(XML_Parser parser,
XML_CharacterDataHandler handler)
{
- characterDataHandler = handler;
+ if (parser != NULL)
+ characterDataHandler = handler;
}
void XMLCALL
XML_SetProcessingInstructionHandler(XML_Parser parser,
XML_ProcessingInstructionHandler handler)
{
- processingInstructionHandler = handler;
+ if (parser != NULL)
+ processingInstructionHandler = handler;
}
void XMLCALL
XML_SetCommentHandler(XML_Parser parser,
XML_CommentHandler handler)
{
- commentHandler = handler;
+ if (parser != NULL)
+ commentHandler = handler;
}
void XMLCALL
XML_SetCdataSectionHandler(XML_Parser parser,
XML_StartCdataSectionHandler start,
XML_EndCdataSectionHandler end)
{
+ if (parser == NULL)
+ return;
startCdataSectionHandler = start;
endCdataSectionHandler = end;
}
void XMLCALL
XML_SetStartCdataSectionHandler(XML_Parser parser,
XML_StartCdataSectionHandler start) {
- startCdataSectionHandler = start;
+ if (parser != NULL)
+ startCdataSectionHandler = start;
}
void XMLCALL
XML_SetEndCdataSectionHandler(XML_Parser parser,
XML_EndCdataSectionHandler end) {
- endCdataSectionHandler = end;
+ if (parser != NULL)
+ endCdataSectionHandler = end;
}
void XMLCALL
XML_SetDefaultHandler(XML_Parser parser,
XML_DefaultHandler handler)
{
+ if (parser == NULL)
+ return;
defaultHandler = handler;
defaultExpandInternalEntities = XML_FALSE;
}
void XMLCALL
XML_SetDefaultHandlerExpand(XML_Parser parser,
XML_DefaultHandler handler)
{
+ if (parser == NULL)
+ return;
defaultHandler = handler;
defaultExpandInternalEntities = XML_TRUE;
}
void XMLCALL
XML_SetDoctypeDeclHandler(XML_Parser parser,
XML_StartDoctypeDeclHandler start,
XML_EndDoctypeDeclHandler end)
{
+ if (parser == NULL)
+ return;
startDoctypeDeclHandler = start;
endDoctypeDeclHandler = end;
}
void XMLCALL
XML_SetStartDoctypeDeclHandler(XML_Parser parser,
XML_StartDoctypeDeclHandler start) {
- startDoctypeDeclHandler = start;
+ if (parser != NULL)
+ startDoctypeDeclHandler = start;
}
void XMLCALL
XML_SetEndDoctypeDeclHandler(XML_Parser parser,
XML_EndDoctypeDeclHandler end) {
- endDoctypeDeclHandler = end;
+ if (parser != NULL)
+ endDoctypeDeclHandler = end;
}
void XMLCALL
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
XML_UnparsedEntityDeclHandler handler)
{
- unparsedEntityDeclHandler = handler;
+ if (parser != NULL)
+ unparsedEntityDeclHandler = handler;
}
void XMLCALL
XML_SetNotationDeclHandler(XML_Parser parser,
XML_NotationDeclHandler handler)
{
- notationDeclHandler = handler;
+ if (parser != NULL)
+ notationDeclHandler = handler;
}
void XMLCALL
XML_SetNamespaceDeclHandler(XML_Parser parser,
XML_StartNamespaceDeclHandler start,
XML_EndNamespaceDeclHandler end)
{
+ if (parser == NULL)
+ return;
startNamespaceDeclHandler = start;
endNamespaceDeclHandler = end;
}
void XMLCALL
XML_SetStartNamespaceDeclHandler(XML_Parser parser,
XML_StartNamespaceDeclHandler start) {
- startNamespaceDeclHandler = start;
+ if (parser != NULL)
+ startNamespaceDeclHandler = start;
}
void XMLCALL
XML_SetEndNamespaceDeclHandler(XML_Parser parser,
XML_EndNamespaceDeclHandler end) {
- endNamespaceDeclHandler = end;
+ if (parser != NULL)
+ endNamespaceDeclHandler = end;
}
void XMLCALL
XML_SetNotStandaloneHandler(XML_Parser parser,
XML_NotStandaloneHandler handler)
{
- notStandaloneHandler = handler;
+ if (parser != NULL)
+ notStandaloneHandler = handler;
}
void XMLCALL
XML_SetExternalEntityRefHandler(XML_Parser parser,
XML_ExternalEntityRefHandler handler)
{
- externalEntityRefHandler = handler;
+ if (parser != NULL)
+ externalEntityRefHandler = handler;
}
void XMLCALL
XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
{
+ if (parser == NULL)
+ return;
if (arg)
externalEntityRefHandlerArg = (XML_Parser)arg;
else
externalEntityRefHandlerArg = parser;
}
void XMLCALL
XML_SetSkippedEntityHandler(XML_Parser parser,
XML_SkippedEntityHandler handler)
{
- skippedEntityHandler = handler;
+ if (parser != NULL)
+ skippedEntityHandler = handler;
}
void XMLCALL
XML_SetUnknownEncodingHandler(XML_Parser parser,
XML_UnknownEncodingHandler handler,
void *data)
{
+ if (parser == NULL)
+ return;
unknownEncodingHandler = handler;
unknownEncodingHandlerData = data;
}
void XMLCALL
XML_SetElementDeclHandler(XML_Parser parser,
XML_ElementDeclHandler eldecl)
{
- elementDeclHandler = eldecl;
+ if (parser != NULL)
+ elementDeclHandler = eldecl;
}
void XMLCALL
XML_SetAttlistDeclHandler(XML_Parser parser,
XML_AttlistDeclHandler attdecl)
{
- attlistDeclHandler = attdecl;
+ if (parser != NULL)
+ attlistDeclHandler = attdecl;
}
void XMLCALL
XML_SetEntityDeclHandler(XML_Parser parser,
XML_EntityDeclHandler handler)
{
- entityDeclHandler = handler;
+ if (parser != NULL)
+ entityDeclHandler = handler;
}
void XMLCALL
XML_SetXmlDeclHandler(XML_Parser parser,
XML_XmlDeclHandler handler) {
- xmlDeclHandler = handler;
+ if (parser != NULL)
+ xmlDeclHandler = handler;
}
int XMLCALL
XML_SetParamEntityParsing(XML_Parser parser,
enum XML_ParamEntityParsing peParsing)
{
+ if (parser == NULL)
+ return 0;
/* block after XML_Parse()/XML_ParseBuffer() has been called */
if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
return 0;
#ifdef XML_DTD
paramEntityParsing = peParsing;
return 1;
#else
return peParsing == XML_PARAM_ENTITY_PARSING_NEVER;
#endif
}
int XMLCALL
XML_SetHashSalt(XML_Parser parser,
unsigned long hash_salt)
{
+ if (parser == NULL)
+ return 0;
+ if (parser->m_parentParser)
+ return XML_SetHashSalt(parser->m_parentParser, hash_salt);
/* block after XML_Parse()/XML_ParseBuffer() has been called */
if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
return 0;
hash_secret_salt = hash_salt;
return 1;
}
enum XML_Status XMLCALL
XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
{
+ if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
+ errorCode = XML_ERROR_INVALID_ARGUMENT;
+ return XML_STATUS_ERROR;
+ }
switch (ps_parsing) {
case XML_SUSPENDED:
errorCode = XML_ERROR_SUSPENDED;
return XML_STATUS_ERROR;
case XML_FINISHED:
errorCode = XML_ERROR_FINISHED;
return XML_STATUS_ERROR;
case XML_INITIALIZED:
if (parentParser == NULL && !startParsing(parser)) {
errorCode = XML_ERROR_NO_MEMORY;
return XML_STATUS_ERROR;
}
default:
ps_parsing = XML_PARSING;
}
if (len == 0) {
ps_finalBuffer = (XML_Bool)isFinal;
if (!isFinal)
return XML_STATUS_OK;
positionPtr = bufferPtr;
parseEndPtr = bufferEnd;
/* If data are left over from last buffer, and we now know that these
data are the final chunk of input, then we have to check them again
to detect errors based on that fact.
*/
errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
if (errorCode == XML_ERROR_NONE) {
switch (ps_parsing) {
case XML_SUSPENDED:
XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
positionPtr = bufferPtr;
return XML_STATUS_SUSPENDED;
case XML_INITIALIZED:
case XML_PARSING:
ps_parsing = XML_FINISHED;
/* fall through */
default:
return XML_STATUS_OK;
}
}
eventEndPtr = eventPtr;
processor = errorProcessor;
return XML_STATUS_ERROR;
}
#ifndef XML_CONTEXT_BYTES
else if (bufferPtr == bufferEnd) {
const char *end;
int nLeftOver;
- enum XML_Error result;
+ enum XML_Status result;
+ /* Detect overflow (a+b > MAX <==> b > MAX-a) */
+ if (len > ((XML_Size)-1) / 2 - parseEndByteIndex) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ eventPtr = eventEndPtr = NULL;
+ processor = errorProcessor;
+ return XML_STATUS_ERROR;
+ }
parseEndByteIndex += len;
positionPtr = s;
ps_finalBuffer = (XML_Bool)isFinal;
errorCode = processor(parser, s, parseEndPtr = s + len, &end);
if (errorCode != XML_ERROR_NONE) {
eventEndPtr = eventPtr;
processor = errorProcessor;
return XML_STATUS_ERROR;
}
else {
switch (ps_parsing) {
case XML_SUSPENDED:
result = XML_STATUS_SUSPENDED;
break;
case XML_INITIALIZED:
case XML_PARSING:
if (isFinal) {
ps_parsing = XML_FINISHED;
return XML_STATUS_OK;
}
/* fall through */
default:
result = XML_STATUS_OK;
}
}
XmlUpdatePosition(encoding, positionPtr, end, &position);
nLeftOver = s + len - end;
if (nLeftOver) {
if (buffer == NULL || nLeftOver > bufferLim - buffer) {
- /* FIXME avoid integer overflow */
- char *temp;
- temp = (buffer == NULL
- ? (char *)MALLOC(len * 2)
- : (char *)REALLOC(buffer, len * 2));
+ /* avoid _signed_ integer overflow */
+ char *temp = NULL;
+ const int bytesToAllocate = (int)((unsigned)len * 2U);
+ if (bytesToAllocate > 0) {
+ temp = (buffer == NULL
+ ? (char *)MALLOC(bytesToAllocate)
+ : (char *)REALLOC(buffer, bytesToAllocate));
+ }
if (temp == NULL) {
errorCode = XML_ERROR_NO_MEMORY;
eventPtr = eventEndPtr = NULL;
processor = errorProcessor;
return XML_STATUS_ERROR;
}
buffer = temp;
- bufferLim = buffer + len * 2;
+ bufferLim = buffer + bytesToAllocate;
}
memcpy(buffer, end, nLeftOver);
}
bufferPtr = buffer;
bufferEnd = buffer + nLeftOver;
positionPtr = bufferPtr;
parseEndPtr = bufferEnd;
eventPtr = bufferPtr;
eventEndPtr = bufferPtr;
return result;
}
#endif /* not defined XML_CONTEXT_BYTES */
else {
void *buff = XML_GetBuffer(parser, len);
if (buff == NULL)
return XML_STATUS_ERROR;
else {
memcpy(buff, s, len);
return XML_ParseBuffer(parser, len, isFinal);
}
}
}
enum XML_Status XMLCALL
XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
{
const char *start;
enum XML_Status result = XML_STATUS_OK;
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
switch (ps_parsing) {
case XML_SUSPENDED:
errorCode = XML_ERROR_SUSPENDED;
return XML_STATUS_ERROR;
case XML_FINISHED:
errorCode = XML_ERROR_FINISHED;
return XML_STATUS_ERROR;
case XML_INITIALIZED:
if (parentParser == NULL && !startParsing(parser)) {
errorCode = XML_ERROR_NO_MEMORY;
return XML_STATUS_ERROR;
}
default:
ps_parsing = XML_PARSING;
}
start = bufferPtr;
positionPtr = start;
bufferEnd += len;
parseEndPtr = bufferEnd;
parseEndByteIndex += len;
ps_finalBuffer = (XML_Bool)isFinal;
errorCode = processor(parser, start, parseEndPtr, &bufferPtr);
if (errorCode != XML_ERROR_NONE) {
eventEndPtr = eventPtr;
processor = errorProcessor;
return XML_STATUS_ERROR;
}
else {
switch (ps_parsing) {
case XML_SUSPENDED:
result = XML_STATUS_SUSPENDED;
break;
case XML_INITIALIZED:
case XML_PARSING:
if (isFinal) {
ps_parsing = XML_FINISHED;
return result;
}
default: ; /* should not happen */
}
}
XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
positionPtr = bufferPtr;
return result;
}
void * XMLCALL
XML_GetBuffer(XML_Parser parser, int len)
{
+ if (parser == NULL)
+ return NULL;
+ if (len < 0) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return NULL;
+ }
switch (ps_parsing) {
case XML_SUSPENDED:
errorCode = XML_ERROR_SUSPENDED;
return NULL;
case XML_FINISHED:
errorCode = XML_ERROR_FINISHED;
return NULL;
default: ;
}
if (len > bufferLim - bufferEnd) {
- /* FIXME avoid integer overflow */
- int neededSize = len + (int)(bufferEnd - bufferPtr);
#ifdef XML_CONTEXT_BYTES
- int keep = (int)(bufferPtr - buffer);
-
+ int keep;
+#endif /* defined XML_CONTEXT_BYTES */
+ /* Do not invoke signed arithmetic overflow: */
+ int neededSize = (int) ((unsigned)len + (unsigned)(bufferEnd - bufferPtr));
+ if (neededSize < 0) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return NULL;
+ }
+#ifdef XML_CONTEXT_BYTES
+ keep = (int)(bufferPtr - buffer);
if (keep > XML_CONTEXT_BYTES)
keep = XML_CONTEXT_BYTES;
neededSize += keep;
#endif /* defined XML_CONTEXT_BYTES */
if (neededSize <= bufferLim - buffer) {
#ifdef XML_CONTEXT_BYTES
if (keep < bufferPtr - buffer) {
int offset = (int)(bufferPtr - buffer) - keep;
memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
bufferEnd -= offset;
bufferPtr -= offset;
}
#else
memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
bufferEnd = buffer + (bufferEnd - bufferPtr);
bufferPtr = buffer;
#endif /* not defined XML_CONTEXT_BYTES */
}
else {
char *newBuf;
int bufferSize = (int)(bufferLim - bufferPtr);
if (bufferSize == 0)
bufferSize = INIT_BUFFER_SIZE;
do {
- bufferSize *= 2;
- } while (bufferSize < neededSize);
+ /* Do not invoke signed arithmetic overflow: */
+ bufferSize = (int) (2U * (unsigned) bufferSize);
+ } while (bufferSize < neededSize && bufferSize > 0);
+ if (bufferSize <= 0) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return NULL;
+ }
newBuf = (char *)MALLOC(bufferSize);
if (newBuf == 0) {
errorCode = XML_ERROR_NO_MEMORY;
return NULL;
}
bufferLim = newBuf + bufferSize;
#ifdef XML_CONTEXT_BYTES
if (bufferPtr) {
int keep = (int)(bufferPtr - buffer);
if (keep > XML_CONTEXT_BYTES)
keep = XML_CONTEXT_BYTES;
memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
FREE(buffer);
buffer = newBuf;
bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
bufferPtr = buffer + keep;
}
else {
bufferEnd = newBuf + (bufferEnd - bufferPtr);
bufferPtr = buffer = newBuf;
}
#else
if (bufferPtr) {
memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
FREE(buffer);
}
bufferEnd = newBuf + (bufferEnd - bufferPtr);
bufferPtr = buffer = newBuf;
#endif /* not defined XML_CONTEXT_BYTES */
}
eventPtr = eventEndPtr = NULL;
positionPtr = NULL;
}
return bufferEnd;
}
enum XML_Status XMLCALL
XML_StopParser(XML_Parser parser, XML_Bool resumable)
{
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
switch (ps_parsing) {
case XML_SUSPENDED:
if (resumable) {
errorCode = XML_ERROR_SUSPENDED;
return XML_STATUS_ERROR;
}
ps_parsing = XML_FINISHED;
break;
case XML_FINISHED:
errorCode = XML_ERROR_FINISHED;
return XML_STATUS_ERROR;
default:
if (resumable) {
#ifdef XML_DTD
if (isParamEntity) {
errorCode = XML_ERROR_SUSPEND_PE;
return XML_STATUS_ERROR;
}
#endif
ps_parsing = XML_SUSPENDED;
}
else
ps_parsing = XML_FINISHED;
}
return XML_STATUS_OK;
}
enum XML_Status XMLCALL
XML_ResumeParser(XML_Parser parser)
{
enum XML_Status result = XML_STATUS_OK;
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
if (ps_parsing != XML_SUSPENDED) {
errorCode = XML_ERROR_NOT_SUSPENDED;
return XML_STATUS_ERROR;
}
ps_parsing = XML_PARSING;
errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
if (errorCode != XML_ERROR_NONE) {
eventEndPtr = eventPtr;
processor = errorProcessor;
return XML_STATUS_ERROR;
}
else {
switch (ps_parsing) {
case XML_SUSPENDED:
result = XML_STATUS_SUSPENDED;
break;
case XML_INITIALIZED:
case XML_PARSING:
if (ps_finalBuffer) {
ps_parsing = XML_FINISHED;
return result;
}
default: ;
}
}
XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
positionPtr = bufferPtr;
return result;
}
void XMLCALL
XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
{
+ if (parser == NULL)
+ return;
assert(status != NULL);
*status = parser->m_parsingStatus;
}
enum XML_Error XMLCALL
XML_GetErrorCode(XML_Parser parser)
{
+ if (parser == NULL)
+ return XML_ERROR_INVALID_ARGUMENT;
return errorCode;
}
XML_Index XMLCALL
XML_GetCurrentByteIndex(XML_Parser parser)
{
+ if (parser == NULL)
+ return -1;
if (eventPtr)
- return parseEndByteIndex - (parseEndPtr - eventPtr);
+ return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr));
return -1;
}
int XMLCALL
XML_GetCurrentByteCount(XML_Parser parser)
{
+ if (parser == NULL)
+ return 0;
if (eventEndPtr && eventPtr)
return (int)(eventEndPtr - eventPtr);
return 0;
}
const char * XMLCALL
XML_GetInputContext(XML_Parser parser, int *offset, int *size)
{
#ifdef XML_CONTEXT_BYTES
+ if (parser == NULL)
+ return NULL;
if (eventPtr && buffer) {
- *offset = (int)(eventPtr - buffer);
- *size = (int)(bufferEnd - buffer);
+ if (offset != NULL)
+ *offset = (int)(eventPtr - buffer);
+ if (size != NULL)
+ *size = (int)(bufferEnd - buffer);
return buffer;
}
+#else
+ (void)parser;
+ (void)offset;
+ (void)size;
#endif /* defined XML_CONTEXT_BYTES */
return (char *) 0;
}
XML_Size XMLCALL
XML_GetCurrentLineNumber(XML_Parser parser)
{
+ if (parser == NULL)
+ return 0;
if (eventPtr && eventPtr >= positionPtr) {
XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
positionPtr = eventPtr;
}
return position.lineNumber + 1;
}
XML_Size XMLCALL
XML_GetCurrentColumnNumber(XML_Parser parser)
{
+ if (parser == NULL)
+ return 0;
if (eventPtr && eventPtr >= positionPtr) {
XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
positionPtr = eventPtr;
}
return position.columnNumber;
}
void XMLCALL
XML_FreeContentModel(XML_Parser parser, XML_Content *model)
{
- FREE(model);
+ if (parser != NULL)
+ FREE(model);
}
void * XMLCALL
XML_MemMalloc(XML_Parser parser, size_t size)
{
+ if (parser == NULL)
+ return NULL;
return MALLOC(size);
}
void * XMLCALL
XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
{
+ if (parser == NULL)
+ return NULL;
return REALLOC(ptr, size);
}
void XMLCALL
XML_MemFree(XML_Parser parser, void *ptr)
{
- FREE(ptr);
+ if (parser != NULL)
+ FREE(ptr);
}
void XMLCALL
XML_DefaultCurrent(XML_Parser parser)
{
+ if (parser == NULL)
+ return;
if (defaultHandler) {
if (openInternalEntities)
reportDefault(parser,
internalEncoding,
openInternalEntities->internalEventPtr,
openInternalEntities->internalEventEndPtr);
else
reportDefault(parser, encoding, eventPtr, eventEndPtr);
}
}
const XML_LChar * XMLCALL
XML_ErrorString(enum XML_Error code)
{
static const XML_LChar* const message[] = {
0,
XML_L("out of memory"),
XML_L("syntax error"),
XML_L("no element found"),
XML_L("not well-formed (invalid token)"),
XML_L("unclosed token"),
XML_L("partial character"),
XML_L("mismatched tag"),
XML_L("duplicate attribute"),
XML_L("junk after document element"),
XML_L("illegal parameter entity reference"),
XML_L("undefined entity"),
XML_L("recursive entity reference"),
XML_L("asynchronous entity"),
XML_L("reference to invalid character number"),
@@ -2388,132 +2701,126 @@ doContent(XML_Parser parser,
if (freeTagList) {
tag = freeTagList;
freeTagList = freeTagList->parent;
}
else {
tag = (TAG *)MALLOC(sizeof(TAG));
if (!tag)
return XML_ERROR_NO_MEMORY;
tag->buf = (char *)MALLOC(INIT_TAG_BUF_SIZE);
if (!tag->buf) {
FREE(tag);
return XML_ERROR_NO_MEMORY;
}
tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
}
tag->bindings = NULL;
tag->parent = tagStack;
tagStack = tag;
tag->name.localPart = NULL;
tag->name.prefix = NULL;
tag->rawName = s + enc->minBytesPerChar;
tag->rawNameLength = XmlNameLength(enc, tag->rawName);
++tagLevel;
{
const char *rawNameEnd = tag->rawName + tag->rawNameLength;
const char *fromPtr = tag->rawName;
toPtr = (XML_Char *)tag->buf;
for (;;) {
int bufSize;
int convLen;
- XmlConvert(enc,
+ const enum XML_Convert_Result convert_res = XmlConvert(enc,
&fromPtr, rawNameEnd,
(ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
convLen = (int)(toPtr - (XML_Char *)tag->buf);
- if (fromPtr == rawNameEnd) {
+ if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) {
tag->name.strLen = convLen;
break;
}
bufSize = (int)(tag->bufEnd - tag->buf) << 1;
{
char *temp = (char *)REALLOC(tag->buf, bufSize);
if (temp == NULL)
return XML_ERROR_NO_MEMORY;
tag->buf = temp;
tag->bufEnd = temp + bufSize;
toPtr = (XML_Char *)temp + convLen;
}
}
}
tag->name.str = (XML_Char *)tag->buf;
*toPtr = XML_T('\0');
result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
if (result)
return result;
if (startElementHandler)
startElementHandler(handlerArg, tag->name.str,
(const XML_Char **)atts);
else if (defaultHandler)
reportDefault(parser, enc, s, next);
poolClear(&tempPool);
break;
}
case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
/* fall through */
case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
{
const char *rawName = s + enc->minBytesPerChar;
enum XML_Error result;
BINDING *bindings = NULL;
XML_Bool noElmHandlers = XML_TRUE;
TAG_NAME name;
name.str = poolStoreString(&tempPool, enc, rawName,
rawName + XmlNameLength(enc, rawName));
if (!name.str)
return XML_ERROR_NO_MEMORY;
poolFinish(&tempPool);
result = storeAtts(parser, enc, s, &name, &bindings);
- if (result)
+ if (result != XML_ERROR_NONE) {
+ freeBindings(parser, bindings);
return result;
+ }
poolFinish(&tempPool);
if (startElementHandler) {
startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
noElmHandlers = XML_FALSE;
}
if (endElementHandler) {
if (startElementHandler)
*eventPP = *eventEndPP;
endElementHandler(handlerArg, name.str);
noElmHandlers = XML_FALSE;
}
if (noElmHandlers && defaultHandler)
reportDefault(parser, enc, s, next);
poolClear(&tempPool);
- while (bindings) {
- BINDING *b = bindings;
- if (endNamespaceDeclHandler)
- endNamespaceDeclHandler(handlerArg, b->prefix->name);
- bindings = bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
- b->prefix->binding = b->prevPrefixBinding;
- }
+ freeBindings(parser, bindings);
}
if (tagLevel == 0)
return epilogProcessor(parser, next, end, nextPtr);
break;
case XML_TOK_END_TAG:
if (tagLevel == startTagLevel)
return XML_ERROR_ASYNC_ENTITY;
else {
int len;
const char *rawName;
TAG *tag = tagStack;
tagStack = tag->parent;
tag->parent = freeTagList;
freeTagList = tag;
rawName = s + enc->minBytesPerChar*2;
len = XmlNameLength(enc, rawName);
if (len != tag->rawNameLength
|| memcmp(tag->rawName, rawName, len) != 0) {
*eventPP = rawName;
return XML_ERROR_TAG_MISMATCH;
}
--tagLevel;
if (endElementHandler) {
const XML_Char *localPart;
const XML_Char *prefix;
XML_Char *uri;
localPart = tag->name.localPart;
if (ns && localPart) {
/* localPart and prefix may have been overwritten in
tag->name.str, since this points to the binding->uri
@@ -2613,104 +2920,127 @@ doContent(XML_Parser parser,
characterDataHandler(handlerArg, dataBuf,
(int)(dataPtr - (ICHAR *)dataBuf));
}
else
characterDataHandler(handlerArg,
(XML_Char *)s,
(int)((XML_Char *)end - (XML_Char *)s));
}
else if (defaultHandler)
reportDefault(parser, enc, s, end);
/* We are at the end of the final buffer, should we check for
XML_SUSPENDED, XML_FINISHED?
*/
if (startTagLevel == 0) {
*eventPP = end;
return XML_ERROR_NO_ELEMENTS;
}
if (tagLevel != startTagLevel) {
*eventPP = end;
return XML_ERROR_ASYNC_ENTITY;
}
*nextPtr = end;
return XML_ERROR_NONE;
case XML_TOK_DATA_CHARS:
{
XML_CharacterDataHandler charDataHandler = characterDataHandler;
if (charDataHandler) {
if (MUST_CONVERT(enc, s)) {
for (;;) {
ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+ const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
*eventEndPP = s;
charDataHandler(handlerArg, dataBuf,
(int)(dataPtr - (ICHAR *)dataBuf));
- if (s == next)
+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
break;
*eventPP = s;
}
}
else
charDataHandler(handlerArg,
(XML_Char *)s,
(int)((XML_Char *)next - (XML_Char *)s));
}
else if (defaultHandler)
reportDefault(parser, enc, s, next);
}
break;
case XML_TOK_PI:
if (!reportProcessingInstruction(parser, enc, s, next))
return XML_ERROR_NO_MEMORY;
break;
case XML_TOK_COMMENT:
if (!reportComment(parser, enc, s, next))
return XML_ERROR_NO_MEMORY;
break;
default:
if (defaultHandler)
reportDefault(parser, enc, s, next);
break;
}
*eventPP = s = next;
switch (ps_parsing) {
case XML_SUSPENDED:
*nextPtr = next;
return XML_ERROR_NONE;
case XML_FINISHED:
return XML_ERROR_ABORTED;
default: ;
}
}
/* not reached */
}
+/* This function does not call free() on the allocated memory, merely
+ * moving it to the parser's freeBindingList where it can be freed or
+ * reused as appropriate.
+ */
+static void
+freeBindings(XML_Parser parser, BINDING *bindings)
+{
+ while (bindings) {
+ BINDING *b = bindings;
+
+ /* startNamespaceDeclHandler will have been called for this
+ * binding in addBindings(), so call the end handler now.
+ */
+ if (endNamespaceDeclHandler)
+ endNamespaceDeclHandler(handlerArg, b->prefix->name);
+
+ bindings = bindings->nextTagBinding;
+ b->nextTagBinding = freeBindingList;
+ freeBindingList = b;
+ b->prefix->binding = b->prevPrefixBinding;
+ }
+}
+
/* Precondition: all arguments must be non-NULL;
Purpose:
- normalize attributes
- check attributes for well-formedness
- generate namespace aware attribute names (URI, prefix)
- build list of attributes for startElementHandler
- default attributes
- process namespace declarations (check and report them)
- generate namespace aware element name (URI, prefix)
*/
static enum XML_Error
storeAtts(XML_Parser parser, const ENCODING *enc,
const char *attStr, TAG_NAME *tagNamePtr,
BINDING **bindingsPtr)
{
DTD * const dtd = _dtd; /* save one level of indirection */
ELEMENT_TYPE *elementType;
int nDefaultAtts;
const XML_Char **appAtts; /* the attribute list for the application */
int attIndex = 0;
int prefixLen;
int i;
int n;
XML_Char *uri;
int nPrefixes = 0;
BINDING *binding;
const XML_Char *localPart;
/* lookup the element type name */
elementType = (ELEMENT_TYPE *)lookup(parser, &dtd->elementTypes, tagNamePtr->str,0);
@@ -2881,146 +3211,156 @@ storeAtts(XML_Parser parser, const ENCODING *enc,
unsigned long version = nsAttsVersion;
int nsAttsSize = (int)1 << nsAttsPower;
/* size of hash table must be at least 2 * (# of prefixed attributes) */
if ((nPrefixes << 1) >> nsAttsPower) { /* true for nsAttsPower = 0 */
NS_ATT *temp;
/* hash table size must also be a power of 2 and >= 8 */
while (nPrefixes >> nsAttsPower++);
if (nsAttsPower < 3)
nsAttsPower = 3;
nsAttsSize = (int)1 << nsAttsPower;
temp = (NS_ATT *)REALLOC(nsAtts, nsAttsSize * sizeof(NS_ATT));
if (!temp)
return XML_ERROR_NO_MEMORY;
nsAtts = temp;
version = 0; /* force re-initialization of nsAtts hash table */
}
/* using a version flag saves us from initializing nsAtts every time */
if (!version) { /* initialize version flags when version wraps around */
version = INIT_ATTS_VERSION;
for (j = nsAttsSize; j != 0; )
nsAtts[--j].version = version;
}
nsAttsVersion = --version;
/* expand prefixed names and check for duplicates */
for (; i < attIndex; i += 2) {
const XML_Char *s = appAtts[i];
if (s[-1] == 2) { /* prefixed */
ATTRIBUTE_ID *id;
const BINDING *b;
- unsigned long uriHash = hash_secret_salt;
+ unsigned long uriHash;
+ struct siphash sip_state;
+ struct sipkey sip_key;
+
+ copy_salt_to_sipkey(parser, &sip_key);
+ sip24_init(&sip_state, &sip_key);
+
((XML_Char *)s)[-1] = 0; /* clear flag */
id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
+ if (!id || !id->prefix)
+ return XML_ERROR_NO_MEMORY;
b = id->prefix->binding;
- if (!b) {
- //return XML_ERROR_UNBOUND_PREFIX;
- continue;
- }
+ if (!b)
+ return XML_ERROR_UNBOUND_PREFIX;
- /* as we expand the name we also calculate its hash value */
for (j = 0; j < b->uriLen; j++) {
const XML_Char c = b->uri[j];
if (!poolAppendChar(&tempPool, c))
return XML_ERROR_NO_MEMORY;
- uriHash = CHAR_HASH(uriHash, c);
}
+
+ sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
+
while (*s++ != XML_T(ASCII_COLON))
;
+
+ sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
+
do { /* copies null terminator */
- const XML_Char c = *s;
if (!poolAppendChar(&tempPool, *s))
return XML_ERROR_NO_MEMORY;
- uriHash = CHAR_HASH(uriHash, c);
} while (*s++);
+ uriHash = (unsigned long)sip24_final(&sip_state);
+
{ /* Check hash table for duplicate of expanded name (uriName).
Derived from code in lookup(parser, HASH_TABLE *table, ...).
*/
unsigned char step = 0;
unsigned long mask = nsAttsSize - 1;
j = uriHash & mask; /* index into hash table */
while (nsAtts[j].version == version) {
/* for speed we compare stored hash values first */
if (uriHash == nsAtts[j].hash) {
const XML_Char *s1 = poolStart(&tempPool);
const XML_Char *s2 = nsAtts[j].uriName;
/* s1 is null terminated, but not s2 */
for (; *s1 == *s2 && *s1 != 0; s1++, s2++);
if (*s1 == 0)
return XML_ERROR_DUPLICATE_ATTRIBUTE;
}
if (!step)
step = PROBE_STEP(uriHash, mask, nsAttsPower);
j < step ? (j += nsAttsSize - step) : (j -= step);
}
}
if (ns_triplets) { /* append namespace separator and prefix */
tempPool.ptr[-1] = namespaceSeparator;
s = b->prefix->name;
do {
if (!poolAppendChar(&tempPool, *s))
return XML_ERROR_NO_MEMORY;
} while (*s++);
}
/* store expanded name in attribute list */
s = poolStart(&tempPool);
poolFinish(&tempPool);
appAtts[i] = s;
/* fill empty slot with new version, uriName and hash value */
nsAtts[j].version = version;
nsAtts[j].hash = uriHash;
nsAtts[j].uriName = s;
if (!--nPrefixes) {
i += 2;
break;
}
}
else /* not prefixed */
((XML_Char *)s)[-1] = 0; /* clear flag */
}
}
/* clear flags for the remaining attributes */
for (; i < attIndex; i += 2)
((XML_Char *)(appAtts[i]))[-1] = 0;
for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
binding->attId->name[-1] = 0;
if (!ns)
return XML_ERROR_NONE;
/* expand the element type name */
- if (elementType->prefix && elementType->prefix->binding) {
+ if (elementType->prefix) {
binding = elementType->prefix->binding;
if (!binding)
return XML_ERROR_UNBOUND_PREFIX;
localPart = tagNamePtr->str;
while (*localPart++ != XML_T(ASCII_COLON))
;
}
else if (dtd->defaultPrefix.binding) {
binding = dtd->defaultPrefix.binding;
localPart = tagNamePtr->str;
}
else
return XML_ERROR_NONE;
prefixLen = 0;
if (ns_triplets && binding->prefix->name) {
for (; binding->prefix->name[prefixLen++];)
; /* prefixLen includes null terminator */
}
tagNamePtr->localPart = localPart;
tagNamePtr->uriLen = binding->uriLen;
tagNamePtr->prefix = binding->prefix->name;
tagNamePtr->prefixLen = prefixLen;
for (i = 0; localPart[i++];)
; /* i includes null terminator */
n = i + binding->uriLen + prefixLen;
if (n > binding->uriAlloc) {
TAG *p;
uri = (XML_Char *)MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
if (!uri)
return XML_ERROR_NO_MEMORY;
@@ -3062,86 +3402,86 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId,
};
static const int xmlLen =
(int)sizeof(xmlNamespace)/sizeof(XML_Char) - 1;
static const XML_Char xmlnsNamespace[] = {
ASCII_h, ASCII_t, ASCII_t, ASCII_p, ASCII_COLON, ASCII_SLASH, ASCII_SLASH,
ASCII_w, ASCII_w, ASCII_w, ASCII_PERIOD, ASCII_w, ASCII_3, ASCII_PERIOD,
ASCII_o, ASCII_r, ASCII_g, ASCII_SLASH, ASCII_2, ASCII_0, ASCII_0,
ASCII_0, ASCII_SLASH, ASCII_x, ASCII_m, ASCII_l, ASCII_n, ASCII_s,
ASCII_SLASH, '\0'
};
static const int xmlnsLen =
(int)sizeof(xmlnsNamespace)/sizeof(XML_Char) - 1;
XML_Bool mustBeXML = XML_FALSE;
XML_Bool isXML = XML_TRUE;
XML_Bool isXMLNS = XML_TRUE;
BINDING *b;
int len;
/* empty URI is only valid for default namespace per XML NS 1.0 (not 1.1) */
if (*uri == XML_T('\0') && prefix->name)
return XML_ERROR_UNDECLARING_PREFIX;
if (prefix->name
&& prefix->name[0] == XML_T(ASCII_x)
&& prefix->name[1] == XML_T(ASCII_m)
&& prefix->name[2] == XML_T(ASCII_l)) {
/* Not allowed to bind xmlns */
- /*if (prefix->name[3] == XML_T(ASCII_n)
+ if (prefix->name[3] == XML_T(ASCII_n)
&& prefix->name[4] == XML_T(ASCII_s)
&& prefix->name[5] == XML_T('\0'))
- return XML_ERROR_RESERVED_PREFIX_XMLNS;*/
+ return XML_ERROR_RESERVED_PREFIX_XMLNS;
if (prefix->name[3] == XML_T('\0'))
mustBeXML = XML_TRUE;
}
for (len = 0; uri[len]; len++) {
if (isXML && (len > xmlLen || uri[len] != xmlNamespace[len]))
isXML = XML_FALSE;
if (!mustBeXML && isXMLNS
&& (len > xmlnsLen || uri[len] != xmlnsNamespace[len]))
isXMLNS = XML_FALSE;
}
isXML = isXML && len == xmlLen;
isXMLNS = isXMLNS && len == xmlnsLen;
- /*if (mustBeXML != isXML)
+ if (mustBeXML != isXML)
return mustBeXML ? XML_ERROR_RESERVED_PREFIX_XML
- : XML_ERROR_RESERVED_NAMESPACE_URI;*/
+ : XML_ERROR_RESERVED_NAMESPACE_URI;
- /*if (isXMLNS)
- return XML_ERROR_RESERVED_NAMESPACE_URI;*/
+ if (isXMLNS)
+ return XML_ERROR_RESERVED_NAMESPACE_URI;
if (namespaceSeparator)
len++;
if (freeBindingList) {
b = freeBindingList;
if (len > b->uriAlloc) {
XML_Char *temp = (XML_Char *)REALLOC(b->uri,
sizeof(XML_Char) * (len + EXPAND_SPARE));
if (temp == NULL)
return XML_ERROR_NO_MEMORY;
b->uri = temp;
b->uriAlloc = len + EXPAND_SPARE;
}
freeBindingList = b->nextTagBinding;
}
else {
b = (BINDING *)MALLOC(sizeof(BINDING));
if (!b)
return XML_ERROR_NO_MEMORY;
b->uri = (XML_Char *)MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
if (!b->uri) {
FREE(b);
return XML_ERROR_NO_MEMORY;
}
b->uriAlloc = len + EXPAND_SPARE;
}
b->uriLen = len;
memcpy(b->uri, uri, len * sizeof(XML_Char));
if (namespaceSeparator)
b->uri[len - 1] = namespaceSeparator;
@@ -3223,65 +3563,65 @@ doCdataSection(XML_Parser parser,
if (endCdataSectionHandler)
endCdataSectionHandler(handlerArg);
#if 0
/* see comment under XML_TOK_CDATA_SECT_OPEN */
else if (characterDataHandler)
characterDataHandler(handlerArg, dataBuf, 0);
#endif
else if (defaultHandler)
reportDefault(parser, enc, s, next);
*startPtr = next;
*nextPtr = next;
if (ps_parsing == XML_FINISHED)
return XML_ERROR_ABORTED;
else
return XML_ERROR_NONE;
case XML_TOK_DATA_NEWLINE:
if (characterDataHandler) {
XML_Char c = 0xA;
characterDataHandler(handlerArg, &c, 1);
}
else if (defaultHandler)
reportDefault(parser, enc, s, next);
break;
case XML_TOK_DATA_CHARS:
{
XML_CharacterDataHandler charDataHandler = characterDataHandler;
if (charDataHandler) {
if (MUST_CONVERT(enc, s)) {
for (;;) {
ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+ const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
*eventEndPP = next;
charDataHandler(handlerArg, dataBuf,
(int)(dataPtr - (ICHAR *)dataBuf));
- if (s == next)
+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
break;
*eventPP = s;
}
}
else
charDataHandler(handlerArg,
(XML_Char *)s,
(int)((XML_Char *)next - (XML_Char *)s));
}
else if (defaultHandler)
reportDefault(parser, enc, s, next);
}
break;
case XML_TOK_INVALID:
*eventPP = next;
return XML_ERROR_INVALID_TOKEN;
case XML_TOK_PARTIAL_CHAR:
if (haveMore) {
*nextPtr = s;
return XML_ERROR_NONE;
}
return XML_ERROR_PARTIAL_CHAR;
case XML_TOK_PARTIAL:
case XML_TOK_NONE:
if (haveMore) {
*nextPtr = s;
return XML_ERROR_NONE;
}
return XML_ERROR_UNCLOSED_CDATA_SECTION;
default:
@@ -3619,60 +3959,68 @@ entityValueInitProcessor(XML_Parser parser,
}
else if (tok == XML_TOK_XML_DECL) {
enum XML_Error result;
result = processXmlDecl(parser, 0, start, next);
if (result != XML_ERROR_NONE)
return result;
switch (ps_parsing) {
case XML_SUSPENDED:
*nextPtr = next;
return XML_ERROR_NONE;
case XML_FINISHED:
return XML_ERROR_ABORTED;
default:
*nextPtr = next;
}
/* stop scanning for text declaration - we found one */
processor = entityValueProcessor;
return entityValueProcessor(parser, next, end, nextPtr);
}
/* If we are at the end of the buffer, this would cause XmlPrologTok to
return XML_TOK_NONE on the next call, which would then cause the
function to exit with *nextPtr set to s - that is what we want for other
tokens, but not for the BOM - we would rather like to skip it;
then, when this routine is entered the next time, XmlPrologTok will
return XML_TOK_INVALID, since the BOM is still in the buffer
*/
else if (tok == XML_TOK_BOM && next == end && !ps_finalBuffer) {
*nextPtr = next;
return XML_ERROR_NONE;
}
+ /* If we get this token, we have the start of what might be a
+ normal tag, but not a declaration (i.e. it doesn't begin with
+ "<!"). In a DTD context, that isn't legal.
+ */
+ else if (tok == XML_TOK_INSTANCE_START) {
+ *nextPtr = next;
+ return XML_ERROR_SYNTAX;
+ }
start = next;
eventPtr = start;
}
}
static enum XML_Error PTRCALL
externalParEntProcessor(XML_Parser parser,
const char *s,
const char *end,
const char **nextPtr)
{
const char *next = s;
int tok;
tok = XmlPrologTok(encoding, s, end, &next);
if (tok <= 0) {
if (!ps_finalBuffer && tok != XML_TOK_INVALID) {
*nextPtr = s;
return XML_ERROR_NONE;
}
switch (tok) {
case XML_TOK_INVALID:
return XML_ERROR_INVALID_TOKEN;
case XML_TOK_PARTIAL:
return XML_ERROR_UNCLOSED_TOKEN;
case XML_TOK_PARTIAL_CHAR:
return XML_ERROR_PARTIAL_CHAR;
case XML_TOK_NONE: /* start == end */
default:
break;
@@ -4795,154 +5143,158 @@ epilogProcessor(XML_Parser parser,
static enum XML_Error
processInternalEntity(XML_Parser parser, ENTITY *entity,
XML_Bool betweenDecl)
{
const char *textStart, *textEnd;
const char *next;
enum XML_Error result;
OPEN_INTERNAL_ENTITY *openEntity;
if (freeInternalEntities) {
openEntity = freeInternalEntities;
freeInternalEntities = openEntity->next;
}
else {
openEntity = (OPEN_INTERNAL_ENTITY *)MALLOC(sizeof(OPEN_INTERNAL_ENTITY));
if (!openEntity)
return XML_ERROR_NO_MEMORY;
}
entity->open = XML_TRUE;
entity->processed = 0;
openEntity->next = openInternalEntities;
openInternalEntities = openEntity;
openEntity->entity = entity;
openEntity->startTagLevel = tagLevel;
openEntity->betweenDecl = betweenDecl;
openEntity->internalEventPtr = NULL;
openEntity->internalEventEndPtr = NULL;
textStart = (char *)entity->textPtr;
textEnd = (char *)(entity->textPtr + entity->textLen);
+ /* Set a safe default value in case 'next' does not get set */
+ next = textStart;
#ifdef XML_DTD
if (entity->is_param) {
int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
next, &next, XML_FALSE);
}
else
#endif /* XML_DTD */
result = doContent(parser, tagLevel, internalEncoding, textStart,
textEnd, &next, XML_FALSE);
if (result == XML_ERROR_NONE) {
if (textEnd != next && ps_parsing == XML_SUSPENDED) {
entity->processed = (int)(next - textStart);
processor = internalEntityProcessor;
}
else {
entity->open = XML_FALSE;
openInternalEntities = openEntity->next;
/* put openEntity back in list of free instances */
openEntity->next = freeInternalEntities;
freeInternalEntities = openEntity;
}
}
return result;
}
static enum XML_Error PTRCALL
internalEntityProcessor(XML_Parser parser,
const char *s,
const char *end,
const char **nextPtr)
{
ENTITY *entity;
const char *textStart, *textEnd;
const char *next;
enum XML_Error result;
OPEN_INTERNAL_ENTITY *openEntity = openInternalEntities;
if (!openEntity)
return XML_ERROR_UNEXPECTED_STATE;
entity = openEntity->entity;
textStart = ((char *)entity->textPtr) + entity->processed;
textEnd = (char *)(entity->textPtr + entity->textLen);
+ /* Set a safe default value in case 'next' does not get set */
+ next = textStart;
#ifdef XML_DTD
if (entity->is_param) {
int tok = XmlPrologTok(internalEncoding, textStart, textEnd, &next);
result = doProlog(parser, internalEncoding, textStart, textEnd, tok,
next, &next, XML_FALSE);
}
else
#endif /* XML_DTD */
result = doContent(parser, openEntity->startTagLevel, internalEncoding,
textStart, textEnd, &next, XML_FALSE);
if (result != XML_ERROR_NONE)
return result;
else if (textEnd != next && ps_parsing == XML_SUSPENDED) {
entity->processed = (int)(next - (char *)entity->textPtr);
return result;
}
else {
entity->open = XML_FALSE;
openInternalEntities = openEntity->next;
/* put openEntity back in list of free instances */
openEntity->next = freeInternalEntities;
freeInternalEntities = openEntity;
}
#ifdef XML_DTD
if (entity->is_param) {
int tok;
processor = prologProcessor;
tok = XmlPrologTok(encoding, s, end, &next);
return doProlog(parser, encoding, s, end, tok, next, nextPtr,
(XML_Bool)!ps_finalBuffer);
}
else
#endif /* XML_DTD */
{
processor = contentProcessor;
/* see externalEntityContentProcessor vs contentProcessor */
return doContent(parser, parentParser ? 1 : 0, encoding, s, end,
nextPtr, (XML_Bool)!ps_finalBuffer);
}
}
static enum XML_Error PTRCALL
errorProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
+ const char *UNUSED_P(s),
+ const char *UNUSED_P(end),
+ const char **UNUSED_P(nextPtr))
{
return errorCode;
}
static enum XML_Error
storeAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
const char *ptr, const char *end,
STRING_POOL *pool)
{
enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr,
end, pool);
if (result)
return result;
if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
poolChop(pool);
if (!poolAppendChar(pool, XML_T('\0')))
return XML_ERROR_NO_MEMORY;
return XML_ERROR_NONE;
}
static enum XML_Error
appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
const char *ptr, const char *end,
STRING_POOL *pool)
{
DTD * const dtd = _dtd; /* save one level of indirection */
for (;;) {
const char *next;
int tok = XmlAttributeValueTok(enc, ptr, end, &next);
switch (tok) {
@@ -5304,77 +5656,78 @@ reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
return 1;
}
static int
reportComment(XML_Parser parser, const ENCODING *enc,
const char *start, const char *end)
{
XML_Char *data;
if (!commentHandler) {
if (defaultHandler)
reportDefault(parser, enc, start, end);
return 1;
}
data = poolStoreString(&tempPool,
enc,
start + enc->minBytesPerChar * 4,
end - enc->minBytesPerChar * 3);
if (!data)
return 0;
normalizeLines(data);
commentHandler(handlerArg, data);
poolClear(&tempPool);
return 1;
}
static void
reportDefault(XML_Parser parser, const ENCODING *enc,
const char *s, const char *end)
{
if (MUST_CONVERT(enc, s)) {
+ enum XML_Convert_Result convert_res;
const char **eventPP;
const char **eventEndPP;
if (enc == encoding) {
eventPP = &eventPtr;
eventEndPP = &eventEndPtr;
}
else {
eventPP = &(openInternalEntities->internalEventPtr);
eventEndPP = &(openInternalEntities->internalEventEndPtr);
}
do {
ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+ convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
*eventEndPP = s;
defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf));
*eventPP = s;
- } while (s != end);
+ } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE));
}
else
defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s));
}
static int
defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
XML_Bool isId, const XML_Char *value, XML_Parser parser)
{
DEFAULT_ATTRIBUTE *att;
if (value || isId) {
/* The handling of default attributes gets messed up if we have
a default which duplicates a non-default. */
int i;
for (i = 0; i < type->nDefaultAtts; i++)
if (attId == type->defaultAtts[i].id)
return 1;
if (isId && !type->idAtt && !attId->xmlns)
type->idAtt = attId;
}
if (type->nDefaultAtts == type->allocDefaultAtts) {
if (type->allocDefaultAtts == 0) {
type->allocDefaultAtts = 8;
type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
* sizeof(DEFAULT_ATTRIBUTE));
if (!type->defaultAtts)
return 0;
}
else {
@@ -5450,60 +5803,62 @@ getAttributeId(XML_Parser parser, const ENCODING *enc,
else {
poolFinish(&dtd->pool);
if (!ns)
;
else if (name[0] == XML_T(ASCII_x)
&& name[1] == XML_T(ASCII_m)
&& name[2] == XML_T(ASCII_l)
&& name[3] == XML_T(ASCII_n)
&& name[4] == XML_T(ASCII_s)
&& (name[5] == XML_T('\0') || name[5] == XML_T(ASCII_COLON))) {
if (name[5] == XML_T('\0'))
id->prefix = &dtd->defaultPrefix;
else
id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, name + 6, sizeof(PREFIX));
id->xmlns = XML_TRUE;
}
else {
int i;
for (i = 0; name[i]; i++) {
/* attributes without prefix are *not* in the default namespace */
if (name[i] == XML_T(ASCII_COLON)) {
int j;
for (j = 0; j < i; j++) {
if (!poolAppendChar(&dtd->pool, name[j]))
return NULL;
}
if (!poolAppendChar(&dtd->pool, XML_T('\0')))
return NULL;
id->prefix = (PREFIX *)lookup(parser, &dtd->prefixes, poolStart(&dtd->pool),
sizeof(PREFIX));
+ if (!id->prefix)
+ return NULL;
if (id->prefix->name == poolStart(&dtd->pool))
poolFinish(&dtd->pool);
else
poolDiscard(&dtd->pool);
break;
}
}
}
}
return id;
}
#define CONTEXT_SEP XML_T(ASCII_FF)
static const XML_Char *
getContext(XML_Parser parser)
{
DTD * const dtd = _dtd; /* save one level of indirection */
HASH_TABLE_ITER iter;
XML_Bool needSep = XML_FALSE;
if (dtd->defaultPrefix.binding) {
int i;
int len;
if (!poolAppendChar(&tempPool, XML_T(ASCII_EQUALS)))
return NULL;
len = dtd->defaultPrefix.binding->uriLen;
if (namespaceSeparator)
len--;
for (i = 0; i < len; i++)
@@ -5797,61 +6152,60 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H
if (oldA->prefix == &oldDtd->defaultPrefix)
newA->prefix = &newDtd->defaultPrefix;
else
newA->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
oldA->prefix->name, 0);
}
}
/* Copy the element type table. */
hashTableIterInit(&iter, &(oldDtd->elementTypes));
for (;;) {
int i;
ELEMENT_TYPE *newE;
const XML_Char *name;
const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
if (!oldE)
break;
name = poolCopyString(&(newDtd->pool), oldE->name);
if (!name)
return 0;
newE = (ELEMENT_TYPE *)lookup(oldParser, &(newDtd->elementTypes), name,
sizeof(ELEMENT_TYPE));
if (!newE)
return 0;
if (oldE->nDefaultAtts) {
newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
if (!newE->defaultAtts) {
- ms->free_fcn(newE);
return 0;
}
}
if (oldE->idAtt)
newE->idAtt = (ATTRIBUTE_ID *)
lookup(oldParser, &(newDtd->attributeIds), oldE->idAtt->name, 0);
newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
if (oldE->prefix)
newE->prefix = (PREFIX *)lookup(oldParser, &(newDtd->prefixes),
oldE->prefix->name, 0);
for (i = 0; i < newE->nDefaultAtts; i++) {
newE->defaultAtts[i].id = (ATTRIBUTE_ID *)
lookup(oldParser, &(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
if (oldE->defaultAtts[i].value) {
newE->defaultAtts[i].value
= poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
if (!newE->defaultAtts[i].value)
return 0;
}
else
newE->defaultAtts[i].value = NULL;
}
}
/* Copy the entity tables. */
if (!copyEntityTable(oldParser,
&(newDtd->generalEntities),
&(newDtd->pool),
&(oldDtd->generalEntities)))
@@ -5932,67 +6286,86 @@ copyEntityTable(XML_Parser oldParser,
const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
oldE->textLen);
if (!tem)
return 0;
newE->textPtr = tem;
newE->textLen = oldE->textLen;
}
if (oldE->notation) {
const XML_Char *tem = poolCopyString(newPool, oldE->notation);
if (!tem)
return 0;
newE->notation = tem;
}
newE->is_param = oldE->is_param;
newE->is_internal = oldE->is_internal;
}
return 1;
}
#define INIT_POWER 6
static XML_Bool FASTCALL
keyeq(KEY s1, KEY s2)
{
for (; *s1 == *s2; s1++, s2++)
if (*s1 == 0)
return XML_TRUE;
return XML_FALSE;
}
+static size_t
+keylen(KEY s)
+{
+ size_t len = 0;
+ for (; *s; s++, len++);
+ return len;
+}
+
+static void
+copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key)
+{
+ key->k[0] = 0;
+ key->k[1] = get_hash_secret_salt(parser);
+}
+
static unsigned long FASTCALL
hash(XML_Parser parser, KEY s)
{
- unsigned long h = hash_secret_salt;
- while (*s)
- h = CHAR_HASH(h, *s++);
- return h;
+ struct siphash state;
+ struct sipkey key;
+ (void)sip_tobin;
+ (void)sip24_valid;
+ copy_salt_to_sipkey(parser, &key);
+ sip24_init(&state, &key);
+ sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
+ return (unsigned long)sip24_final(&state);
}
static NAMED *
lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize)
{
size_t i;
if (table->size == 0) {
size_t tsize;
if (!createSize)
return NULL;
table->power = INIT_POWER;
/* table->size is a power of 2 */
table->size = (size_t)1 << INIT_POWER;
tsize = table->size * sizeof(NAMED *);
table->v = (NAMED **)table->mem->malloc_fcn(tsize);
if (!table->v) {
table->size = 0;
return NULL;
}
memset(table->v, 0, tsize);
i = hash(parser, name) & ((unsigned long)table->size - 1);
}
else {
unsigned long h = hash(parser, name);
unsigned long mask = (unsigned long)table->size - 1;
unsigned char step = 0;
i = h & mask;
while (table->v[i]) {
if (keyeq(name, table->v[i]->name))
return table->v[i];
@@ -6123,167 +6496,218 @@ poolClear(STRING_POOL *pool)
pool->blocks = NULL;
pool->start = NULL;
pool->ptr = NULL;
pool->end = NULL;
}
static void FASTCALL
poolDestroy(STRING_POOL *pool)
{
BLOCK *p = pool->blocks;
while (p) {
BLOCK *tem = p->next;
pool->mem->free_fcn(p);
p = tem;
}
p = pool->freeBlocks;
while (p) {
BLOCK *tem = p->next;
pool->mem->free_fcn(p);
p = tem;
}
}
static XML_Char *
poolAppend(STRING_POOL *pool, const ENCODING *enc,
const char *ptr, const char *end)
{
if (!pool->ptr && !poolGrow(pool))
return NULL;
for (;;) {
- XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
- if (ptr == end)
+ const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
+ if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE))
break;
if (!poolGrow(pool))
return NULL;
}
return pool->start;
}
static const XML_Char * FASTCALL
poolCopyString(STRING_POOL *pool, const XML_Char *s)
{
do {
if (!poolAppendChar(pool, *s))
return NULL;
} while (*s++);
s = pool->start;
poolFinish(pool);
return s;
}
static const XML_Char *
poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
{
if (!pool->ptr && !poolGrow(pool))
return NULL;
for (; n > 0; --n, s++) {
if (!poolAppendChar(pool, *s))
return NULL;
}
s = pool->start;
poolFinish(pool);
return s;
}
static const XML_Char * FASTCALL
poolAppendString(STRING_POOL *pool, const XML_Char *s)
{
while (*s) {
if (!poolAppendChar(pool, *s))
return NULL;
s++;
}
return pool->start;
}
static XML_Char *
poolStoreString(STRING_POOL *pool, const ENCODING *enc,
const char *ptr, const char *end)
{
if (!poolAppend(pool, enc, ptr, end))
return NULL;
if (pool->ptr == pool->end && !poolGrow(pool))
return NULL;
*(pool->ptr)++ = 0;
return pool->start;
}
+static size_t
+poolBytesToAllocateFor(int blockSize)
+{
+ /* Unprotected math would be:
+ ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
+ **
+ ** Detect overflow, avoiding _signed_ overflow undefined behavior
+ ** For a + b * c we check b * c in isolation first, so that addition of a
+ ** on top has no chance of making us accept a small non-negative number
+ */
+ const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */
+
+ if (blockSize <= 0)
+ return 0;
+
+ if (blockSize > (int)(INT_MAX / stretch))
+ return 0;
+
+ {
+ const int stretchedBlockSize = blockSize * (int)stretch;
+ const int bytesToAllocate = (int)(
+ offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
+ if (bytesToAllocate < 0)
+ return 0;
+
+ return (size_t)bytesToAllocate;
+ }
+}
+
static XML_Bool FASTCALL
poolGrow(STRING_POOL *pool)
{
if (pool->freeBlocks) {
if (pool->start == 0) {
pool->blocks = pool->freeBlocks;
pool->freeBlocks = pool->freeBlocks->next;
pool->blocks->next = NULL;
pool->start = pool->blocks->s;
pool->end = pool->start + pool->blocks->size;
pool->ptr = pool->start;
return XML_TRUE;
}
if (pool->end - pool->start < pool->freeBlocks->size) {
BLOCK *tem = pool->freeBlocks->next;
pool->freeBlocks->next = pool->blocks;
pool->blocks = pool->freeBlocks;
pool->freeBlocks = tem;
memcpy(pool->blocks->s, pool->start,
(pool->end - pool->start) * sizeof(XML_Char));
pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
pool->start = pool->blocks->s;
pool->end = pool->start + pool->blocks->size;
return XML_TRUE;
}
}
if (pool->blocks && pool->start == pool->blocks->s) {
- int blockSize = (int)(pool->end - pool->start)*2;
- BLOCK *temp = (BLOCK *)
- pool->mem->realloc_fcn(pool->blocks,
- (offsetof(BLOCK, s)
- + blockSize * sizeof(XML_Char)));
+ BLOCK *temp;
+ int blockSize = (int)((unsigned)(pool->end - pool->start)*2U);
+ size_t bytesToAllocate;
+
+ if (blockSize < 0)
+ return XML_FALSE;
+
+ bytesToAllocate = poolBytesToAllocateFor(blockSize);
+ if (bytesToAllocate == 0)
+ return XML_FALSE;
+
+ temp = (BLOCK *)
+ pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate);
if (temp == NULL)
return XML_FALSE;
pool->blocks = temp;
pool->blocks->size = blockSize;
pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
pool->start = pool->blocks->s;
pool->end = pool->start + blockSize;
}
else {
BLOCK *tem;
int blockSize = (int)(pool->end - pool->start);
+ size_t bytesToAllocate;
+
+ if (blockSize < 0)
+ return XML_FALSE;
+
if (blockSize < INIT_BLOCK_SIZE)
blockSize = INIT_BLOCK_SIZE;
- else
+ else {
+ /* Detect overflow, avoiding _signed_ overflow undefined behavior */
+ if ((int)((unsigned)blockSize * 2U) < 0) {
+ return XML_FALSE;
+ }
blockSize *= 2;
- tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
- + blockSize * sizeof(XML_Char));
+ }
+
+ bytesToAllocate = poolBytesToAllocateFor(blockSize);
+ if (bytesToAllocate == 0)
+ return XML_FALSE;
+
+ tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);
if (!tem)
return XML_FALSE;
tem->size = blockSize;
tem->next = pool->blocks;
pool->blocks = tem;
if (pool->ptr != pool->start)
memcpy(tem->s, pool->start,
(pool->ptr - pool->start) * sizeof(XML_Char));
pool->ptr = tem->s + (pool->ptr - pool->start);
pool->start = tem->s;
pool->end = tem->s + blockSize;
}
return XML_TRUE;
}
static int FASTCALL
nextScaffoldPart(XML_Parser parser)
{
DTD * const dtd = _dtd; /* save one level of indirection */
CONTENT_SCAFFOLD * me;
int next;
if (!dtd->scaffIndex) {
dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
if (!dtd->scaffIndex)
return -1;
dtd->scaffIndex[0] = 0;
}
if (dtd->scaffCount >= dtd->scaffSize) {
diff --git a/3rdParty/Expat/src/xmlrole.c b/3rdParty/Expat/src/xmlrole.c
index 44772e2..a7c5630 100644
--- a/3rdParty/Expat/src/xmlrole.c
+++ b/3rdParty/Expat/src/xmlrole.c
@@ -1,49 +1,43 @@
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file COPYING for copying permission.
*/
#include <stddef.h>
-#ifdef COMPILED_FROM_DSP
+#ifdef _WIN32
#include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-#elif defined(__amigaos__)
-#include "amigaconfig.h"
-#elif defined(__WATCOMC__)
-#include "watcomconfig.h"
#else
#ifdef HAVE_EXPAT_CONFIG_H
#include <expat_config.h>
#endif
-#endif /* ndef COMPILED_FROM_DSP */
+#endif /* ndef _WIN32 */
#include "expat_external.h"
#include "internal.h"
#include "xmlrole.h"
#include "ascii.h"
/* Doesn't check:
that ,| are not mixed in a model group
content of literals
*/
static const char KW_ANY[] = {
ASCII_A, ASCII_N, ASCII_Y, '\0' };
static const char KW_ATTLIST[] = {
ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' };
static const char KW_CDATA[] = {
ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
static const char KW_DOCTYPE[] = {
ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' };
static const char KW_ELEMENT[] = {
ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' };
static const char KW_EMPTY[] = {
ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' };
static const char KW_ENTITIES[] = {
ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S,
'\0' };
static const char KW_ENTITY[] = {
ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
@@ -168,186 +162,186 @@ prolog1(PROLOG_STATE *state,
const char *end,
const ENCODING *enc)
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NONE;
case XML_TOK_PI:
return XML_ROLE_PI;
case XML_TOK_COMMENT:
return XML_ROLE_COMMENT;
case XML_TOK_BOM:
return XML_ROLE_NONE;
case XML_TOK_DECL_OPEN:
if (!XmlNameMatchesAscii(enc,
ptr + 2 * MIN_BYTES_PER_CHAR(enc),
end,
KW_DOCTYPE))
break;
state->handler = doctype0;
return XML_ROLE_DOCTYPE_NONE;
case XML_TOK_INSTANCE_START:
state->handler = error;
return XML_ROLE_INSTANCE_START;
}
return common(state, tok);
}
static int PTRCALL
prolog2(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NONE;
case XML_TOK_PI:
return XML_ROLE_PI;
case XML_TOK_COMMENT:
return XML_ROLE_COMMENT;
case XML_TOK_INSTANCE_START:
state->handler = error;
return XML_ROLE_INSTANCE_START;
}
return common(state, tok);
}
static int PTRCALL
doctype0(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_DOCTYPE_NONE;
case XML_TOK_NAME:
case XML_TOK_PREFIXED_NAME:
state->handler = doctype1;
return XML_ROLE_DOCTYPE_NAME;
}
return common(state, tok);
}
static int PTRCALL
doctype1(PROLOG_STATE *state,
int tok,
const char *ptr,
const char *end,
const ENCODING *enc)
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_DOCTYPE_NONE;
case XML_TOK_OPEN_BRACKET:
state->handler = internalSubset;
return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
case XML_TOK_DECL_CLOSE:
state->handler = prolog2;
return XML_ROLE_DOCTYPE_CLOSE;
case XML_TOK_NAME:
if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
state->handler = doctype3;
return XML_ROLE_DOCTYPE_NONE;
}
if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
state->handler = doctype2;
return XML_ROLE_DOCTYPE_NONE;
}
break;
}
return common(state, tok);
}
static int PTRCALL
doctype2(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_DOCTYPE_NONE;
case XML_TOK_LITERAL:
state->handler = doctype3;
return XML_ROLE_DOCTYPE_PUBLIC_ID;
}
return common(state, tok);
}
static int PTRCALL
doctype3(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_DOCTYPE_NONE;
case XML_TOK_LITERAL:
state->handler = doctype4;
return XML_ROLE_DOCTYPE_SYSTEM_ID;
}
return common(state, tok);
}
static int PTRCALL
doctype4(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_DOCTYPE_NONE;
case XML_TOK_OPEN_BRACKET:
state->handler = internalSubset;
return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
case XML_TOK_DECL_CLOSE:
state->handler = prolog2;
return XML_ROLE_DOCTYPE_CLOSE;
}
return common(state, tok);
}
static int PTRCALL
doctype5(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_DOCTYPE_NONE;
case XML_TOK_DECL_CLOSE:
state->handler = prolog2;
return XML_ROLE_DOCTYPE_CLOSE;
}
return common(state, tok);
}
static int PTRCALL
internalSubset(PROLOG_STATE *state,
int tok,
const char *ptr,
const char *end,
const ENCODING *enc)
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NONE;
case XML_TOK_DECL_OPEN:
if (XmlNameMatchesAscii(enc,
ptr + 2 * MIN_BYTES_PER_CHAR(enc),
end,
KW_ENTITY)) {
state->handler = entity0;
return XML_ROLE_ENTITY_NONE;
}
if (XmlNameMatchesAscii(enc,
@@ -410,610 +404,610 @@ externalSubset1(PROLOG_STATE *state,
const ENCODING *enc)
{
switch (tok) {
case XML_TOK_COND_SECT_OPEN:
state->handler = condSect0;
return XML_ROLE_NONE;
case XML_TOK_COND_SECT_CLOSE:
if (state->includeLevel == 0)
break;
state->includeLevel -= 1;
return XML_ROLE_NONE;
case XML_TOK_PROLOG_S:
return XML_ROLE_NONE;
case XML_TOK_CLOSE_BRACKET:
break;
case XML_TOK_NONE:
if (state->includeLevel)
break;
return XML_ROLE_NONE;
default:
return internalSubset(state, tok, ptr, end, enc);
}
return common(state, tok);
}
#endif /* XML_DTD */
static int PTRCALL
entity0(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
case XML_TOK_PERCENT:
state->handler = entity1;
return XML_ROLE_ENTITY_NONE;
case XML_TOK_NAME:
state->handler = entity2;
return XML_ROLE_GENERAL_ENTITY_NAME;
}
return common(state, tok);
}
static int PTRCALL
entity1(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
case XML_TOK_NAME:
state->handler = entity7;
return XML_ROLE_PARAM_ENTITY_NAME;
}
return common(state, tok);
}
static int PTRCALL
entity2(PROLOG_STATE *state,
int tok,
const char *ptr,
const char *end,
const ENCODING *enc)
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
case XML_TOK_NAME:
if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
state->handler = entity4;
return XML_ROLE_ENTITY_NONE;
}
if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
state->handler = entity3;
return XML_ROLE_ENTITY_NONE;
}
break;
case XML_TOK_LITERAL:
state->handler = declClose;
state->role_none = XML_ROLE_ENTITY_NONE;
return XML_ROLE_ENTITY_VALUE;
}
return common(state, tok);
}
static int PTRCALL
entity3(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
case XML_TOK_LITERAL:
state->handler = entity4;
return XML_ROLE_ENTITY_PUBLIC_ID;
}
return common(state, tok);
}
static int PTRCALL
entity4(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
case XML_TOK_LITERAL:
state->handler = entity5;
return XML_ROLE_ENTITY_SYSTEM_ID;
}
return common(state, tok);
}
static int PTRCALL
entity5(PROLOG_STATE *state,
int tok,
const char *ptr,
const char *end,
const ENCODING *enc)
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
case XML_TOK_DECL_CLOSE:
setTopLevel(state);
return XML_ROLE_ENTITY_COMPLETE;
case XML_TOK_NAME:
if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) {
state->handler = entity6;
return XML_ROLE_ENTITY_NONE;
}
break;
}
return common(state, tok);
}
static int PTRCALL
entity6(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
case XML_TOK_NAME:
state->handler = declClose;
state->role_none = XML_ROLE_ENTITY_NONE;
return XML_ROLE_ENTITY_NOTATION_NAME;
}
return common(state, tok);
}
static int PTRCALL
entity7(PROLOG_STATE *state,
int tok,
const char *ptr,
const char *end,
const ENCODING *enc)
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
case XML_TOK_NAME:
if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
state->handler = entity9;
return XML_ROLE_ENTITY_NONE;
}
if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
state->handler = entity8;
return XML_ROLE_ENTITY_NONE;
}
break;
case XML_TOK_LITERAL:
state->handler = declClose;
state->role_none = XML_ROLE_ENTITY_NONE;
return XML_ROLE_ENTITY_VALUE;
}
return common(state, tok);
}
static int PTRCALL
entity8(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
case XML_TOK_LITERAL:
state->handler = entity9;
return XML_ROLE_ENTITY_PUBLIC_ID;
}
return common(state, tok);
}
static int PTRCALL
entity9(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
case XML_TOK_LITERAL:
state->handler = entity10;
return XML_ROLE_ENTITY_SYSTEM_ID;
}
return common(state, tok);
}
static int PTRCALL
entity10(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ENTITY_NONE;
case XML_TOK_DECL_CLOSE:
setTopLevel(state);
return XML_ROLE_ENTITY_COMPLETE;
}
return common(state, tok);
}
static int PTRCALL
notation0(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NOTATION_NONE;
case XML_TOK_NAME:
state->handler = notation1;
return XML_ROLE_NOTATION_NAME;
}
return common(state, tok);
}
static int PTRCALL
notation1(PROLOG_STATE *state,
int tok,
const char *ptr,
const char *end,
const ENCODING *enc)
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NOTATION_NONE;
case XML_TOK_NAME:
if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
state->handler = notation3;
return XML_ROLE_NOTATION_NONE;
}
if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
state->handler = notation2;
return XML_ROLE_NOTATION_NONE;
}
break;
}
return common(state, tok);
}
static int PTRCALL
notation2(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NOTATION_NONE;
case XML_TOK_LITERAL:
state->handler = notation4;
return XML_ROLE_NOTATION_PUBLIC_ID;
}
return common(state, tok);
}
static int PTRCALL
notation3(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NOTATION_NONE;
case XML_TOK_LITERAL:
state->handler = declClose;
state->role_none = XML_ROLE_NOTATION_NONE;
return XML_ROLE_NOTATION_SYSTEM_ID;
}
return common(state, tok);
}
static int PTRCALL
notation4(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NOTATION_NONE;
case XML_TOK_LITERAL:
state->handler = declClose;
state->role_none = XML_ROLE_NOTATION_NONE;
return XML_ROLE_NOTATION_SYSTEM_ID;
case XML_TOK_DECL_CLOSE:
setTopLevel(state);
return XML_ROLE_NOTATION_NO_SYSTEM_ID;
}
return common(state, tok);
}
static int PTRCALL
attlist0(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
case XML_TOK_NAME:
case XML_TOK_PREFIXED_NAME:
state->handler = attlist1;
return XML_ROLE_ATTLIST_ELEMENT_NAME;
}
return common(state, tok);
}
static int PTRCALL
attlist1(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
case XML_TOK_DECL_CLOSE:
setTopLevel(state);
return XML_ROLE_ATTLIST_NONE;
case XML_TOK_NAME:
case XML_TOK_PREFIXED_NAME:
state->handler = attlist2;
return XML_ROLE_ATTRIBUTE_NAME;
}
return common(state, tok);
}
static int PTRCALL
attlist2(PROLOG_STATE *state,
int tok,
const char *ptr,
const char *end,
const ENCODING *enc)
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
case XML_TOK_NAME:
{
static const char * const types[] = {
KW_CDATA,
KW_ID,
KW_IDREF,
KW_IDREFS,
KW_ENTITY,
KW_ENTITIES,
KW_NMTOKEN,
KW_NMTOKENS,
};
int i;
for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)
if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
state->handler = attlist8;
return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
}
}
if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) {
state->handler = attlist5;
return XML_ROLE_ATTLIST_NONE;
}
break;
case XML_TOK_OPEN_PAREN:
state->handler = attlist3;
return XML_ROLE_ATTLIST_NONE;
}
return common(state, tok);
}
static int PTRCALL
attlist3(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
case XML_TOK_NMTOKEN:
case XML_TOK_NAME:
case XML_TOK_PREFIXED_NAME:
state->handler = attlist4;
return XML_ROLE_ATTRIBUTE_ENUM_VALUE;
}
return common(state, tok);
}
static int PTRCALL
attlist4(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
case XML_TOK_CLOSE_PAREN:
state->handler = attlist8;
return XML_ROLE_ATTLIST_NONE;
case XML_TOK_OR:
state->handler = attlist3;
return XML_ROLE_ATTLIST_NONE;
}
return common(state, tok);
}
static int PTRCALL
attlist5(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
case XML_TOK_OPEN_PAREN:
state->handler = attlist6;
return XML_ROLE_ATTLIST_NONE;
}
return common(state, tok);
}
static int PTRCALL
attlist6(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
case XML_TOK_NAME:
state->handler = attlist7;
return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
}
return common(state, tok);
}
static int PTRCALL
attlist7(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
case XML_TOK_CLOSE_PAREN:
state->handler = attlist8;
return XML_ROLE_ATTLIST_NONE;
case XML_TOK_OR:
state->handler = attlist6;
return XML_ROLE_ATTLIST_NONE;
}
return common(state, tok);
}
/* default value */
static int PTRCALL
attlist8(PROLOG_STATE *state,
int tok,
const char *ptr,
const char *end,
const ENCODING *enc)
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
case XML_TOK_POUND_NAME:
if (XmlNameMatchesAscii(enc,
ptr + MIN_BYTES_PER_CHAR(enc),
end,
KW_IMPLIED)) {
state->handler = attlist1;
return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
}
if (XmlNameMatchesAscii(enc,
ptr + MIN_BYTES_PER_CHAR(enc),
end,
KW_REQUIRED)) {
state->handler = attlist1;
return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
}
if (XmlNameMatchesAscii(enc,
ptr + MIN_BYTES_PER_CHAR(enc),
end,
KW_FIXED)) {
state->handler = attlist9;
return XML_ROLE_ATTLIST_NONE;
}
break;
case XML_TOK_LITERAL:
state->handler = attlist1;
return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE;
}
return common(state, tok);
}
static int PTRCALL
attlist9(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ATTLIST_NONE;
case XML_TOK_LITERAL:
state->handler = attlist1;
return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
}
return common(state, tok);
}
static int PTRCALL
element0(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ELEMENT_NONE;
case XML_TOK_NAME:
case XML_TOK_PREFIXED_NAME:
state->handler = element1;
return XML_ROLE_ELEMENT_NAME;
}
return common(state, tok);
}
static int PTRCALL
element1(PROLOG_STATE *state,
int tok,
const char *ptr,
const char *end,
const ENCODING *enc)
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ELEMENT_NONE;
case XML_TOK_NAME:
if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) {
state->handler = declClose;
state->role_none = XML_ROLE_ELEMENT_NONE;
return XML_ROLE_CONTENT_EMPTY;
}
if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) {
state->handler = declClose;
@@ -1045,157 +1039,157 @@ element2(PROLOG_STATE *state,
end,
KW_PCDATA)) {
state->handler = element3;
return XML_ROLE_CONTENT_PCDATA;
}
break;
case XML_TOK_OPEN_PAREN:
state->level = 2;
state->handler = element6;
return XML_ROLE_GROUP_OPEN;
case XML_TOK_NAME:
case XML_TOK_PREFIXED_NAME:
state->handler = element7;
return XML_ROLE_CONTENT_ELEMENT;
case XML_TOK_NAME_QUESTION:
state->handler = element7;
return XML_ROLE_CONTENT_ELEMENT_OPT;
case XML_TOK_NAME_ASTERISK:
state->handler = element7;
return XML_ROLE_CONTENT_ELEMENT_REP;
case XML_TOK_NAME_PLUS:
state->handler = element7;
return XML_ROLE_CONTENT_ELEMENT_PLUS;
}
return common(state, tok);
}
static int PTRCALL
element3(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ELEMENT_NONE;
case XML_TOK_CLOSE_PAREN:
state->handler = declClose;
state->role_none = XML_ROLE_ELEMENT_NONE;
return XML_ROLE_GROUP_CLOSE;
case XML_TOK_CLOSE_PAREN_ASTERISK:
state->handler = declClose;
state->role_none = XML_ROLE_ELEMENT_NONE;
return XML_ROLE_GROUP_CLOSE_REP;
case XML_TOK_OR:
state->handler = element4;
return XML_ROLE_ELEMENT_NONE;
}
return common(state, tok);
}
static int PTRCALL
element4(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ELEMENT_NONE;
case XML_TOK_NAME:
case XML_TOK_PREFIXED_NAME:
state->handler = element5;
return XML_ROLE_CONTENT_ELEMENT;
}
return common(state, tok);
}
static int PTRCALL
element5(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ELEMENT_NONE;
case XML_TOK_CLOSE_PAREN_ASTERISK:
state->handler = declClose;
state->role_none = XML_ROLE_ELEMENT_NONE;
return XML_ROLE_GROUP_CLOSE_REP;
case XML_TOK_OR:
state->handler = element4;
return XML_ROLE_ELEMENT_NONE;
}
return common(state, tok);
}
static int PTRCALL
element6(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ELEMENT_NONE;
case XML_TOK_OPEN_PAREN:
state->level += 1;
return XML_ROLE_GROUP_OPEN;
case XML_TOK_NAME:
case XML_TOK_PREFIXED_NAME:
state->handler = element7;
return XML_ROLE_CONTENT_ELEMENT;
case XML_TOK_NAME_QUESTION:
state->handler = element7;
return XML_ROLE_CONTENT_ELEMENT_OPT;
case XML_TOK_NAME_ASTERISK:
state->handler = element7;
return XML_ROLE_CONTENT_ELEMENT_REP;
case XML_TOK_NAME_PLUS:
state->handler = element7;
return XML_ROLE_CONTENT_ELEMENT_PLUS;
}
return common(state, tok);
}
static int PTRCALL
element7(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_ELEMENT_NONE;
case XML_TOK_CLOSE_PAREN:
state->level -= 1;
if (state->level == 0) {
state->handler = declClose;
state->role_none = XML_ROLE_ELEMENT_NONE;
}
return XML_ROLE_GROUP_CLOSE;
case XML_TOK_CLOSE_PAREN_ASTERISK:
state->level -= 1;
if (state->level == 0) {
state->handler = declClose;
state->role_none = XML_ROLE_ELEMENT_NONE;
}
return XML_ROLE_GROUP_CLOSE_REP;
case XML_TOK_CLOSE_PAREN_QUESTION:
state->level -= 1;
if (state->level == 0) {
state->handler = declClose;
state->role_none = XML_ROLE_ELEMENT_NONE;
}
return XML_ROLE_GROUP_CLOSE_OPT;
case XML_TOK_CLOSE_PAREN_PLUS:
state->level -= 1;
if (state->level == 0) {
state->handler = declClose;
state->role_none = XML_ROLE_ELEMENT_NONE;
@@ -1213,117 +1207,117 @@ element7(PROLOG_STATE *state,
#ifdef XML_DTD
static int PTRCALL
condSect0(PROLOG_STATE *state,
int tok,
const char *ptr,
const char *end,
const ENCODING *enc)
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NONE;
case XML_TOK_NAME:
if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) {
state->handler = condSect1;
return XML_ROLE_NONE;
}
if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) {
state->handler = condSect2;
return XML_ROLE_NONE;
}
break;
}
return common(state, tok);
}
static int PTRCALL
condSect1(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NONE;
case XML_TOK_OPEN_BRACKET:
state->handler = externalSubset1;
state->includeLevel += 1;
return XML_ROLE_NONE;
}
return common(state, tok);
}
static int PTRCALL
condSect2(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return XML_ROLE_NONE;
case XML_TOK_OPEN_BRACKET:
state->handler = externalSubset1;
return XML_ROLE_IGNORE_SECT;
}
return common(state, tok);
}
#endif /* XML_DTD */
static int PTRCALL
declClose(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
return state->role_none;
case XML_TOK_DECL_CLOSE:
setTopLevel(state);
return state->role_none;
}
return common(state, tok);
}
static int PTRCALL
-error(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+error(PROLOG_STATE *UNUSED_P(state),
+ int UNUSED_P(tok),
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
return XML_ROLE_NONE;
}
static int FASTCALL
common(PROLOG_STATE *state, int tok)
{
#ifdef XML_DTD
if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
return XML_ROLE_INNER_PARAM_ENTITY_REF;
#endif
state->handler = error;
return XML_ROLE_ERROR;
}
void
XmlPrologStateInit(PROLOG_STATE *state)
{
state->handler = prolog0;
#ifdef XML_DTD
state->documentEntity = 1;
state->includeLevel = 0;
state->inEntityValue = 0;
#endif /* XML_DTD */
}
#ifdef XML_DTD
void
XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
diff --git a/3rdParty/Expat/src/xmltok.c b/3rdParty/Expat/src/xmltok.c
index bf09dfc..cdf0720 100644
--- a/3rdParty/Expat/src/xmltok.c
+++ b/3rdParty/Expat/src/xmltok.c
@@ -1,254 +1,259 @@
/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
See the file COPYING for copying permission.
*/
#include <stddef.h>
-#ifdef COMPILED_FROM_DSP
+#ifdef _WIN32
#include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-#elif defined(__amigaos__)
-#include "amigaconfig.h"
-#elif defined(__WATCOMC__)
-#include "watcomconfig.h"
#else
#ifdef HAVE_EXPAT_CONFIG_H
#include <expat_config.h>
#endif
-#endif /* ndef COMPILED_FROM_DSP */
+#endif /* ndef _WIN32 */
#include "expat_external.h"
#include "internal.h"
#include "xmltok.h"
#include "nametab.h"
#ifdef XML_DTD
#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
#else
#define IGNORE_SECTION_TOK_VTABLE /* as nothing */
#endif
#define VTABLE1 \
{ PREFIX(prologTok), PREFIX(contentTok), \
PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \
{ PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \
PREFIX(sameName), \
PREFIX(nameMatchesAscii), \
PREFIX(nameLength), \
PREFIX(skipS), \
PREFIX(getAtts), \
PREFIX(charRefNumber), \
PREFIX(predefinedEntityName), \
PREFIX(updatePosition), \
PREFIX(isPublicId)
#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
#define UCS2_GET_NAMING(pages, hi, lo) \
- (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
+ (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F)))
/* A 2 byte UTF-8 representation splits the characters 11 bits between
the bottom 5 and 6 bits of the bytes. We need 8 bits to index into
pages, 3 bits to add to that index and 5 bits to generate the mask.
*/
#define UTF8_GET_NAMING2(pages, byte) \
(namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
+ ((((byte)[0]) & 3) << 1) \
+ ((((byte)[1]) >> 5) & 1)] \
- & (1 << (((byte)[1]) & 0x1F)))
+ & (1u << (((byte)[1]) & 0x1F)))
/* A 3 byte UTF-8 representation splits the characters 16 bits between
the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index
into pages, 3 bits to add to that index and 5 bits to generate the
mask.
*/
#define UTF8_GET_NAMING3(pages, byte) \
(namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
+ ((((byte)[1]) >> 2) & 0xF)] \
<< 3) \
+ ((((byte)[1]) & 3) << 1) \
+ ((((byte)[2]) >> 5) & 1)] \
- & (1 << (((byte)[2]) & 0x1F)))
+ & (1u << (((byte)[2]) & 0x1F)))
#define UTF8_GET_NAMING(pages, p, n) \
((n) == 2 \
? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
: ((n) == 3 \
? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
: 0))
/* Detection of invalid UTF-8 sequences is based on Table 3.1B
of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/
with the additional restriction of not allowing the Unicode
code points 0xFFFF and 0xFFFE (sequences EF,BF,BF and EF,BF,BE).
Implementation details:
(A & 0x80) == 0 means A < 0x80
and
(A & 0xC0) == 0xC0 means A > 0xBF
*/
#define UTF8_INVALID2(p) \
((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0)
#define UTF8_INVALID3(p) \
(((p)[2] & 0x80) == 0 \
|| \
((*p) == 0xEF && (p)[1] == 0xBF \
? \
(p)[2] > 0xBD \
: \
((p)[2] & 0xC0) == 0xC0) \
|| \
((*p) == 0xE0 \
? \
(p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \
: \
((p)[1] & 0x80) == 0 \
|| \
((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
#define UTF8_INVALID4(p) \
(((p)[3] & 0x80) == 0 || ((p)[3] & 0xC0) == 0xC0 \
|| \
((p)[2] & 0x80) == 0 || ((p)[2] & 0xC0) == 0xC0 \
|| \
((*p) == 0xF0 \
? \
(p)[1] < 0x90 || ((p)[1] & 0xC0) == 0xC0 \
: \
((p)[1] & 0x80) == 0 \
|| \
((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
static int PTRFASTCALL
-isNever(const ENCODING *enc, const char *p)
+isNever(const ENCODING *UNUSED_P(enc), const char *UNUSED_P(p))
{
return 0;
}
static int PTRFASTCALL
-utf8_isName2(const ENCODING *enc, const char *p)
+utf8_isName2(const ENCODING *UNUSED_P(enc), const char *p)
{
return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
}
static int PTRFASTCALL
-utf8_isName3(const ENCODING *enc, const char *p)
+utf8_isName3(const ENCODING *UNUSED_P(enc), const char *p)
{
return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
}
#define utf8_isName4 isNever
static int PTRFASTCALL
-utf8_isNmstrt2(const ENCODING *enc, const char *p)
+utf8_isNmstrt2(const ENCODING *UNUSED_P(enc), const char *p)
{
return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
}
static int PTRFASTCALL
-utf8_isNmstrt3(const ENCODING *enc, const char *p)
+utf8_isNmstrt3(const ENCODING *UNUSED_P(enc), const char *p)
{
return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
}
#define utf8_isNmstrt4 isNever
static int PTRFASTCALL
-utf8_isInvalid2(const ENCODING *enc, const char *p)
+utf8_isInvalid2(const ENCODING *UNUSED_P(enc), const char *p)
{
return UTF8_INVALID2((const unsigned char *)p);
}
static int PTRFASTCALL
-utf8_isInvalid3(const ENCODING *enc, const char *p)
+utf8_isInvalid3(const ENCODING *UNUSED_P(enc), const char *p)
{
return UTF8_INVALID3((const unsigned char *)p);
}
static int PTRFASTCALL
-utf8_isInvalid4(const ENCODING *enc, const char *p)
+utf8_isInvalid4(const ENCODING *UNUSED_P(enc), const char *p)
{
return UTF8_INVALID4((const unsigned char *)p);
}
struct normal_encoding {
ENCODING enc;
unsigned char type[256];
#ifdef XML_MIN_SIZE
int (PTRFASTCALL *byteType)(const ENCODING *, const char *);
int (PTRFASTCALL *isNameMin)(const ENCODING *, const char *);
int (PTRFASTCALL *isNmstrtMin)(const ENCODING *, const char *);
int (PTRFASTCALL *byteToAscii)(const ENCODING *, const char *);
int (PTRCALL *charMatches)(const ENCODING *, const char *, int);
#endif /* XML_MIN_SIZE */
int (PTRFASTCALL *isName2)(const ENCODING *, const char *);
int (PTRFASTCALL *isName3)(const ENCODING *, const char *);
int (PTRFASTCALL *isName4)(const ENCODING *, const char *);
int (PTRFASTCALL *isNmstrt2)(const ENCODING *, const char *);
int (PTRFASTCALL *isNmstrt3)(const ENCODING *, const char *);
int (PTRFASTCALL *isNmstrt4)(const ENCODING *, const char *);
int (PTRFASTCALL *isInvalid2)(const ENCODING *, const char *);
int (PTRFASTCALL *isInvalid3)(const ENCODING *, const char *);
int (PTRFASTCALL *isInvalid4)(const ENCODING *, const char *);
};
#define AS_NORMAL_ENCODING(enc) ((const struct normal_encoding *) (enc))
#ifdef XML_MIN_SIZE
#define STANDARD_VTABLE(E) \
E ## byteType, \
E ## isNameMin, \
E ## isNmstrtMin, \
E ## byteToAscii, \
E ## charMatches,
#else
#define STANDARD_VTABLE(E) /* as nothing */
#endif
#define NORMAL_VTABLE(E) \
E ## isName2, \
E ## isName3, \
E ## isName4, \
E ## isNmstrt2, \
E ## isNmstrt3, \
E ## isNmstrt4, \
E ## isInvalid2, \
E ## isInvalid3, \
E ## isInvalid4
+#define NULL_VTABLE \
+ /* isName2 */ NULL, \
+ /* isName3 */ NULL, \
+ /* isName4 */ NULL, \
+ /* isNmstrt2 */ NULL, \
+ /* isNmstrt3 */ NULL, \
+ /* isNmstrt4 */ NULL, \
+ /* isInvalid2 */ NULL, \
+ /* isInvalid3 */ NULL, \
+ /* isInvalid4 */ NULL
+
static int FASTCALL checkCharRefNumber(int);
#include "xmltok_impl.h"
#include "ascii.h"
#ifdef XML_MIN_SIZE
#define sb_isNameMin isNever
#define sb_isNmstrtMin isNever
#endif
#ifdef XML_MIN_SIZE
#define MINBPC(enc) ((enc)->minBytesPerChar)
#else
/* minimum bytes per character */
#define MINBPC(enc) 1
#endif
#define SB_BYTE_TYPE(enc, p) \
(((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
#ifdef XML_MIN_SIZE
static int PTRFASTCALL
sb_byteType(const ENCODING *enc, const char *p)
{
return SB_BYTE_TYPE(enc, p);
}
#define BYTE_TYPE(enc, p) \
(AS_NORMAL_ENCODING(enc)->byteType(enc, p))
#else
#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
@@ -291,352 +296,438 @@ sb_charMatches(const ENCODING *enc, const char *p, int c)
{
return *p == c;
}
#else
/* c is an ASCII character */
#define CHAR_MATCHES(enc, p, c) (*(p) == c)
#endif
#define PREFIX(ident) normal_ ## ident
#define XML_TOK_IMPL_C
#include "xmltok_impl.c"
#undef XML_TOK_IMPL_C
#undef MINBPC
#undef BYTE_TYPE
#undef BYTE_TO_ASCII
#undef CHAR_MATCHES
#undef IS_NAME_CHAR
#undef IS_NAME_CHAR_MINBPC
#undef IS_NMSTRT_CHAR
#undef IS_NMSTRT_CHAR_MINBPC
#undef IS_INVALID_CHAR
enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */
UTF8_cval1 = 0x00,
UTF8_cval2 = 0xc0,
UTF8_cval3 = 0xe0,
UTF8_cval4 = 0xf0
};
-static void PTRCALL
-utf8_toUtf8(const ENCODING *enc,
+void
+align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef)
+{
+ const char * fromLim = *fromLimRef;
+ size_t walked = 0;
+ for (; fromLim > from; fromLim--, walked++) {
+ const unsigned char prev = (unsigned char)fromLim[-1];
+ if ((prev & 0xf8u) == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */
+ if (walked + 1 >= 4) {
+ fromLim += 4 - 1;
+ break;
+ } else {
+ walked = 0;
+ }
+ } else if ((prev & 0xf0u) == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */
+ if (walked + 1 >= 3) {
+ fromLim += 3 - 1;
+ break;
+ } else {
+ walked = 0;
+ }
+ } else if ((prev & 0xe0u) == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */
+ if (walked + 1 >= 2) {
+ fromLim += 2 - 1;
+ break;
+ } else {
+ walked = 0;
+ }
+ } else if ((prev & 0x80u) == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */
+ break;
+ }
+ }
+ *fromLimRef = fromLim;
+}
+
+static enum XML_Convert_Result PTRCALL
+utf8_toUtf8(const ENCODING *UNUSED_P(enc),
const char **fromP, const char *fromLim,
char **toP, const char *toLim)
{
char *to;
const char *from;
- if (fromLim - *fromP > toLim - *toP) {
- /* Avoid copying partial characters. */
- for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
- if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
- break;
- }
- for (to = *toP, from = *fromP; from != fromLim; from++, to++)
+ const char *fromLimInitial = fromLim;
+
+ /* Avoid copying partial characters. */
+ align_limit_to_full_utf8_characters(*fromP, &fromLim);
+
+ for (to = *toP, from = *fromP; (from < fromLim) && (to < toLim); from++, to++)
*to = *from;
*fromP = from;
*toP = to;
+
+ if (fromLim < fromLimInitial)
+ return XML_CONVERT_INPUT_INCOMPLETE;
+ else if ((to == toLim) && (from < fromLim))
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
+ else
+ return XML_CONVERT_COMPLETED;
}
-static void PTRCALL
+static enum XML_Convert_Result PTRCALL
utf8_toUtf16(const ENCODING *enc,
const char **fromP, const char *fromLim,
unsigned short **toP, const unsigned short *toLim)
{
+ enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
unsigned short *to = *toP;
const char *from = *fromP;
- while (from != fromLim && to != toLim) {
+ while (from < fromLim && to < toLim) {
switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
case BT_LEAD2:
+ if (fromLim - from < 2) {
+ res = XML_CONVERT_INPUT_INCOMPLETE;
+ goto after;
+ }
*to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
from += 2;
break;
case BT_LEAD3:
+ if (fromLim - from < 3) {
+ res = XML_CONVERT_INPUT_INCOMPLETE;
+ goto after;
+ }
*to++ = (unsigned short)(((from[0] & 0xf) << 12)
| ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
from += 3;
break;
case BT_LEAD4:
{
unsigned long n;
- if (to + 1 == toLim)
+ if (toLim - to < 2) {
+ res = XML_CONVERT_OUTPUT_EXHAUSTED;
+ goto after;
+ }
+ if (fromLim - from < 4) {
+ res = XML_CONVERT_INPUT_INCOMPLETE;
goto after;
+ }
n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12)
| ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
n -= 0x10000;
to[0] = (unsigned short)((n >> 10) | 0xD800);
to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
to += 2;
from += 4;
}
break;
default:
*to++ = *from++;
break;
}
}
+ if (from < fromLim)
+ res = XML_CONVERT_OUTPUT_EXHAUSTED;
after:
*fromP = from;
*toP = to;
+ return res;
}
#ifdef XML_NS
static const struct normal_encoding utf8_encoding_ns = {
{ VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
{
#include "asciitab.h"
#include "utf8tab.h"
},
STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
};
#endif
static const struct normal_encoding utf8_encoding = {
{ VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
{
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
#include "utf8tab.h"
},
STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
};
#ifdef XML_NS
static const struct normal_encoding internal_utf8_encoding_ns = {
{ VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
{
#include "iasciitab.h"
#include "utf8tab.h"
},
STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
};
#endif
static const struct normal_encoding internal_utf8_encoding = {
{ VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
{
#define BT_COLON BT_NMSTRT
#include "iasciitab.h"
#undef BT_COLON
#include "utf8tab.h"
},
STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
};
-static void PTRCALL
-latin1_toUtf8(const ENCODING *enc,
+static enum XML_Convert_Result PTRCALL
+latin1_toUtf8(const ENCODING *UNUSED_P(enc),
const char **fromP, const char *fromLim,
char **toP, const char *toLim)
{
for (;;) {
unsigned char c;
if (*fromP == fromLim)
- break;
+ return XML_CONVERT_COMPLETED;
c = (unsigned char)**fromP;
if (c & 0x80) {
if (toLim - *toP < 2)
- break;
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
*(*toP)++ = (char)((c >> 6) | UTF8_cval2);
*(*toP)++ = (char)((c & 0x3f) | 0x80);
(*fromP)++;
}
else {
if (*toP == toLim)
- break;
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
*(*toP)++ = *(*fromP)++;
}
}
}
-static void PTRCALL
-latin1_toUtf16(const ENCODING *enc,
+static enum XML_Convert_Result PTRCALL
+latin1_toUtf16(const ENCODING *UNUSED_P(enc),
const char **fromP, const char *fromLim,
unsigned short **toP, const unsigned short *toLim)
{
- while (*fromP != fromLim && *toP != toLim)
+ while (*fromP < fromLim && *toP < toLim)
*(*toP)++ = (unsigned char)*(*fromP)++;
+
+ if ((*toP == toLim) && (*fromP < fromLim))
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
+ else
+ return XML_CONVERT_COMPLETED;
}
#ifdef XML_NS
static const struct normal_encoding latin1_encoding_ns = {
{ VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
{
#include "asciitab.h"
#include "latin1tab.h"
},
- STANDARD_VTABLE(sb_)
+ STANDARD_VTABLE(sb_) NULL_VTABLE
};
#endif
static const struct normal_encoding latin1_encoding = {
{ VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
{
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
#include "latin1tab.h"
},
- STANDARD_VTABLE(sb_)
+ STANDARD_VTABLE(sb_) NULL_VTABLE
};
-static void PTRCALL
-ascii_toUtf8(const ENCODING *enc,
+static enum XML_Convert_Result PTRCALL
+ascii_toUtf8(const ENCODING *UNUSED_P(enc),
const char **fromP, const char *fromLim,
char **toP, const char *toLim)
{
- while (*fromP != fromLim && *toP != toLim)
+ while (*fromP < fromLim && *toP < toLim)
*(*toP)++ = *(*fromP)++;
+
+ if ((*toP == toLim) && (*fromP < fromLim))
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
+ else
+ return XML_CONVERT_COMPLETED;
}
#ifdef XML_NS
static const struct normal_encoding ascii_encoding_ns = {
{ VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
{
#include "asciitab.h"
/* BT_NONXML == 0 */
},
- STANDARD_VTABLE(sb_)
+ STANDARD_VTABLE(sb_) NULL_VTABLE
};
#endif
static const struct normal_encoding ascii_encoding = {
{ VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
{
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
/* BT_NONXML == 0 */
},
- STANDARD_VTABLE(sb_)
+ STANDARD_VTABLE(sb_) NULL_VTABLE
};
static int PTRFASTCALL
unicode_byte_type(char hi, char lo)
{
switch ((unsigned char)hi) {
case 0xD8: case 0xD9: case 0xDA: case 0xDB:
return BT_LEAD4;
case 0xDC: case 0xDD: case 0xDE: case 0xDF:
return BT_TRAIL;
case 0xFF:
switch ((unsigned char)lo) {
case 0xFF:
case 0xFE:
return BT_NONXML;
}
break;
}
return BT_NONASCII;
}
#define DEFINE_UTF16_TO_UTF8(E) \
-static void PTRCALL \
-E ## toUtf8(const ENCODING *enc, \
+static enum XML_Convert_Result PTRCALL \
+E ## toUtf8(const ENCODING *UNUSED_P(enc), \
const char **fromP, const char *fromLim, \
char **toP, const char *toLim) \
{ \
- const char *from; \
- for (from = *fromP; from != fromLim; from += 2) { \
+ const char *from = *fromP; \
+ fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \
+ for (; from < fromLim; from += 2) { \
int plane; \
unsigned char lo2; \
unsigned char lo = GET_LO(from); \
unsigned char hi = GET_HI(from); \
switch (hi) { \
case 0: \
if (lo < 0x80) { \
if (*toP == toLim) { \
*fromP = from; \
- return; \
+ return XML_CONVERT_OUTPUT_EXHAUSTED; \
} \
*(*toP)++ = lo; \
break; \
} \
/* fall through */ \
case 0x1: case 0x2: case 0x3: \
case 0x4: case 0x5: case 0x6: case 0x7: \
if (toLim - *toP < 2) { \
*fromP = from; \
- return; \
+ return XML_CONVERT_OUTPUT_EXHAUSTED; \
} \
*(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \
*(*toP)++ = ((lo & 0x3f) | 0x80); \
break; \
default: \
if (toLim - *toP < 3) { \
*fromP = from; \
- return; \
+ return XML_CONVERT_OUTPUT_EXHAUSTED; \
} \
/* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
*(*toP)++ = ((hi >> 4) | UTF8_cval3); \
*(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
*(*toP)++ = ((lo & 0x3f) | 0x80); \
break; \
case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
if (toLim - *toP < 4) { \
*fromP = from; \
- return; \
+ return XML_CONVERT_OUTPUT_EXHAUSTED; \
+ } \
+ if (fromLim - from < 4) { \
+ *fromP = from; \
+ return XML_CONVERT_INPUT_INCOMPLETE; \
} \
plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
*(*toP)++ = ((plane >> 2) | UTF8_cval4); \
*(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
from += 2; \
lo2 = GET_LO(from); \
*(*toP)++ = (((lo & 0x3) << 4) \
| ((GET_HI(from) & 0x3) << 2) \
| (lo2 >> 6) \
| 0x80); \
*(*toP)++ = ((lo2 & 0x3f) | 0x80); \
break; \
} \
} \
*fromP = from; \
+ if (from < fromLim) \
+ return XML_CONVERT_INPUT_INCOMPLETE; \
+ else \
+ return XML_CONVERT_COMPLETED; \
}
#define DEFINE_UTF16_TO_UTF16(E) \
-static void PTRCALL \
-E ## toUtf16(const ENCODING *enc, \
+static enum XML_Convert_Result PTRCALL \
+E ## toUtf16(const ENCODING *UNUSED_P(enc), \
const char **fromP, const char *fromLim, \
unsigned short **toP, const unsigned short *toLim) \
{ \
+ enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \
+ fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \
/* Avoid copying first half only of surrogate */ \
if (fromLim - *fromP > ((toLim - *toP) << 1) \
- && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \
+ && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \
fromLim -= 2; \
- for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \
+ res = XML_CONVERT_INPUT_INCOMPLETE; \
+ } \
+ for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \
*(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
+ if ((*toP == toLim) && (*fromP < fromLim)) \
+ return XML_CONVERT_OUTPUT_EXHAUSTED; \
+ else \
+ return res; \
}
#define SET2(ptr, ch) \
(((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
#define GET_LO(ptr) ((unsigned char)(ptr)[0])
#define GET_HI(ptr) ((unsigned char)(ptr)[1])
DEFINE_UTF16_TO_UTF8(little2_)
DEFINE_UTF16_TO_UTF16(little2_)
#undef SET2
#undef GET_LO
#undef GET_HI
#define SET2(ptr, ch) \
(((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
#define GET_LO(ptr) ((unsigned char)(ptr)[1])
#define GET_HI(ptr) ((unsigned char)(ptr)[0])
DEFINE_UTF16_TO_UTF8(big2_)
DEFINE_UTF16_TO_UTF16(big2_)
#undef SET2
#undef GET_LO
#undef GET_HI
#define LITTLE2_BYTE_TYPE(enc, p) \
((p)[1] == 0 \
? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
: unicode_byte_type((p)[1], (p)[0]))
@@ -699,106 +790,106 @@ little2_isNmstrtMin(const ENCODING *enc, const char *p)
#define XML_TOK_IMPL_C
#include "xmltok_impl.c"
#undef XML_TOK_IMPL_C
#undef MINBPC
#undef BYTE_TYPE
#undef BYTE_TO_ASCII
#undef CHAR_MATCHES
#undef IS_NAME_CHAR
#undef IS_NAME_CHAR_MINBPC
#undef IS_NMSTRT_CHAR
#undef IS_NMSTRT_CHAR_MINBPC
#undef IS_INVALID_CHAR
#endif /* not XML_MIN_SIZE */
#ifdef XML_NS
static const struct normal_encoding little2_encoding_ns = {
{ VTABLE, 2, 0,
#if BYTEORDER == 1234
1
#else
0
#endif
},
{
#include "asciitab.h"
#include "latin1tab.h"
},
- STANDARD_VTABLE(little2_)
+ STANDARD_VTABLE(little2_) NULL_VTABLE
};
#endif
static const struct normal_encoding little2_encoding = {
{ VTABLE, 2, 0,
#if BYTEORDER == 1234
1
#else
0
#endif
},
{
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
#include "latin1tab.h"
},
- STANDARD_VTABLE(little2_)
+ STANDARD_VTABLE(little2_) NULL_VTABLE
};
#if BYTEORDER != 4321
#ifdef XML_NS
static const struct normal_encoding internal_little2_encoding_ns = {
{ VTABLE, 2, 0, 1 },
{
#include "iasciitab.h"
#include "latin1tab.h"
},
- STANDARD_VTABLE(little2_)
+ STANDARD_VTABLE(little2_) NULL_VTABLE
};
#endif
static const struct normal_encoding internal_little2_encoding = {
{ VTABLE, 2, 0, 1 },
{
#define BT_COLON BT_NMSTRT
#include "iasciitab.h"
#undef BT_COLON
#include "latin1tab.h"
},
- STANDARD_VTABLE(little2_)
+ STANDARD_VTABLE(little2_) NULL_VTABLE
};
#endif
#define BIG2_BYTE_TYPE(enc, p) \
((p)[0] == 0 \
? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
: unicode_byte_type((p)[0], (p)[1]))
#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \
UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
#ifdef XML_MIN_SIZE
static int PTRFASTCALL
big2_byteType(const ENCODING *enc, const char *p)
{
return BIG2_BYTE_TYPE(enc, p);
}
static int PTRFASTCALL
big2_byteToAscii(const ENCODING *enc, const char *p)
{
return BIG2_BYTE_TO_ASCII(enc, p);
}
@@ -840,132 +931,132 @@ big2_isNmstrtMin(const ENCODING *enc, const char *p)
#define XML_TOK_IMPL_C
#include "xmltok_impl.c"
#undef XML_TOK_IMPL_C
#undef MINBPC
#undef BYTE_TYPE
#undef BYTE_TO_ASCII
#undef CHAR_MATCHES
#undef IS_NAME_CHAR
#undef IS_NAME_CHAR_MINBPC
#undef IS_NMSTRT_CHAR
#undef IS_NMSTRT_CHAR_MINBPC
#undef IS_INVALID_CHAR
#endif /* not XML_MIN_SIZE */
#ifdef XML_NS
static const struct normal_encoding big2_encoding_ns = {
{ VTABLE, 2, 0,
#if BYTEORDER == 4321
1
#else
0
#endif
},
{
#include "asciitab.h"
#include "latin1tab.h"
},
- STANDARD_VTABLE(big2_)
+ STANDARD_VTABLE(big2_) NULL_VTABLE
};
#endif
static const struct normal_encoding big2_encoding = {
{ VTABLE, 2, 0,
#if BYTEORDER == 4321
1
#else
0
#endif
},
{
#define BT_COLON BT_NMSTRT
#include "asciitab.h"
#undef BT_COLON
#include "latin1tab.h"
},
- STANDARD_VTABLE(big2_)
+ STANDARD_VTABLE(big2_) NULL_VTABLE
};
#if BYTEORDER != 1234
#ifdef XML_NS
static const struct normal_encoding internal_big2_encoding_ns = {
{ VTABLE, 2, 0, 1 },
{
#include "iasciitab.h"
#include "latin1tab.h"
},
- STANDARD_VTABLE(big2_)
+ STANDARD_VTABLE(big2_) NULL_VTABLE
};
#endif
static const struct normal_encoding internal_big2_encoding = {
{ VTABLE, 2, 0, 1 },
{
#define BT_COLON BT_NMSTRT
#include "iasciitab.h"
#undef BT_COLON
#include "latin1tab.h"
},
- STANDARD_VTABLE(big2_)
+ STANDARD_VTABLE(big2_) NULL_VTABLE
};
#endif
#undef PREFIX
static int FASTCALL
streqci(const char *s1, const char *s2)
{
for (;;) {
char c1 = *s1++;
char c2 = *s2++;
if (ASCII_a <= c1 && c1 <= ASCII_z)
c1 += ASCII_A - ASCII_a;
if (ASCII_a <= c2 && c2 <= ASCII_z)
c2 += ASCII_A - ASCII_a;
if (c1 != c2)
return 0;
if (!c1)
break;
}
return 1;
}
static void PTRCALL
-initUpdatePosition(const ENCODING *enc, const char *ptr,
+initUpdatePosition(const ENCODING *UNUSED_P(enc), const char *ptr,
const char *end, POSITION *pos)
{
normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
}
static int
toAscii(const ENCODING *enc, const char *ptr, const char *end)
{
char buf[1];
char *p = buf;
XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
if (p == buf)
return -1;
else
return buf[0];
}
static int FASTCALL
isSpace(int c)
{
switch (c) {
case 0x20:
case 0xD:
case 0xA:
case 0x9:
return 1;
}
return 0;
}
@@ -1261,112 +1352,117 @@ XmlSizeOfUnknownEncoding(void)
}
static int PTRFASTCALL
unknown_isName(const ENCODING *enc, const char *p)
{
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
int c = uenc->convert(uenc->userData, p);
if (c & ~0xFFFF)
return 0;
return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
}
static int PTRFASTCALL
unknown_isNmstrt(const ENCODING *enc, const char *p)
{
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
int c = uenc->convert(uenc->userData, p);
if (c & ~0xFFFF)
return 0;
return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
}
static int PTRFASTCALL
unknown_isInvalid(const ENCODING *enc, const char *p)
{
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
int c = uenc->convert(uenc->userData, p);
return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
}
-static void PTRCALL
+static enum XML_Convert_Result PTRCALL
unknown_toUtf8(const ENCODING *enc,
const char **fromP, const char *fromLim,
char **toP, const char *toLim)
{
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
char buf[XML_UTF8_ENCODE_MAX];
for (;;) {
const char *utf8;
int n;
if (*fromP == fromLim)
- break;
+ return XML_CONVERT_COMPLETED;
utf8 = uenc->utf8[(unsigned char)**fromP];
n = *utf8++;
if (n == 0) {
int c = uenc->convert(uenc->userData, *fromP);
n = XmlUtf8Encode(c, buf);
if (n > toLim - *toP)
- break;
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
utf8 = buf;
*fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
- (BT_LEAD2 - 2));
}
else {
if (n > toLim - *toP)
- break;
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
(*fromP)++;
}
do {
*(*toP)++ = *utf8++;
} while (--n != 0);
}
}
-static void PTRCALL
+static enum XML_Convert_Result PTRCALL
unknown_toUtf16(const ENCODING *enc,
const char **fromP, const char *fromLim,
unsigned short **toP, const unsigned short *toLim)
{
const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc);
- while (*fromP != fromLim && *toP != toLim) {
+ while (*fromP < fromLim && *toP < toLim) {
unsigned short c = uenc->utf16[(unsigned char)**fromP];
if (c == 0) {
c = (unsigned short)
uenc->convert(uenc->userData, *fromP);
*fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP]
- (BT_LEAD2 - 2));
}
else
(*fromP)++;
*(*toP)++ = c;
}
+
+ if ((*toP == toLim) && (*fromP < fromLim))
+ return XML_CONVERT_OUTPUT_EXHAUSTED;
+ else
+ return XML_CONVERT_COMPLETED;
}
ENCODING *
XmlInitUnknownEncoding(void *mem,
int *table,
CONVERTER convert,
void *userData)
{
int i;
struct unknown_encoding *e = (struct unknown_encoding *)mem;
for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
((char *)mem)[i] = ((char *)&latin1_encoding)[i];
for (i = 0; i < 128; i++)
if (latin1_encoding.type[i] != BT_OTHER
&& latin1_encoding.type[i] != BT_NONXML
&& table[i] != i)
return 0;
for (i = 0; i < 256; i++) {
int c = table[i];
if (c == -1) {
e->normal.type[i] = BT_MALFORM;
/* This shouldn't really get used. */
e->utf16[i] = 0xFFFF;
e->utf8[i][0] = 1;
e->utf8[i][1] = 0;
}
else if (c < 0) {
if (c < -4)
return 0;
e->normal.type[i] = (unsigned char)(BT_LEAD2 - (c + 2));
@@ -1476,61 +1572,61 @@ getEncodingIndex(const char *name)
if (streqci(name, encodingNames[i]))
return i;
return UNKNOWN_ENC;
}
/* For binary compatibility, we store the index of the encoding
specified at initialization in the isUtf16 member.
*/
#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)
#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i)
/* This is what detects the encoding. encodingTable maps from
encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of
the external (protocol) specified encoding; state is
XML_CONTENT_STATE if we're parsing an external text entity, and
XML_PROLOG_STATE otherwise.
*/
static int
initScan(const ENCODING * const *encodingTable,
const INIT_ENCODING *enc,
int state,
const char *ptr,
const char *end,
const char **nextTokPtr)
{
const ENCODING **encPtr;
- if (ptr == end)
+ if (ptr >= end)
return XML_TOK_NONE;
encPtr = enc->encPtr;
if (ptr + 1 == end) {
/* only a single byte available for auto-detection */
#ifndef XML_DTD /* FIXME */
/* a well-formed document entity must have more than one byte */
if (state != XML_CONTENT_STATE)
return XML_TOK_PARTIAL;
#endif
/* so we're parsing an external text entity... */
/* if UTF-16 was externally specified, then we need at least 2 bytes */
switch (INIT_ENC_INDEX(enc)) {
case UTF_16_ENC:
case UTF_16LE_ENC:
case UTF_16BE_ENC:
return XML_TOK_PARTIAL;
}
switch ((unsigned char)*ptr) {
case 0xFE:
case 0xFF:
case 0xEF: /* possibly first byte of UTF-8 BOM */
if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
&& state == XML_CONTENT_STATE)
break;
/* fall through */
case 0x00:
case 0x3C:
return XML_TOK_PARTIAL;
}
}
diff --git a/3rdParty/Expat/src/xmltok.h b/3rdParty/Expat/src/xmltok.h
index ca867aa..752007e 100644
--- a/3rdParty/Expat/src/xmltok.h
+++ b/3rdParty/Expat/src/xmltok.h
@@ -103,94 +103,100 @@ extern "C" {
#define XML_N_LITERAL_TYPES 2
#define XML_ATTRIBUTE_VALUE_LITERAL 0
#define XML_ENTITY_VALUE_LITERAL 1
/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
#define XML_UTF8_ENCODE_MAX 4
/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
#define XML_UTF16_ENCODE_MAX 2
typedef struct position {
/* first line and first column are 0 not 1 */
XML_Size lineNumber;
XML_Size columnNumber;
} POSITION;
typedef struct {
const char *name;
const char *valuePtr;
const char *valueEnd;
char normalized;
} ATTRIBUTE;
struct encoding;
typedef struct encoding ENCODING;
typedef int (PTRCALL *SCANNER)(const ENCODING *,
const char *,
const char *,
const char **);
+enum XML_Convert_Result {
+ XML_CONVERT_COMPLETED = 0,
+ XML_CONVERT_INPUT_INCOMPLETE = 1,
+ XML_CONVERT_OUTPUT_EXHAUSTED = 2 /* and therefore potentially input remaining as well */
+};
+
struct encoding {
SCANNER scanners[XML_N_STATES];
SCANNER literalScanners[XML_N_LITERAL_TYPES];
int (PTRCALL *sameName)(const ENCODING *,
const char *,
const char *);
int (PTRCALL *nameMatchesAscii)(const ENCODING *,
const char *,
const char *,
const char *);
int (PTRFASTCALL *nameLength)(const ENCODING *, const char *);
const char *(PTRFASTCALL *skipS)(const ENCODING *, const char *);
int (PTRCALL *getAtts)(const ENCODING *enc,
const char *ptr,
int attsMax,
ATTRIBUTE *atts);
int (PTRFASTCALL *charRefNumber)(const ENCODING *enc, const char *ptr);
int (PTRCALL *predefinedEntityName)(const ENCODING *,
const char *,
const char *);
void (PTRCALL *updatePosition)(const ENCODING *,
const char *ptr,
const char *end,
POSITION *);
int (PTRCALL *isPublicId)(const ENCODING *enc,
const char *ptr,
const char *end,
const char **badPtr);
- void (PTRCALL *utf8Convert)(const ENCODING *enc,
+ enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc,
const char **fromP,
const char *fromLim,
char **toP,
const char *toLim);
- void (PTRCALL *utf16Convert)(const ENCODING *enc,
+ enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc,
const char **fromP,
const char *fromLim,
unsigned short **toP,
const unsigned short *toLim);
int minBytesPerChar;
char isUtf8;
char isUtf16;
};
/* Scan the string starting at ptr until the end of the next complete
token, but do not scan past eptr. Return an integer giving the
type of token.
Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
Return XML_TOK_PARTIAL when the string does not contain a complete
token; nextTokPtr will not be set.
Return XML_TOK_INVALID when the string does not start a valid
token; nextTokPtr will be set to point to the character which made
the token invalid.
Otherwise the string starts with a valid token; nextTokPtr will be
set to point to the character following the end of that token.
Each data character counts as a single token, but adjacent data
characters may be returned together. Similarly for characters in
the prolog outside literals, comments and processing instructions.
*/
diff --git a/3rdParty/Expat/src/xmltok_impl.c b/3rdParty/Expat/src/xmltok_impl.c
index 9c2895b..5f779c0 100644
--- a/3rdParty/Expat/src/xmltok_impl.c
+++ b/3rdParty/Expat/src/xmltok_impl.c
@@ -60,1039 +60,1032 @@
#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
case BT_LEAD ## n: \
if (end - ptr < n) \
return XML_TOK_PARTIAL_CHAR; \
if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
*nextTokPtr = ptr; \
return XML_TOK_INVALID; \
} \
ptr += n; \
break;
#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
case BT_NONASCII: \
if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
*nextTokPtr = ptr; \
return XML_TOK_INVALID; \
} \
case BT_NMSTRT: \
case BT_HEX: \
ptr += MINBPC(enc); \
break; \
CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
#ifndef PREFIX
#define PREFIX(ident) ident
#endif
+
+#define HAS_CHARS(enc, ptr, end, count) \
+ (end - ptr >= count * MINBPC(enc))
+
+#define HAS_CHAR(enc, ptr, end) \
+ HAS_CHARS(enc, ptr, end, 1)
+
+#define REQUIRE_CHARS(enc, ptr, end, count) \
+ { \
+ if (! HAS_CHARS(enc, ptr, end, count)) { \
+ return XML_TOK_PARTIAL; \
+ } \
+ }
+
+#define REQUIRE_CHAR(enc, ptr, end) \
+ REQUIRE_CHARS(enc, ptr, end, 1)
+
+
/* ptr points to character following "<!-" */
static int PTRCALL
PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
- if (ptr != end) {
+ if (HAS_CHAR(enc, ptr, end)) {
if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
ptr += MINBPC(enc);
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
INVALID_CASES(ptr, nextTokPtr)
case BT_MINUS:
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_COMMENT;
}
break;
default:
ptr += MINBPC(enc);
break;
}
}
}
return XML_TOK_PARTIAL;
}
/* ptr points to character following "<!" */
static int PTRCALL
PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
case BT_MINUS:
return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
case BT_LSQB:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_COND_SECT_OPEN;
case BT_NMSTRT:
case BT_HEX:
ptr += MINBPC(enc);
break;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_PERCNT:
- if (ptr + MINBPC(enc) == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHARS(enc, ptr, end, 2);
/* don't allow <!ENTITY% foo "whatever"> */
switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
/* fall through */
case BT_S: case BT_CR: case BT_LF:
*nextTokPtr = ptr;
return XML_TOK_DECL_OPEN;
case BT_NMSTRT:
case BT_HEX:
ptr += MINBPC(enc);
break;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
}
return XML_TOK_PARTIAL;
}
static int PTRCALL
-PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr,
+PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(enc), const char *ptr,
const char *end, int *tokPtr)
{
int upper = 0;
*tokPtr = XML_TOK_PI;
if (end - ptr != MINBPC(enc)*3)
return 1;
switch (BYTE_TO_ASCII(enc, ptr)) {
case ASCII_x:
break;
case ASCII_X:
upper = 1;
break;
default:
return 1;
}
ptr += MINBPC(enc);
switch (BYTE_TO_ASCII(enc, ptr)) {
case ASCII_m:
break;
case ASCII_M:
upper = 1;
break;
default:
return 1;
}
ptr += MINBPC(enc);
switch (BYTE_TO_ASCII(enc, ptr)) {
case ASCII_l:
break;
case ASCII_L:
upper = 1;
break;
default:
return 1;
}
if (upper)
return 0;
*tokPtr = XML_TOK_XML_DECL;
return 1;
}
/* ptr points to character following "<?" */
static int PTRCALL
PREFIX(scanPi)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
int tok;
const char *target = ptr;
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_S: case BT_CR: case BT_LF:
if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
ptr += MINBPC(enc);
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
INVALID_CASES(ptr, nextTokPtr)
case BT_QUEST:
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
*nextTokPtr = ptr + MINBPC(enc);
return tok;
}
break;
default:
ptr += MINBPC(enc);
break;
}
}
return XML_TOK_PARTIAL;
case BT_QUEST:
if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
*nextTokPtr = ptr + MINBPC(enc);
return tok;
}
/* fall through */
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
}
return XML_TOK_PARTIAL;
}
static int PTRCALL
-PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr,
+PREFIX(scanCdataSection)(const ENCODING *UNUSED_P(enc), const char *ptr,
const char *end, const char **nextTokPtr)
{
static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A,
ASCII_T, ASCII_A, ASCII_LSQB };
int i;
/* CDATA[ */
- if (end - ptr < 6 * MINBPC(enc))
- return XML_TOK_PARTIAL;
+ REQUIRE_CHARS(enc, ptr, end, 6);
for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
}
*nextTokPtr = ptr;
return XML_TOK_CDATA_SECT_OPEN;
}
static int PTRCALL
PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
- if (ptr == end)
+ if (ptr >= end)
return XML_TOK_NONE;
if (MINBPC(enc) > 1) {
size_t n = end - ptr;
if (n & (MINBPC(enc) - 1)) {
n &= ~(MINBPC(enc) - 1);
if (n == 0)
return XML_TOK_PARTIAL;
end = ptr + n;
}
}
switch (BYTE_TYPE(enc, ptr)) {
case BT_RSQB:
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
break;
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
ptr -= MINBPC(enc);
break;
}
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_CDATA_SECT_CLOSE;
case BT_CR:
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
if (BYTE_TYPE(enc, ptr) == BT_LF)
ptr += MINBPC(enc);
*nextTokPtr = ptr;
return XML_TOK_DATA_NEWLINE;
case BT_LF:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_DATA_NEWLINE;
INVALID_CASES(ptr, nextTokPtr)
default:
ptr += MINBPC(enc);
break;
}
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
#define LEAD_CASE(n) \
case BT_LEAD ## n: \
if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
*nextTokPtr = ptr; \
return XML_TOK_DATA_CHARS; \
} \
ptr += n; \
break;
LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
#undef LEAD_CASE
case BT_NONXML:
case BT_MALFORM:
case BT_TRAIL:
case BT_CR:
case BT_LF:
case BT_RSQB:
*nextTokPtr = ptr;
return XML_TOK_DATA_CHARS;
default:
ptr += MINBPC(enc);
break;
}
}
*nextTokPtr = ptr;
return XML_TOK_DATA_CHARS;
}
/* ptr points to character following "</" */
static int PTRCALL
PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_S: case BT_CR: case BT_LF:
- for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+ for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_S: case BT_CR: case BT_LF:
break;
case BT_GT:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_END_TAG;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
}
return XML_TOK_PARTIAL;
#ifdef XML_NS
case BT_COLON:
/* no need to check qname syntax here,
since end-tag must match exactly */
ptr += MINBPC(enc);
break;
#endif
case BT_GT:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_END_TAG;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
}
return XML_TOK_PARTIAL;
}
/* ptr points to character following "&#X" */
static int PTRCALL
PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
- if (ptr != end) {
+ if (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_DIGIT:
case BT_HEX:
break;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+ for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_DIGIT:
case BT_HEX:
break;
case BT_SEMI:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_CHAR_REF;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
}
}
return XML_TOK_PARTIAL;
}
/* ptr points to character following "&#" */
static int PTRCALL
PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
- if (ptr != end) {
+ if (HAS_CHAR(enc, ptr, end)) {
if (CHAR_MATCHES(enc, ptr, ASCII_x))
return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
switch (BYTE_TYPE(enc, ptr)) {
case BT_DIGIT:
break;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+ for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_DIGIT:
break;
case BT_SEMI:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_CHAR_REF;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
}
}
return XML_TOK_PARTIAL;
}
/* ptr points to character following "&" */
static int PTRCALL
PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
case BT_NUM:
return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_SEMI:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_ENTITY_REF;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
}
return XML_TOK_PARTIAL;
}
/* ptr points to character following first character of attribute name */
static int PTRCALL
PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
#ifdef XML_NS
int hadColon = 0;
#endif
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
#ifdef XML_NS
case BT_COLON:
if (hadColon) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
hadColon = 1;
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
break;
#endif
case BT_S: case BT_CR: case BT_LF:
for (;;) {
int t;
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
t = BYTE_TYPE(enc, ptr);
if (t == BT_EQUALS)
break;
switch (t) {
case BT_S:
case BT_LF:
case BT_CR:
break;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
}
/* fall through */
case BT_EQUALS:
{
int open;
#ifdef XML_NS
hadColon = 0;
#endif
for (;;) {
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
open = BYTE_TYPE(enc, ptr);
if (open == BT_QUOT || open == BT_APOS)
break;
switch (open) {
case BT_S:
case BT_LF:
case BT_CR:
break;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
}
ptr += MINBPC(enc);
/* in attribute value */
for (;;) {
int t;
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
t = BYTE_TYPE(enc, ptr);
if (t == open)
break;
switch (t) {
INVALID_CASES(ptr, nextTokPtr)
case BT_AMP:
{
int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
if (tok <= 0) {
if (tok == XML_TOK_INVALID)
*nextTokPtr = ptr;
return tok;
}
break;
}
case BT_LT:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
default:
ptr += MINBPC(enc);
break;
}
}
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
case BT_S:
case BT_CR:
case BT_LF:
break;
case BT_SOL:
goto sol;
case BT_GT:
goto gt;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
/* ptr points to closing quote */
for (;;) {
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
case BT_S: case BT_CR: case BT_LF:
continue;
case BT_GT:
gt:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_START_TAG_WITH_ATTS;
case BT_SOL:
sol:
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
break;
}
break;
}
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
}
return XML_TOK_PARTIAL;
}
/* ptr points to character following "<" */
static int PTRCALL
PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
#ifdef XML_NS
int hadColon;
#endif
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
case BT_EXCL:
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
case BT_MINUS:
return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
case BT_LSQB:
return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc),
end, nextTokPtr);
}
*nextTokPtr = ptr;
return XML_TOK_INVALID;
case BT_QUEST:
return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
case BT_SOL:
return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr);
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
#ifdef XML_NS
hadColon = 0;
#endif
/* we have a start-tag */
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
#ifdef XML_NS
case BT_COLON:
if (hadColon) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
hadColon = 1;
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
break;
#endif
case BT_S: case BT_CR: case BT_LF:
{
ptr += MINBPC(enc);
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
case BT_GT:
goto gt;
case BT_SOL:
goto sol;
case BT_S: case BT_CR: case BT_LF:
ptr += MINBPC(enc);
continue;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
}
return XML_TOK_PARTIAL;
}
case BT_GT:
gt:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_START_TAG_NO_ATTS;
case BT_SOL:
sol:
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
}
return XML_TOK_PARTIAL;
}
static int PTRCALL
PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
- if (ptr == end)
+ if (ptr >= end)
return XML_TOK_NONE;
if (MINBPC(enc) > 1) {
size_t n = end - ptr;
if (n & (MINBPC(enc) - 1)) {
n &= ~(MINBPC(enc) - 1);
if (n == 0)
return XML_TOK_PARTIAL;
end = ptr + n;
}
}
switch (BYTE_TYPE(enc, ptr)) {
case BT_LT:
return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);
case BT_AMP:
return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
case BT_CR:
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return XML_TOK_TRAILING_CR;
if (BYTE_TYPE(enc, ptr) == BT_LF)
ptr += MINBPC(enc);
*nextTokPtr = ptr;
return XML_TOK_DATA_NEWLINE;
case BT_LF:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_DATA_NEWLINE;
case BT_RSQB:
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return XML_TOK_TRAILING_RSQB;
if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
break;
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return XML_TOK_TRAILING_RSQB;
if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
ptr -= MINBPC(enc);
break;
}
*nextTokPtr = ptr;
return XML_TOK_INVALID;
INVALID_CASES(ptr, nextTokPtr)
default:
ptr += MINBPC(enc);
break;
}
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
#define LEAD_CASE(n) \
case BT_LEAD ## n: \
if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
*nextTokPtr = ptr; \
return XML_TOK_DATA_CHARS; \
} \
ptr += n; \
break;
LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
#undef LEAD_CASE
case BT_RSQB:
- if (ptr + MINBPC(enc) != end) {
+ if (HAS_CHARS(enc, ptr, end, 2)) {
if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
ptr += MINBPC(enc);
break;
}
- if (ptr + 2*MINBPC(enc) != end) {
+ if (HAS_CHARS(enc, ptr, end, 3)) {
if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
ptr += MINBPC(enc);
break;
}
*nextTokPtr = ptr + 2*MINBPC(enc);
return XML_TOK_INVALID;
}
}
/* fall through */
case BT_AMP:
case BT_LT:
case BT_NONXML:
case BT_MALFORM:
case BT_TRAIL:
case BT_CR:
case BT_LF:
*nextTokPtr = ptr;
return XML_TOK_DATA_CHARS;
default:
ptr += MINBPC(enc);
break;
}
}
*nextTokPtr = ptr;
return XML_TOK_DATA_CHARS;
}
/* ptr points to character following "%" */
static int PTRCALL
PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
*nextTokPtr = ptr;
return XML_TOK_PERCENT;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_SEMI:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_PARAM_ENTITY_REF;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
}
return XML_TOK_PARTIAL;
}
static int PTRCALL
PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_CR: case BT_LF: case BT_S:
case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
*nextTokPtr = ptr;
return XML_TOK_POUND_NAME;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
}
return -XML_TOK_POUND_NAME;
}
static int PTRCALL
PREFIX(scanLit)(int open, const ENCODING *enc,
const char *ptr, const char *end,
const char **nextTokPtr)
{
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
int t = BYTE_TYPE(enc, ptr);
switch (t) {
INVALID_CASES(ptr, nextTokPtr)
case BT_QUOT:
case BT_APOS:
ptr += MINBPC(enc);
if (t != open)
break;
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return -XML_TOK_LITERAL;
*nextTokPtr = ptr;
switch (BYTE_TYPE(enc, ptr)) {
case BT_S: case BT_CR: case BT_LF:
case BT_GT: case BT_PERCNT: case BT_LSQB:
return XML_TOK_LITERAL;
default:
return XML_TOK_INVALID;
}
default:
ptr += MINBPC(enc);
break;
}
}
return XML_TOK_PARTIAL;
}
static int PTRCALL
PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
int tok;
- if (ptr == end)
+ if (ptr >= end)
return XML_TOK_NONE;
if (MINBPC(enc) > 1) {
size_t n = end - ptr;
if (n & (MINBPC(enc) - 1)) {
n &= ~(MINBPC(enc) - 1);
if (n == 0)
return XML_TOK_PARTIAL;
end = ptr + n;
}
}
switch (BYTE_TYPE(enc, ptr)) {
case BT_QUOT:
return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
case BT_APOS:
return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
case BT_LT:
{
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
case BT_EXCL:
return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
case BT_QUEST:
return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
case BT_NMSTRT:
case BT_HEX:
case BT_NONASCII:
case BT_LEAD2:
case BT_LEAD3:
case BT_LEAD4:
*nextTokPtr = ptr - MINBPC(enc);
return XML_TOK_INSTANCE_START;
}
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
case BT_CR:
if (ptr + MINBPC(enc) == end) {
*nextTokPtr = end;
/* indicate that this might be part of a CR/LF pair */
return -XML_TOK_PROLOG_S;
}
/* fall through */
case BT_S: case BT_LF:
for (;;) {
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
break;
switch (BYTE_TYPE(enc, ptr)) {
case BT_S: case BT_LF:
break;
case BT_CR:
/* don't split CR/LF pair */
if (ptr + MINBPC(enc) != end)
break;
/* fall through */
default:
*nextTokPtr = ptr;
return XML_TOK_PROLOG_S;
}
}
*nextTokPtr = ptr;
return XML_TOK_PROLOG_S;
case BT_PERCNT:
return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
case BT_COMMA:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_COMMA;
case BT_LSQB:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_OPEN_BRACKET;
case BT_RSQB:
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return -XML_TOK_CLOSE_BRACKET;
if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
- if (ptr + MINBPC(enc) == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHARS(enc, ptr, end, 2);
if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
*nextTokPtr = ptr + 2*MINBPC(enc);
return XML_TOK_COND_SECT_CLOSE;
}
}
*nextTokPtr = ptr;
return XML_TOK_CLOSE_BRACKET;
case BT_LPAR:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_OPEN_PAREN;
case BT_RPAR:
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return -XML_TOK_CLOSE_PAREN;
switch (BYTE_TYPE(enc, ptr)) {
case BT_AST:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_CLOSE_PAREN_ASTERISK;
case BT_QUEST:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_CLOSE_PAREN_QUESTION;
case BT_PLUS:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_CLOSE_PAREN_PLUS;
case BT_CR: case BT_LF: case BT_S:
case BT_GT: case BT_COMMA: case BT_VERBAR:
case BT_RPAR:
*nextTokPtr = ptr;
return XML_TOK_CLOSE_PAREN;
}
*nextTokPtr = ptr;
return XML_TOK_INVALID;
case BT_VERBAR:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_OR;
case BT_GT:
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_DECL_CLOSE;
case BT_NUM:
return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);
#define LEAD_CASE(n) \
case BT_LEAD ## n: \
if (end - ptr < n) \
@@ -1114,293 +1107,296 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
case BT_NMSTRT:
case BT_HEX:
tok = XML_TOK_NAME;
ptr += MINBPC(enc);
break;
case BT_DIGIT:
case BT_NAME:
case BT_MINUS:
#ifdef XML_NS
case BT_COLON:
#endif
tok = XML_TOK_NMTOKEN;
ptr += MINBPC(enc);
break;
case BT_NONASCII:
if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {
ptr += MINBPC(enc);
tok = XML_TOK_NAME;
break;
}
if (IS_NAME_CHAR_MINBPC(enc, ptr)) {
ptr += MINBPC(enc);
tok = XML_TOK_NMTOKEN;
break;
}
/* fall through */
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_GT: case BT_RPAR: case BT_COMMA:
case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
case BT_S: case BT_CR: case BT_LF:
*nextTokPtr = ptr;
return tok;
#ifdef XML_NS
case BT_COLON:
ptr += MINBPC(enc);
switch (tok) {
case XML_TOK_NAME:
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
tok = XML_TOK_PREFIXED_NAME;
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
default:
tok = XML_TOK_NMTOKEN;
break;
}
break;
case XML_TOK_PREFIXED_NAME:
tok = XML_TOK_NMTOKEN;
break;
}
break;
#endif
case BT_PLUS:
if (tok == XML_TOK_NMTOKEN) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_NAME_PLUS;
case BT_AST:
if (tok == XML_TOK_NMTOKEN) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_NAME_ASTERISK;
case BT_QUEST:
if (tok == XML_TOK_NMTOKEN) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_NAME_QUESTION;
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
}
return -tok;
}
static int PTRCALL
PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
const char *start;
- if (ptr == end)
+ if (ptr >= end)
return XML_TOK_NONE;
+ else if (! HAS_CHAR(enc, ptr, end))
+ return XML_TOK_PARTIAL;
start = ptr;
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
#define LEAD_CASE(n) \
case BT_LEAD ## n: ptr += n; break;
LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
#undef LEAD_CASE
case BT_AMP:
if (ptr == start)
return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
*nextTokPtr = ptr;
return XML_TOK_DATA_CHARS;
case BT_LT:
/* this is for inside entity references */
*nextTokPtr = ptr;
return XML_TOK_INVALID;
case BT_LF:
if (ptr == start) {
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_DATA_NEWLINE;
}
*nextTokPtr = ptr;
return XML_TOK_DATA_CHARS;
case BT_CR:
if (ptr == start) {
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return XML_TOK_TRAILING_CR;
if (BYTE_TYPE(enc, ptr) == BT_LF)
ptr += MINBPC(enc);
*nextTokPtr = ptr;
return XML_TOK_DATA_NEWLINE;
}
*nextTokPtr = ptr;
return XML_TOK_DATA_CHARS;
case BT_S:
if (ptr == start) {
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_ATTRIBUTE_VALUE_S;
}
*nextTokPtr = ptr;
return XML_TOK_DATA_CHARS;
default:
ptr += MINBPC(enc);
break;
}
}
*nextTokPtr = ptr;
return XML_TOK_DATA_CHARS;
}
static int PTRCALL
PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
const char *start;
- if (ptr == end)
+ if (ptr >= end)
return XML_TOK_NONE;
+ else if (! HAS_CHAR(enc, ptr, end))
+ return XML_TOK_PARTIAL;
start = ptr;
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
#define LEAD_CASE(n) \
case BT_LEAD ## n: ptr += n; break;
LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
#undef LEAD_CASE
case BT_AMP:
if (ptr == start)
return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
*nextTokPtr = ptr;
return XML_TOK_DATA_CHARS;
case BT_PERCNT:
if (ptr == start) {
int tok = PREFIX(scanPercent)(enc, ptr + MINBPC(enc),
end, nextTokPtr);
return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok;
}
*nextTokPtr = ptr;
return XML_TOK_DATA_CHARS;
case BT_LF:
if (ptr == start) {
*nextTokPtr = ptr + MINBPC(enc);
return XML_TOK_DATA_NEWLINE;
}
*nextTokPtr = ptr;
return XML_TOK_DATA_CHARS;
case BT_CR:
if (ptr == start) {
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return XML_TOK_TRAILING_CR;
if (BYTE_TYPE(enc, ptr) == BT_LF)
ptr += MINBPC(enc);
*nextTokPtr = ptr;
return XML_TOK_DATA_NEWLINE;
}
*nextTokPtr = ptr;
return XML_TOK_DATA_CHARS;
default:
ptr += MINBPC(enc);
break;
}
}
*nextTokPtr = ptr;
return XML_TOK_DATA_CHARS;
}
#ifdef XML_DTD
static int PTRCALL
PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
int level = 0;
if (MINBPC(enc) > 1) {
size_t n = end - ptr;
if (n & (MINBPC(enc) - 1)) {
n &= ~(MINBPC(enc) - 1);
end = ptr + n;
}
}
- while (ptr != end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
INVALID_CASES(ptr, nextTokPtr)
case BT_LT:
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
++level;
ptr += MINBPC(enc);
}
}
break;
case BT_RSQB:
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
ptr += MINBPC(enc);
if (level == 0) {
*nextTokPtr = ptr;
return XML_TOK_IGNORE_SECT;
}
--level;
}
}
break;
default:
ptr += MINBPC(enc);
break;
}
}
return XML_TOK_PARTIAL;
}
#endif /* XML_DTD */
static int PTRCALL
PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
const char **badPtr)
{
ptr += MINBPC(enc);
end -= MINBPC(enc);
- for (; ptr != end; ptr += MINBPC(enc)) {
+ for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_DIGIT:
case BT_HEX:
case BT_MINUS:
case BT_APOS:
case BT_LPAR:
case BT_RPAR:
case BT_PLUS:
case BT_COMMA:
case BT_SOL:
case BT_EQUALS:
case BT_QUEST:
case BT_CR:
case BT_LF:
case BT_SEMI:
case BT_EXCL:
case BT_AST:
case BT_PERCNT:
case BT_NUM:
#ifdef XML_NS
case BT_COLON:
#endif
break;
case BT_S:
if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {
*badPtr = ptr;
return 0;
}
break;
case BT_NAME:
@@ -1494,105 +1490,105 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
else if (state == inValue
&& nAtts < attsMax
&& atts[nAtts].normalized
&& (ptr == atts[nAtts].valuePtr
|| BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
|| BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
|| BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
atts[nAtts].normalized = 0;
break;
case BT_CR: case BT_LF:
/* This case ensures that the first attribute name is counted
Apart from that we could just change state on the quote. */
if (state == inName)
state = other;
else if (state == inValue && nAtts < attsMax)
atts[nAtts].normalized = 0;
break;
case BT_GT:
case BT_SOL:
if (state != inValue)
return nAtts;
break;
default:
break;
}
}
/* not reached */
}
static int PTRFASTCALL
-PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
+PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr)
{
int result = 0;
/* skip &# */
ptr += 2*MINBPC(enc);
if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
for (ptr += MINBPC(enc);
!CHAR_MATCHES(enc, ptr, ASCII_SEMI);
ptr += MINBPC(enc)) {
int c = BYTE_TO_ASCII(enc, ptr);
switch (c) {
case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4:
case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9:
result <<= 4;
result |= (c - ASCII_0);
break;
case ASCII_A: case ASCII_B: case ASCII_C:
case ASCII_D: case ASCII_E: case ASCII_F:
result <<= 4;
result += 10 + (c - ASCII_A);
break;
case ASCII_a: case ASCII_b: case ASCII_c:
case ASCII_d: case ASCII_e: case ASCII_f:
result <<= 4;
result += 10 + (c - ASCII_a);
break;
}
if (result >= 0x110000)
return -1;
}
}
else {
for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
int c = BYTE_TO_ASCII(enc, ptr);
result *= 10;
result += (c - ASCII_0);
if (result >= 0x110000)
return -1;
}
}
return checkCharRefNumber(result);
}
static int PTRCALL
-PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
+PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr,
const char *end)
{
switch ((end - ptr)/MINBPC(enc)) {
case 2:
if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
switch (BYTE_TO_ASCII(enc, ptr)) {
case ASCII_l:
return ASCII_LT;
case ASCII_g:
return ASCII_GT;
}
}
break;
case 3:
if (CHAR_MATCHES(enc, ptr, ASCII_a)) {
ptr += MINBPC(enc);
if (CHAR_MATCHES(enc, ptr, ASCII_m)) {
ptr += MINBPC(enc);
if (CHAR_MATCHES(enc, ptr, ASCII_p))
return ASCII_AMP;
}
}
break;
case 4:
switch (BYTE_TO_ASCII(enc, ptr)) {
case ASCII_q:
ptr += MINBPC(enc);
if (CHAR_MATCHES(enc, ptr, ASCII_u)) {
ptr += MINBPC(enc);
if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
@@ -1656,128 +1652,128 @@ PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
}
}
}
break;
default:
if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
return 1;
switch (BYTE_TYPE(enc, ptr2)) {
case BT_LEAD2:
case BT_LEAD3:
case BT_LEAD4:
case BT_NONASCII:
case BT_NMSTRT:
#ifdef XML_NS
case BT_COLON:
#endif
case BT_HEX:
case BT_DIGIT:
case BT_NAME:
case BT_MINUS:
return 0;
default:
return 1;
}
}
}
/* not reached */
}
static int PTRCALL
-PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
+PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1,
const char *end1, const char *ptr2)
{
for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
- if (ptr1 == end1)
+ if (end1 - ptr1 < MINBPC(enc))
return 0;
if (!CHAR_MATCHES(enc, ptr1, *ptr2))
return 0;
}
return ptr1 == end1;
}
static int PTRFASTCALL
PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
{
const char *start = ptr;
for (;;) {
switch (BYTE_TYPE(enc, ptr)) {
#define LEAD_CASE(n) \
case BT_LEAD ## n: ptr += n; break;
LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
#undef LEAD_CASE
case BT_NONASCII:
case BT_NMSTRT:
#ifdef XML_NS
case BT_COLON:
#endif
case BT_HEX:
case BT_DIGIT:
case BT_NAME:
case BT_MINUS:
ptr += MINBPC(enc);
break;
default:
return (int)(ptr - start);
}
}
}
static const char * PTRFASTCALL
PREFIX(skipS)(const ENCODING *enc, const char *ptr)
{
for (;;) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_LF:
case BT_CR:
case BT_S:
ptr += MINBPC(enc);
break;
default:
return ptr;
}
}
}
static void PTRCALL
PREFIX(updatePosition)(const ENCODING *enc,
const char *ptr,
const char *end,
POSITION *pos)
{
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
#define LEAD_CASE(n) \
case BT_LEAD ## n: \
ptr += n; \
break;
LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
#undef LEAD_CASE
case BT_LF:
pos->columnNumber = (XML_Size)-1;
pos->lineNumber++;
ptr += MINBPC(enc);
break;
case BT_CR:
pos->lineNumber++;
ptr += MINBPC(enc);
- if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
+ if (HAS_CHAR(enc, ptr, end) && BYTE_TYPE(enc, ptr) == BT_LF)
ptr += MINBPC(enc);
pos->columnNumber = (XML_Size)-1;
break;
default:
ptr += MINBPC(enc);
break;
}
pos->columnNumber++;
}
}
#undef DO_LEAD_CASE
#undef MULTIBYTE_CASES
#undef INVALID_CASES
#undef CHECK_NAME_CASE
#undef CHECK_NAME_CASES
#undef CHECK_NMSTRT_CASE
#undef CHECK_NMSTRT_CASES
#endif /* XML_TOK_IMPL_C */