--- /dev/null
+Expat is brought to you by:
+
+Clark Cooper
+Fred L. Drake, Jr.
+Greg Stein
+James Clark
+Karl Waclawek
+Rhodri James
+Sebastian Pipping
+Steven Solie
-Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
- and Clark Cooper
-Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers.
+Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper
+Copyright (c) 2001-2017 Expat maintainers
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
+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
#520: Symbol XML_SetHashSalt was not exported
Output of "xmlwf -h" was incomplete
- Other changes
+ 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.
- #2895533: CVE-2012-1147 - Resource leak in readfilemap.c.
#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.
- #1990430: CVE-2009-3720 - Parser crash with special UTF-8 sequences.
#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.
- #2894085: CVE-2009-3560 - Buffer over-read and crash in big2_toUtf8().
- #2958794: CVE-2012-1148 - Memory leak in poolGrow.
#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.
- #3496608: CVE-2012-0876 - Hash DOS attack.
- Patches:
#1749198: pkg-config support.
#3010222: Fix for bug #3010819.
-# $OpenBSD: Makefile,v 1.11 2016/09/14 06:26:02 natano Exp $
+# $OpenBSD: Makefile,v 1.12 2017/06/30 11:25:29 bluhm Exp $
.PATH: ${.CURDIR}/lib
PC_FILES=expat.pc
CLEANFILES+=${PC_FILES}
+VERSION_SCRIPT= ${.CURDIR}/Symbols.map
+
includes:
cmp -s ${DESTDIR}/usr/include/expat.h ${.CURDIR}/lib/expat.h || \
${INSTALL} ${INSTALL_COPY} -m 444 -o $(BINOWN) -g $(BINGRP) \
- Expat, Release 2.1.1
+ Expat, Release 2.2.1
This is Expat, a C library for parsing XML, written by James Clark.
Expat is a stream-oriented XML parser. This means that you register
"/usr/ccs/bin", which is not in the default PATH. You will need to
add this to your path for the "make" command, and probably also switch
to GNU make (the "make" found in /usr/ccs/bin does not seem to work
-properly -- appearantly it does not understand .PHONY directives). If
+properly -- apparently it does not understand .PHONY directives). If
you're using ksh or bash, use this command to build:
PATH=/usr/ccs/bin:$PATH make
--- /dev/null
+{
+ local:
+ align_limit_to_full_utf8_characters;
+};
<p>If you're using the GNU compiler under cygwin, follow the Unix
directions in the next section. Otherwise if you have Microsoft's
Developer Studio installed, then from Windows Explorer double-click on
-"expat.dsp" in the lib directory and build and install in the usual
+"expat.vcxproj" in the lib directory and build and install in the usual
manner.</p>
<p>Alternatively, you may download the Win32 binary package that
*/
#include <stdio.h>
-#include "expat.h"
-
-#if defined(__amigaos__) && defined(__USE_INLINE__)
-#include <proto/expat.h>
-#endif
+#include <expat.h>
#ifdef XML_LARGE_SIZE
#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
{
int i;
int *depthPtr = (int *)userData;
+ (void)atts;
+
for (i = 0; i < *depthPtr; i++)
putchar('\t');
puts(name);
endElement(void *userData, const char *name)
{
int *depthPtr = (int *)userData;
+ (void)name;
+
*depthPtr -= 1;
}
XML_Parser parser = XML_ParserCreate(NULL);
int done;
int depth = 0;
+ (void)argc;
+ (void)argv;
+
XML_SetUserData(parser, &depth);
XML_SetElementHandler(parser, startElement, endElement);
do {
#include <stdio.h>
#include <expat.h>
-#if defined(__amigaos__) && defined(__USE_INLINE__)
-#include <proto/expat.h>
-#endif
-
#ifdef XML_LARGE_SIZE
#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
#define XML_FMT_INT_MOD "I64"
start(void *data, const char *el, const char **attr)
{
int i;
+ (void)data;
for (i = 0; i < Depth; i++)
printf(" ");
static void XMLCALL
end(void *data, const char *el)
{
+ (void)data;
+ (void)el;
+
Depth--;
}
main(int argc, char *argv[])
{
XML_Parser p = XML_ParserCreate(NULL);
+ (void)argc;
+ (void)argv;
+
if (! p) {
fprintf(stderr, "Couldn't allocate memory for parser\n");
exit(-1);
-/* $OpenBSD: expat_config.h,v 1.2 2015/05/23 00:53:25 jsg Exp $ */
+/* $OpenBSD: expat_config.h,v 1.3 2017/06/30 11:25:29 bluhm Exp $ */
/* quick and dirty conf for OpenBSD */
+#define HAVE_ARC4RANDOM_BUF 1
#define HAVE_MEMMOVE 1
#define XML_CONTEXT_BYTES 1024
#define XML_DTD 1
/* Added in 2.0. */
XML_ERROR_RESERVED_PREFIX_XML,
XML_ERROR_RESERVED_PREFIX_XMLNS,
- XML_ERROR_RESERVED_NAMESPACE_URI
+ XML_ERROR_RESERVED_NAMESPACE_URI,
+ /* Added in 2.2.1. */
+ XML_ERROR_INVALID_ARGUMENT
};
enum XML_Content_Type {
XML_EntityDeclHandler handler);
/* OBSOLETE -- OBSOLETE -- OBSOLETE
- This handler has been superceded by the EntityDeclHandler above.
+ This handler has been superseded by the EntityDeclHandler above.
It is provided here for backward compatibility.
This is called for a declaration of an unparsed (NDATA) entity.
be called, despite an external subset being parsed.
Note: If XML_DTD is not defined when Expat is compiled, returns
XML_ERROR_FEATURE_REQUIRES_XML_DTD.
+ Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT.
*/
XMLPARSEAPI(enum XML_Error)
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD);
to the XML_StartElementHandler that were specified in the start-tag
rather than defaulted. Each attribute/value pair counts as 2; thus
this correspondds to an index into the atts array passed to the
- XML_StartElementHandler.
+ XML_StartElementHandler. Returns -1 if parser == NULL.
*/
XMLPARSEAPI(int)
XML_GetSpecifiedAttributeCount(XML_Parser parser);
/* Returns the index of the ID attribute passed in the last call to
- XML_StartElementHandler, or -1 if there is no ID attribute. Each
- attribute/value pair counts as 2; thus this correspondds to an
- index into the atts array passed to the XML_StartElementHandler.
+ XML_StartElementHandler, or -1 if there is no ID attribute or
+ parser == NULL. Each attribute/value pair counts as 2; thus this
+ correspondds to an index into the atts array passed to the
+ XML_StartElementHandler.
*/
XMLPARSEAPI(int)
XML_GetIdAttributeIndex(XML_Parser parser);
entities is requested; otherwise it will return non-zero.
Note: If XML_SetParamEntityParsing is called after XML_Parse or
XML_ParseBuffer, then it has no effect and will always return 0.
+ Note: If parser == NULL, the function will do nothing and return 0.
*/
XMLPARSEAPI(int)
XML_SetParamEntityParsing(XML_Parser parser,
Helps in preventing DoS attacks based on predicting hash
function behavior. This must be called before parsing is started.
Returns 1 if successful, 0 when called after parsing has started.
+ Note: If parser == NULL, the function will do nothing and return 0.
*/
XMLPARSEAPI(int)
XML_SetHashSalt(XML_Parser parser,
the location is the location of the character at which the error
was detected; otherwise the location is the location of the last
parse event, as described above.
+
+ Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber
+ return 0 to indicate an error.
+ Note: XML_GetCurrentByteIndex returns -1 to indicate an error.
*/
XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser);
XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser);
/* Exposing the memory handling functions used in Expat */
XMLPARSEAPI(void *)
+XML_ATTR_MALLOC
+XML_ATTR_ALLOC_SIZE(2)
XML_MemMalloc(XML_Parser parser, size_t size);
XMLPARSEAPI(void *)
+XML_ATTR_ALLOC_SIZE(3)
XML_MemRealloc(XML_Parser parser, void *ptr, size_t size);
XMLPARSEAPI(void)
XML_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_MINOR_VERSION 2
#define XML_MICRO_VERSION 1
#ifdef __cplusplus
#endif
#endif /* not defined XML_STATIC */
+#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4)
+#define XMLIMPORT __attribute__ ((visibility ("default")))
+#endif
/* If we didn't define it above, define it away: */
#ifndef XMLIMPORT
#define XMLIMPORT
#endif
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
+#define XML_ATTR_MALLOC __attribute__((__malloc__))
+#else
+#define XML_ATTR_MALLOC
+#endif
+
+#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+#define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
+#else
+#define XML_ATTR_ALLOC_SIZE(x)
+#endif
#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL
#endif
#ifdef XML_UNICODE_WCHAR_T
-#define XML_UNICODE
+# define XML_UNICODE
+# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2)
+# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc"
+# endif
#endif
#ifdef XML_UNICODE /* Information is UTF-16 encoded. */
and therefore subject to change.
*/
-#if defined(__GNUC__) && (defined(__i386__) || defined(__amd64__)) && !defined(__MINGW32__)
+#if defined(__GNUC__) && defined(__i386__) && !defined(__MINGW32__)
/* We'll use this version by default only where we know it helps.
regparm() generates warnings on Solaris boxes. See SF bug #692878.
#define inline
#endif
#endif
+
+#ifndef UNUSED_P
+# ifdef __GNUC__
+# define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__))
+# else
+# define UNUSED_P(p) UNUSED_ ## p
+# endif
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void
+align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef);
+
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null
+/* ==========================================================================
+ * 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 */
#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
/* Windows has memmove() available. */
#define HAVE_MEMMOVE
+
+#endif /* !defined(HAVE_EXPAT_CONFIG_H) */
+
+
#endif /* ndef WINCONFIG_H */
/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
See the file COPYING for copying permission.
+
+ 77fea421d361dca90041d0040ecf1dca651167fadf2af79e990e35168d70d933 (2.2.1+)
*/
+#define _GNU_SOURCE /* syscall prototype */
+
#include <stddef.h>
#include <string.h> /* memset(), memcpy() */
#include <assert.h>
#include <limits.h> /* UINT_MAX */
-#include <time.h> /* time() */
+#include <stdio.h> /* fprintf */
+#include <stdlib.h> /* getenv */
+
+#ifdef _WIN32
+#define getpid GetCurrentProcessId
+#else
+#include <sys/time.h> /* gettimeofday() */
+#include <sys/types.h> /* getpid() */
+#include <unistd.h> /* getpid() */
+#endif
#define XML_BUILDING_EXPAT 1
-#ifdef COMPILED_FROM_DSP
+#ifdef _WIN32
#include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-#elif defined(__amigaos__)
-#include "amigaconfig.h"
-#elif defined(__WATCOMC__)
-#include "watcomconfig.h"
#elif defined(HAVE_EXPAT_CONFIG_H)
#include <expat_config.h>
-#endif /* ndef COMPILED_FROM_DSP */
+#endif /* ndef _WIN32 */
#include "ascii.h"
#include "expat.h"
+#include "siphash.h"
#ifdef XML_UNICODE
#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
const XML_Memory_Handling_Suite *mem;
} HASH_TABLE;
-/* Basic character hash algorithm, taken from Python's string hash:
- h = h * 1000003 ^ character, the constant being a prime number.
+static size_t
+keylen(KEY s);
-*/
-#ifdef XML_UNICODE
-#define CHAR_HASH(h, c) \
- (((h) * 0xF4243) ^ (unsigned short)(c))
-#else
-#define CHAR_HASH(h, c) \
- (((h) * 0xF4243) ^ (unsigned char)(c))
-#endif
+static void
+copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key);
/* For probing (after a collision) we need a step size relative prime
to the hash table size, which is a power of 2. We use double-hashing,
const char *end, const char **nextPtr, XML_Bool haveMore);
#endif /* XML_DTD */
+static void
+freeBindings(XML_Parser parser, BINDING *bindings);
static enum XML_Error
storeAtts(XML_Parser parser, const ENCODING *, const char *s,
TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
getElementType(XML_Parser parser, const ENCODING *enc,
const char *ptr, const char *end);
-static unsigned long generate_hash_secret_salt(void);
+static unsigned long generate_hash_secret_salt(XML_Parser parser);
static XML_Bool startParsing(XML_Parser parser);
static XML_Parser
#endif /* XML_DTD */
#define hash_secret_salt (parser->m_hash_secret_salt)
-#define MAXLEN 0x7fffffff
-
XML_Parser XMLCALL
XML_ParserCreate(const XML_Char *encodingName)
{
};
static unsigned long
-generate_hash_secret_salt(void)
+generate_hash_secret_salt(XML_Parser parser)
{
- return arc4random();
+ unsigned long entropy;
+ (void)parser;
+ arc4random_buf(&entropy, sizeof(entropy));
+ return entropy;
+}
+
+static unsigned long
+get_hash_secret_salt(XML_Parser parser) {
+ if (parser->m_parentParser != NULL)
+ return get_hash_secret_salt(parser->m_parentParser);
+ return parser->m_hash_secret_salt;
}
static XML_Bool /* only valid for root parser */
{
/* hash functions must be initialized before setContext() is called */
if (hash_secret_salt == 0)
- hash_secret_salt = generate_hash_secret_salt();
+ hash_secret_salt = generate_hash_secret_salt(parser);
if (ns) {
/* implicit context only set for root parser, since child
parsers (i.e. external entity parsers) will inherit it
{
TAG *tStk;
OPEN_INTERNAL_ENTITY *openEntityList;
+
+ if (parser == NULL)
+ return XML_FALSE;
+
if (parentParser)
return XML_FALSE;
/* move tagStack to freeTagList */
enum XML_Status XMLCALL
XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
{
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
/* Block after XML_Parse()/XML_ParseBuffer() has been called.
XXX There's no way for the caller to determine which of the
XXX possible error cases caused the XML_STATUS_ERROR return.
{
XML_Parser parser = oldParser;
DTD *newDtd = NULL;
- DTD *oldDtd = _dtd;
- XML_StartElementHandler oldStartElementHandler = startElementHandler;
- XML_EndElementHandler oldEndElementHandler = endElementHandler;
- XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
- XML_ProcessingInstructionHandler oldProcessingInstructionHandler
- = processingInstructionHandler;
- XML_CommentHandler oldCommentHandler = commentHandler;
- XML_StartCdataSectionHandler oldStartCdataSectionHandler
- = startCdataSectionHandler;
- XML_EndCdataSectionHandler oldEndCdataSectionHandler
- = endCdataSectionHandler;
- XML_DefaultHandler oldDefaultHandler = defaultHandler;
- XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler
- = unparsedEntityDeclHandler;
- XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
- XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler
- = startNamespaceDeclHandler;
- XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler
- = endNamespaceDeclHandler;
- XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
- XML_ExternalEntityRefHandler oldExternalEntityRefHandler
- = externalEntityRefHandler;
- XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler;
- XML_UnknownEncodingHandler oldUnknownEncodingHandler
- = unknownEncodingHandler;
- XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
- XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
- XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
- XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
- ELEMENT_TYPE * oldDeclElementType = declElementType;
-
- void *oldUserData = userData;
- void *oldHandlerArg = handlerArg;
- XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
- XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+ DTD *oldDtd;
+ XML_StartElementHandler oldStartElementHandler;
+ XML_EndElementHandler oldEndElementHandler;
+ XML_CharacterDataHandler oldCharacterDataHandler;
+ XML_ProcessingInstructionHandler oldProcessingInstructionHandler;
+ XML_CommentHandler oldCommentHandler;
+ XML_StartCdataSectionHandler oldStartCdataSectionHandler;
+ XML_EndCdataSectionHandler oldEndCdataSectionHandler;
+ XML_DefaultHandler oldDefaultHandler;
+ XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler;
+ XML_NotationDeclHandler oldNotationDeclHandler;
+ XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler;
+ XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler;
+ XML_NotStandaloneHandler oldNotStandaloneHandler;
+ XML_ExternalEntityRefHandler oldExternalEntityRefHandler;
+ XML_SkippedEntityHandler oldSkippedEntityHandler;
+ XML_UnknownEncodingHandler oldUnknownEncodingHandler;
+ XML_ElementDeclHandler oldElementDeclHandler;
+ XML_AttlistDeclHandler oldAttlistDeclHandler;
+ XML_EntityDeclHandler oldEntityDeclHandler;
+ XML_XmlDeclHandler oldXmlDeclHandler;
+ ELEMENT_TYPE * oldDeclElementType;
+
+ void *oldUserData;
+ void *oldHandlerArg;
+ XML_Bool oldDefaultExpandInternalEntities;
+ XML_Parser oldExternalEntityRefHandlerArg;
#ifdef XML_DTD
- enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing;
- int oldInEntityValue = prologState.inEntityValue;
+ enum XML_ParamEntityParsing oldParamEntityParsing;
+ int oldInEntityValue;
#endif
- XML_Bool oldns_triplets = ns_triplets;
+ XML_Bool oldns_triplets;
/* Note that the new parser shares the same hash secret as the old
parser, so that dtdCopy and copyEntityTable can lookup values
from hash tables associated with either parser without us having
to worry which hash secrets each table has.
*/
- unsigned long oldhash_secret_salt = hash_secret_salt;
+ unsigned long oldhash_secret_salt;
+
+ /* Validate the oldParser parameter before we pull everything out of it */
+ if (oldParser == NULL)
+ return NULL;
+
+ /* Stash the original parser contents on the stack */
+ oldDtd = _dtd;
+ oldStartElementHandler = startElementHandler;
+ oldEndElementHandler = endElementHandler;
+ oldCharacterDataHandler = characterDataHandler;
+ oldProcessingInstructionHandler = processingInstructionHandler;
+ oldCommentHandler = commentHandler;
+ oldStartCdataSectionHandler = startCdataSectionHandler;
+ oldEndCdataSectionHandler = endCdataSectionHandler;
+ oldDefaultHandler = defaultHandler;
+ oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
+ oldNotationDeclHandler = notationDeclHandler;
+ oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
+ oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
+ oldNotStandaloneHandler = notStandaloneHandler;
+ oldExternalEntityRefHandler = externalEntityRefHandler;
+ oldSkippedEntityHandler = skippedEntityHandler;
+ oldUnknownEncodingHandler = unknownEncodingHandler;
+ oldElementDeclHandler = elementDeclHandler;
+ oldAttlistDeclHandler = attlistDeclHandler;
+ oldEntityDeclHandler = entityDeclHandler;
+ oldXmlDeclHandler = xmlDeclHandler;
+ oldDeclElementType = declElementType;
+
+ oldUserData = userData;
+ oldHandlerArg = handlerArg;
+ oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
+ oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+#ifdef XML_DTD
+ oldParamEntityParsing = paramEntityParsing;
+ oldInEntityValue = prologState.inEntityValue;
+#endif
+ oldns_triplets = ns_triplets;
+ /* Note that the new parser shares the same hash secret as the old
+ parser, so that dtdCopy and copyEntityTable can lookup values
+ from hash tables associated with either parser without us having
+ to worry which hash secrets each table has.
+ */
+ oldhash_secret_salt = hash_secret_salt;
#ifdef XML_DTD
if (!context)
void XMLCALL
XML_UseParserAsHandlerArg(XML_Parser parser)
{
- handlerArg = parser;
+ if (parser != NULL)
+ handlerArg = parser;
}
enum XML_Error XMLCALL
XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD)
{
+ if (parser == NULL)
+ return XML_ERROR_INVALID_ARGUMENT;
#ifdef XML_DTD
/* block after XML_Parse()/XML_ParseBuffer() has been called */
if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
void XMLCALL
XML_SetReturnNSTriplet(XML_Parser parser, int do_nst)
{
+ if (parser == NULL)
+ return;
/* block after XML_Parse()/XML_ParseBuffer() has been called */
if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
return;
void XMLCALL
XML_SetUserData(XML_Parser parser, void *p)
{
+ if (parser == NULL)
+ return;
if (handlerArg == userData)
handlerArg = userData = p;
else
enum XML_Status XMLCALL
XML_SetBase(XML_Parser parser, const XML_Char *p)
{
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
if (p) {
p = poolCopyString(&_dtd->pool, p);
if (!p)
const XML_Char * XMLCALL
XML_GetBase(XML_Parser parser)
{
+ if (parser == NULL)
+ return NULL;
return curBase;
}
int XMLCALL
XML_GetSpecifiedAttributeCount(XML_Parser parser)
{
+ if (parser == NULL)
+ return -1;
return nSpecifiedAtts;
}
int XMLCALL
XML_GetIdAttributeIndex(XML_Parser parser)
{
+ if (parser == NULL)
+ return -1;
return idAttIndex;
}
const XML_AttrInfo * XMLCALL
XML_GetAttributeInfo(XML_Parser parser)
{
+ if (parser == NULL)
+ return NULL;
return attInfo;
}
#endif
XML_StartElementHandler start,
XML_EndElementHandler end)
{
+ if (parser == NULL)
+ return;
startElementHandler = start;
endElementHandler = end;
}
void XMLCALL
XML_SetStartElementHandler(XML_Parser parser,
XML_StartElementHandler start) {
- startElementHandler = start;
+ if (parser != NULL)
+ startElementHandler = start;
}
void XMLCALL
XML_SetEndElementHandler(XML_Parser parser,
XML_EndElementHandler end) {
- endElementHandler = end;
+ if (parser != NULL)
+ endElementHandler = end;
}
void XMLCALL
XML_SetCharacterDataHandler(XML_Parser parser,
XML_CharacterDataHandler handler)
{
- characterDataHandler = handler;
+ if (parser != NULL)
+ characterDataHandler = handler;
}
void XMLCALL
XML_SetProcessingInstructionHandler(XML_Parser parser,
XML_ProcessingInstructionHandler handler)
{
- processingInstructionHandler = handler;
+ if (parser != NULL)
+ processingInstructionHandler = handler;
}
void XMLCALL
XML_SetCommentHandler(XML_Parser parser,
XML_CommentHandler handler)
{
- commentHandler = handler;
+ if (parser != NULL)
+ commentHandler = handler;
}
void XMLCALL
XML_StartCdataSectionHandler start,
XML_EndCdataSectionHandler end)
{
+ if (parser == NULL)
+ return;
startCdataSectionHandler = start;
endCdataSectionHandler = end;
}
void XMLCALL
XML_SetStartCdataSectionHandler(XML_Parser parser,
XML_StartCdataSectionHandler start) {
- startCdataSectionHandler = start;
+ if (parser != NULL)
+ startCdataSectionHandler = start;
}
void XMLCALL
XML_SetEndCdataSectionHandler(XML_Parser parser,
XML_EndCdataSectionHandler end) {
- endCdataSectionHandler = end;
+ if (parser != NULL)
+ endCdataSectionHandler = end;
}
void XMLCALL
XML_SetDefaultHandler(XML_Parser parser,
XML_DefaultHandler handler)
{
+ if (parser == NULL)
+ return;
defaultHandler = handler;
defaultExpandInternalEntities = XML_FALSE;
}
XML_SetDefaultHandlerExpand(XML_Parser parser,
XML_DefaultHandler handler)
{
+ if (parser == NULL)
+ return;
defaultHandler = handler;
defaultExpandInternalEntities = XML_TRUE;
}
XML_StartDoctypeDeclHandler start,
XML_EndDoctypeDeclHandler end)
{
+ if (parser == NULL)
+ return;
startDoctypeDeclHandler = start;
endDoctypeDeclHandler = end;
}
void XMLCALL
XML_SetStartDoctypeDeclHandler(XML_Parser parser,
XML_StartDoctypeDeclHandler start) {
- startDoctypeDeclHandler = start;
+ if (parser != NULL)
+ startDoctypeDeclHandler = start;
}
void XMLCALL
XML_SetEndDoctypeDeclHandler(XML_Parser parser,
XML_EndDoctypeDeclHandler end) {
- endDoctypeDeclHandler = end;
+ if (parser != NULL)
+ endDoctypeDeclHandler = end;
}
void XMLCALL
XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
XML_UnparsedEntityDeclHandler handler)
{
- unparsedEntityDeclHandler = handler;
+ if (parser != NULL)
+ unparsedEntityDeclHandler = handler;
}
void XMLCALL
XML_SetNotationDeclHandler(XML_Parser parser,
XML_NotationDeclHandler handler)
{
- notationDeclHandler = handler;
+ if (parser != NULL)
+ notationDeclHandler = handler;
}
void XMLCALL
XML_StartNamespaceDeclHandler start,
XML_EndNamespaceDeclHandler end)
{
+ if (parser == NULL)
+ return;
startNamespaceDeclHandler = start;
endNamespaceDeclHandler = end;
}
void XMLCALL
XML_SetStartNamespaceDeclHandler(XML_Parser parser,
XML_StartNamespaceDeclHandler start) {
- startNamespaceDeclHandler = start;
+ if (parser != NULL)
+ startNamespaceDeclHandler = start;
}
void XMLCALL
XML_SetEndNamespaceDeclHandler(XML_Parser parser,
XML_EndNamespaceDeclHandler end) {
- endNamespaceDeclHandler = end;
+ if (parser != NULL)
+ endNamespaceDeclHandler = end;
}
void XMLCALL
XML_SetNotStandaloneHandler(XML_Parser parser,
XML_NotStandaloneHandler handler)
{
- notStandaloneHandler = handler;
+ if (parser != NULL)
+ notStandaloneHandler = handler;
}
void XMLCALL
XML_SetExternalEntityRefHandler(XML_Parser parser,
XML_ExternalEntityRefHandler handler)
{
- externalEntityRefHandler = handler;
+ if (parser != NULL)
+ externalEntityRefHandler = handler;
}
void XMLCALL
XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
{
+ if (parser == NULL)
+ return;
if (arg)
externalEntityRefHandlerArg = (XML_Parser)arg;
else
XML_SetSkippedEntityHandler(XML_Parser parser,
XML_SkippedEntityHandler handler)
{
- skippedEntityHandler = handler;
+ if (parser != NULL)
+ skippedEntityHandler = handler;
}
void XMLCALL
XML_UnknownEncodingHandler handler,
void *data)
{
+ if (parser == NULL)
+ return;
unknownEncodingHandler = handler;
unknownEncodingHandlerData = data;
}
XML_SetElementDeclHandler(XML_Parser parser,
XML_ElementDeclHandler eldecl)
{
- elementDeclHandler = eldecl;
+ if (parser != NULL)
+ elementDeclHandler = eldecl;
}
void XMLCALL
XML_SetAttlistDeclHandler(XML_Parser parser,
XML_AttlistDeclHandler attdecl)
{
- attlistDeclHandler = attdecl;
+ if (parser != NULL)
+ attlistDeclHandler = attdecl;
}
void XMLCALL
XML_SetEntityDeclHandler(XML_Parser parser,
XML_EntityDeclHandler handler)
{
- entityDeclHandler = handler;
+ if (parser != NULL)
+ entityDeclHandler = handler;
}
void XMLCALL
XML_SetXmlDeclHandler(XML_Parser parser,
XML_XmlDeclHandler handler) {
- xmlDeclHandler = handler;
+ if (parser != NULL)
+ xmlDeclHandler = handler;
}
int XMLCALL
XML_SetParamEntityParsing(XML_Parser parser,
enum XML_ParamEntityParsing peParsing)
{
+ if (parser == NULL)
+ return 0;
/* block after XML_Parse()/XML_ParseBuffer() has been called */
if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
return 0;
XML_SetHashSalt(XML_Parser parser,
unsigned long hash_salt)
{
+ if (parser == NULL)
+ return 0;
+ if (parser->m_parentParser)
+ return XML_SetHashSalt(parser->m_parentParser, hash_salt);
/* block after XML_Parse()/XML_ParseBuffer() has been called */
if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED)
return 0;
enum XML_Status XMLCALL
XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
{
+ if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) {
+ errorCode = XML_ERROR_INVALID_ARGUMENT;
+ return XML_STATUS_ERROR;
+ }
switch (ps_parsing) {
case XML_SUSPENDED:
errorCode = XML_ERROR_SUSPENDED;
ps_parsing = XML_PARSING;
}
- /* Avoid integer overflow */
- if (len > MAXLEN / 2) {
- errorCode = XML_ERROR_NO_MEMORY;
- return XML_STATUS_ERROR;
- }
if (len == 0) {
ps_finalBuffer = (XML_Bool)isFinal;
if (!isFinal)
const char *end;
int nLeftOver;
enum XML_Status result;
+ /* Detect overflow (a+b > MAX <==> b > MAX-a) */
+ if (len > ((XML_Size)-1) / 2 - parseEndByteIndex) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ eventPtr = eventEndPtr = NULL;
+ processor = errorProcessor;
+ return XML_STATUS_ERROR;
+ }
parseEndByteIndex += len;
positionPtr = s;
ps_finalBuffer = (XML_Bool)isFinal;
nLeftOver = s + len - end;
if (nLeftOver) {
if (buffer == NULL || nLeftOver > bufferLim - buffer) {
- /* FIXME avoid integer overflow */
- char *temp;
- temp = (buffer == NULL
- ? (char *)MALLOC(len * 2)
- : (char *)REALLOC(buffer, len * 2));
+ /* avoid _signed_ integer overflow */
+ char *temp = NULL;
+ const int bytesToAllocate = (int)((unsigned)len * 2U);
+ if (bytesToAllocate > 0) {
+ temp = (buffer == NULL
+ ? (char *)MALLOC(bytesToAllocate)
+ : (char *)REALLOC(buffer, bytesToAllocate));
+ }
if (temp == NULL) {
errorCode = XML_ERROR_NO_MEMORY;
eventPtr = eventEndPtr = NULL;
return XML_STATUS_ERROR;
}
buffer = temp;
- bufferLim = buffer + len * 2;
+ bufferLim = buffer + bytesToAllocate;
}
memcpy(buffer, end, nLeftOver);
}
const char *start;
enum XML_Status result = XML_STATUS_OK;
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
switch (ps_parsing) {
case XML_SUSPENDED:
errorCode = XML_ERROR_SUSPENDED;
void * XMLCALL
XML_GetBuffer(XML_Parser parser, int len)
{
- if (len < 0 || len > MAXLEN - (bufferEnd - bufferPtr)) {
+ if (parser == NULL)
+ return NULL;
+ if (len < 0) {
errorCode = XML_ERROR_NO_MEMORY;
return NULL;
}
}
if (len > bufferLim - bufferEnd) {
- int neededSize = len + (int)(bufferEnd - bufferPtr);
+#ifdef XML_CONTEXT_BYTES
+ 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
- int keep = (int)(bufferPtr - buffer);
-
+ keep = (int)(bufferPtr - buffer);
if (keep > XML_CONTEXT_BYTES)
keep = XML_CONTEXT_BYTES;
neededSize += keep;
if (bufferSize == 0)
bufferSize = INIT_BUFFER_SIZE;
do {
- if (bufferSize > MAXLEN / 2) {
- errorCode = XML_ERROR_NO_MEMORY;
- return NULL;
- }
- bufferSize *= 2;
- } while (bufferSize < neededSize);
+ /* Do not invoke signed arithmetic overflow: */
+ bufferSize = (int) (2U * (unsigned) bufferSize);
+ } while (bufferSize < neededSize && bufferSize > 0);
+ if (bufferSize <= 0) {
+ errorCode = XML_ERROR_NO_MEMORY;
+ return NULL;
+ }
newBuf = (char *)MALLOC(bufferSize);
if (newBuf == 0) {
errorCode = XML_ERROR_NO_MEMORY;
enum XML_Status XMLCALL
XML_StopParser(XML_Parser parser, XML_Bool resumable)
{
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
switch (ps_parsing) {
case XML_SUSPENDED:
if (resumable) {
{
enum XML_Status result = XML_STATUS_OK;
+ if (parser == NULL)
+ return XML_STATUS_ERROR;
if (ps_parsing != XML_SUSPENDED) {
errorCode = XML_ERROR_NOT_SUSPENDED;
return XML_STATUS_ERROR;
void XMLCALL
XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
{
+ if (parser == NULL)
+ return;
assert(status != NULL);
*status = parser->m_parsingStatus;
}
enum XML_Error XMLCALL
XML_GetErrorCode(XML_Parser parser)
{
+ if (parser == NULL)
+ return XML_ERROR_INVALID_ARGUMENT;
return errorCode;
}
XML_Index XMLCALL
XML_GetCurrentByteIndex(XML_Parser parser)
{
+ if (parser == NULL)
+ return -1;
if (eventPtr)
- return parseEndByteIndex - (parseEndPtr - eventPtr);
+ return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr));
return -1;
}
int XMLCALL
XML_GetCurrentByteCount(XML_Parser parser)
{
+ if (parser == NULL)
+ return 0;
if (eventEndPtr && eventPtr)
return (int)(eventEndPtr - eventPtr);
return 0;
XML_GetInputContext(XML_Parser parser, int *offset, int *size)
{
#ifdef XML_CONTEXT_BYTES
+ if (parser == NULL)
+ return NULL;
if (eventPtr && buffer) {
- *offset = (int)(eventPtr - buffer);
- *size = (int)(bufferEnd - buffer);
+ if (offset != NULL)
+ *offset = (int)(eventPtr - buffer);
+ if (size != NULL)
+ *size = (int)(bufferEnd - buffer);
return buffer;
}
+#else
+ (void)parser;
+ (void)offset;
+ (void)size;
#endif /* defined XML_CONTEXT_BYTES */
return (char *) 0;
}
XML_Size XMLCALL
XML_GetCurrentLineNumber(XML_Parser parser)
{
+ if (parser == NULL)
+ return 0;
if (eventPtr && eventPtr >= positionPtr) {
XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
positionPtr = eventPtr;
XML_Size XMLCALL
XML_GetCurrentColumnNumber(XML_Parser parser)
{
+ if (parser == NULL)
+ return 0;
if (eventPtr && eventPtr >= positionPtr) {
XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
positionPtr = eventPtr;
void XMLCALL
XML_FreeContentModel(XML_Parser parser, XML_Content *model)
{
- FREE(model);
+ if (parser != NULL)
+ FREE(model);
}
void * XMLCALL
XML_MemMalloc(XML_Parser parser, size_t size)
{
+ if (parser == NULL)
+ return NULL;
return MALLOC(size);
}
void * XMLCALL
XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
{
+ if (parser == NULL)
+ return NULL;
return REALLOC(ptr, size);
}
void XMLCALL
XML_MemFree(XML_Parser parser, void *ptr)
{
- FREE(ptr);
+ if (parser != NULL)
+ FREE(ptr);
}
void XMLCALL
XML_DefaultCurrent(XML_Parser parser)
{
+ if (parser == NULL)
+ return;
if (defaultHandler) {
if (openInternalEntities)
reportDefault(parser,
return XML_ERROR_NO_MEMORY;
poolFinish(&tempPool);
result = storeAtts(parser, enc, s, &name, &bindings);
- if (result)
+ if (result != XML_ERROR_NONE) {
+ freeBindings(parser, bindings);
return result;
+ }
poolFinish(&tempPool);
if (startElementHandler) {
startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
if (noElmHandlers && defaultHandler)
reportDefault(parser, enc, s, next);
poolClear(&tempPool);
- while (bindings) {
- BINDING *b = bindings;
- if (endNamespaceDeclHandler)
- endNamespaceDeclHandler(handlerArg, b->prefix->name);
- bindings = bindings->nextTagBinding;
- b->nextTagBinding = freeBindingList;
- freeBindingList = b;
- b->prefix->binding = b->prevPrefixBinding;
- }
+ freeBindings(parser, bindings);
}
if (tagLevel == 0)
return epilogProcessor(parser, next, end, nextPtr);
/* not reached */
}
+/* This function does not call free() on the allocated memory, merely
+ * moving it to the parser's freeBindingList where it can be freed or
+ * reused as appropriate.
+ */
+static void
+freeBindings(XML_Parser parser, BINDING *bindings)
+{
+ while (bindings) {
+ BINDING *b = bindings;
+
+ /* startNamespaceDeclHandler will have been called for this
+ * binding in addBindings(), so call the end handler now.
+ */
+ if (endNamespaceDeclHandler)
+ endNamespaceDeclHandler(handlerArg, b->prefix->name);
+
+ bindings = bindings->nextTagBinding;
+ b->nextTagBinding = freeBindingList;
+ freeBindingList = b;
+ b->prefix->binding = b->prevPrefixBinding;
+ }
+}
+
/* Precondition: all arguments must be non-NULL;
Purpose:
- normalize attributes
if (s[-1] == 2) { /* prefixed */
ATTRIBUTE_ID *id;
const BINDING *b;
- unsigned long uriHash = hash_secret_salt;
+ unsigned long uriHash;
+ struct siphash sip_state;
+ struct sipkey sip_key;
+
+ copy_salt_to_sipkey(parser, &sip_key);
+ sip24_init(&sip_state, &sip_key);
+
((XML_Char *)s)[-1] = 0; /* clear flag */
id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0);
if (!id || !id->prefix)
if (!b)
return XML_ERROR_UNBOUND_PREFIX;
- /* as we expand the name we also calculate its hash value */
for (j = 0; j < b->uriLen; j++) {
const XML_Char c = b->uri[j];
if (!poolAppendChar(&tempPool, c))
return XML_ERROR_NO_MEMORY;
- uriHash = CHAR_HASH(uriHash, c);
}
+
+ sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char));
+
while (*s++ != XML_T(ASCII_COLON))
;
+
+ sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char));
+
do { /* copies null terminator */
- const XML_Char c = *s;
if (!poolAppendChar(&tempPool, *s))
return XML_ERROR_NO_MEMORY;
- uriHash = CHAR_HASH(uriHash, c);
} while (*s++);
+ uriHash = (unsigned long)sip24_final(&sip_state);
+
{ /* Check hash table for duplicate of expanded name (uriName).
Derived from code in lookup(parser, HASH_TABLE *table, ...).
*/
*nextPtr = next;
return XML_ERROR_NONE;
}
+ /* If we get this token, we have the start of what might be a
+ normal tag, but not a declaration (i.e. it doesn't begin with
+ "<!"). In a DTD context, that isn't legal.
+ */
+ else if (tok == XML_TOK_INSTANCE_START) {
+ *nextPtr = next;
+ return XML_ERROR_SYNTAX;
+ }
start = next;
eventPtr = start;
}
openEntity->internalEventEndPtr = NULL;
textStart = (char *)entity->textPtr;
textEnd = (char *)(entity->textPtr + entity->textLen);
+ /* Set a safe default value in case 'next' does not get set */
+ next = textStart;
#ifdef XML_DTD
if (entity->is_param) {
entity = openEntity->entity;
textStart = ((char *)entity->textPtr) + entity->processed;
textEnd = (char *)(entity->textPtr + entity->textLen);
+ /* Set a safe default value in case 'next' does not get set */
+ next = textStart;
#ifdef XML_DTD
if (entity->is_param) {
static enum XML_Error PTRCALL
errorProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
+ const char *UNUSED_P(s),
+ const char *UNUSED_P(end),
+ const char **UNUSED_P(nextPtr))
{
return errorCode;
}
newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
if (!newE->defaultAtts) {
- ms->free_fcn(newE);
return 0;
}
}
return XML_FALSE;
}
+static size_t
+keylen(KEY s)
+{
+ size_t len = 0;
+ for (; *s; s++, len++);
+ return len;
+}
+
+static void
+copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key)
+{
+ key->k[0] = 0;
+ key->k[1] = get_hash_secret_salt(parser);
+}
+
static unsigned long FASTCALL
hash(XML_Parser parser, KEY s)
{
- unsigned long h = hash_secret_salt;
- while (*s)
- h = CHAR_HASH(h, *s++);
- return h;
+ struct siphash state;
+ struct sipkey key;
+ (void)sip_tobin;
+ (void)sip24_valid;
+ copy_salt_to_sipkey(parser, &key);
+ sip24_init(&state, &key);
+ sip24_update(&state, s, keylen(s) * sizeof(XML_Char));
+ return (unsigned long)sip24_final(&state);
}
static NAMED *
return pool->start;
}
+static size_t
+poolBytesToAllocateFor(int blockSize)
+{
+ /* Unprotected math would be:
+ ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
+ **
+ ** Detect overflow, avoiding _signed_ overflow undefined behavior
+ ** For a + b * c we check b * c in isolation first, so that addition of a
+ ** on top has no chance of making us accept a small non-negative number
+ */
+ const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */
+
+ if (blockSize <= 0)
+ return 0;
+
+ if (blockSize > (int)(INT_MAX / stretch))
+ return 0;
+
+ {
+ const int stretchedBlockSize = blockSize * (int)stretch;
+ const int bytesToAllocate = (int)(
+ offsetof(BLOCK, s) + (unsigned)stretchedBlockSize);
+ if (bytesToAllocate < 0)
+ return 0;
+
+ return (size_t)bytesToAllocate;
+ }
+}
+
static XML_Bool FASTCALL
poolGrow(STRING_POOL *pool)
{
if (pool->blocks && pool->start == pool->blocks->s) {
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,
- (offsetof(BLOCK, s)
- + blockSize * sizeof(XML_Char)));
+ pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate);
if (temp == NULL)
return XML_FALSE;
pool->blocks = temp;
else {
BLOCK *tem;
int blockSize = (int)(pool->end - pool->start);
+ size_t bytesToAllocate;
if (blockSize < 0)
return XML_FALSE;
if (blockSize < INIT_BLOCK_SIZE)
blockSize = INIT_BLOCK_SIZE;
- else
+ else {
+ /* Detect overflow, avoiding _signed_ overflow undefined behavior */
+ if ((int)((unsigned)blockSize * 2U) < 0) {
+ return XML_FALSE;
+ }
blockSize *= 2;
- tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s)
- + blockSize * sizeof(XML_Char));
+ }
+
+ bytesToAllocate = poolBytesToAllocateFor(blockSize);
+ if (bytesToAllocate == 0)
+ return XML_FALSE;
+
+ tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate);
if (!tem)
return XML_FALSE;
tem->size = blockSize;
#include <stddef.h>
-#ifdef COMPILED_FROM_DSP
+#ifdef _WIN32
#include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-#elif defined(__amigaos__)
-#include "amigaconfig.h"
-#elif defined(__WATCOMC__)
-#include "watcomconfig.h"
#else
#ifdef HAVE_EXPAT_CONFIG_H
#include <expat_config.h>
#endif
-#endif /* ndef COMPILED_FROM_DSP */
+#endif /* ndef _WIN32 */
#include "expat_external.h"
#include "internal.h"
static int PTRCALL
prolog2(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
doctype0(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
doctype2(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
doctype3(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
doctype4(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
doctype5(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
entity0(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
entity1(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
entity3(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
entity4(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
entity6(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
entity8(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
entity9(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
entity10(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
notation0(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
notation2(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
notation3(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
notation4(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
attlist0(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
attlist1(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
attlist3(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
attlist4(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
attlist5(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
attlist6(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
attlist7(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
attlist9(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
element0(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
element3(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
element4(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
element5(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
element6(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
element7(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
condSect1(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
condSect2(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
static int PTRCALL
declClose(PROLOG_STATE *state,
int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
switch (tok) {
case XML_TOK_PROLOG_S:
}
static int PTRCALL
-error(PROLOG_STATE *state,
- int tok,
- const char *ptr,
- const char *end,
- const ENCODING *enc)
+error(PROLOG_STATE *UNUSED_P(state),
+ int UNUSED_P(tok),
+ const char *UNUSED_P(ptr),
+ const char *UNUSED_P(end),
+ const ENCODING *UNUSED_P(enc))
{
return XML_ROLE_NONE;
}
#include <stddef.h>
-#ifdef COMPILED_FROM_DSP
+#ifdef _WIN32
#include "winconfig.h"
-#elif defined(MACOS_CLASSIC)
-#include "macconfig.h"
-#elif defined(__amigaos__)
-#include "amigaconfig.h"
-#elif defined(__WATCOMC__)
-#include "watcomconfig.h"
#else
#ifdef HAVE_EXPAT_CONFIG_H
#include <expat_config.h>
#endif
-#endif /* ndef COMPILED_FROM_DSP */
+#endif /* ndef _WIN32 */
#include "expat_external.h"
#include "internal.h"
#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
#define UCS2_GET_NAMING(pages, hi, lo) \
- (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
+ (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F)))
/* A 2 byte UTF-8 representation splits the characters 11 bits between
the bottom 5 and 6 bits of the bytes. We need 8 bits to index into
(namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
+ ((((byte)[0]) & 3) << 1) \
+ ((((byte)[1]) >> 5) & 1)] \
- & (1 << (((byte)[1]) & 0x1F)))
+ & (1u << (((byte)[1]) & 0x1F)))
/* A 3 byte UTF-8 representation splits the characters 16 bits between
the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index
<< 3) \
+ ((((byte)[1]) & 3) << 1) \
+ ((((byte)[2]) >> 5) & 1)] \
- & (1 << (((byte)[2]) & 0x1F)))
+ & (1u << (((byte)[2]) & 0x1F)))
#define UTF8_GET_NAMING(pages, p, n) \
((n) == 2 \
((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0)))
static int PTRFASTCALL
-isNever(const ENCODING *enc, const char *p)
+isNever(const ENCODING *UNUSED_P(enc), const char *UNUSED_P(p))
{
return 0;
}
static int PTRFASTCALL
-utf8_isName2(const ENCODING *enc, const char *p)
+utf8_isName2(const ENCODING *UNUSED_P(enc), const char *p)
{
return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
}
static int PTRFASTCALL
-utf8_isName3(const ENCODING *enc, const char *p)
+utf8_isName3(const ENCODING *UNUSED_P(enc), const char *p)
{
return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
}
#define utf8_isName4 isNever
static int PTRFASTCALL
-utf8_isNmstrt2(const ENCODING *enc, const char *p)
+utf8_isNmstrt2(const ENCODING *UNUSED_P(enc), const char *p)
{
return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
}
static int PTRFASTCALL
-utf8_isNmstrt3(const ENCODING *enc, const char *p)
+utf8_isNmstrt3(const ENCODING *UNUSED_P(enc), const char *p)
{
return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
}
#define utf8_isNmstrt4 isNever
static int PTRFASTCALL
-utf8_isInvalid2(const ENCODING *enc, const char *p)
+utf8_isInvalid2(const ENCODING *UNUSED_P(enc), const char *p)
{
return UTF8_INVALID2((const unsigned char *)p);
}
static int PTRFASTCALL
-utf8_isInvalid3(const ENCODING *enc, const char *p)
+utf8_isInvalid3(const ENCODING *UNUSED_P(enc), const char *p)
{
return UTF8_INVALID3((const unsigned char *)p);
}
static int PTRFASTCALL
-utf8_isInvalid4(const ENCODING *enc, const char *p)
+utf8_isInvalid4(const ENCODING *UNUSED_P(enc), const char *p)
{
return UTF8_INVALID4((const unsigned char *)p);
}
E ## isInvalid3, \
E ## isInvalid4
+#define NULL_VTABLE \
+ /* isName2 */ NULL, \
+ /* isName3 */ NULL, \
+ /* isName4 */ NULL, \
+ /* isNmstrt2 */ NULL, \
+ /* isNmstrt3 */ NULL, \
+ /* isNmstrt4 */ NULL, \
+ /* isInvalid2 */ NULL, \
+ /* isInvalid3 */ NULL, \
+ /* isInvalid4 */ NULL
+
static int FASTCALL checkCharRefNumber(int);
#include "xmltok_impl.h"
UTF8_cval4 = 0xf0
};
+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 *enc,
+utf8_toUtf8(const ENCODING *UNUSED_P(enc),
const char **fromP, const char *fromLim,
char **toP, const char *toLim)
{
- enum XML_Convert_Result res = XML_CONVERT_COMPLETED;
char *to;
const char *from;
- if (fromLim - *fromP > toLim - *toP) {
- /* Avoid copying partial characters. */
- res = XML_CONVERT_OUTPUT_EXHAUSTED;
- for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
- if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
- break;
- }
+ const char *fromLimInitial = fromLim;
+
+ /* Avoid copying partial characters. */
+ align_limit_to_full_utf8_characters(*fromP, &fromLim);
+
for (to = *toP, from = *fromP; (from < fromLim) && (to < toLim); from++, to++)
*to = *from;
*fromP = from;
*toP = to;
- if ((to == toLim) && (from < fromLim))
+ if (fromLim < fromLimInitial)
+ return XML_CONVERT_INPUT_INCOMPLETE;
+ else if ((to == toLim) && (from < fromLim))
return XML_CONVERT_OUTPUT_EXHAUSTED;
else
- return res;
+ return XML_CONVERT_COMPLETED;
}
static enum XML_Convert_Result PTRCALL
case BT_LEAD2:
if (fromLim - from < 2) {
res = XML_CONVERT_INPUT_INCOMPLETE;
- break;
+ goto after;
}
*to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f));
from += 2;
case BT_LEAD3:
if (fromLim - from < 3) {
res = XML_CONVERT_INPUT_INCOMPLETE;
- break;
+ goto after;
}
*to++ = (unsigned short)(((from[0] & 0xf) << 12)
| ((from[1] & 0x3f) << 6) | (from[2] & 0x3f));
break;
}
}
+ if (from < fromLim)
+ res = XML_CONVERT_OUTPUT_EXHAUSTED;
after:
*fromP = from;
*toP = to;
};
static enum XML_Convert_Result PTRCALL
-latin1_toUtf8(const ENCODING *enc,
+latin1_toUtf8(const ENCODING *UNUSED_P(enc),
const char **fromP, const char *fromLim,
char **toP, const char *toLim)
{
}
static enum XML_Convert_Result PTRCALL
-latin1_toUtf16(const ENCODING *enc,
+latin1_toUtf16(const ENCODING *UNUSED_P(enc),
const char **fromP, const char *fromLim,
unsigned short **toP, const unsigned short *toLim)
{
#include "asciitab.h"
#include "latin1tab.h"
},
- STANDARD_VTABLE(sb_)
+ STANDARD_VTABLE(sb_) NULL_VTABLE
};
#endif
#undef BT_COLON
#include "latin1tab.h"
},
- STANDARD_VTABLE(sb_)
+ STANDARD_VTABLE(sb_) NULL_VTABLE
};
static enum XML_Convert_Result PTRCALL
-ascii_toUtf8(const ENCODING *enc,
+ascii_toUtf8(const ENCODING *UNUSED_P(enc),
const char **fromP, const char *fromLim,
char **toP, const char *toLim)
{
#include "asciitab.h"
/* BT_NONXML == 0 */
},
- STANDARD_VTABLE(sb_)
+ STANDARD_VTABLE(sb_) NULL_VTABLE
};
#endif
#undef BT_COLON
/* BT_NONXML == 0 */
},
- STANDARD_VTABLE(sb_)
+ STANDARD_VTABLE(sb_) NULL_VTABLE
};
static int PTRFASTCALL
#define DEFINE_UTF16_TO_UTF8(E) \
static enum XML_Convert_Result PTRCALL \
-E ## toUtf8(const ENCODING *enc, \
+E ## toUtf8(const ENCODING *UNUSED_P(enc), \
const char **fromP, const char *fromLim, \
char **toP, const char *toLim) \
{ \
#define DEFINE_UTF16_TO_UTF16(E) \
static enum XML_Convert_Result PTRCALL \
-E ## toUtf16(const ENCODING *enc, \
+E ## toUtf16(const ENCODING *UNUSED_P(enc), \
const char **fromP, const char *fromLim, \
unsigned short **toP, const unsigned short *toLim) \
{ \
#include "asciitab.h"
#include "latin1tab.h"
},
- STANDARD_VTABLE(little2_)
+ STANDARD_VTABLE(little2_) NULL_VTABLE
};
#endif
#undef BT_COLON
#include "latin1tab.h"
},
- STANDARD_VTABLE(little2_)
+ STANDARD_VTABLE(little2_) NULL_VTABLE
};
#if BYTEORDER != 4321
#include "iasciitab.h"
#include "latin1tab.h"
},
- STANDARD_VTABLE(little2_)
+ STANDARD_VTABLE(little2_) NULL_VTABLE
};
#endif
#undef BT_COLON
#include "latin1tab.h"
},
- STANDARD_VTABLE(little2_)
+ STANDARD_VTABLE(little2_) NULL_VTABLE
};
#endif
#include "asciitab.h"
#include "latin1tab.h"
},
- STANDARD_VTABLE(big2_)
+ STANDARD_VTABLE(big2_) NULL_VTABLE
};
#endif
#undef BT_COLON
#include "latin1tab.h"
},
- STANDARD_VTABLE(big2_)
+ STANDARD_VTABLE(big2_) NULL_VTABLE
};
#if BYTEORDER != 1234
#include "iasciitab.h"
#include "latin1tab.h"
},
- STANDARD_VTABLE(big2_)
+ STANDARD_VTABLE(big2_) NULL_VTABLE
};
#endif
#undef BT_COLON
#include "latin1tab.h"
},
- STANDARD_VTABLE(big2_)
+ STANDARD_VTABLE(big2_) NULL_VTABLE
};
#endif
}
static void PTRCALL
-initUpdatePosition(const ENCODING *enc, const char *ptr,
+initUpdatePosition(const ENCODING *UNUSED_P(enc), const char *ptr,
const char *end, POSITION *pos)
{
normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
#define PREFIX(ident) ident
#endif
+
+#define HAS_CHARS(enc, ptr, end, count) \
+ (end - ptr >= count * MINBPC(enc))
+
+#define HAS_CHAR(enc, ptr, end) \
+ HAS_CHARS(enc, ptr, end, 1)
+
+#define REQUIRE_CHARS(enc, ptr, end, count) \
+ { \
+ if (! HAS_CHARS(enc, ptr, end, count)) { \
+ return XML_TOK_PARTIAL; \
+ } \
+ }
+
+#define REQUIRE_CHAR(enc, ptr, end) \
+ REQUIRE_CHARS(enc, ptr, end, 1)
+
+
/* ptr points to character following "<!-" */
static int PTRCALL
PREFIX(scanComment)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
- if (ptr < end) {
+ if (HAS_CHAR(enc, ptr, end)) {
if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
ptr += MINBPC(enc);
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
INVALID_CASES(ptr, nextTokPtr)
case BT_MINUS:
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
PREFIX(scanDecl)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
case BT_MINUS:
return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_PERCNT:
- if (ptr + MINBPC(enc) == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHARS(enc, ptr, end, 2);
/* don't allow <!ENTITY% foo "whatever"> */
switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
}
static int PTRCALL
-PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr,
+PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(enc), const char *ptr,
const char *end, int *tokPtr)
{
int upper = 0;
{
int tok;
const char *target = ptr;
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_S: case BT_CR: case BT_LF:
return XML_TOK_INVALID;
}
ptr += MINBPC(enc);
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
INVALID_CASES(ptr, nextTokPtr)
case BT_QUEST:
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
*nextTokPtr = ptr + MINBPC(enc);
return tok;
return XML_TOK_INVALID;
}
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
*nextTokPtr = ptr + MINBPC(enc);
return tok;
}
static int PTRCALL
-PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr,
+PREFIX(scanCdataSection)(const ENCODING *UNUSED_P(enc), const char *ptr,
const char *end, const char **nextTokPtr)
{
static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A,
ASCII_T, ASCII_A, ASCII_LSQB };
int i;
/* CDATA[ */
- if (end - ptr < 6 * MINBPC(enc))
- return XML_TOK_PARTIAL;
+ REQUIRE_CHARS(enc, ptr, end, 6);
for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
*nextTokPtr = ptr;
switch (BYTE_TYPE(enc, ptr)) {
case BT_RSQB:
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
break;
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
ptr -= MINBPC(enc);
break;
return XML_TOK_CDATA_SECT_CLOSE;
case BT_CR:
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
if (BYTE_TYPE(enc, ptr) == BT_LF)
ptr += MINBPC(enc);
*nextTokPtr = ptr;
ptr += MINBPC(enc);
break;
}
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
#define LEAD_CASE(n) \
case BT_LEAD ## n: \
PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_S: case BT_CR: case BT_LF:
- for (ptr += MINBPC(enc); ptr < end; ptr += MINBPC(enc)) {
+ for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_S: case BT_CR: case BT_LF:
break;
PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
- if (ptr < end) {
+ if (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_DIGIT:
case BT_HEX:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- for (ptr += MINBPC(enc); ptr < end; ptr += MINBPC(enc)) {
+ for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_DIGIT:
case BT_HEX:
PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr,
const char *end, const char **nextTokPtr)
{
- if (ptr < end) {
+ if (HAS_CHAR(enc, ptr, end)) {
if (CHAR_MATCHES(enc, ptr, ASCII_x))
return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
switch (BYTE_TYPE(enc, ptr)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- for (ptr += MINBPC(enc); ptr < end; ptr += MINBPC(enc)) {
+ for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_DIGIT:
break;
PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
case BT_NUM:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_SEMI:
#ifdef XML_NS
int hadColon = 0;
#endif
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
#ifdef XML_NS
}
hadColon = 1;
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
default:
int t;
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
t = BYTE_TYPE(enc, ptr);
if (t == BT_EQUALS)
break;
#endif
for (;;) {
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
open = BYTE_TYPE(enc, ptr);
if (open == BT_QUOT || open == BT_APOS)
break;
/* in attribute value */
for (;;) {
int t;
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
t = BYTE_TYPE(enc, ptr);
if (t == open)
break;
}
}
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
case BT_S:
case BT_CR:
/* ptr points to closing quote */
for (;;) {
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
case BT_S: case BT_CR: case BT_LF:
case BT_SOL:
sol:
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
#ifdef XML_NS
int hadColon;
#endif
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
case BT_EXCL:
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
case BT_MINUS:
return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
hadColon = 0;
#endif
/* we have a start-tag */
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
#ifdef XML_NS
}
hadColon = 1;
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
default:
case BT_S: case BT_CR: case BT_LF:
{
ptr += MINBPC(enc);
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
case BT_GT:
case BT_SOL:
sol:
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
*nextTokPtr = ptr;
return XML_TOK_INVALID;
return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
case BT_CR:
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return XML_TOK_TRAILING_CR;
if (BYTE_TYPE(enc, ptr) == BT_LF)
ptr += MINBPC(enc);
return XML_TOK_DATA_NEWLINE;
case BT_RSQB:
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return XML_TOK_TRAILING_RSQB;
if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
break;
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return XML_TOK_TRAILING_RSQB;
if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
ptr -= MINBPC(enc);
ptr += MINBPC(enc);
break;
}
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
#define LEAD_CASE(n) \
case BT_LEAD ## n: \
LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
#undef LEAD_CASE
case BT_RSQB:
- if (ptr + MINBPC(enc) != end) {
+ if (HAS_CHARS(enc, ptr, end, 2)) {
if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
ptr += MINBPC(enc);
break;
}
- if (ptr + 2*MINBPC(enc) != end) {
+ if (HAS_CHARS(enc, ptr, end, 3)) {
if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
ptr += MINBPC(enc);
break;
PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_SEMI:
PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
const char **nextTokPtr)
{
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
default:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_CR: case BT_LF: case BT_S:
const char *ptr, const char *end,
const char **nextTokPtr)
{
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
int t = BYTE_TYPE(enc, ptr);
switch (t) {
INVALID_CASES(ptr, nextTokPtr)
ptr += MINBPC(enc);
if (t != open)
break;
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return -XML_TOK_LITERAL;
*nextTokPtr = ptr;
switch (BYTE_TYPE(enc, ptr)) {
case BT_LT:
{
ptr += MINBPC(enc);
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
switch (BYTE_TYPE(enc, ptr)) {
case BT_EXCL:
return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
case BT_S: case BT_LF:
for (;;) {
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
break;
switch (BYTE_TYPE(enc, ptr)) {
case BT_S: case BT_LF:
return XML_TOK_OPEN_BRACKET;
case BT_RSQB:
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return -XML_TOK_CLOSE_BRACKET;
if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
- if (ptr + MINBPC(enc) == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHARS(enc, ptr, end, 2);
if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
*nextTokPtr = ptr + 2*MINBPC(enc);
return XML_TOK_COND_SECT_CLOSE;
return XML_TOK_OPEN_PAREN;
case BT_RPAR:
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return -XML_TOK_CLOSE_PAREN;
switch (BYTE_TYPE(enc, ptr)) {
case BT_AST:
*nextTokPtr = ptr;
return XML_TOK_INVALID;
}
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
case BT_GT: case BT_RPAR: case BT_COMMA:
ptr += MINBPC(enc);
switch (tok) {
case XML_TOK_NAME:
- if (ptr == end)
- return XML_TOK_PARTIAL;
+ REQUIRE_CHAR(enc, ptr, end);
tok = XML_TOK_PREFIXED_NAME;
switch (BYTE_TYPE(enc, ptr)) {
CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
const char *start;
if (ptr >= end)
return XML_TOK_NONE;
+ else if (! HAS_CHAR(enc, ptr, end))
+ return XML_TOK_PARTIAL;
start = ptr;
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
#define LEAD_CASE(n) \
case BT_LEAD ## n: ptr += n; break;
case BT_CR:
if (ptr == start) {
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return XML_TOK_TRAILING_CR;
if (BYTE_TYPE(enc, ptr) == BT_LF)
ptr += MINBPC(enc);
const char *start;
if (ptr >= end)
return XML_TOK_NONE;
+ else if (! HAS_CHAR(enc, ptr, end))
+ return XML_TOK_PARTIAL;
start = ptr;
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
#define LEAD_CASE(n) \
case BT_LEAD ## n: ptr += n; break;
case BT_CR:
if (ptr == start) {
ptr += MINBPC(enc);
- if (ptr == end)
+ if (! HAS_CHAR(enc, ptr, end))
return XML_TOK_TRAILING_CR;
if (BYTE_TYPE(enc, ptr) == BT_LF)
ptr += MINBPC(enc);
end = ptr + n;
}
}
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
INVALID_CASES(ptr, nextTokPtr)
case BT_LT:
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
++level;
ptr += MINBPC(enc);
}
break;
case BT_RSQB:
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
- if ((ptr += MINBPC(enc)) == end)
- return XML_TOK_PARTIAL;
+ ptr += MINBPC(enc);
+ REQUIRE_CHAR(enc, ptr, end);
if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
ptr += MINBPC(enc);
if (level == 0) {
{
ptr += MINBPC(enc);
end -= MINBPC(enc);
- for (; ptr < end; ptr += MINBPC(enc)) {
+ for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) {
switch (BYTE_TYPE(enc, ptr)) {
case BT_DIGIT:
case BT_HEX:
}
static int PTRFASTCALL
-PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
+PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr)
{
int result = 0;
/* skip &# */
}
static int PTRCALL
-PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr,
+PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr,
const char *end)
{
switch ((end - ptr)/MINBPC(enc)) {
}
static int PTRCALL
-PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
+PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1,
const char *end1, const char *ptr2)
{
for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
- if (ptr1 == end1)
+ if (end1 - ptr1 < MINBPC(enc))
return 0;
if (!CHAR_MATCHES(enc, ptr1, *ptr2))
return 0;
const char *end,
POSITION *pos)
{
- while (ptr < end) {
+ while (HAS_CHAR(enc, ptr, end)) {
switch (BYTE_TYPE(enc, ptr)) {
#define LEAD_CASE(n) \
case BT_LEAD ## n: \
case BT_CR:
pos->lineNumber++;
ptr += MINBPC(enc);
- if (ptr < end && BYTE_TYPE(enc, ptr) == BT_LF)
+ if (HAS_CHAR(enc, ptr, end) && BYTE_TYPE(enc, ptr) == BT_LF)
ptr += MINBPC(enc);
pos->columnNumber = (XML_Size)-1;
break;