Vendor import of expat 2.5.0
This commit is contained in:
parent
66082b6c88
commit
9fc8132eca
34
Changes
34
Changes
@ -2,6 +2,40 @@ NOTE: We are looking for help with a few things:
|
|||||||
https://github.com/libexpat/libexpat/labels/help%20wanted
|
https://github.com/libexpat/libexpat/labels/help%20wanted
|
||||||
If you can help, please get in touch. Thanks!
|
If you can help, please get in touch. Thanks!
|
||||||
|
|
||||||
|
Release 2.5.0 Tue October 25 2022
|
||||||
|
Security fixes:
|
||||||
|
#616 #649 #650 CVE-2022-43680 -- Fix heap use-after-free after overeager
|
||||||
|
destruction of a shared DTD in function
|
||||||
|
XML_ExternalEntityParserCreate in out-of-memory situations.
|
||||||
|
Expected impact is denial of service or potentially
|
||||||
|
arbitrary code execution.
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
#612 #645 Fix curruption from undefined entities
|
||||||
|
#613 #654 Fix case when parsing was suspended while processing nested
|
||||||
|
entities
|
||||||
|
#616 #652 #653 Stop leaking opening tag bindings after a closing tag
|
||||||
|
mismatch error where a parser is reset through
|
||||||
|
XML_ParserReset and then reused to parse
|
||||||
|
#656 CMake: Fix generation of pkg-config file
|
||||||
|
#658 MinGW|CMake: Fix static library name
|
||||||
|
|
||||||
|
Other changes:
|
||||||
|
#663 Protect header expat_config.h from multiple inclusion
|
||||||
|
#666 examples: Make use of XML_GetBuffer and be more
|
||||||
|
consistent across examples
|
||||||
|
#648 Address compiler warnings
|
||||||
|
#667 #668 Version info bumped from 9:9:8 to 9:10:8;
|
||||||
|
see https://verbump.de/ for what these numbers do
|
||||||
|
|
||||||
|
Special thanks to:
|
||||||
|
Jann Horn
|
||||||
|
Mark Brand
|
||||||
|
Osyotr
|
||||||
|
Rhodri James
|
||||||
|
and
|
||||||
|
Google Project Zero
|
||||||
|
|
||||||
Release 2.4.9 Tue September 20 2022
|
Release 2.4.9 Tue September 20 2022
|
||||||
Security fixes:
|
Security fixes:
|
||||||
#629 #640 CVE-2022-40674 -- Heap use-after-free vulnerability in
|
#629 #640 CVE-2022-40674 -- Heap use-after-free vulnerability in
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
[![Downloads GitHub](https://img.shields.io/github/downloads/libexpat/libexpat/total?label=Downloads%20GitHub)](https://github.com/libexpat/libexpat/releases)
|
[![Downloads GitHub](https://img.shields.io/github/downloads/libexpat/libexpat/total?label=Downloads%20GitHub)](https://github.com/libexpat/libexpat/releases)
|
||||||
|
|
||||||
|
|
||||||
# Expat, Release 2.4.9
|
# Expat, Release 2.5.0
|
||||||
|
|
||||||
This is Expat, a C library for parsing XML, started by
|
This is Expat, a C library for parsing XML, started by
|
||||||
[James Clark](https://en.wikipedia.org/wiki/James_Clark_%28programmer%29) in 1997.
|
[James Clark](https://en.wikipedia.org/wiki/James_Clark_%28programmer%29) in 1997.
|
||||||
|
@ -81,11 +81,14 @@ dnl
|
|||||||
dnl If the API changes incompatibly set LIBAGE back to 0
|
dnl If the API changes incompatibly set LIBAGE back to 0
|
||||||
dnl
|
dnl
|
||||||
|
|
||||||
LIBCURRENT=9 # sync
|
LIBCURRENT=9 # sync
|
||||||
LIBREVISION=9 # with
|
LIBREVISION=10 # with
|
||||||
LIBAGE=8 # CMakeLists.txt!
|
LIBAGE=8 # CMakeLists.txt!
|
||||||
|
|
||||||
AC_CONFIG_HEADERS([expat_config.h])
|
AC_CONFIG_HEADERS([expat_config.h])
|
||||||
|
AH_TOP([#ifndef EXPAT_CONFIG_H
|
||||||
|
#define EXPAT_CONFIG_H 1])
|
||||||
|
AH_BOTTOM([#endif // ndef EXPAT_CONFIG_H])
|
||||||
|
|
||||||
AM_PROG_AR
|
AM_PROG_AR
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<h1>
|
<h1>
|
||||||
The Expat XML Parser
|
The Expat XML Parser
|
||||||
<small>Release 2.4.9</small>
|
<small>Release 2.5.0</small>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
\\$2 \(la\\$1\(ra\\$3
|
\\$2 \(la\\$1\(ra\\$3
|
||||||
..
|
..
|
||||||
.if \n(.g .mso www.tmac
|
.if \n(.g .mso www.tmac
|
||||||
.TH XMLWF 1 "September 20, 2022" "" ""
|
.TH XMLWF 1 "October 25, 2022" "" ""
|
||||||
.SH NAME
|
.SH NAME
|
||||||
xmlwf \- Determines if an XML document is well-formed
|
xmlwf \- Determines if an XML document is well-formed
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||||
<!ENTITY dhfirstname "<firstname>Scott</firstname>">
|
<!ENTITY dhfirstname "<firstname>Scott</firstname>">
|
||||||
<!ENTITY dhsurname "<surname>Bronson</surname>">
|
<!ENTITY dhsurname "<surname>Bronson</surname>">
|
||||||
<!ENTITY dhdate "<date>September 20, 2022</date>">
|
<!ENTITY dhdate "<date>October 25, 2022</date>">
|
||||||
<!-- Please adjust this^^ date whenever cutting a new release. -->
|
<!-- Please adjust this^^ date whenever cutting a new release. -->
|
||||||
<!ENTITY dhsection "<manvolnum>1</manvolnum>">
|
<!ENTITY dhsection "<manvolnum>1</manvolnum>">
|
||||||
<!ENTITY dhemail "<email>bronson@rinspin.com</email>">
|
<!ENTITY dhemail "<email>bronson@rinspin.com</email>">
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
|
Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
|
||||||
Copyright (c) 2004-2006 Karl Waclawek <karl@waclawek.net>
|
Copyright (c) 2004-2006 Karl Waclawek <karl@waclawek.net>
|
||||||
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
|
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
|
||||||
Copyright (c) 2016-2019 Sebastian Pipping <sebastian@pipping.org>
|
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
|
||||||
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
|
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
|
||||||
Copyright (c) 2019 Zhongyuan Zhou <zhouzhongyuan@huawei.com>
|
Copyright (c) 2019 Zhongyuan Zhou <zhouzhongyuan@huawei.com>
|
||||||
Licensed under the MIT license:
|
Licensed under the MIT license:
|
||||||
@ -49,7 +49,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef XML_UNICODE_WCHAR_T
|
#ifdef XML_UNICODE_WCHAR_T
|
||||||
# include <wchar.h>
|
|
||||||
# define XML_FMT_STR "ls"
|
# define XML_FMT_STR "ls"
|
||||||
#else
|
#else
|
||||||
# define XML_FMT_STR "s"
|
# define XML_FMT_STR "s"
|
||||||
@ -58,7 +57,7 @@
|
|||||||
static void XMLCALL
|
static void XMLCALL
|
||||||
startElement(void *userData, const XML_Char *name, const XML_Char **atts) {
|
startElement(void *userData, const XML_Char *name, const XML_Char **atts) {
|
||||||
int i;
|
int i;
|
||||||
int *depthPtr = (int *)userData;
|
int *const depthPtr = (int *)userData;
|
||||||
(void)atts;
|
(void)atts;
|
||||||
|
|
||||||
for (i = 0; i < *depthPtr; i++)
|
for (i = 0; i < *depthPtr; i++)
|
||||||
@ -69,34 +68,54 @@ startElement(void *userData, const XML_Char *name, const XML_Char **atts) {
|
|||||||
|
|
||||||
static void XMLCALL
|
static void XMLCALL
|
||||||
endElement(void *userData, const XML_Char *name) {
|
endElement(void *userData, const XML_Char *name) {
|
||||||
int *depthPtr = (int *)userData;
|
int *const depthPtr = (int *)userData;
|
||||||
(void)name;
|
(void)name;
|
||||||
|
|
||||||
*depthPtr -= 1;
|
*depthPtr -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[]) {
|
main(void) {
|
||||||
char buf[BUFSIZ];
|
|
||||||
XML_Parser parser = XML_ParserCreate(NULL);
|
XML_Parser parser = XML_ParserCreate(NULL);
|
||||||
int done;
|
int done;
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
(void)argc;
|
|
||||||
(void)argv;
|
if (! parser) {
|
||||||
|
fprintf(stderr, "Couldn't allocate memory for parser\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
XML_SetUserData(parser, &depth);
|
XML_SetUserData(parser, &depth);
|
||||||
XML_SetElementHandler(parser, startElement, endElement);
|
XML_SetElementHandler(parser, startElement, endElement);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
size_t len = fread(buf, 1, sizeof(buf), stdin);
|
void *const buf = XML_GetBuffer(parser, BUFSIZ);
|
||||||
done = len < sizeof(buf);
|
if (! buf) {
|
||||||
if (XML_Parse(parser, buf, (int)len, done) == XML_STATUS_ERROR) {
|
fprintf(stderr, "Couldn't allocate memory for buffer\n");
|
||||||
fprintf(stderr, "%" XML_FMT_STR " at line %" XML_FMT_INT_MOD "u\n",
|
XML_ParserFree(parser);
|
||||||
XML_ErrorString(XML_GetErrorCode(parser)),
|
return 1;
|
||||||
XML_GetCurrentLineNumber(parser));
|
}
|
||||||
|
|
||||||
|
const size_t len = fread(buf, 1, BUFSIZ, stdin);
|
||||||
|
|
||||||
|
if (ferror(stdin)) {
|
||||||
|
fprintf(stderr, "Read error\n");
|
||||||
|
XML_ParserFree(parser);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
done = feof(stdin);
|
||||||
|
|
||||||
|
if (XML_ParseBuffer(parser, (int)len, done) == XML_STATUS_ERROR) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Parse error at line %" XML_FMT_INT_MOD "u:\n%" XML_FMT_STR "\n",
|
||||||
|
XML_GetCurrentLineNumber(parser),
|
||||||
|
XML_ErrorString(XML_GetErrorCode(parser)));
|
||||||
XML_ParserFree(parser);
|
XML_ParserFree(parser);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} while (! done);
|
} while (! done);
|
||||||
|
|
||||||
XML_ParserFree(parser);
|
XML_ParserFree(parser);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
|
Copyright (c) 2001-2003 Fred L. Drake, Jr. <fdrake@users.sourceforge.net>
|
||||||
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
|
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
|
||||||
Copyright (c) 2005-2006 Karl Waclawek <karl@waclawek.net>
|
Copyright (c) 2005-2006 Karl Waclawek <karl@waclawek.net>
|
||||||
Copyright (c) 2016-2019 Sebastian Pipping <sebastian@pipping.org>
|
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
|
||||||
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
|
Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
|
||||||
Licensed under the MIT license:
|
Licensed under the MIT license:
|
||||||
|
|
||||||
@ -51,73 +51,74 @@
|
|||||||
# define XML_FMT_STR "s"
|
# define XML_FMT_STR "s"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BUFFSIZE 8192
|
|
||||||
|
|
||||||
char Buff[BUFFSIZE];
|
|
||||||
|
|
||||||
int Depth;
|
|
||||||
|
|
||||||
static void XMLCALL
|
static void XMLCALL
|
||||||
start(void *data, const XML_Char *el, const XML_Char **attr) {
|
startElement(void *userData, const XML_Char *name, const XML_Char **atts) {
|
||||||
int i;
|
int i;
|
||||||
(void)data;
|
int *const depthPtr = (int *)userData;
|
||||||
|
|
||||||
for (i = 0; i < Depth; i++)
|
for (i = 0; i < *depthPtr; i++)
|
||||||
printf(" ");
|
printf(" ");
|
||||||
|
|
||||||
printf("%" XML_FMT_STR, el);
|
printf("%" XML_FMT_STR, name);
|
||||||
|
|
||||||
for (i = 0; attr[i]; i += 2) {
|
for (i = 0; atts[i]; i += 2) {
|
||||||
printf(" %" XML_FMT_STR "='%" XML_FMT_STR "'", attr[i], attr[i + 1]);
|
printf(" %" XML_FMT_STR "='%" XML_FMT_STR "'", atts[i], atts[i + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
Depth++;
|
*depthPtr += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void XMLCALL
|
static void XMLCALL
|
||||||
end(void *data, const XML_Char *el) {
|
endElement(void *userData, const XML_Char *name) {
|
||||||
(void)data;
|
int *const depthPtr = (int *)userData;
|
||||||
(void)el;
|
(void)name;
|
||||||
|
|
||||||
Depth--;
|
*depthPtr -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[]) {
|
main(void) {
|
||||||
XML_Parser p = XML_ParserCreate(NULL);
|
XML_Parser parser = XML_ParserCreate(NULL);
|
||||||
(void)argc;
|
int done;
|
||||||
(void)argv;
|
int depth = 0;
|
||||||
|
|
||||||
if (! p) {
|
if (! parser) {
|
||||||
fprintf(stderr, "Couldn't allocate memory for parser\n");
|
fprintf(stderr, "Couldn't allocate memory for parser\n");
|
||||||
exit(-1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XML_SetElementHandler(p, start, end);
|
XML_SetUserData(parser, &depth);
|
||||||
|
XML_SetElementHandler(parser, startElement, endElement);
|
||||||
|
|
||||||
for (;;) {
|
do {
|
||||||
int done;
|
void *const buf = XML_GetBuffer(parser, BUFSIZ);
|
||||||
int len;
|
if (! buf) {
|
||||||
|
fprintf(stderr, "Couldn't allocate memory for buffer\n");
|
||||||
|
XML_ParserFree(parser);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t len = fread(buf, 1, BUFSIZ, stdin);
|
||||||
|
|
||||||
len = (int)fread(Buff, 1, BUFFSIZE, stdin);
|
|
||||||
if (ferror(stdin)) {
|
if (ferror(stdin)) {
|
||||||
fprintf(stderr, "Read error\n");
|
fprintf(stderr, "Read error\n");
|
||||||
exit(-1);
|
XML_ParserFree(parser);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
done = feof(stdin);
|
done = feof(stdin);
|
||||||
|
|
||||||
if (XML_Parse(p, Buff, len, done) == XML_STATUS_ERROR) {
|
if (XML_ParseBuffer(parser, (int)len, done) == XML_STATUS_ERROR) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Parse error at line %" XML_FMT_INT_MOD "u:\n%" XML_FMT_STR "\n",
|
"Parse error at line %" XML_FMT_INT_MOD "u:\n%" XML_FMT_STR "\n",
|
||||||
XML_GetCurrentLineNumber(p),
|
XML_GetCurrentLineNumber(parser),
|
||||||
XML_ErrorString(XML_GetErrorCode(p)));
|
XML_ErrorString(XML_GetErrorCode(parser)));
|
||||||
exit(-1);
|
XML_ParserFree(parser);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
} while (! done);
|
||||||
|
|
||||||
if (done)
|
XML_ParserFree(parser);
|
||||||
break;
|
|
||||||
}
|
|
||||||
XML_ParserFree(p);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
/* expat_config.h.in. Generated from configure.ac by autoheader. */
|
/* expat_config.h.in. Generated from configure.ac by autoheader. */
|
||||||
|
|
||||||
|
#ifndef EXPAT_CONFIG_H
|
||||||
|
#define EXPAT_CONFIG_H 1
|
||||||
|
|
||||||
/* Define if building universal (internal helper macro) */
|
/* Define if building universal (internal helper macro) */
|
||||||
#undef AC_APPLE_UNIVERSAL_BUILD
|
#undef AC_APPLE_UNIVERSAL_BUILD
|
||||||
|
|
||||||
@ -132,3 +135,5 @@
|
|||||||
|
|
||||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||||
#undef size_t
|
#undef size_t
|
||||||
|
|
||||||
|
#endif // ndef EXPAT_CONFIG_H
|
||||||
|
@ -1054,8 +1054,8 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold(
|
|||||||
See http://semver.org.
|
See http://semver.org.
|
||||||
*/
|
*/
|
||||||
#define XML_MAJOR_VERSION 2
|
#define XML_MAJOR_VERSION 2
|
||||||
#define XML_MINOR_VERSION 4
|
#define XML_MINOR_VERSION 5
|
||||||
#define XML_MICRO_VERSION 9
|
#define XML_MICRO_VERSION 0
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* 90815a2b2c80c03b2b889fe1d427bb2b9e3282aa065e42784e001db4f23de324 (2.4.9+)
|
/* 5ab094ffadd6edfc94c3eee53af44a86951f9f1f0933ada3114bbce2bfb02c99 (2.5.0+)
|
||||||
__ __ _
|
__ __ _
|
||||||
___\ \/ /_ __ __ _| |_
|
___\ \/ /_ __ __ _| |_
|
||||||
/ _ \\ /| '_ \ / _` | __|
|
/ _ \\ /| '_ \ / _` | __|
|
||||||
@ -35,6 +35,7 @@
|
|||||||
Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
|
Copyright (c) 2021 Dong-hee Na <donghee.na@python.org>
|
||||||
Copyright (c) 2022 Samanta Navarro <ferivoz@riseup.net>
|
Copyright (c) 2022 Samanta Navarro <ferivoz@riseup.net>
|
||||||
Copyright (c) 2022 Jeffrey Walton <noloader@gmail.com>
|
Copyright (c) 2022 Jeffrey Walton <noloader@gmail.com>
|
||||||
|
Copyright (c) 2022 Jann Horn <jannh@google.com>
|
||||||
Licensed under the MIT license:
|
Licensed under the MIT license:
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
@ -1068,6 +1069,14 @@ parserCreate(const XML_Char *encodingName,
|
|||||||
parserInit(parser, encodingName);
|
parserInit(parser, encodingName);
|
||||||
|
|
||||||
if (encodingName && ! parser->m_protocolEncodingName) {
|
if (encodingName && ! parser->m_protocolEncodingName) {
|
||||||
|
if (dtd) {
|
||||||
|
// We need to stop the upcoming call to XML_ParserFree from happily
|
||||||
|
// destroying parser->m_dtd because the DTD is shared with the parent
|
||||||
|
// parser and the only guard that keeps XML_ParserFree from destroying
|
||||||
|
// parser->m_dtd is parser->m_isParamEntity but it will be set to
|
||||||
|
// XML_TRUE only later in XML_ExternalEntityParserCreate (or not at all).
|
||||||
|
parser->m_dtd = NULL;
|
||||||
|
}
|
||||||
XML_ParserFree(parser);
|
XML_ParserFree(parser);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -3011,9 +3020,6 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
|
|||||||
int len;
|
int len;
|
||||||
const char *rawName;
|
const char *rawName;
|
||||||
TAG *tag = parser->m_tagStack;
|
TAG *tag = parser->m_tagStack;
|
||||||
parser->m_tagStack = tag->parent;
|
|
||||||
tag->parent = parser->m_freeTagList;
|
|
||||||
parser->m_freeTagList = tag;
|
|
||||||
rawName = s + enc->minBytesPerChar * 2;
|
rawName = s + enc->minBytesPerChar * 2;
|
||||||
len = XmlNameLength(enc, rawName);
|
len = XmlNameLength(enc, rawName);
|
||||||
if (len != tag->rawNameLength
|
if (len != tag->rawNameLength
|
||||||
@ -3021,6 +3027,9 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
|
|||||||
*eventPP = rawName;
|
*eventPP = rawName;
|
||||||
return XML_ERROR_TAG_MISMATCH;
|
return XML_ERROR_TAG_MISMATCH;
|
||||||
}
|
}
|
||||||
|
parser->m_tagStack = tag->parent;
|
||||||
|
tag->parent = parser->m_freeTagList;
|
||||||
|
parser->m_freeTagList = tag;
|
||||||
--parser->m_tagLevel;
|
--parser->m_tagLevel;
|
||||||
if (parser->m_endElementHandler) {
|
if (parser->m_endElementHandler) {
|
||||||
const XML_Char *localPart;
|
const XML_Char *localPart;
|
||||||
@ -4975,10 +4984,10 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
|
|||||||
parser->m_handlerArg, parser->m_declElementType->name,
|
parser->m_handlerArg, parser->m_declElementType->name,
|
||||||
parser->m_declAttributeId->name, parser->m_declAttributeType, 0,
|
parser->m_declAttributeId->name, parser->m_declAttributeType, 0,
|
||||||
role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
|
role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
|
||||||
poolClear(&parser->m_tempPool);
|
|
||||||
handleDefault = XML_FALSE;
|
handleDefault = XML_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
poolClear(&parser->m_tempPool);
|
||||||
break;
|
break;
|
||||||
case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
|
case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
|
||||||
case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
|
case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
|
||||||
@ -5386,7 +5395,7 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
|
|||||||
*
|
*
|
||||||
* If 'standalone' is false, the DTD must have no
|
* If 'standalone' is false, the DTD must have no
|
||||||
* parameter entities or we wouldn't have passed the outer
|
* parameter entities or we wouldn't have passed the outer
|
||||||
* 'if' statement. That measn the only entity in the hash
|
* 'if' statement. That means the only entity in the hash
|
||||||
* table is the external subset name "#" which cannot be
|
* table is the external subset name "#" which cannot be
|
||||||
* given as a parameter entity name in XML syntax, so the
|
* given as a parameter entity name in XML syntax, so the
|
||||||
* lookup must have returned NULL and we don't even reach
|
* lookup must have returned NULL and we don't even reach
|
||||||
@ -5798,19 +5807,27 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
|
|||||||
|
|
||||||
if (result != XML_ERROR_NONE)
|
if (result != XML_ERROR_NONE)
|
||||||
return result;
|
return result;
|
||||||
else if (textEnd != next
|
|
||||||
&& parser->m_parsingStatus.parsing == XML_SUSPENDED) {
|
if (textEnd != next && parser->m_parsingStatus.parsing == XML_SUSPENDED) {
|
||||||
entity->processed = (int)(next - (const char *)entity->textPtr);
|
entity->processed = (int)(next - (const char *)entity->textPtr);
|
||||||
return result;
|
return result;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
#ifdef XML_DTD
|
#ifdef XML_DTD
|
||||||
entityTrackingOnClose(parser, entity, __LINE__);
|
entityTrackingOnClose(parser, entity, __LINE__);
|
||||||
#endif
|
#endif
|
||||||
entity->open = XML_FALSE;
|
entity->open = XML_FALSE;
|
||||||
parser->m_openInternalEntities = openEntity->next;
|
parser->m_openInternalEntities = openEntity->next;
|
||||||
/* put openEntity back in list of free instances */
|
/* put openEntity back in list of free instances */
|
||||||
openEntity->next = parser->m_freeInternalEntities;
|
openEntity->next = parser->m_freeInternalEntities;
|
||||||
parser->m_freeInternalEntities = openEntity;
|
parser->m_freeInternalEntities = openEntity;
|
||||||
|
|
||||||
|
// If there are more open entities we want to stop right here and have the
|
||||||
|
// upcoming call to XML_ResumeParser continue with entity content, or it would
|
||||||
|
// be ignored altogether.
|
||||||
|
if (parser->m_openInternalEntities != NULL
|
||||||
|
&& parser->m_parsingStatus.parsing == XML_SUSPENDED) {
|
||||||
|
return XML_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XML_DTD
|
#ifdef XML_DTD
|
||||||
|
@ -45,7 +45,7 @@ enum {
|
|||||||
BT_LF, /* line feed = "\n" */
|
BT_LF, /* line feed = "\n" */
|
||||||
BT_GT, /* greater than = ">" */
|
BT_GT, /* greater than = ">" */
|
||||||
BT_QUOT, /* quotation character = "\"" */
|
BT_QUOT, /* quotation character = "\"" */
|
||||||
BT_APOS, /* aposthrophe = "'" */
|
BT_APOS, /* apostrophe = "'" */
|
||||||
BT_EQUALS, /* equal sign = "=" */
|
BT_EQUALS, /* equal sign = "=" */
|
||||||
BT_QUEST, /* question mark = "?" */
|
BT_QUEST, /* question mark = "?" */
|
||||||
BT_EXCL, /* exclamation mark = "!" */
|
BT_EXCL, /* exclamation mark = "!" */
|
||||||
|
177
tests/runtests.c
177
tests/runtests.c
@ -11,7 +11,7 @@
|
|||||||
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
|
Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
|
||||||
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
|
Copyright (c) 2005-2012 Karl Waclawek <karl@waclawek.net>
|
||||||
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
|
Copyright (c) 2016-2022 Sebastian Pipping <sebastian@pipping.org>
|
||||||
Copyright (c) 2017-2018 Rhodri James <rhodri@wildebeest.org.uk>
|
Copyright (c) 2017-2022 Rhodri James <rhodri@wildebeest.org.uk>
|
||||||
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
|
Copyright (c) 2017 Joe Orton <jorton@redhat.com>
|
||||||
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
|
Copyright (c) 2017 José Gutiérrez de la Concha <jose@zeroc.com>
|
||||||
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
|
Copyright (c) 2018 Marco Maggi <marco.maggi-ipsu@poste.it>
|
||||||
@ -4990,7 +4990,7 @@ START_TEST(test_suspend_resume_internal_entity) {
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
void
|
static void XMLCALL
|
||||||
suspending_comment_handler(void *userData, const XML_Char *data) {
|
suspending_comment_handler(void *userData, const XML_Char *data) {
|
||||||
UNUSED_P(data);
|
UNUSED_P(data);
|
||||||
XML_Parser parser = (XML_Parser)userData;
|
XML_Parser parser = (XML_Parser)userData;
|
||||||
@ -6734,6 +6734,102 @@ START_TEST(test_empty_element_abort) {
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
/* Regression test for GH issue #612: unfinished m_declAttributeType
|
||||||
|
* allocation in ->m_tempPool can corrupt following allocation.
|
||||||
|
*/
|
||||||
|
static int XMLCALL
|
||||||
|
external_entity_unfinished_attlist(XML_Parser parser, const XML_Char *context,
|
||||||
|
const XML_Char *base,
|
||||||
|
const XML_Char *systemId,
|
||||||
|
const XML_Char *publicId) {
|
||||||
|
const char *text = "<!ELEMENT barf ANY>\n"
|
||||||
|
"<!ATTLIST barf my_attr (blah|%blah;a|foo) #REQUIRED>\n"
|
||||||
|
"<!--COMMENT-->\n";
|
||||||
|
XML_Parser ext_parser;
|
||||||
|
|
||||||
|
UNUSED_P(base);
|
||||||
|
UNUSED_P(publicId);
|
||||||
|
if (systemId == NULL)
|
||||||
|
return XML_STATUS_OK;
|
||||||
|
|
||||||
|
ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
|
||||||
|
if (ext_parser == NULL)
|
||||||
|
fail("Could not create external entity parser");
|
||||||
|
|
||||||
|
if (_XML_Parse_SINGLE_BYTES(ext_parser, text, (int)strlen(text), XML_TRUE)
|
||||||
|
== XML_STATUS_ERROR)
|
||||||
|
xml_failure(ext_parser);
|
||||||
|
|
||||||
|
XML_ParserFree(ext_parser);
|
||||||
|
return XML_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(test_pool_integrity_with_unfinished_attr) {
|
||||||
|
const char *text = "<?xml version='1.0' encoding='UTF-8'?>\n"
|
||||||
|
"<!DOCTYPE foo [\n"
|
||||||
|
"<!ELEMENT foo ANY>\n"
|
||||||
|
"<!ENTITY % entp SYSTEM \"external.dtd\">\n"
|
||||||
|
"%entp;\n"
|
||||||
|
"]>\n"
|
||||||
|
"<a></a>\n";
|
||||||
|
const XML_Char *expected = XCS("COMMENT");
|
||||||
|
CharData storage;
|
||||||
|
|
||||||
|
CharData_Init(&storage);
|
||||||
|
XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
|
||||||
|
XML_SetExternalEntityRefHandler(g_parser, external_entity_unfinished_attlist);
|
||||||
|
XML_SetAttlistDeclHandler(g_parser, dummy_attlist_decl_handler);
|
||||||
|
XML_SetCommentHandler(g_parser, accumulate_comment);
|
||||||
|
XML_SetUserData(g_parser, &storage);
|
||||||
|
if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
|
||||||
|
== XML_STATUS_ERROR)
|
||||||
|
xml_failure(g_parser);
|
||||||
|
CharData_CheckXMLChars(&storage, expected);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
XML_Parser parser;
|
||||||
|
CharData *storage;
|
||||||
|
} ParserPlusStorage;
|
||||||
|
|
||||||
|
static void XMLCALL
|
||||||
|
accumulate_and_suspend_comment_handler(void *userData, const XML_Char *data) {
|
||||||
|
ParserPlusStorage *const parserPlusStorage = (ParserPlusStorage *)userData;
|
||||||
|
accumulate_comment(parserPlusStorage->storage, data);
|
||||||
|
XML_StopParser(parserPlusStorage->parser, XML_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(test_nested_entity_suspend) {
|
||||||
|
const char *const text = "<!DOCTYPE a [\n"
|
||||||
|
" <!ENTITY e1 '<!--e1-->'>\n"
|
||||||
|
" <!ENTITY e2 '<!--e2 head-->&e1;<!--e2 tail-->'>\n"
|
||||||
|
" <!ENTITY e3 '<!--e3 head-->&e2;<!--e3 tail-->'>\n"
|
||||||
|
"]>\n"
|
||||||
|
"<a><!--start-->&e3;<!--end--></a>";
|
||||||
|
const XML_Char *const expected = XCS("start") XCS("e3 head") XCS("e2 head")
|
||||||
|
XCS("e1") XCS("e2 tail") XCS("e3 tail") XCS("end");
|
||||||
|
CharData storage;
|
||||||
|
XML_Parser parser = XML_ParserCreate(NULL);
|
||||||
|
ParserPlusStorage parserPlusStorage = {parser, &storage};
|
||||||
|
|
||||||
|
CharData_Init(&storage);
|
||||||
|
XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
|
||||||
|
XML_SetCommentHandler(parser, accumulate_and_suspend_comment_handler);
|
||||||
|
XML_SetUserData(parser, &parserPlusStorage);
|
||||||
|
|
||||||
|
enum XML_Status status = XML_Parse(parser, text, (int)strlen(text), XML_TRUE);
|
||||||
|
while (status == XML_STATUS_SUSPENDED) {
|
||||||
|
status = XML_ResumeParser(parser);
|
||||||
|
}
|
||||||
|
if (status != XML_STATUS_OK)
|
||||||
|
xml_failure(parser);
|
||||||
|
|
||||||
|
CharData_CheckXMLChars(&storage, expected);
|
||||||
|
XML_ParserFree(parser);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Namespaces tests.
|
* Namespaces tests.
|
||||||
*/
|
*/
|
||||||
@ -7661,7 +7757,7 @@ START_TEST(test_misc_version) {
|
|||||||
fail("Version mismatch");
|
fail("Version mismatch");
|
||||||
|
|
||||||
#if ! defined(XML_UNICODE) || defined(XML_UNICODE_WCHAR_T)
|
#if ! defined(XML_UNICODE) || defined(XML_UNICODE_WCHAR_T)
|
||||||
if (xcstrcmp(version_text, XCS("expat_2.4.9"))) /* needs bump on releases */
|
if (xcstrcmp(version_text, XCS("expat_2.5.0"))) /* needs bump on releases */
|
||||||
fail("XML_*_VERSION in expat.h out of sync?\n");
|
fail("XML_*_VERSION in expat.h out of sync?\n");
|
||||||
#else
|
#else
|
||||||
/* If we have XML_UNICODE defined but not XML_UNICODE_WCHAR_T
|
/* If we have XML_UNICODE defined but not XML_UNICODE_WCHAR_T
|
||||||
@ -7873,6 +7969,28 @@ START_TEST(test_misc_deny_internal_entity_closing_doctype_issue_317) {
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_misc_tag_mismatch_reset_leak) {
|
||||||
|
#ifdef XML_NS
|
||||||
|
const char *const text = "<open xmlns='https://namespace1.test'></close>";
|
||||||
|
XML_Parser parser = XML_ParserCreateNS(NULL, XCS('\n'));
|
||||||
|
|
||||||
|
if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR)
|
||||||
|
fail("Call to parse was expected to fail");
|
||||||
|
if (XML_GetErrorCode(parser) != XML_ERROR_TAG_MISMATCH)
|
||||||
|
fail("Call to parse was expected to fail from a closing tag mismatch");
|
||||||
|
|
||||||
|
XML_ParserReset(parser, NULL);
|
||||||
|
|
||||||
|
if (XML_Parse(parser, text, (int)strlen(text), XML_TRUE) != XML_STATUS_ERROR)
|
||||||
|
fail("Call to parse was expected to fail");
|
||||||
|
if (XML_GetErrorCode(parser) != XML_ERROR_TAG_MISMATCH)
|
||||||
|
fail("Call to parse was expected to fail from a closing tag mismatch");
|
||||||
|
|
||||||
|
XML_ParserFree(parser);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
static void
|
static void
|
||||||
alloc_setup(void) {
|
alloc_setup(void) {
|
||||||
XML_Memory_Handling_Suite memsuite = {duff_allocator, duff_reallocator, free};
|
XML_Memory_Handling_Suite memsuite = {duff_allocator, duff_reallocator, free};
|
||||||
@ -10090,6 +10208,53 @@ START_TEST(test_alloc_long_notation) {
|
|||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
static int XMLCALL
|
||||||
|
external_entity_parser_create_alloc_fail_handler(XML_Parser parser,
|
||||||
|
const XML_Char *context,
|
||||||
|
const XML_Char *base,
|
||||||
|
const XML_Char *systemId,
|
||||||
|
const XML_Char *publicId) {
|
||||||
|
UNUSED_P(base);
|
||||||
|
UNUSED_P(systemId);
|
||||||
|
UNUSED_P(publicId);
|
||||||
|
|
||||||
|
if (context != NULL)
|
||||||
|
fail("Unexpected non-NULL context");
|
||||||
|
|
||||||
|
// The following number intends to fail the upcoming allocation in line
|
||||||
|
// "parser->m_protocolEncodingName = copyString(encodingName,
|
||||||
|
// &(parser->m_mem));" in function parserInit.
|
||||||
|
allocation_count = 3;
|
||||||
|
|
||||||
|
const XML_Char *const encodingName = XCS("UTF-8"); // needs something non-NULL
|
||||||
|
const XML_Parser ext_parser
|
||||||
|
= XML_ExternalEntityParserCreate(parser, context, encodingName);
|
||||||
|
if (ext_parser != NULL)
|
||||||
|
fail(
|
||||||
|
"Call to XML_ExternalEntityParserCreate was expected to fail out-of-memory");
|
||||||
|
|
||||||
|
allocation_count = ALLOC_ALWAYS_SUCCEED;
|
||||||
|
return XML_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(test_alloc_reset_after_external_entity_parser_create_fail) {
|
||||||
|
const char *const text = "<!DOCTYPE doc SYSTEM 'foo'><doc/>";
|
||||||
|
|
||||||
|
XML_SetExternalEntityRefHandler(
|
||||||
|
g_parser, external_entity_parser_create_alloc_fail_handler);
|
||||||
|
XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
|
||||||
|
|
||||||
|
if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE)
|
||||||
|
!= XML_STATUS_ERROR)
|
||||||
|
fail("Call to parse was expected to fail");
|
||||||
|
|
||||||
|
if (XML_GetErrorCode(g_parser) != XML_ERROR_EXTERNAL_ENTITY_HANDLING)
|
||||||
|
fail("Call to parse was expected to fail from the external entity handler");
|
||||||
|
|
||||||
|
XML_ParserReset(g_parser, NULL);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nsalloc_setup(void) {
|
nsalloc_setup(void) {
|
||||||
XML_Memory_Handling_Suite memsuite = {duff_allocator, duff_reallocator, free};
|
XML_Memory_Handling_Suite memsuite = {duff_allocator, duff_reallocator, free};
|
||||||
@ -12169,6 +12334,9 @@ make_suite(void) {
|
|||||||
tcase_add_test(tc_basic, test_bad_notation);
|
tcase_add_test(tc_basic, test_bad_notation);
|
||||||
tcase_add_test(tc_basic, test_default_doctype_handler);
|
tcase_add_test(tc_basic, test_default_doctype_handler);
|
||||||
tcase_add_test(tc_basic, test_empty_element_abort);
|
tcase_add_test(tc_basic, test_empty_element_abort);
|
||||||
|
tcase_add_test__ifdef_xml_dtd(tc_basic,
|
||||||
|
test_pool_integrity_with_unfinished_attr);
|
||||||
|
tcase_add_test(tc_basic, test_nested_entity_suspend);
|
||||||
|
|
||||||
suite_add_tcase(s, tc_namespace);
|
suite_add_tcase(s, tc_namespace);
|
||||||
tcase_add_checked_fixture(tc_namespace, namespace_setup, namespace_teardown);
|
tcase_add_checked_fixture(tc_namespace, namespace_setup, namespace_teardown);
|
||||||
@ -12221,6 +12389,7 @@ make_suite(void) {
|
|||||||
tcase_add_test(tc_misc, test_misc_stop_during_end_handler_issue_240_2);
|
tcase_add_test(tc_misc, test_misc_stop_during_end_handler_issue_240_2);
|
||||||
tcase_add_test__ifdef_xml_dtd(
|
tcase_add_test__ifdef_xml_dtd(
|
||||||
tc_misc, test_misc_deny_internal_entity_closing_doctype_issue_317);
|
tc_misc, test_misc_deny_internal_entity_closing_doctype_issue_317);
|
||||||
|
tcase_add_test(tc_misc, test_misc_tag_mismatch_reset_leak);
|
||||||
|
|
||||||
suite_add_tcase(s, tc_alloc);
|
suite_add_tcase(s, tc_alloc);
|
||||||
tcase_add_checked_fixture(tc_alloc, alloc_setup, alloc_teardown);
|
tcase_add_checked_fixture(tc_alloc, alloc_setup, alloc_teardown);
|
||||||
@ -12279,6 +12448,8 @@ make_suite(void) {
|
|||||||
tcase_add_test(tc_alloc, test_alloc_long_public_id);
|
tcase_add_test(tc_alloc, test_alloc_long_public_id);
|
||||||
tcase_add_test(tc_alloc, test_alloc_long_entity_value);
|
tcase_add_test(tc_alloc, test_alloc_long_entity_value);
|
||||||
tcase_add_test(tc_alloc, test_alloc_long_notation);
|
tcase_add_test(tc_alloc, test_alloc_long_notation);
|
||||||
|
tcase_add_test__ifdef_xml_dtd(
|
||||||
|
tc_alloc, test_alloc_reset_after_external_entity_parser_create_fail);
|
||||||
|
|
||||||
suite_add_tcase(s, tc_nsalloc);
|
suite_add_tcase(s, tc_nsalloc);
|
||||||
tcase_add_checked_fixture(tc_nsalloc, nsalloc_setup, nsalloc_teardown);
|
tcase_add_checked_fixture(tc_nsalloc, nsalloc_setup, nsalloc_teardown);
|
||||||
|
Loading…
Reference in New Issue
Block a user