diff options
author | Tobias Markmann <tm@ayena.de> | 2017-06-20 12:17:48 (GMT) |
---|---|---|
committer | Tobias Markmann <tm@ayena.de> | 2017-06-20 14:43:05 (GMT) |
commit | a507a88a189bb603c9f2d686c9c8dafca49c053d (patch) | |
tree | ac32d8281fdefb83f3a0d9ef79c3983d98bed24d | |
parent | b807e3fa975cf25e5e901b59643419a5a73a12fe (diff) | |
download | swift-a507a88a189bb603c9f2d686c9c8dafca49c053d.zip swift-a507a88a189bb603c9f2d686c9c8dafca49c053d.tar.bz2 |
Update 3rdParty/Expat to version 2.2.1
Test-Information:
Build successfully on macOS 10.12.5 with clang trunk and
./scons test=all try_libxml=no try_expat=no .
Change-Id: I0cc0680086ea40f92bbfa7296d10beb08cc657e3
-rw-r--r-- | 3rdParty/Expat/src/COPYING | 5 | ||||
-rw-r--r-- | 3rdParty/Expat/src/Changes | 389 | ||||
-rw-r--r-- | 3rdParty/Expat/src/expat.h | 35 | ||||
-rw-r--r-- | 3rdParty/Expat/src/expat_external.h | 19 | ||||
-rw-r--r-- | 3rdParty/Expat/src/internal.h | 22 | ||||
-rw-r--r-- | 3rdParty/Expat/src/siphash.h | 344 | ||||
-rw-r--r-- | 3rdParty/Expat/src/winconfig.h | 40 | ||||
-rw-r--r-- | 3rdParty/Expat/src/xmlparse.c | 734 | ||||
-rw-r--r-- | 3rdParty/Expat/src/xmlrole.c | 230 | ||||
-rw-r--r-- | 3rdParty/Expat/src/xmltok.c | 244 | ||||
-rw-r--r-- | 3rdParty/Expat/src/xmltok.h | 10 | ||||
-rw-r--r-- | 3rdParty/Expat/src/xmltok_impl.c | 226 | ||||
-rw-r--r-- | COPYING.dependencies | 5 |
13 files changed, 1820 insertions, 483 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,4 +1,3 @@ -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 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 @@ -97,3 +97,5 @@ enum XML_Error { XML_ERROR_RESERVED_PREFIX_XMLNS, - XML_ERROR_RESERVED_NAMESPACE_URI + XML_ERROR_RESERVED_NAMESPACE_URI, + /* Added in 2.2.1. */ + XML_ERROR_INVALID_ARGUMENT }; @@ -344,3 +346,3 @@ XML_SetEntityDeclHandler(XML_Parser parser, /* 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. @@ -708,2 +710,3 @@ XML_UseParserAsHandlerArg(XML_Parser parser); XML_ERROR_FEATURE_REQUIRES_XML_DTD. + Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT. */ @@ -731,3 +734,3 @@ XML_GetBase(XML_Parser parser); this correspondds to an index into the atts array passed to the - XML_StartElementHandler. + XML_StartElementHandler. Returns -1 if parser == NULL. */ @@ -737,5 +740,6 @@ 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. */ @@ -903,2 +907,3 @@ enum XML_ParamEntityParsing { XML_ParseBuffer, then it has no effect and will always return 0. + Note: If parser == NULL, the function will do nothing and return 0. */ @@ -912,2 +917,3 @@ XML_SetParamEntityParsing(XML_Parser parser, Returns 1 if successful, 0 when called after parsing has started. + Note: If parser == NULL, the function will do nothing and return 0. */ @@ -938,2 +944,6 @@ XML_GetErrorCode(XML_Parser parser); 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. */ @@ -975,2 +985,4 @@ XML_FreeContentModel(XML_Parser parser, XML_Content *model); XMLPARSEAPI(void *) +XML_ATTR_MALLOC +XML_ATTR_ALLOC_SIZE(2) XML_MemMalloc(XML_Parser parser, size_t size); @@ -978,2 +990,3 @@ 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); @@ -1033,10 +1046,8 @@ 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 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 @@ -67,2 +67,5 @@ +#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4) +#define XMLIMPORT __attribute__ ((visibility ("default"))) +#endif @@ -73,2 +76,13 @@ +#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 @@ -81,3 +95,6 @@ extern "C" { #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 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 @@ -73 +73,23 @@ #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 @@ -2,4 +2,8 @@ See the file COPYING for copying permission. + + 77fea421d361dca90041d0040ecf1dca651167fadf2af79e990e35168d70d933 (2.2.1+) */ +#define _GNU_SOURCE /* syscall prototype */ + #include <stddef.h> @@ -8,3 +12,12 @@ #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 @@ -12,13 +25,7 @@ -#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 */ @@ -26,2 +33,3 @@ #include "expat.h" +#include "siphash.h" @@ -104,13 +112,7 @@ typedef struct { -/* 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); @@ -350,2 +352,4 @@ doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, +static void +freeBindings(XML_Parser parser, BINDING *bindings); static enum XML_Error @@ -434,3 +438,3 @@ getElementType(XML_Parser parser, const ENCODING *enc, -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); @@ -692,8 +696,151 @@ static const XML_Char implicitContext[] = { + +#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; } @@ -705,3 +852,3 @@ startParsing(XML_Parser parser) if (hash_secret_salt == 0) - hash_secret_salt = generate_hash_secret_salt(); + hash_secret_salt = generate_hash_secret_salt(parser); if (ns) { @@ -928,2 +1075,6 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) OPEN_INTERNAL_ENTITY *openEntityList; + + if (parser == NULL) + return XML_FALSE; + if (parentParser) @@ -962,2 +1113,4 @@ 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. @@ -985,42 +1138,34 @@ XML_ExternalEntityParserCreate(XML_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 @@ -1030,3 +1175,47 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, */ - 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; @@ -1196,3 +1385,4 @@ XML_UseParserAsHandlerArg(XML_Parser parser) { - handlerArg = parser; + if (parser != NULL) + handlerArg = parser; } @@ -1202,2 +1392,4 @@ XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) { + if (parser == NULL) + return XML_ERROR_INVALID_ARGUMENT; #ifdef XML_DTD @@ -1216,2 +1408,4 @@ XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) { + if (parser == NULL) + return; /* block after XML_Parse()/XML_ParseBuffer() has been called */ @@ -1225,2 +1419,4 @@ XML_SetUserData(XML_Parser parser, void *p) { + if (parser == NULL) + return; if (handlerArg == userData) @@ -1234,2 +1430,4 @@ XML_SetBase(XML_Parser parser, const XML_Char *p) { + if (parser == NULL) + return XML_STATUS_ERROR; if (p) { @@ -1248,2 +1446,4 @@ XML_GetBase(XML_Parser parser) { + if (parser == NULL) + return NULL; return curBase; @@ -1254,2 +1454,4 @@ XML_GetSpecifiedAttributeCount(XML_Parser parser) { + if (parser == NULL) + return -1; return nSpecifiedAtts; @@ -1260,2 +1462,4 @@ XML_GetIdAttributeIndex(XML_Parser parser) { + if (parser == NULL) + return -1; return idAttIndex; @@ -1267,2 +1471,4 @@ XML_GetAttributeInfo(XML_Parser parser) { + if (parser == NULL) + return NULL; return attInfo; @@ -1276,2 +1482,4 @@ XML_SetElementHandler(XML_Parser parser, { + if (parser == NULL) + return; startElementHandler = start; @@ -1283,3 +1491,4 @@ XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) { - startElementHandler = start; + if (parser != NULL) + startElementHandler = start; } @@ -1289,3 +1498,4 @@ XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) { - endElementHandler = end; + if (parser != NULL) + endElementHandler = end; } @@ -1296,3 +1506,4 @@ XML_SetCharacterDataHandler(XML_Parser parser, { - characterDataHandler = handler; + if (parser != NULL) + characterDataHandler = handler; } @@ -1303,3 +1514,4 @@ XML_SetProcessingInstructionHandler(XML_Parser parser, { - processingInstructionHandler = handler; + if (parser != NULL) + processingInstructionHandler = handler; } @@ -1310,3 +1522,4 @@ XML_SetCommentHandler(XML_Parser parser, { - commentHandler = handler; + if (parser != NULL) + commentHandler = handler; } @@ -1318,2 +1531,4 @@ XML_SetCdataSectionHandler(XML_Parser parser, { + if (parser == NULL) + return; startCdataSectionHandler = start; @@ -1325,3 +1540,4 @@ XML_SetStartCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start) { - startCdataSectionHandler = start; + if (parser != NULL) + startCdataSectionHandler = start; } @@ -1331,3 +1547,4 @@ XML_SetEndCdataSectionHandler(XML_Parser parser, XML_EndCdataSectionHandler end) { - endCdataSectionHandler = end; + if (parser != NULL) + endCdataSectionHandler = end; } @@ -1338,2 +1555,4 @@ XML_SetDefaultHandler(XML_Parser parser, { + if (parser == NULL) + return; defaultHandler = handler; @@ -1346,2 +1565,4 @@ XML_SetDefaultHandlerExpand(XML_Parser parser, { + if (parser == NULL) + return; defaultHandler = handler; @@ -1355,2 +1576,4 @@ XML_SetDoctypeDeclHandler(XML_Parser parser, { + if (parser == NULL) + return; startDoctypeDeclHandler = start; @@ -1362,3 +1585,4 @@ XML_SetStartDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start) { - startDoctypeDeclHandler = start; + if (parser != NULL) + startDoctypeDeclHandler = start; } @@ -1368,3 +1592,4 @@ XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) { - endDoctypeDeclHandler = end; + if (parser != NULL) + endDoctypeDeclHandler = end; } @@ -1375,3 +1600,4 @@ XML_SetUnparsedEntityDeclHandler(XML_Parser parser, { - unparsedEntityDeclHandler = handler; + if (parser != NULL) + unparsedEntityDeclHandler = handler; } @@ -1382,3 +1608,4 @@ XML_SetNotationDeclHandler(XML_Parser parser, { - notationDeclHandler = handler; + if (parser != NULL) + notationDeclHandler = handler; } @@ -1390,2 +1617,4 @@ XML_SetNamespaceDeclHandler(XML_Parser parser, { + if (parser == NULL) + return; startNamespaceDeclHandler = start; @@ -1397,3 +1626,4 @@ XML_SetStartNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start) { - startNamespaceDeclHandler = start; + if (parser != NULL) + startNamespaceDeclHandler = start; } @@ -1403,3 +1633,4 @@ XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler end) { - endNamespaceDeclHandler = end; + if (parser != NULL) + endNamespaceDeclHandler = end; } @@ -1410,3 +1641,4 @@ XML_SetNotStandaloneHandler(XML_Parser parser, { - notStandaloneHandler = handler; + if (parser != NULL) + notStandaloneHandler = handler; } @@ -1417,3 +1649,4 @@ XML_SetExternalEntityRefHandler(XML_Parser parser, { - externalEntityRefHandler = handler; + if (parser != NULL) + externalEntityRefHandler = handler; } @@ -1423,2 +1656,4 @@ XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) { + if (parser == NULL) + return; if (arg) @@ -1433,3 +1668,4 @@ XML_SetSkippedEntityHandler(XML_Parser parser, { - skippedEntityHandler = handler; + if (parser != NULL) + skippedEntityHandler = handler; } @@ -1441,2 +1677,4 @@ XML_SetUnknownEncodingHandler(XML_Parser parser, { + if (parser == NULL) + return; unknownEncodingHandler = handler; @@ -1449,3 +1687,4 @@ XML_SetElementDeclHandler(XML_Parser parser, { - elementDeclHandler = eldecl; + if (parser != NULL) + elementDeclHandler = eldecl; } @@ -1456,3 +1695,4 @@ XML_SetAttlistDeclHandler(XML_Parser parser, { - attlistDeclHandler = attdecl; + if (parser != NULL) + attlistDeclHandler = attdecl; } @@ -1463,3 +1703,4 @@ XML_SetEntityDeclHandler(XML_Parser parser, { - entityDeclHandler = handler; + if (parser != NULL) + entityDeclHandler = handler; } @@ -1469,3 +1710,4 @@ XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) { - xmlDeclHandler = handler; + if (parser != NULL) + xmlDeclHandler = handler; } @@ -1476,2 +1718,4 @@ XML_SetParamEntityParsing(XML_Parser parser, { + if (parser == NULL) + return 0; /* block after XML_Parse()/XML_ParseBuffer() has been called */ @@ -1491,2 +1735,6 @@ XML_SetHashSalt(XML_Parser parser, { + 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 */ @@ -1501,2 +1749,6 @@ 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) { @@ -1552,3 +1804,10 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) 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; @@ -1585,7 +1844,10 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) 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) { @@ -1597,3 +1859,3 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) buffer = temp; - bufferLim = buffer + len * 2; + bufferLim = buffer + bytesToAllocate; } @@ -1627,2 +1889,4 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) + if (parser == NULL) + return XML_STATUS_ERROR; switch (ps_parsing) { @@ -1680,2 +1944,8 @@ 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) { @@ -1691,7 +1961,13 @@ XML_GetBuffer(XML_Parser parser, int len) 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) @@ -1720,4 +1996,9 @@ XML_GetBuffer(XML_Parser parser, int len) 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); @@ -1761,2 +2042,4 @@ XML_StopParser(XML_Parser parser, XML_Bool resumable) { + if (parser == NULL) + return XML_STATUS_ERROR; switch (ps_parsing) { @@ -1793,2 +2076,4 @@ XML_ResumeParser(XML_Parser parser) + if (parser == NULL) + return XML_STATUS_ERROR; if (ps_parsing != XML_SUSPENDED) { @@ -1829,2 +2114,4 @@ XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) { + if (parser == NULL) + return; assert(status != NULL); @@ -1836,2 +2123,4 @@ XML_GetErrorCode(XML_Parser parser) { + if (parser == NULL) + return XML_ERROR_INVALID_ARGUMENT; return errorCode; @@ -1842,4 +2131,6 @@ XML_GetCurrentByteIndex(XML_Parser parser) { + if (parser == NULL) + return -1; if (eventPtr) - return parseEndByteIndex - (parseEndPtr - eventPtr); + return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr)); return -1; @@ -1850,2 +2141,4 @@ XML_GetCurrentByteCount(XML_Parser parser) { + if (parser == NULL) + return 0; if (eventEndPtr && eventPtr) @@ -1859,7 +2152,15 @@ 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 */ @@ -1871,2 +2172,4 @@ XML_GetCurrentLineNumber(XML_Parser parser) { + if (parser == NULL) + return 0; if (eventPtr && eventPtr >= positionPtr) { @@ -1881,2 +2184,4 @@ XML_GetCurrentColumnNumber(XML_Parser parser) { + if (parser == NULL) + return 0; if (eventPtr && eventPtr >= positionPtr) { @@ -1891,3 +2196,4 @@ XML_FreeContentModel(XML_Parser parser, XML_Content *model) { - FREE(model); + if (parser != NULL) + FREE(model); } @@ -1897,2 +2203,4 @@ XML_MemMalloc(XML_Parser parser, size_t size) { + if (parser == NULL) + return NULL; return MALLOC(size); @@ -1903,2 +2211,4 @@ XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) { + if (parser == NULL) + return NULL; return REALLOC(ptr, size); @@ -1909,3 +2219,4 @@ XML_MemFree(XML_Parser parser, void *ptr) { - FREE(ptr); + if (parser != NULL) + FREE(ptr); } @@ -1915,2 +2226,4 @@ XML_DefaultCurrent(XML_Parser parser) { + if (parser == NULL) + return; if (defaultHandler) { @@ -2417,3 +2730,3 @@ doContent(XML_Parser parser, int convLen; - XmlConvert(enc, + const enum XML_Convert_Result convert_res = XmlConvert(enc, &fromPtr, rawNameEnd, @@ -2421,3 +2734,3 @@ doContent(XML_Parser parser, convLen = (int)(toPtr - (XML_Char *)tag->buf); - if (fromPtr == rawNameEnd) { + if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { tag->name.strLen = convLen; @@ -2464,4 +2777,6 @@ doContent(XML_Parser parser, result = storeAtts(parser, enc, s, &name, &bindings); - if (result) + if (result != XML_ERROR_NONE) { + freeBindings(parser, bindings); return result; + } poolFinish(&tempPool); @@ -2480,11 +2795,3 @@ doContent(XML_Parser parser, 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); } @@ -2642,3 +2949,3 @@ doContent(XML_Parser parser, 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; @@ -2646,3 +2953,3 @@ doContent(XML_Parser parser, (int)(dataPtr - (ICHAR *)dataBuf)); - if (s == next) + if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) break; @@ -2686,2 +2993,25 @@ doContent(XML_Parser parser, +/* 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; @@ -2910,12 +3240,17 @@ storeAtts(XML_Parser parser, const ENCODING *enc, 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++) { @@ -2924,13 +3259,18 @@ storeAtts(XML_Parser parser, const ENCODING *enc, 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). @@ -2995,3 +3335,3 @@ storeAtts(XML_Parser parser, const ENCODING *enc, /* expand the element type name */ - if (elementType->prefix && elementType->prefix->binding) { + if (elementType->prefix) { binding = elementType->prefix->binding; @@ -3091,6 +3431,6 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, /* 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; @@ -3111,8 +3451,8 @@ addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, - /*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; @@ -3252,3 +3592,3 @@ doCdataSection(XML_Parser parser, 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; @@ -3256,3 +3596,3 @@ doCdataSection(XML_Parser parser, (int)(dataPtr - (ICHAR *)dataBuf)); - if (s == next) + if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) break; @@ -3648,2 +3988,10 @@ entityValueInitProcessor(XML_Parser parser, } + /* 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; @@ -4824,2 +5172,4 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, textEnd = (char *)(entity->textPtr + entity->textLen); + /* Set a safe default value in case 'next' does not get set */ + next = textStart; @@ -4869,2 +5219,4 @@ internalEntityProcessor(XML_Parser parser, textEnd = (char *)(entity->textPtr + entity->textLen); + /* Set a safe default value in case 'next' does not get set */ + next = textStart; @@ -4915,5 +5267,5 @@ 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)) { @@ -5333,2 +5685,3 @@ reportDefault(XML_Parser parser, const ENCODING *enc, if (MUST_CONVERT(enc, s)) { + enum XML_Convert_Result convert_res; const char **eventPP; @@ -5345,3 +5698,3 @@ reportDefault(XML_Parser parser, const ENCODING *enc, ICHAR *dataPtr = (ICHAR *)dataBuf; - XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); + convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); *eventEndPP = s; @@ -5349,3 +5702,3 @@ reportDefault(XML_Parser parser, const ENCODING *enc, *eventPP = s; - } while (s != end); + } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE)); } @@ -5479,2 +5832,4 @@ getAttributeId(XML_Parser parser, const ENCODING *enc, sizeof(PREFIX)); + if (!id->prefix) + return NULL; if (id->prefix->name == poolStart(&dtd->pool)) @@ -5826,3 +6181,2 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H if (!newE->defaultAtts) { - ms->free_fcn(newE); return 0; @@ -5961,2 +6315,17 @@ keyeq(KEY s1, KEY s2) +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 @@ -5964,6 +6333,10 @@ 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); } @@ -6152,4 +6525,4 @@ poolAppend(STRING_POOL *pool, const ENCODING *enc, 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; @@ -6210,2 +6583,31 @@ poolStoreString(STRING_POOL *pool, const ENCODING *enc, +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 @@ -6237,7 +6639,15 @@ poolGrow(STRING_POOL *pool) 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) @@ -6253,8 +6663,22 @@ poolGrow(STRING_POOL *pool) 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) 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 @@ -6,10 +6,4 @@ -#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 @@ -18,3 +12,3 @@ #endif -#endif /* ndef COMPILED_FROM_DSP */ +#endif /* ndef _WIN32 */ @@ -197,5 +191,5 @@ 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)) { @@ -218,5 +212,5 @@ 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)) { @@ -266,5 +260,5 @@ 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)) { @@ -283,5 +277,5 @@ 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)) { @@ -300,5 +294,5 @@ 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)) { @@ -320,5 +314,5 @@ 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)) { @@ -439,5 +433,5 @@ 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)) { @@ -459,5 +453,5 @@ 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)) { @@ -504,5 +498,5 @@ 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)) { @@ -521,5 +515,5 @@ 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)) { @@ -561,5 +555,5 @@ 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)) { @@ -607,5 +601,5 @@ 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)) { @@ -624,5 +618,5 @@ 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)) { @@ -641,5 +635,5 @@ 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)) { @@ -658,5 +652,5 @@ 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)) { @@ -699,5 +693,5 @@ 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)) { @@ -716,5 +710,5 @@ 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)) { @@ -734,5 +728,5 @@ 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)) { @@ -755,5 +749,5 @@ 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)) { @@ -773,5 +767,5 @@ 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)) { @@ -835,5 +829,5 @@ 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)) { @@ -854,5 +848,5 @@ 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)) { @@ -874,5 +868,5 @@ 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)) { @@ -891,5 +885,5 @@ 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)) { @@ -908,5 +902,5 @@ 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)) { @@ -969,5 +963,5 @@ 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)) { @@ -986,5 +980,5 @@ 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)) { @@ -1074,5 +1068,5 @@ 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)) { @@ -1099,5 +1093,5 @@ 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)) { @@ -1117,5 +1111,5 @@ 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)) { @@ -1138,5 +1132,5 @@ 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)) { @@ -1168,5 +1162,5 @@ 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)) { @@ -1242,5 +1236,5 @@ 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)) { @@ -1260,5 +1254,5 @@ 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)) { @@ -1279,5 +1273,5 @@ 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)) { @@ -1294,7 +1288,7 @@ declClose(PROLOG_STATE *state, 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)) { 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 @@ -6,10 +6,4 @@ -#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 @@ -18,3 +12,3 @@ #endif -#endif /* ndef COMPILED_FROM_DSP */ +#endif /* ndef _WIN32 */ @@ -48,3 +42,3 @@ #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))) @@ -58,3 +52,3 @@ + ((((byte)[1]) >> 5) & 1)] \ - & (1 << (((byte)[1]) & 0x1F))) + & (1u << (((byte)[1]) & 0x1F))) @@ -71,3 +65,3 @@ + ((((byte)[2]) >> 5) & 1)] \ - & (1 << (((byte)[2]) & 0x1F))) + & (1u << (((byte)[2]) & 0x1F))) @@ -124,3 +118,3 @@ static int PTRFASTCALL -isNever(const ENCODING *enc, const char *p) +isNever(const ENCODING *UNUSED_P(enc), const char *UNUSED_P(p)) { @@ -130,3 +124,3 @@ isNever(const ENCODING *enc, const char *p) static int PTRFASTCALL -utf8_isName2(const ENCODING *enc, const char *p) +utf8_isName2(const ENCODING *UNUSED_P(enc), const char *p) { @@ -136,3 +130,3 @@ utf8_isName2(const ENCODING *enc, const char *p) static int PTRFASTCALL -utf8_isName3(const ENCODING *enc, const char *p) +utf8_isName3(const ENCODING *UNUSED_P(enc), const char *p) { @@ -144,3 +138,3 @@ utf8_isName3(const ENCODING *enc, const char *p) static int PTRFASTCALL -utf8_isNmstrt2(const ENCODING *enc, const char *p) +utf8_isNmstrt2(const ENCODING *UNUSED_P(enc), const char *p) { @@ -150,3 +144,3 @@ utf8_isNmstrt2(const ENCODING *enc, const char *p) static int PTRFASTCALL -utf8_isNmstrt3(const ENCODING *enc, const char *p) +utf8_isNmstrt3(const ENCODING *UNUSED_P(enc), const char *p) { @@ -158,3 +152,3 @@ utf8_isNmstrt3(const ENCODING *enc, const char *p) static int PTRFASTCALL -utf8_isInvalid2(const ENCODING *enc, const char *p) +utf8_isInvalid2(const ENCODING *UNUSED_P(enc), const char *p) { @@ -164,3 +158,3 @@ utf8_isInvalid2(const ENCODING *enc, const char *p) static int PTRFASTCALL -utf8_isInvalid3(const ENCODING *enc, const char *p) +utf8_isInvalid3(const ENCODING *UNUSED_P(enc), const char *p) { @@ -170,3 +164,3 @@ utf8_isInvalid3(const ENCODING *enc, const char *p) static int PTRFASTCALL -utf8_isInvalid4(const ENCODING *enc, const char *p) +utf8_isInvalid4(const ENCODING *UNUSED_P(enc), const char *p) { @@ -224,2 +218,13 @@ struct normal_encoding { +#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); @@ -320,4 +325,39 @@ enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ -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, @@ -327,9 +367,8 @@ utf8_toUtf8(const ENCODING *enc, 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; @@ -337,5 +376,12 @@ utf8_toUtf8(const ENCODING *enc, *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, @@ -344,7 +390,12 @@ utf8_toUtf16(const ENCODING *enc, { + 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)); @@ -353,2 +404,6 @@ utf8_toUtf16(const ENCODING *enc, case BT_LEAD3: + if (fromLim - from < 3) { + res = XML_CONVERT_INPUT_INCOMPLETE; + goto after; + } *to++ = (unsigned short)(((from[0] & 0xf) << 12) @@ -360,4 +415,10 @@ utf8_toUtf16(const ENCODING *enc, 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) @@ -376,2 +437,4 @@ utf8_toUtf16(const ENCODING *enc, } + if (from < fromLim) + res = XML_CONVERT_OUTPUT_EXHAUSTED; after: @@ -379,2 +442,3 @@ after: *toP = to; + return res; } @@ -427,4 +491,4 @@ static const struct normal_encoding internal_utf8_encoding = { -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, @@ -435,3 +499,3 @@ latin1_toUtf8(const ENCODING *enc, if (*fromP == fromLim) - break; + return XML_CONVERT_COMPLETED; c = (unsigned char)**fromP; @@ -439,3 +503,3 @@ latin1_toUtf8(const ENCODING *enc, if (toLim - *toP < 2) - break; + return XML_CONVERT_OUTPUT_EXHAUSTED; *(*toP)++ = (char)((c >> 6) | UTF8_cval2); @@ -446,3 +510,3 @@ latin1_toUtf8(const ENCODING *enc, if (*toP == toLim) - break; + return XML_CONVERT_OUTPUT_EXHAUSTED; *(*toP)++ = *(*fromP)++; @@ -452,4 +516,4 @@ latin1_toUtf8(const ENCODING *enc, -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, @@ -457,4 +521,9 @@ latin1_toUtf16(const ENCODING *enc, { - 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; } @@ -469,3 +538,3 @@ static const struct normal_encoding latin1_encoding_ns = { }, - STANDARD_VTABLE(sb_) + STANDARD_VTABLE(sb_) NULL_VTABLE }; @@ -482,7 +551,7 @@ static const struct normal_encoding latin1_encoding = { }, - 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, @@ -490,4 +559,9 @@ ascii_toUtf8(const ENCODING *enc, { - 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; } @@ -502,3 +576,3 @@ static const struct normal_encoding ascii_encoding_ns = { }, - STANDARD_VTABLE(sb_) + STANDARD_VTABLE(sb_) NULL_VTABLE }; @@ -515,3 +589,3 @@ static const struct normal_encoding ascii_encoding = { }, - STANDARD_VTABLE(sb_) + STANDARD_VTABLE(sb_) NULL_VTABLE }; @@ -538,4 +612,4 @@ unicode_byte_type(char hi, char lo) #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, \ @@ -543,4 +617,5 @@ E ## toUtf8(const ENCODING *enc, \ { \ - 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; \ @@ -554,3 +629,3 @@ E ## toUtf8(const ENCODING *enc, \ *fromP = from; \ - return; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ @@ -564,3 +639,3 @@ E ## toUtf8(const ENCODING *enc, \ *fromP = from; \ - return; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ @@ -572,3 +647,3 @@ E ## toUtf8(const ENCODING *enc, \ *fromP = from; \ - return; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ @@ -582,3 +657,7 @@ E ## toUtf8(const ENCODING *enc, \ *fromP = from; \ - return; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + } \ + if (fromLim - from < 4) { \ + *fromP = from; \ + return XML_CONVERT_INPUT_INCOMPLETE; \ } \ @@ -598,2 +677,6 @@ E ## toUtf8(const ENCODING *enc, \ *fromP = from; \ + if (from < fromLim) \ + return XML_CONVERT_INPUT_INCOMPLETE; \ + else \ + return XML_CONVERT_COMPLETED; \ } @@ -601,4 +684,4 @@ E ## toUtf8(const ENCODING *enc, \ #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, \ @@ -606,8 +689,16 @@ E ## toUtf16(const ENCODING *enc, \ { \ + 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; \ } @@ -728,3 +819,3 @@ static const struct normal_encoding little2_encoding_ns = { }, - STANDARD_VTABLE(little2_) + STANDARD_VTABLE(little2_) NULL_VTABLE }; @@ -747,3 +838,3 @@ static const struct normal_encoding little2_encoding = { }, - STANDARD_VTABLE(little2_) + STANDARD_VTABLE(little2_) NULL_VTABLE }; @@ -760,3 +851,3 @@ static const struct normal_encoding internal_little2_encoding_ns = { }, - STANDARD_VTABLE(little2_) + STANDARD_VTABLE(little2_) NULL_VTABLE }; @@ -773,3 +864,3 @@ static const struct normal_encoding internal_little2_encoding = { }, - STANDARD_VTABLE(little2_) + STANDARD_VTABLE(little2_) NULL_VTABLE }; @@ -869,3 +960,3 @@ static const struct normal_encoding big2_encoding_ns = { }, - STANDARD_VTABLE(big2_) + STANDARD_VTABLE(big2_) NULL_VTABLE }; @@ -888,3 +979,3 @@ static const struct normal_encoding big2_encoding = { }, - STANDARD_VTABLE(big2_) + STANDARD_VTABLE(big2_) NULL_VTABLE }; @@ -901,3 +992,3 @@ static const struct normal_encoding internal_big2_encoding_ns = { }, - STANDARD_VTABLE(big2_) + STANDARD_VTABLE(big2_) NULL_VTABLE }; @@ -914,3 +1005,3 @@ static const struct normal_encoding internal_big2_encoding = { }, - STANDARD_VTABLE(big2_) + STANDARD_VTABLE(big2_) NULL_VTABLE }; @@ -940,3 +1031,3 @@ streqci(const char *s1, const char *s2) static void PTRCALL -initUpdatePosition(const ENCODING *enc, const char *ptr, +initUpdatePosition(const ENCODING *UNUSED_P(enc), const char *ptr, const char *end, POSITION *pos) @@ -1290,3 +1381,3 @@ unknown_isInvalid(const ENCODING *enc, const char *p) -static void PTRCALL +static enum XML_Convert_Result PTRCALL unknown_toUtf8(const ENCODING *enc, @@ -1301,3 +1392,3 @@ unknown_toUtf8(const ENCODING *enc, if (*fromP == fromLim) - break; + return XML_CONVERT_COMPLETED; utf8 = uenc->utf8[(unsigned char)**fromP]; @@ -1308,3 +1399,3 @@ unknown_toUtf8(const ENCODING *enc, if (n > toLim - *toP) - break; + return XML_CONVERT_OUTPUT_EXHAUSTED; utf8 = buf; @@ -1315,3 +1406,3 @@ unknown_toUtf8(const ENCODING *enc, if (n > toLim - *toP) - break; + return XML_CONVERT_OUTPUT_EXHAUSTED; (*fromP)++; @@ -1324,3 +1415,3 @@ unknown_toUtf8(const ENCODING *enc, -static void PTRCALL +static enum XML_Convert_Result PTRCALL unknown_toUtf16(const ENCODING *enc, @@ -1330,3 +1421,3 @@ unknown_toUtf16(const ENCODING *enc, 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]; @@ -1342,2 +1433,7 @@ unknown_toUtf16(const ENCODING *enc, } + + if ((*toP == toLim) && (*fromP < fromLim)) + return XML_CONVERT_OUTPUT_EXHAUSTED; + else + return XML_CONVERT_COMPLETED; } @@ -1505,3 +1601,3 @@ initScan(const ENCODING * const *encodingTable, - if (ptr == end) + if (ptr >= end) return XML_TOK_NONE; 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 @@ -132,2 +132,8 @@ typedef int (PTRCALL *SCANNER)(const ENCODING *, +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 { @@ -160,3 +166,3 @@ struct encoding { const char **badPtr); - void (PTRCALL *utf8Convert)(const ENCODING *enc, + enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc, const char **fromP, @@ -165,3 +171,3 @@ struct encoding { const char *toLim); - void (PTRCALL *utf16Convert)(const ENCODING *enc, + enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc, const char **fromP, 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 @@ -89,2 +89,20 @@ + +#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 "<!-" */ @@ -95,3 +113,3 @@ PREFIX(scanComment)(const ENCODING *enc, const char *ptr, { - if (ptr != end) { + if (HAS_CHAR(enc, ptr, end)) { if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) { @@ -101,3 +119,3 @@ PREFIX(scanComment)(const ENCODING *enc, const char *ptr, ptr += MINBPC(enc); - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -105,7 +123,7 @@ PREFIX(scanComment)(const ENCODING *enc, const char *ptr, 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)) { @@ -133,4 +151,3 @@ PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, { - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { @@ -149,7 +166,6 @@ PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, } - 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"> */ @@ -177,3 +193,3 @@ PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, 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) @@ -227,4 +243,3 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *target = ptr; - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { @@ -235,3 +250,3 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr, } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -244,3 +259,3 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr, ptr += MINBPC(enc); - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -249,4 +264,3 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr, ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { @@ -268,4 +282,3 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr, ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { @@ -284,3 +297,3 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr, 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) @@ -291,4 +304,3 @@ PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, /* 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)) { @@ -307,3 +319,3 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, { - if (ptr == end) + if (ptr >= end) return XML_TOK_NONE; @@ -321,4 +333,3 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) @@ -326,4 +337,3 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { @@ -336,4 +346,3 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); if (BYTE_TYPE(enc, ptr) == BT_LF) @@ -350,3 +359,3 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -385,4 +394,3 @@ PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, { - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { @@ -393,3 +401,3 @@ PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -397,3 +405,3 @@ PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, 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)) { @@ -434,3 +442,3 @@ PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, { - if (ptr != end) { + if (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -443,3 +451,3 @@ PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, } - 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)) { @@ -466,3 +474,3 @@ PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, { - if (ptr != end) { + if (HAS_CHAR(enc, ptr, end)) { if (CHAR_MATCHES(enc, ptr, ASCII_x)) @@ -476,3 +484,3 @@ PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, } - 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)) { @@ -498,4 +506,3 @@ PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, { - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { @@ -508,3 +515,3 @@ PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -531,3 +538,3 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, #endif - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -542,4 +549,3 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { @@ -557,4 +563,3 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); t = BYTE_TYPE(enc, ptr); @@ -581,4 +586,3 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); open = BYTE_TYPE(enc, ptr); @@ -600,4 +604,3 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, int t; - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); t = BYTE_TYPE(enc, ptr); @@ -626,4 +629,3 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { @@ -644,4 +646,3 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { @@ -657,4 +658,3 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { @@ -690,4 +690,3 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, #endif - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { @@ -695,4 +694,4 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, 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)) { @@ -718,3 +717,3 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, /* we have a start-tag */ - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -729,4 +728,3 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { @@ -742,3 +740,3 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -767,4 +765,3 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { @@ -787,3 +784,3 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, { - if (ptr == end) + if (ptr >= end) return XML_TOK_NONE; @@ -805,3 +802,3 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; @@ -816,3 +813,3 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_RSQB; @@ -821,3 +818,3 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_RSQB; @@ -834,3 +831,3 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -847,3 +844,3 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, case BT_RSQB: - if (ptr + MINBPC(enc) != end) { + if (HAS_CHARS(enc, ptr, end, 2)) { if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) { @@ -852,3 +849,3 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, } - if (ptr + 2*MINBPC(enc) != end) { + if (HAS_CHARS(enc, ptr, end, 3)) { if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) { @@ -886,4 +883,3 @@ PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, { - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { @@ -897,3 +893,3 @@ PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -915,4 +911,3 @@ PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, { - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { @@ -923,3 +918,3 @@ PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -943,3 +938,3 @@ PREFIX(scanLit)(int open, const ENCODING *enc, { - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { int t = BYTE_TYPE(enc, ptr); @@ -952,3 +947,3 @@ PREFIX(scanLit)(int open, const ENCODING *enc, break; - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_LITERAL; @@ -975,3 +970,3 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, int tok; - if (ptr == end) + if (ptr >= end) return XML_TOK_NONE; @@ -994,4 +989,3 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { @@ -1023,3 +1017,3 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) break; @@ -1050,7 +1044,6 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, 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)) { @@ -1067,3 +1060,3 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_CLOSE_PAREN; @@ -1143,3 +1136,3 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -1156,4 +1149,3 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, case XML_TOK_NAME: - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); tok = XML_TOK_PREFIXED_NAME; @@ -1206,6 +1198,8 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, 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)) { @@ -1234,3 +1228,3 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, ptr += MINBPC(enc); - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; @@ -1264,6 +1258,8 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, 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)) { @@ -1296,3 +1292,3 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, ptr += MINBPC(enc); - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; @@ -1328,3 +1324,3 @@ PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -1332,7 +1328,7 @@ PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, 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)) { @@ -1344,7 +1340,7 @@ PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, 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)) { @@ -1375,3 +1371,3 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, end -= MINBPC(enc); - for (; ptr != end; ptr += MINBPC(enc)) { + for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { @@ -1523,3 +1519,3 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr, static int PTRFASTCALL -PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) +PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr) { @@ -1567,3 +1563,3 @@ PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) static int PTRCALL -PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, +PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr, const char *end) @@ -1685,3 +1681,3 @@ PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) 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) @@ -1689,3 +1685,3 @@ PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { - if (ptr1 == end1) + if (end1 - ptr1 < MINBPC(enc)) return 0; @@ -1746,3 +1742,3 @@ PREFIX(updatePosition)(const ENCODING *enc, { - while (ptr < end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { @@ -1762,3 +1758,3 @@ PREFIX(updatePosition)(const ENCODING *enc, 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); diff --git a/COPYING.dependencies b/COPYING.dependencies index 08823e8..50a9984 100644 --- a/COPYING.dependencies +++ b/COPYING.dependencies @@ -83,5 +83,4 @@ Expat -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 |