Compare commits

..

No commits in common. "imports/c10s/xmlrpc-c-1.59.02-3.el10" and "c8" have entirely different histories.

20 changed files with 2979 additions and 177 deletions

9
.gitignore vendored
View File

@ -1,7 +1,2 @@
/xmlrpc-c-1.32.5.tar.xz
/xmlrpc-c-1.47.1.tar.xz
/xmlrpc-c-1.48.0.tar.xz
/xmlrpc-c-1.49.02.tar.xz
/xmlrpc-c-1.51.0.tar.xz
/xmlrpc-1.51.08.tgz
/xmlrpc-c-1.59.02.tgz
SOURCES/benchmark-tests.tar.xz
SOURCES/xmlrpc-c-1.51.0.tar.xz

2
.xmlrpc-c.metadata Normal file
View File

@ -0,0 +1,2 @@
b4fb65d500c1af5fe83917ab2976a47ae6268fdd SOURCES/benchmark-tests.tar.xz
784a3e74971f3b7d992d768c732daa891ffd2412 SOURCES/xmlrpc-c-1.51.0.tar.xz

View File

@ -1,10 +0,0 @@
MAKEFILE_COMMON = $(HOME)/.fedora/common.mk
-include $(MAKEFILE_COMMON)
all:
SVN_VER ?= ${VERSION}
svn-sources:
cd $(DESTDIR) . && svn export https://xmlrpc-c.svn.sourceforge.net/svnroot/xmlrpc-c/advanced@${SVN_REV} xmlrpc-c-${SVN_VER}
cd $(DESTDIR) . && tar cJf xmlrpc-c-${SVN_VER}.tar.xz xmlrpc-c-${SVN_VER} --owner root --group root --mode=go-w,a+rX

View File

@ -0,0 +1,83 @@
From 78e995f9f2958fc54e2a559a52c81684dc3460cf Mon Sep 17 00:00:00 2001
From: giraffedata <giraffedata@98333e67-4a24-44d7-a75c-e53540dd3050>
Date: Sun, 21 Jan 2018 22:27:31 +0000
Subject: [PATCH] Remove trace statements accidentally committed with 2977
git-svn-id: https://svn.code.sf.net/p/xmlrpc-c/code/trunk@2981 98333e67-4a24-44d7-a75c-e53540dd3050
---
src/cpp/value.cpp | 8 --------
src/xmlrpc_string.c | 5 -----
2 files changed, 13 deletions(-)
diff --git a/src/cpp/value.cpp b/src/cpp/value.cpp
index e2c12372..b319430e 100644
--- a/src/cpp/value.cpp
+++ b/src/cpp/value.cpp
@@ -1,4 +1,3 @@
-#include <iostream>
/*****************************************************************************
value.cpp
******************************************************************************
@@ -622,13 +621,9 @@ public:
switch (nlCode) {
case value_string::nlCode_all:
- cerr << "Going to call xmlrpc_string_new_lp" << endl;
- cerr << "length = " << cppvalue.length() << ", value = "
- << cppvalue.c_str() << endl;
this->valueP = xmlrpc_string_new_lp(&env.env_c,
cppvalue.length(),
cppvalue.c_str());
- cerr << "Back from xmlrpc_string_new_lp" << endl;
break;
case value_string::nlCode_lf:
this->valueP = xmlrpc_string_new_lp_cr(&env.env_c,
@@ -661,12 +656,9 @@ value_string::value_string(std::string const& cppvalue,
value_string::value_string(std::string const& cppvalue) {
- cerr << "value_string constructor entered" << endl;
cNewStringWrapper wrapper(cppvalue, nlCode_all);
- cerr << "wrapper constructed" << endl;
this->instantiate(wrapper.valueP);
- cerr << "value_string constructor exiting" << endl;
}
diff --git a/src/xmlrpc_string.c b/src/xmlrpc_string.c
index 2da61e4e..e6e00716 100644
--- a/src/xmlrpc_string.c
+++ b/src/xmlrpc_string.c
@@ -1,4 +1,3 @@
-#include <stdio.h>
/*=============================================================================
xmlrpc_string
===============================================================================
@@ -746,15 +745,12 @@ stringNew(xmlrpc_env * const envP,
enum crTreatment const crTreatment,
xmlrpc_value ** const valPP) {
- fprintf(stderr, "stringNew entered\n");
xmlrpc_value * valP;
xmlrpc_validate_utf8(envP, value, length);
if (!envP->fault_occurred) {
- fprintf(stderr, "Going to xmlrpc_createXmlrpcValue\n");
xmlrpc_createXmlrpcValue(envP, &valP);
- fprintf(stderr, "Back from createXmlrpcValue\n");
if (!envP->fault_occurred) {
valP->_type = XMLRPC_TYPE_STRING;
@@ -774,7 +770,6 @@ stringNew(xmlrpc_env * const envP,
*valPP = valP;
}
}
- fprintf(stderr, "stringNew exiting\n");
}
--
2.17.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
From d31c2ffbf5181053330fa32e4f03c47283bd1448 Mon Sep 17 00:00:00 2001
From: Igor Gnatenko <i.gnatenko.brain@gmail.com>
Date: Sat, 17 Dec 2016 10:28:31 +0100
Subject: [PATCH 1/3] xmlrpc_server_abyss: use va_args properly
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
../src/xmlrpc_server_abyss.c: In function createServer:
../src/xmlrpc_server_abyss.c:783:13: error: format not a string literal and no format arguments [-Werror=format-security]
xmlrpc_faultf(envP, error);
^~~~~~~~~~~~~
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
---
src/xmlrpc_server_abyss.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/xmlrpc_server_abyss.c b/src/xmlrpc_server_abyss.c
index 8aacb4b..58f5ba0 100644
--- a/src/xmlrpc_server_abyss.c
+++ b/src/xmlrpc_server_abyss.c
@@ -780,7 +780,7 @@ createServer(xmlrpc_env * const envP,
ServerInit2(abyssServerP, &error);
if (error) {
- xmlrpc_faultf(envP, error);
+ xmlrpc_faultf(envP, "%s", error);
xmlrpc_strfree(error);
}
}
--
2.13.1

View File

@ -0,0 +1,16 @@
From d97ec6e652690a321d7ce8c81aa30f87d9c0de8f Mon Sep 17 00:00:00 2001
From: Igor Gnatenko <i.gnatenko.brain@gmail.com>
Date: Mon, 19 Dec 2016 21:33:47 +0100
Subject: [PATCH 2/2] chmod +x xml-rpc-api2txt
It's script which is installing into $bindir, so it must be executable.
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
---
tools/xml-rpc-api2txt/xml-rpc-api2txt | 0
1 file changed, 0 insertions(+), 0 deletions(-)
mode change 100644 => 100755 tools/xml-rpc-api2txt/xml-rpc-api2txt
diff --git a/tools/xml-rpc-api2txt/xml-rpc-api2txt b/tools/xml-rpc-api2txt/xml-rpc-api2txt
old mode 100644
new mode 100755

View File

@ -12,7 +12,6 @@ index f0aafae..b5392a9 100644
--- a/lib/curl_transport/curltransaction.c
+++ b/lib/curl_transport/curltransaction.c
@@ -671,6 +671,10 @@ setupCurlSession(xmlrpc_env * const envP,
curl_easy_setopt(curlSessionP, CURLOPT_POST, 1);
curl_easy_setopt(curlSessionP, CURLOPT_URL, transP->serverUrl);

View File

@ -0,0 +1,89 @@
From 6aee99f381cc5bdfb6e514ac1e82f5e7b0fa7e2d Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Fri, 25 Feb 2022 16:42:35 -0500
Subject: [PATCH 5/6] Add missing validation of encoding (CVE-2022-25235)
Backported from upstream https://github.com/libexpat/libexpat/pull/562
Resolves: #2058114
---
lib/expat/xmltok/xmltok.c | 21 +++++++++++++++------
lib/expat/xmltok/xmltok_impl.c | 8 ++++++--
2 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/lib/expat/xmltok/xmltok.c b/lib/expat/xmltok/xmltok.c
index 7b31fbb..3b0c950 100644
--- a/lib/expat/xmltok/xmltok.c
+++ b/lib/expat/xmltok/xmltok.c
@@ -61,12 +61,17 @@ We need 8 bits to index into pages, 3 bits to add to that index and
? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
: 0))
+#define UTF8_INVALID2(p) \
+ ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0)
+
#define UTF8_INVALID3(p) \
- ((*p) == 0xED \
- ? (((p)[1] & 0x20) != 0) \
- : ((*p) == 0xEF \
- ? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) \
- : 0))
+ (((p)[2] & 0x80) == 0 \
+ || ((*p) == 0xEF && (p)[1] == 0xBF ? (p)[2] > 0xBD \
+ : ((p)[2] & 0xC0) == 0xC0) \
+ || ((*p) == 0xE0 \
+ ? (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \
+ : ((p)[1] & 0x80) == 0 \
+ || ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
#define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0)
@@ -104,7 +109,11 @@ int utf8_isNmstrt3(const ENCODING *enc ATTR_UNUSED, const char *p)
#define utf8_isNmstrt4 isNever
-#define utf8_isInvalid2 isNever
+static
+int utf8_isInvalid2(const ENCODING *enc ATTR_UNUSED, const char *p)
+{
+ return UTF8_INVALID2((const unsigned char *)p);
+}
static
int utf8_isInvalid3(const ENCODING *enc ATTR_UNUSED, const char *p)
diff --git a/lib/expat/xmltok/xmltok_impl.c b/lib/expat/xmltok/xmltok_impl.c
index d035527..bae79b9 100644
--- a/lib/expat/xmltok/xmltok_impl.c
+++ b/lib/expat/xmltok/xmltok_impl.c
@@ -43,7 +43,7 @@ See the file copying.txt for copying permission.
case BT_LEAD ## n: \
if (end - ptr < n) \
return XML_TOK_PARTIAL_CHAR; \
- if (!IS_NAME_CHAR(enc, ptr, n)) { \
+ if (IS_INVALID_CHAR(enc, ptr, n) || !IS_NAME_CHAR(enc, ptr, n)) { \
*nextTokPtr = ptr; \
return XML_TOK_INVALID; \
} \
@@ -71,7 +71,7 @@ See the file copying.txt for copying permission.
case BT_LEAD ## n: \
if (end - ptr < n) \
return XML_TOK_PARTIAL_CHAR; \
- if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
+ if (IS_INVALID_CHAR(enc, ptr, n) || !IS_NMSTRT_CHAR(enc, ptr, n)) { \
*nextTokPtr = ptr; \
return XML_TOK_INVALID; \
} \
@@ -1168,6 +1168,10 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
case BT_LEAD ## n: \
if (end - ptr < n) \
return XML_TOK_PARTIAL_CHAR; \
+ if (IS_INVALID_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
ptr += n; \
tok = XML_TOK_NAME; \
--
2.31.1

View File

@ -0,0 +1,92 @@
From ce6eddc1a167dafaac17c7bad9fa6b013fada31b Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Fri, 25 Feb 2022 13:07:07 -0500
Subject: [PATCH 5/6] lib: Prevent more integer overflows (CVE-2022-22822 to
CVE-2022-22827)
Backport fixes from https://github.com/libexpat/libexpat/pull/539
Resolves: #2058567, #2058576, #2058282, #2058589, #2058595, #2058602
---
lib/expat/xmlparse/xmlparse.c | 40 +++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/lib/expat/xmlparse/xmlparse.c b/lib/expat/xmlparse/xmlparse.c
index 48adfb3..16ab82a 100644
--- a/lib/expat/xmlparse/xmlparse.c
+++ b/lib/expat/xmlparse/xmlparse.c
@@ -19,6 +19,7 @@ See the file copying.txt for copying permission.
#include <assert.h>
#include <limits.h> /* UINT_MAX */
#include <time.h> /* time() */
+#include <stdint.h>
#include "xmlrpc_config.h"
#include "c_util.h"
@@ -1076,6 +1077,9 @@ int addBinding(XML_Parser parser,
;
if (namespaceSeparator)
len++;
+ if (namespaceSeparator && (uri[len] == namespaceSeparator)) {
+ return XML_ERROR_SYNTAX;
+ }
if (freeBindingList) {
b = freeBindingList;
if (len > b->uriAlloc) {
@@ -2116,10 +2120,32 @@ storeAtts(XML_Parser const xmlParserP,
}
/* get the attributes from the tokenizer */
n = XmlGetAttributes(enc, attStr, attsSize, atts);
+
+
+ /* Detect and prevent integer overflow */
+ if (n > INT_MAX - nDefaultAtts) {
+ return XML_ERROR_NO_MEMORY;
+ }
+
if (n + nDefaultAtts > attsSize) {
int oldAttsSize = attsSize;
ATTRIBUTE *temp;
+ /* Detect and prevent integer overflow */
+ if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE)
+ || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) {
+ return XML_ERROR_NO_MEMORY;
+ }
attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) {
+ attsSize = oldAttsSize;
+ return XML_ERROR_NO_MEMORY;
+ }
+#endif
temp = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE));
if (!temp)
return XML_ERROR_NO_MEMORY;
@@ -2297,6 +2323,20 @@ storeAtts(XML_Parser const xmlParserP,
n = i + binding->uriLen;
if (n > binding->uriAlloc) {
TAG *p;
+
+ /* Detect and prevent integer overflow */
+ if (n > INT_MAX - EXPAND_SPARE) {
+ return XML_ERROR_NO_MEMORY;
+ }
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
+ return XML_ERROR_NO_MEMORY;
+ }
+#endif
XML_Char *uri = malloc((n + EXPAND_SPARE) * sizeof(XML_Char));
if (!uri)
return XML_ERROR_NO_MEMORY;
--
2.31.1

View File

@ -0,0 +1,32 @@
From 06d354807ac297374973631a6418edf7e3fcbf30 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Mon, 28 Feb 2022 10:43:23 -0500
Subject: [PATCH 6/6] Prevent integer overflow on m_groupSize in doProlog
(CVE-2021-46143)
Backported from upstream https://github.com/libexpat/libexpat/pull/538
Resolves: #2058560
---
lib/expat/xmlparse/xmlparse.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lib/expat/xmlparse/xmlparse.c b/lib/expat/xmlparse/xmlparse.c
index 16ab82a..b9aa927 100644
--- a/lib/expat/xmlparse/xmlparse.c
+++ b/lib/expat/xmlparse/xmlparse.c
@@ -3991,6 +3991,11 @@ doProlog(XML_Parser const xmlParserP,
case XML_ROLE_GROUP_OPEN:
if (prologState.level >= groupSize) {
if (groupSize) {
+ /* Detect and prevent integer overflow */
+ if (groupSize > (unsigned int)(-1) / 2u) {
+ *errorCodeP = XML_ERROR_NO_MEMORY;
+ return;
+ }
char *temp = realloc(groupConnector, groupSize *= 2);
if (!temp) {
*errorCodeP = XML_ERROR_NO_MEMORY;
--
2.31.1

View File

@ -0,0 +1,106 @@
From 66e6f8700959f7a54056ed7946c179d808e838e8 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Thu, 25 Apr 2024 09:26:04 -0400
Subject: [PATCH] Address segfault found in CVE-2023-52425
The CVE addresses a possible DoS when unreasonably large tokens
are passed into the XML parser for processing. These were taking
upwards of 8 seconds per file processed with the exception of
aaaaaa_cdata.xml which caused a segmentation fault. The XML
processor was effectively losing the start of the string, setting
it to NULL. This caused a cascade of errors trying to parse both
the next token and in handling errors if a new token was not found.
This handles both those cases but not the underlying reason why
the pointer to inputStart is lost.
Trying to backport the libexpat changes to address the performance
issue would be enormous since the xmlrpc-c custom version of libexpat
is extremely old. Since xmlrpc-c is mostly used as a client passing
in random values is less of an issue.
Include the libexpat upstream benchmark test to validate that the
tests pass, albeit slowly.
To run the benchmarks:
extract the sources
cd xmlrpc-c-1.51.0
make
cd test
make
cd benchmark
for file in *.xml; do ./benchmark $file 4096 1; done
One test will error out but this is expected as part of the fix.
The tests will be extracted as a Source because of their
uncompressed size (~48M)
Fixes: RHEL-24226
---
lib/expat/xmlparse/xmlparse.c | 3 +++
lib/expat/xmltok/xmltok_impl.c | 4 ++++
test/Makefile | 7 +++++--
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/lib/expat/xmlparse/xmlparse.c b/lib/expat/xmlparse/xmlparse.c
index 16ab82a..6621d18 100644
--- a/lib/expat/xmlparse/xmlparse.c
+++ b/lib/expat/xmlparse/xmlparse.c
@@ -35,6 +35,9 @@ extractXmlSample(const char * const start,
size_t const maximumLen) {
size_t const len = MIN(maximumLen, (size_t)(end - start));
+ if (start == NULL) {
+ return strdup("");
+ }
return xmlrpc_makePrintable_lp(start, len);
}
diff --git a/lib/expat/xmltok/xmltok_impl.c b/lib/expat/xmltok/xmltok_impl.c
index bae79b9..80da94f 100644
--- a/lib/expat/xmltok/xmltok_impl.c
+++ b/lib/expat/xmltok/xmltok_impl.c
@@ -871,6 +871,10 @@ PREFIX(contentTok)(const ENCODING * const enc,
*/
PREFIX(chopToWholeCharacters)(inputStart, inputEnd, &end);
+ if (inputStart == NULL) {
+ *nextTokPtr = NULL;
+ return XML_TOK_INVALID;
+ }
if (end == inputStart) {
*nextTokPtr = inputStart;
return XML_TOK_PARTIAL;
diff --git a/test/Makefile b/test/Makefile
index 4fce824..1242910 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -7,7 +7,7 @@ SUBDIR := test
include $(BLDDIR)/config.mk
-SUBDIRS = cpp
+SUBDIRS = cpp benchmark
XMLRPC_C_CONFIG = $(BLDDIR)/xmlrpc-c-config.test
@@ -98,11 +98,14 @@ runtests_local: test cgitest1
./test
.PHONY: runtests
-runtests: runtests_local cpp/runtests
+runtests: runtests_local cpp/runtests benchmark/runtests
cpp/runtests: FORCE
$(MAKE) -C $(dir $@) $(notdir $@)
+benchmark/runtests:
+ $(MAKE) -C $(dir $@) $(notdir $@)
+
.PHONY: install
install:
--
2.42.0

View File

@ -0,0 +1,40 @@
From d15ba056c15db75c9153fda27a62b1a6cfb8196e Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Mon, 9 Sep 2024 14:35:28 -0400
Subject: [PATCH] Prevent integer overflow or wraparound CVE-2024-45491
An issue was discovered in libexpat before 2.6.3. dtdCopy in
xmlparse.c can have an integer overflow for nDefaultAtts on
32-bit platforms (where UINT_MAX equals SIZE_MAX).
Backported from upstream https://github.com/libexpat/libexpat/pull/891
Resolves: RHEL-57519
---
lib/expat/xmlparse/xmlparse.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/lib/expat/xmlparse/xmlparse.c b/lib/expat/xmlparse/xmlparse.c
index 359267a..40f753b 100644
--- a/lib/expat/xmlparse/xmlparse.c
+++ b/lib/expat/xmlparse/xmlparse.c
@@ -1020,6 +1020,16 @@ static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd)
if (!newE)
return 0;
if (oldE->nDefaultAtts) {
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if ((size_t)oldE->nDefaultAtts
+ > ((size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE))) {
+ return 0;
+ }
+#endif
newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
if (!newE->defaultAtts)
--
2.45.0

View File

@ -0,0 +1,473 @@
From 6d8259c43c7d675987d96bf990b6b57402d27f28 Mon Sep 17 00:00:00 2001
From: root <root@vm-10-0-185-207.hosted.upshift.rdu2.redhat.com>
Date: Wed, 19 Mar 2025 12:52:04 -0400
Subject: [PATCH 09/10] Restrict XML Entity Expansion Depth in libexpat
CVE-2024-8176
The embedded libexpat library is vulnerable to a stack overflow
due to uncontrolled recursion when processing deeply nested XML
entities. This can cause the application to crash, resulting in
a denial of service (DoS) or potentially leading to memory
corruption, depending on the user's environment and how the
library is used. The issue is triggered by supplying a specially
crafted XML document designed to create a long chain of recursive
entities.
libexpat addressed this upstream in
https://github.com/libexpat/libexpat/pull/973
but the embedded copy within xmlrpc-c is so old there is no chance
of applying this without rebasing it. Instead a recursion counter
is added to the parser to limit the depth.
Resolves: RHEL-57536
---
lib/expat/xmlparse/xmlparse.c | 40 +++++++++++++---
test/Makefile | 30 ++++++++++--
test/overflow_attr_test.c | 88 +++++++++++++++++++++++++++++++++++
test/overflow_entity_test.c | 86 ++++++++++++++++++++++++++++++++++
4 files changed, 234 insertions(+), 10 deletions(-)
create mode 100644 test/overflow_attr_test.c
create mode 100644 test/overflow_entity_test.c
diff --git a/lib/expat/xmlparse/xmlparse.c b/lib/expat/xmlparse/xmlparse.c
index c440ac7..467910a 100644
--- a/lib/expat/xmlparse/xmlparse.c
+++ b/lib/expat/xmlparse/xmlparse.c
@@ -29,6 +29,8 @@ See the file copying.txt for copying permission.
#include "xmldef.h"
#include "xmlparse.h"
+#define MAX_RECURSE 28
+
static const char *
extractXmlSample(const char * const start,
const char * const end,
@@ -312,6 +314,7 @@ typedef struct {
enum XML_ParamEntityParsing m_paramEntityParsing;
XML_Parser m_parentParser;
unsigned long m_hash_secret_salt;
+ int m_recurse_lock;
} Parser;
#define userData (((Parser *)parser)->m_userData)
@@ -388,6 +391,7 @@ typedef struct {
#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
#define parentParser (((Parser *)parser)->m_parentParser)
#define hash_secret_salt (((Parser *)parser)->m_hash_secret_salt)
+#define recurse_lock (((Parser *)parser)->m_recurse_lock)
@@ -515,7 +519,7 @@ poolGrow(STRING_POOL * const poolP,
size_t const newSize =
offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
- BLOCK * const newBlocksP = malloc(newSize);
+ BLOCK * const newBlocksP = calloc(offsetof(BLOCK, s) + blockSize, sizeof(XML_Char));
if (newBlocksP) {
newBlocksP->size = blockSize;
@@ -1143,6 +1147,7 @@ const XML_Char *getContext(XML_Parser parser)
{
HASH_TABLE_ITER iter;
int needSep = 0;
+ Parser * const parserP = (Parser *) parser;
if (dtd.defaultPrefix.binding) {
int i;
@@ -1191,7 +1196,7 @@ const XML_Char *getContext(XML_Parser parser)
ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
if (!e)
break;
- if (!e->open)
+ if (!e->open || parserP->m_recurse_lock > MAX_RECURSE)
continue;
if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
return 0;
@@ -1210,6 +1215,7 @@ static
int setContext(XML_Parser parser, const XML_Char *context)
{
const XML_Char *s = context;
+ Parser * const parserP = (Parser *) parser;
while (*context != XML_T('\0')) {
if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
@@ -1218,8 +1224,9 @@ int setContext(XML_Parser parser, const XML_Char *context)
return 0;
e = (ENTITY *)lookup(parser, &dtd.generalEntities, poolStart(&tempPool),
0);
- if (e)
+ if (e) {
e->open = 1;
+ }
if (*s != XML_T('\0'))
s++;
context = s;
@@ -1860,7 +1867,7 @@ appendAttributeValue(XML_Parser const xmlParserP,
return XML_ERROR_UNDEFINED_ENTITY;
}
}
- else if (entity->open) {
+ else if (entity->open || parser->m_recurse_lock > MAX_RECURSE) {
if (enc == parser->m_encoding)
eventPtr = ptr;
return XML_ERROR_RECURSIVE_ENTITY_REF;
@@ -1879,10 +1886,12 @@ appendAttributeValue(XML_Parser const xmlParserP,
enum XML_Error result;
const XML_Char *textEnd = entity->textPtr + entity->textLen;
entity->open = 1;
+ parser->m_recurse_lock++;
result = appendAttributeValue(xmlParserP, internalEncoding,
isCdata, (char *)entity->textPtr,
(char *)textEnd, pool);
entity->open = 0;
+ parser->m_recurse_lock--;
if (result)
return result;
}
@@ -1952,7 +1961,7 @@ storeEntityValue(XML_Parser const xmlParserP,
eventPtr = entityTextPtr;
return XML_ERROR_UNDEFINED_ENTITY;
}
- if (entity->open) {
+ if (entity->open || parser->m_recurse_lock > MAX_RECURSE) {
if (enc == parser->m_encoding)
eventPtr = entityTextPtr;
return XML_ERROR_RECURSIVE_ENTITY_REF;
@@ -2641,8 +2650,13 @@ doInternalEntityRef(XML_Parser const xmlParserP,
*errorP = NULL;
} else {
OPEN_INTERNAL_ENTITY openEntity;
+ if (entityP->open || parserP->m_recurse_lock > MAX_RECURSE) {
+ *errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF;
+ return;
+ }
entityP->open = 1; /* recursion control */
+ parserP->m_recurse_lock++;
openEntity.next = parserP->m_openInternalEntities;
@@ -2659,6 +2673,7 @@ doInternalEntityRef(XML_Parser const xmlParserP,
0, errorCodeP, errorP);
entityP->open = 0; /* recursion control */
+ parserP->m_recurse_lock--;
parserP->m_openInternalEntities = openEntity.next;
}
}
@@ -2681,8 +2696,14 @@ doExternalEntityRef(XML_Parser const xmlParserP,
if (parserP->m_externalEntityRefHandler) {
const XML_Char * contextP;
+ if (entityP->open || parserP->m_recurse_lock > MAX_RECURSE) {
+ *errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF;
+ return;
+ }
entityP->open = 1;
+ parserP->m_recurse_lock++;
contextP = getContext(xmlParserP);
+ parserP->m_recurse_lock--;
entityP->open = 0;
if (!contextP)
@@ -2753,7 +2774,7 @@ doEntityRef(XML_Parser const xmlParserP,
*errorCodeP = XML_ERROR_NONE;
}
} else {
- if (entityP->open)
+ if (entityP->open || parserP->m_recurse_lock > MAX_RECURSE)
*errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF;
else if (entityP->notation)
*errorCodeP = XML_ERROR_BINARY_ENTITY_REF;
@@ -4059,7 +4080,7 @@ doProlog(XML_Parser const xmlParserP,
*errorCodeP = XML_ERROR_UNDEFINED_ENTITY;
return;
}
- if (entity->open) {
+ if (entity->open || parser->m_recurse_lock > MAX_RECURSE) {
*errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF;
return;
}
@@ -4076,16 +4097,19 @@ doProlog(XML_Parser const xmlParserP,
if (externalEntityRefHandler) {
dtd.complete = 0;
entity->open = 1;
+ parser->m_recurse_lock++;
if (!externalEntityRefHandler(externalEntityRefHandlerArg,
0,
entity->base,
entity->systemId,
entity->publicId)) {
entity->open = 0;
+ parser->m_recurse_lock--;
*errorCodeP = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
return;
}
entity->open = 0;
+ parser->m_recurse_lock--;
if (dtd.complete)
break;
}
@@ -4199,6 +4223,7 @@ processInternalParamEntity(XML_Parser const parser,
const char *s, *end, *next;
int tok;
OPEN_INTERNAL_ENTITY openEntity;
+ Parser * const parserP = (Parser *) parser;
entity->open = 1;
openEntity.next = openInternalEntities;
@@ -4292,6 +4317,7 @@ xmlrpc_XML_ParserCreate(const XML_Char * const encodingName) {
parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
parser->m_hash_secret_salt = 0;
parser->m_ns = 0;
+ parser->m_recurse_lock = 0;
poolInit(&parser->m_tempPool);
poolInit(&parser->m_temp2Pool);
parser->m_protocolEncodingName =
diff --git a/test/Makefile b/test/Makefile
index 1242910..59c698c 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -16,9 +16,9 @@ LDADD_CGI_SERVER = \
default: all
-INCLUDES = -I$(BLDDIR) -Isrcdir/include -Isrcdir/lib/util/include \
+INCLUDES = -I$(BLDDIR) -I$(SRCDIR)/include -I$(SRCDIR)/lib/util/include \
-PROGS = test cgitest1
+PROGS = test cgitest1 overflow_attr_test overflow_entity_test
all: $(PROGS) $(SUBDIRS:%=%/all)
@@ -86,6 +86,28 @@ OBJS = $(TEST_OBJS) cgitest1.o
$(OBJS):%.o:%.c
$(CC) -c $(INCLUDES) $(CFLAGS_ALL) $<
+OVERFLOW_ATTR_OBJS = overflow_attr_test.o
+
+overflow_attr_test: $(OVERFLOW_ATTR_OBJS) $(LIBXMLRPC_SERVER_A) \
+ $(LIBXMLRPC_A) $(LIBXMLRPC_UTIL_A) $(LIBXMLRPC_XML)
+ $(CCLD) -o $@ $(LDFLAGS_ALL) \
+ $(OVERFLOW_ATTR_OBJS) $(LDADD_CLIENT) $(LDADD_ABYSS_SERVER) $(CASPRINTF)
+OBJS = overflow_attr_test.o
+
+$(OBJS):%.o:%.c
+ $(CC) -c $(INCLUDES) -I$(SRCDIR)/lib/expat/xmlparse/ $(CFLAGS_ALL) $<
+
+OVERFLOW_ENTITY_OBJS = overflow_entity_test.o
+
+overflow_entity_test: $(OVERFLOW_ENTITY_OBJS) $(LIBXMLRPC_SERVER_A) \
+ $(LIBXMLRPC_A) $(LIBXMLRPC_UTIL_A) $(LIBXMLRPC_XML)
+ $(CCLD) -o $@ $(LDFLAGS_ALL) \
+ $(OVERFLOW_ENTITY_OBJS) $(LDADD_CLIENT) $(LDADD_ABYSS_SERVER) $(CASPRINTF)
+OBJS = overflow_entity_test.o
+
+$(OBJS):%.o:%.c
+ $(CC) -c $(INCLUDES) -I$(SRCDIR)/lib/expat/xmlparse/ $(CFLAGS_ALL) $<
+
# Note the difference between 'check' and 'runtests'. 'check' means to check
# our own correctness. 'runtests' means to run the tests that check our
# parent's correctness
@@ -94,8 +116,10 @@ $(OBJS):%.o:%.c
check:
.PHONY: runtests_local
-runtests_local: test cgitest1
+runtests_local: test cgitest1 overflow_attr_test overflow_entity_test
./test
+ ./overflow_attr_test
+ ./overflow_entity_test
.PHONY: runtests
runtests: runtests_local cpp/runtests benchmark/runtests
diff --git a/test/overflow_attr_test.c b/test/overflow_attr_test.c
new file mode 100644
index 0000000..eb06556
--- /dev/null
+++ b/test/overflow_attr_test.c
@@ -0,0 +1,88 @@
+/* gcc -g -std=c11 -D_POSIX_C_SOURCE=200809L -I lib/expat/xmlparse -lxmlrpc_xmlparse -lxmlrpc_xmltok overflow_attr_test.c -o overflow_attr_test */
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include "xmlparse.h"
+#include <string.h>
+
+#define XML_STATUS_OK 1
+#define XML_STATUS_ERROR 0
+
+typedef unsigned char XML_Bool;
+#define XML_TRUE ((XML_Bool)1)
+#define XML_FALSE ((XML_Bool)0)
+
+#define SIZE_PER_LINE 50
+
+static int
+doParse(int N_LINES) {
+ XML_Parser parser;
+ char tmp[SIZE_PER_LINE];
+ int ret = 0;
+ int rval = 0;
+
+ if ((parser = xmlrpc_XML_ParserCreate(NULL)) == NULL)
+ errx(1, "XML_ParserCreate");
+
+ char *const text = (char *)malloc((N_LINES + 4) * SIZE_PER_LINE);
+ if (text == NULL) {
+ printf("malloc failed");
+ return 1;
+ }
+
+ // Create the XML
+ snprintf(text, SIZE_PER_LINE,
+ "<!DOCTYPE foo [\n"
+ " <!ENTITY s0 'deepText'>\n");
+
+ for (size_t i = 1; i < N_LINES; ++i) {
+ snprintf(tmp, SIZE_PER_LINE, " <!ENTITY s%lu '&s%lu;'>\n",
+ (long unsigned)i, (long unsigned)(i - 1));
+ strncat(text, tmp, SIZE_PER_LINE);
+ }
+
+ snprintf(tmp, SIZE_PER_LINE, "]> <foo name='&s%lu;'>mainText</foo>\n",
+ (long unsigned)(N_LINES - 1));
+ strncat(text, tmp, SIZE_PER_LINE);
+
+ ret = xmlrpc_XML_Parse(parser, text, strlen(text), XML_TRUE);
+ if (ret == XML_STATUS_ERROR) {
+ int err = xmlrpc_XML_GetErrorCode(parser);
+ if (err == XML_ERROR_RECURSIVE_ENTITY_REF) {
+ if (N_LINES <= 28) {
+ printf("%d Unexpected FAIL (%s)\n", N_LINES, xmlrpc_XML_ErrorString(err));
+ } else {
+ printf("%d expected failure OK (%s)\n", N_LINES, xmlrpc_XML_ErrorString(err));
+ }
+ } else {
+ printf("%d Unexpected FAIL (%s)\n", N_LINES, xmlrpc_XML_ErrorString(err));
+ rval = 1;
+ }
+ } else {
+ printf("%d OK\n", N_LINES);
+ }
+ free(text);
+ xmlrpc_XML_ParserFree(parser);
+ return rval;
+}
+
+int main(int argc, char *argv[]) {
+ int status = 0;
+
+ for (int i = 2; i <= 28; i++ )
+ status += doParse(i);
+
+ status += doParse(29);
+ status += doParse(30);
+ status += doParse(100);
+ status += doParse(1000);
+ status += doParse(10000);
+ status += doParse(60000);
+
+ if (status == 0)
+ printf("PASSED\n");
+ return (status != 0);
+}
diff --git a/test/overflow_entity_test.c b/test/overflow_entity_test.c
new file mode 100644
index 0000000..d0d1290
--- /dev/null
+++ b/test/overflow_entity_test.c
@@ -0,0 +1,86 @@
+/* gcc -g -std=c11 -D_POSIX_C_SOURCE=200809L -I lib/expat/xmlparse -lxmlrpc_xmlparse -lxmlrpc_xmltok overflow_entity_test.c -o overflow_entity_test */
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include "xmlparse.h"
+#include <string.h>
+
+#define XML_STATUS_OK 1
+#define XML_STATUS_ERROR 0
+
+typedef unsigned char XML_Bool;
+#define XML_TRUE ((XML_Bool)1)
+#define XML_FALSE ((XML_Bool)0)
+
+#define SIZE_PER_LINE 50
+
+static int
+doParse(int N_LINES) {
+ XML_Parser parser;
+ char tmp[SIZE_PER_LINE];
+ int ret = 0;
+ int rval = 0;
+
+ if ((parser = xmlrpc_XML_ParserCreate(NULL)) == NULL)
+ errx(1, "XML_ParserCreate");
+
+ char *const text = (char *)malloc((N_LINES + 4) * SIZE_PER_LINE);
+ if (text == NULL) {
+ printf("malloc failed");
+ return 1;
+ }
+
+ // Create the XML
+ snprintf(text, SIZE_PER_LINE,
+ "<!DOCTYPE foo [\n"
+ " <!ENTITY s0 'deepText'>\n");
+
+ for (size_t i = 1; i < N_LINES; ++i) {
+ snprintf(tmp, SIZE_PER_LINE, " <!ENTITY s%lu '&s%lu;'>\n",
+ (long unsigned)i, (long unsigned)(i - 1));
+ strncat(text, tmp, SIZE_PER_LINE);
+ }
+
+ snprintf(tmp, SIZE_PER_LINE, "]> <foo>&s%lu;</foo>\n",
+ (long unsigned)(N_LINES - 1));
+ strncat(text, tmp, SIZE_PER_LINE);
+
+ ret = xmlrpc_XML_Parse(parser, text, strlen(text), XML_TRUE);
+ if (ret == XML_STATUS_ERROR){
+ int err = xmlrpc_XML_GetErrorCode(parser);
+ if (err == XML_ERROR_RECURSIVE_ENTITY_REF) {
+ if (N_LINES <= 28) {
+ printf("%d Unexpected FAIL (%s)\n", N_LINES, xmlrpc_XML_ErrorString(err));
+ rval = 1;
+ } else {
+ printf("%d expected failure OK (%s)\n", N_LINES, xmlrpc_XML_ErrorString(err));
+ }
+ }
+ } else {
+ printf("%d OK\n", N_LINES);
+ }
+ free(text);
+ xmlrpc_XML_ParserFree(parser);
+ return rval;
+}
+
+int main(int argc, char *argv[]) {
+ int status = 0;
+
+ for (int i = 2; i <= 28; i++ )
+ status += doParse(i);
+
+ status += doParse(29);
+ status += doParse(30);
+ status += doParse(100);
+ status += doParse(1000);
+ status += doParse(10000);
+ status += doParse(60000);
+
+ if (status == 0)
+ printf("PASSED\n");
+ return (status != 0);
+}
--
2.43.5

View File

@ -0,0 +1,286 @@
From 0f3661572b50df9878412181dc600e69eafbd868 Mon Sep 17 00:00:00 2001
From: root <root@vm-10-0-185-207.hosted.upshift.rdu2.redhat.com>
Date: Wed, 19 Mar 2025 13:54:48 -0400
Subject: [PATCH] Add missing files for the benchmark tests
The SOURCES tarball needs to be manually unpacked.
---
test/benchmark/Makefile | 82 ++++++++++++++++++++
test/benchmark/README.txt | 16 ++++
test/benchmark/benchmark.c | 152 +++++++++++++++++++++++++++++++++++++
3 files changed, 250 insertions(+)
create mode 100644 test/benchmark/Makefile
create mode 100644 test/benchmark/README.txt
create mode 100644 test/benchmark/benchmark.c
diff --git a/test/benchmark/Makefile b/test/benchmark/Makefile
new file mode 100644
index 0000000..20e648c
--- /dev/null
+++ b/test/benchmark/Makefile
@@ -0,0 +1,82 @@
+ifeq ($(SRCDIR),)
+ updir = $(shell echo $(dir $(1)) | sed 's/.$$//')
+ testDIR := $(call updir,$(CURDIR))
+ SRCDIR := $(call updir,$(testDIR))
+ BLDDIR := $(SRCDIR)
+endif
+SUBDIR := test/benchmark
+
+include $(BLDDIR)/config.mk
+
+PROGS = benchmark
+
+default: all
+
+all: $(PROGS)
+
+XMLRPC_C_CONFIG = $(BLDDIR)/xmlrpc-c-config.test
+
+LIBS :=
+
+LIBS += $(SOCKETLIBOPT) $(THREAD_LIBS)
+
+INCLUDES = -Isrcdir/include -I$(BLDDIR) -Isrcdir -Isrcdir/lib/util/include -Isrcdir/lib/expat/xmlparse
+
+# This 'common.mk' dependency makes sure the symlinks get built before
+# this make file is used for anything.
+
+$(SRCDIR)/common.mk: srcdir blddir
+
+include $(SRCDIR)/common.mk
+
+CFLAGS += $(INCLUDES)
+
+TEST_OBJS = benchmark.o
+
+#-----------------------------------------------------------------------------
+# TEST_LIBS
+#-----------------------------------------------------------------------------
+TEST_LIBS =
+TEST_LIBS += $(LIBXMLRPC_UTIL_A)
+TEST_LIBS += $(LIBXMLRPC_XMLPARSE_A)
+TEST_LIBS += $(LIBXMLRPC_XMLTOK_A)
+
+benchmark: $(TEST_OBJS) $(TEST_LIBS)
+ $(CXXLD) -o $@ $(INCLUDES) $(LDFLAGS_ALL) $^ $(LIB_XML) $(TEST_LIBS)
+
+%.o:%.cpp
+ $(CC) -c $(INCLUDES) $(CXXFLAGS_ALL) $(D_INTERNAL_EXPAT) $<
+
+# Note the difference between 'check' and 'runtests'. 'check' means to check
+# our own correctness. 'runtests' means to run the tests that check our
+# parent's correctness
+
+.PHONY: check
+check:
+
+.PHONY: runtests
+runtests: benchmark
+ ./benchmark aaaaaa_attr.xml 4096 1
+ ./benchmark aaaaaa_comment.xml 4096 1
+ ./benchmark aaaaaa_tag.xml 4096 1
+ ./benchmark aaaaaa_text.xml 4096 1
+ -./benchmark aaaaaa_cdata.xml 4096 1
+ echo "PASSED"
+
+.PHONY: install
+install:
+
+.PHONY: uninstall
+uninstall:
+
+.PHONY: clean clean-local distclean
+clean: clean-common clean-local
+clean-local:
+ rm -f $(PROGS)
+
+distclean: clean distclean-common
+
+.PHONY: dep
+dep: dep-common
+
+include depend.mk
diff --git a/test/benchmark/README.txt b/test/benchmark/README.txt
new file mode 100644
index 0000000..86414d5
--- /dev/null
+++ b/test/benchmark/README.txt
@@ -0,0 +1,16 @@
+Use this benchmark command line utility as follows:
+
+ benchmark [-n] <file name> <buffer size> <# iterations>
+
+The command line arguments are:
+
+ -n ... optional; if supplied, namespace processing is turned on
+ <file name> ... name/path of test xml file
+ <buffer size> ... size of processing buffer;
+ the file is parsed in chunks of this size
+ <# iterations> ... how often will the file be parsed
+
+Returns:
+
+ The time (in seconds) it takes to parse the test file,
+ averaged over the number of iterations.@
diff --git a/test/benchmark/benchmark.c b/test/benchmark/benchmark.c
new file mode 100644
index 0000000..3864280
--- /dev/null
+++ b/test/benchmark/benchmark.c
@@ -0,0 +1,152 @@
+/*
+ __ __ _
+ ___\ \/ /_ __ __ _| |_
+ / _ \\ /| '_ \ / _` | __|
+ | __// \| |_) | (_| | |_
+ \___/_/\_\ .__/ \__,_|\__|
+ |_| XML parser
+
+ Copyright (c) 2003-2006 Karl Waclawek <karl@waclawek.net>
+ Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
+ Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
+ Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
+ Licensed under the MIT license:
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to permit
+ persons to whom the Software is furnished to do so, subject to the
+ following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <sys/stat.h>
+#include <assert.h>
+#include <stddef.h> // ptrdiff_t
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include "xmlparse.h"
+
+#ifdef XML_LARGE_SIZE
+# define XML_FMT_INT_MOD "ll"
+#else
+# define XML_FMT_INT_MOD "l"
+#endif
+
+#ifdef XML_UNICODE_WCHAR_T
+# define XML_FMT_STR "ls"
+#else
+# define XML_FMT_STR "s"
+#endif
+
+static void
+usage(const char *prog, int rc) {
+ fprintf(stderr, "usage: %s [-n] filename bufferSize nr_of_loops\n", prog);
+ exit(rc);
+}
+
+int
+main(int argc, char *argv[]) {
+ XML_Parser parser;
+ char *XMLBuf, *XMLBufEnd, *XMLBufPtr;
+ FILE *fd;
+ struct stat fileAttr;
+ int nrOfLoops, bufferSize, i, isFinal;
+ size_t fileSize;
+ int j = 0, ns = 0;
+ clock_t tstart, tend;
+ double cpuTime = 0.0;
+
+ if (argc > 1) {
+ if (argv[1][0] == '-') {
+ if (argv[1][1] == 'n' && argv[1][2] == '\0') {
+ ns = 1;
+ j = 1;
+ } else
+ usage(argv[0], 1);
+ }
+ }
+
+ if (argc != j + 4)
+ usage(argv[0], 1);
+
+ if (stat(argv[j + 1], &fileAttr) != 0) {
+ fprintf(stderr, "could not access file '%s'\n", argv[j + 1]);
+ return 2;
+ }
+
+ fd = fopen(argv[j + 1], "r");
+ if (! fd) {
+ fprintf(stderr, "could not open file '%s'\n", argv[j + 1]);
+ exit(2);
+ }
+
+ bufferSize = atoi(argv[j + 2]);
+ nrOfLoops = atoi(argv[j + 3]);
+ if (bufferSize <= 0 || nrOfLoops <= 0) {
+ fprintf(stderr, "buffer size and nr of loops must be greater than zero.\n");
+ exit(3);
+ }
+
+ XMLBuf = malloc(fileAttr.st_size);
+ fileSize = fread(XMLBuf, sizeof(char), fileAttr.st_size, fd);
+ fclose(fd);
+
+ if (ns)
+ parser = xmlrpc_XML_ParserCreateNS(NULL, '!');
+ else
+ parser = xmlrpc_XML_ParserCreate(NULL);
+
+ i = 0;
+ XMLBufEnd = XMLBuf + fileSize;
+ while (i < nrOfLoops) {
+ XMLBufPtr = XMLBuf;
+ isFinal = 0;
+ tstart = clock();
+ do {
+ ptrdiff_t parseBufferSize = XMLBufEnd - XMLBufPtr;
+ if (parseBufferSize <= (ptrdiff_t)bufferSize)
+ isFinal = 1;
+ else
+ parseBufferSize = bufferSize;
+ assert(parseBufferSize <= (ptrdiff_t)bufferSize);
+ if (! xmlrpc_XML_Parse(parser, XMLBufPtr, (int)parseBufferSize, isFinal)) {
+ fprintf(stderr,
+ "error '%" XML_FMT_STR "' at line %" XML_FMT_INT_MOD
+ "u character %" XML_FMT_INT_MOD "u\n",
+ xmlrpc_XML_ErrorString(xmlrpc_XML_GetErrorCode(parser)),
+ xmlrpc_XML_GetCurrentLineNumber(parser),
+ xmlrpc_XML_GetCurrentColumnNumber(parser));
+ free(XMLBuf);
+ xmlrpc_XML_ParserFree(parser);
+ exit(4);
+ }
+ XMLBufPtr += bufferSize;
+ } while (! isFinal);
+ tend = clock();
+ cpuTime += ((double)(tend - tstart)) / CLOCKS_PER_SEC;
+ //xmlrpc-c lacks XML_ParserReset
+ //xmlrpc_XML_ParserReset(parser, NULL);
+ i++;
+ }
+
+ xmlrpc_XML_ParserFree(parser);
+ free(XMLBuf);
+
+ printf("%d loops, with buffer size %d. Average time per loop: %f\n",
+ nrOfLoops, bufferSize, cpuTime / (double)nrOfLoops);
+ return 0;
+}
--
2.43.5

View File

@ -1,21 +1,49 @@
# Upstream libxml2 backend is completely broken since 2015 https://sourceforge.net/p/xmlrpc-c/patches/49/
%global advanced_branch 1
# Upstream libxml2 backend is completely broken since 2015
# https://sourceforge.net/p/xmlrpc-c/patches/49/
%bcond_with libxml2
Name: xmlrpc-c
Version: 1.59.02
Release: 3%{?dist}
Version: 1.51.0
Release: 11%{?dist}
Summary: Lightweight RPC library based on XML and HTTP
# See doc/COPYING for details.
# The Python 1.5.2 license used by a few files is just BSD.
License: BSD and MIT
URL: http://xmlrpc-c.sourceforge.net/
Source: http://dl.sourceforge.net/sourceforge/xmlrpc-c/xmlrpc-c-%version.tgz
%{!?advanced_branch:Source0: http://dl.sourceforge.net/sourceforge/xmlrpc-c/xmlrpc-%version.tgz}
# generated by 'make svn-sources [SVN_VER=%version SVN_REV=%svnrev]'. Unfortunately,
# upstream does not tag versions so we must fetch from the branch and
# check which version was used for it
%{?advanced_branch:Source0: xmlrpc-c-%version.tar.xz}
%{?advanced_branch:Source1: benchmark-tests.tar.xz}
# Upstreamable patches
Patch101: 0001-xmlrpc_server_abyss-use-va_args-properly.patch
Patch102: 0002-Use-proper-datatypes-for-long-long.patch
Patch103: 0003-allow-30x-redirections.patch
#Patch104: xmlrpc-c-printf-size_t.patch
#Patch105: xmlrpc-c-check-vasprintf-return-value.patch
Patch104: 0004-Add-missing-validation-of-encoding-CVE-2022-25235.patch
Patch105: 0005-lib-Prevent-more-integer-overflows-CVE-2022-22822-to.patch
Patch106: 0006-Prevent-integer-overflow-on-m_groupSize-in-doProlog-.patch
Patch107: 0007-Address-segfault-found-in-CVE-2023-52425.patch
Patch108: 0008-Prevent-integer-overflow-or-wraparound-CVE-2024-4549.patch
Patch109: 0009-Restrict-XML-Entity-Expansion-Depth-in-libexpat-CVE-.patch
Patch110: 0010-Add-missing-files-for-the-benchmark-tests.patch
# Backported patches
# https://sourceforge.net/p/xmlrpc-c/code/2981/
# Fixes RHBZ #1541868
Patch201: 0001-Remove-trace-statements-accidentally-committed-with-.patch
# Meson buildsystem, see https://blogs.gnome.org/ignatenko/2016/12/17/meson-%E2%99%A5-xmlrpc-c/
Patch1001: 0001-add-meson-buildsystem-definitions.patch
Patch1002: 0002-chmod-x-xml-rpc-api2txt.patch
BuildRequires: git-core
BuildRequires: meson >= 0.36.0
BuildRequires: gcc
BuildRequires: gcc-c++
%if %{with libxml2}
@ -106,23 +134,19 @@ This package contains some handy XML-RPC demo applications.
%prep
%autosetup -Sgit
tar xf %{SOURCE1}
%build
%configure
%make_build
# build order matters and multiple threads break it
%make_build -j1 -C tools
%meson %{?with_libxml2:-Dlibxml2-backend=true}
%meson_build
%install
%make_install
%make_install -C tools
%check
#%%make_test
%meson_install
%ldconfig_scriptlets
%ldconfig_scriptlets client
%ldconfig_scriptlets c++
%ldconfig_scriptlets client++
%files
%license doc/COPYING lib/abyss/license.txt
@ -130,14 +154,13 @@ This package contains some handy XML-RPC demo applications.
%if ! %{with libxml2}
%{_libdir}/libxmlrpc_xml*.so.*
%endif
%{_libdir}/libxmlrpc_openssl.so.*
%{_libdir}/libxmlrpc.so.*
%{_libdir}/libxmlrpc_util.so.*
%{_libdir}/libxmlrpc_abyss.so.*
%{_libdir}/libxmlrpc_server.so.*
%{_libdir}/libxmlrpc_server_abyss.so.*
%{_libdir}/libxmlrpc_server_cgi.so.*
%exclude %{_libdir}/libxmlrpc*.a
%files client
%{_libdir}/libxmlrpc_client.so.*
@ -177,62 +200,26 @@ This package contains some handy XML-RPC demo applications.
%{_bindir}/xmlrpc_dumpserver
%changelog
* Mon Jun 24 2024 Troy Dawson <tdawson@redhat.com> - 1.59.02-3
- Bump release for June 2024 mass rebuild
* Wed Mar 19 2025 Rob Crittenden <rcritten@redhat.com> - 1.51.0-11
- Restrict XML Entity Expansion Depth in libexpat CVE-2024-8176
* Sat Jan 27 2024 Fedora Release Engineering <releng@fedoraproject.org> - 1.59.02-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Thu Sep 19 2024 Rob Crittenden <rcritten@redhat.com> - 1.51.0-10
- Prevent integer overflow or wraparound, CVE-2024-4549 (RHEL-57519)
* Wed Jan 03 2024 Jonathan Wright <jonathan@almalinux.org> - 1.59.02-1
- Update to 1.59.02 rhbz#1694044
* Thu Apr 25 2024 Rob Crittenden <rcritten@redhat.com> - 1.51.0-9
- Address segfault found in CVE-2023-52425 (RHEL-24226)
* Sat Jul 22 2023 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.08-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Thu Apr 14 2022 Rob Crittenden <rcritten@redhat.com> - 1.51.0-8
- Address some Coverity issues in the patch set
* Sat Jan 21 2023 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.08-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Tue Apr 05 2022 Rob Crittenden <rcritten@redhat.com> - 1.51.0-7
- lib: Prevent more integer overflows (CVE-2022-22822 to CVE-2022-22827)
(#2058567, #2058576, #2058582, #2058589, #2058595, #2058602)
- Prevent integer overflow on m_groupSize in doProlog
(CVE-2021-46143) (#2058560)
* Tue Dec 06 2022 Jonathan Wright <jonathan@almalinux.org> - 1.51.08-1
- update to 1.51.08
- Remove meson build code, follow upstream build methods
- rhbz#2009098
- rhbz#2010890
* Tue Dec 06 2022 Jonathan Wright <jonathan@almalinux.org> - 1.51.0-17
- Merge PR from yselkowitz to fix meson builds
* Sat Jul 23 2022 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-16
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Sat Jan 22 2022 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-15
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Tue Sep 14 2021 Sahana Prasad <sahana@redhat.com> - 1.51.0-14
- Rebuilt with OpenSSL 3.0.0
* Fri Jul 23 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-13
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Thu Jan 28 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-12
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Wed Jul 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-11
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Fri Jan 31 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-10
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Sat Jul 27 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Sun Feb 17 2019 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 1.51.0-8
- Rebuild for readline 8.0
* Sun Feb 03 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Sat Jul 14 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Thu Mar 03 2022 Rob Crittenden <rcritten@redhat.com> - 1.51.0-6
- Add missing validation of encoding (CVE-2022-25235) (#2070481)
* Thu Apr 19 2018 Adam Williamson <awilliam@redhat.com> - 1.51.0-5
- Backport upstream fix for console spam with debug messages (#1541868)

View File

@ -1 +0,0 @@
SHA512 (xmlrpc-c-1.59.02.tgz) = 95bfc08d97af54d109e873b3f9e048d8c4779121408e3648ca43bc14cf502ec2d1a516c5b4fc62fc63dcbc6406f368d0285024f008a51af0eb2e2607c946ec5c

View File

@ -1,41 +0,0 @@
From 80047d74644eeda55c451aea59951eb502649cf4 Mon Sep 17 00:00:00 2001
From: Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
Date: Thu, 29 Jul 2010 19:43:08 +0200
Subject: [PATCH 7/8] check vasprintf return value
---
lib/libutil/asprintf.c | 3 ++-
lib/util/casprintf.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/libutil/asprintf.c b/lib/libutil/asprintf.c
index a79cd81..5a06f0f 100644
--- a/lib/libutil/asprintf.c
+++ b/lib/libutil/asprintf.c
@@ -121,7 +121,8 @@ xmlrpc_vasprintf(const char ** const retvalP,
char * string;
#if HAVE_ASPRINTF
- vasprintf(&string, fmt, varargs);
+ if (vasprintf(&string, fmt, varargs) < 0)
+ string = NULL;
#else
simpleVasprintf(&string, fmt, varargs);
#endif
diff --git a/lib/util/casprintf.c b/lib/util/casprintf.c
index 643f145..9139253 100644
--- a/lib/util/casprintf.c
+++ b/lib/util/casprintf.c
@@ -99,7 +99,8 @@ cvasprintf(const char ** const retvalP,
char * string;
#if HAVE_ASPRINTF
- vasprintf(&string, fmt, varargs);
+ if (vasprintf(&string, fmt, varargs) < 0)
+ string = NULL;
#else
simpleVasprintf(&string, fmt, varargs);
#endif
--
1.7.3.4

View File

@ -1,48 +0,0 @@
From 25a777bb0ee2e2ee17d87006f76b3cea5d15a9f7 Mon Sep 17 00:00:00 2001
From: Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
Date: Mon, 25 Feb 2008 17:48:25 +0100
Subject: [PATCH 2/9] fixed broken format string modifiers
---
examples/json.c | 4 ++--
examples/parse_xml.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/examples/json.c b/examples/json.c
index 89fe82b..91ea50d 100644
--- a/examples/json.c
+++ b/examples/json.c
@@ -41,7 +41,7 @@ printAsXml(xmlrpc_value * const valP) {
printf("XML-RPC XML:\n");
printf("%.*s\n",
- XMLRPC_MEMBLOCK_SIZE(char, &out),
+ (int)XMLRPC_MEMBLOCK_SIZE(char, &out),
XMLRPC_MEMBLOCK_CONTENTS(char, &out));
XMLRPC_MEMBLOCK_CLEAN(char, &out);
@@ -70,7 +70,7 @@ printAsJson(xmlrpc_value * const valP) {
printf("JSON:\n");
printf("%.*s\n",
- XMLRPC_MEMBLOCK_SIZE(char, &out),
+ (int)XMLRPC_MEMBLOCK_SIZE(char, &out),
XMLRPC_MEMBLOCK_CONTENTS(char, &out));
XMLRPC_MEMBLOCK_CLEAN(char, &out);
diff --git a/examples/parse_xml.c b/examples/parse_xml.c
index 2e6c508..4f6c308 100644
--- a/examples/parse_xml.c
+++ b/examples/parse_xml.c
@@ -58,7 +58,7 @@ describeXmlElement(const xml_element * const elemP,
printf("%sXML element type: '%s'\n",
prefix, xml_element_name(elemP));
- printf("%sNumber of child elements: %u\n",
+ printf("%sNumber of child elements: %zu\n",
prefix, xml_element_children_size(elemP));
for (i = 0; i < xml_element_children_size(elemP); ++i) {
--
1.7.6