Created
June 26, 2025 06:40
-
-
Save comex/6f300555ef8ddf27bcd18aba9a08fb75 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Only in libxml2: .git | |
Only in libxml2: .gitattributes | |
Only in libxml2: .gitignore | |
diff -ru libxml2/CMakeLists.txt libxml2-apple/libxml2/CMakeLists.txt | |
--- libxml2/CMakeLists.txt 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/CMakeLists.txt 2025-06-26 01:54:56 | |
@@ -60,6 +60,7 @@ | |
option(LIBXML2_WITH_XINCLUDE "Add the XInclude support" ON) | |
option(LIBXML2_WITH_XPATH "Add the XPATH support" ON) | |
option(LIBXML2_WITH_XPTR "Add the XPointer support" ON) | |
+option(LIBXML2_WITH_XPTR_LOCS "Add support for XPointer locations" OFF) | |
option(LIBXML2_WITH_ZLIB "Use libz" ON) | |
set(LIBXML2_XMLCONF_WORKING_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH "Working directory for XML Conformance Test Suite") | |
@@ -97,7 +98,7 @@ | |
find_package(ZLIB REQUIRED) | |
endif() | |
-foreach(VARIABLE IN ITEMS WITH_AUTOMATA WITH_C14N WITH_CATALOG WITH_DEBUG WITH_DOCB WITH_EXPR WITH_FTP WITH_HTML WITH_HTTP WITH_ICONV WITH_ICU WITH_ISO8859X WITH_LEGACY WITH_LZMA WITH_MEM_DEBUG WITH_MODULES WITH_OUTPUT WITH_PATTERN WITH_PUSH WITH_READER WITH_REGEXPS WITH_RUN_DEBUG WITH_SAX1 WITH_SCHEMAS WITH_SCHEMATRON WITH_THREADS WITH_THREAD_ALLOC WITH_TREE WITH_TRIO WITH_UNICODE WITH_VALID WITH_WRITER WITH_XINCLUDE WITH_XPATH WITH_XPTR WITH_ZLIB) | |
+foreach(VARIABLE IN ITEMS WITH_AUTOMATA WITH_C14N WITH_CATALOG WITH_DEBUG WITH_DOCB WITH_EXPR WITH_FTP WITH_HTML WITH_HTTP WITH_ICONV WITH_ICU WITH_ISO8859X WITH_LEGACY WITH_LZMA WITH_MEM_DEBUG WITH_MODULES WITH_OUTPUT WITH_PATTERN WITH_PUSH WITH_READER WITH_REGEXPS WITH_RUN_DEBUG WITH_SAX1 WITH_SCHEMAS WITH_SCHEMATRON WITH_THREADS WITH_THREAD_ALLOC WITH_TREE WITH_TRIO WITH_UNICODE WITH_VALID WITH_WRITER WITH_XINCLUDE WITH_XPATH WITH_XPTR WITH_XPTR_LOCS WITH_ZLIB) | |
if(LIBXML2_${VARIABLE}) | |
set(${VARIABLE} 1) | |
else() | |
@@ -380,6 +381,7 @@ | |
xmlschemastypes.c | |
xmlstring.c | |
xmlunicode.c | |
+ xmlversion.c | |
xmlwriter.c | |
xpath.c | |
xpointer.c | |
diff -ru libxml2/HTMLparser.c libxml2-apple/libxml2/HTMLparser.c | |
--- libxml2/HTMLparser.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/HTMLparser.c 2025-06-26 01:54:56 | |
@@ -114,11 +114,14 @@ | |
return; | |
if (ctxt != NULL) | |
ctxt->errNo = error; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_HTML, error, | |
XML_ERR_ERROR, NULL, 0, | |
(const char *) str1, (const char *) str2, | |
NULL, 0, 0, | |
msg, str1, str2); | |
+#pragma clang diagnostic pop | |
if (ctxt != NULL) | |
ctxt->wellFormed = 0; | |
} | |
@@ -141,9 +144,12 @@ | |
return; | |
if (ctxt != NULL) | |
ctxt->errNo = error; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_HTML, error, | |
XML_ERR_ERROR, NULL, 0, NULL, NULL, | |
NULL, val, 0, msg, val); | |
+#pragma clang diagnostic pop | |
if (ctxt != NULL) | |
ctxt->wellFormed = 0; | |
} | |
@@ -327,10 +333,12 @@ | |
#define NEXTL(l) do { \ | |
- if (*(ctxt->input->cur) == '\n') { \ | |
- ctxt->input->line++; ctxt->input->col = 1; \ | |
- } else ctxt->input->col++; \ | |
- ctxt->token = 0; ctxt->input->cur += l; \ | |
+ if (ctxt->input->cur + l <= ctxt->input->end) { \ | |
+ if (*(ctxt->input->cur) == '\n') { \ | |
+ ctxt->input->line++; ctxt->input->col = 1; \ | |
+ } else ctxt->input->col++; \ | |
+ ctxt->token = 0; ctxt->input->cur += l; ctxt->nbChars++; \ | |
+ } \ | |
} while (0) | |
/************ | |
@@ -450,7 +458,12 @@ | |
*/ | |
guess = htmlFindEncoding(ctxt); | |
if (guess == NULL) { | |
- xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1); | |
+ int ret = xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1); | |
+ if (ret < 0) { | |
+ htmlParseErr(ctxt, ctxt->errNo ? ctxt->errNo : XML_I18N_CONV_FAILED, | |
+ "htmlCheckEncoding: error switching to encoding 'ISO-8859-1'\n", | |
+ NULL, NULL); | |
+ } | |
} else { | |
if (ctxt->input->encoding != NULL) | |
xmlFree((xmlChar *) ctxt->input->encoding); | |
@@ -461,8 +474,14 @@ | |
* Don't use UTF-8 encoder which isn't required and | |
* can produce invalid UTF-8. | |
*/ | |
- if (!xmlStrEqual(BAD_CAST handler->name, BAD_CAST "UTF-8")) | |
- xmlSwitchToEncoding(ctxt, handler); | |
+ if (!xmlStrEqual(BAD_CAST handler->name, BAD_CAST "UTF-8")) { | |
+ int ret = xmlSwitchToEncoding(ctxt, handler); | |
+ if (ret < 0) { | |
+ htmlParseErr(ctxt, ctxt->errNo ? ctxt->errNo : XML_I18N_CONV_FAILED, | |
+ "htmlCheckEncoding: error switching to encoding '%s'\n", | |
+ guess, NULL); | |
+ } | |
+ } | |
} else { | |
htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING, | |
"Unsupported encoding %s", guess, NULL); | |
@@ -485,29 +504,38 @@ | |
cur = ctxt->input->cur; | |
c = *cur; | |
if (c & 0x80) { | |
+ size_t avail; | |
+ | |
if ((c & 0x40) == 0) | |
goto encoding_error; | |
- if (cur[1] == 0) { | |
+ | |
+ avail = ctxt->input->end - ctxt->input->cur; | |
+ | |
+ if (avail < 2) { | |
xmlParserInputGrow(ctxt->input, INPUT_CHUNK); | |
cur = ctxt->input->cur; | |
+ avail = ctxt->input->end - ctxt->input->cur; | |
} | |
- if ((cur[1] & 0xc0) != 0x80) | |
+ | |
+ if ((avail < 2) || ((cur[1] & 0xc0) != 0x80)) | |
goto encoding_error; | |
if ((c & 0xe0) == 0xe0) { | |
- if (cur[2] == 0) { | |
+ if (avail < 3) { | |
xmlParserInputGrow(ctxt->input, INPUT_CHUNK); | |
cur = ctxt->input->cur; | |
+ avail = ctxt->input->end - ctxt->input->cur; | |
} | |
- if ((cur[2] & 0xc0) != 0x80) | |
+ if ((avail < 3) || ((cur[2] & 0xc0) != 0x80)) | |
goto encoding_error; | |
if ((c & 0xf0) == 0xf0) { | |
- if (cur[3] == 0) { | |
+ if (avail < 4) { | |
xmlParserInputGrow(ctxt->input, INPUT_CHUNK); | |
cur = ctxt->input->cur; | |
+ avail = ctxt->input->end - ctxt->input->cur; | |
} | |
if (((c & 0xf8) != 0xf0) || | |
- ((cur[3] & 0xc0) != 0x80)) | |
+ (avail < 4) || ((cur[3] & 0xc0) != 0x80)) | |
goto encoding_error; | |
/* 4-byte code */ | |
*len = 4; | |
@@ -600,7 +628,7 @@ | |
static int | |
htmlSkipBlankChars(xmlParserCtxtPtr ctxt) { | |
- int res = 0; | |
+ size_t res = 0; | |
while (IS_BLANK_CH(*(ctxt->input->cur))) { | |
if ((*ctxt->input->cur == 0) && | |
@@ -616,7 +644,7 @@ | |
} | |
res++; | |
} | |
- return(res); | |
+ return(res > INT_MAX ? INT_MAX : (int)res); | |
} | |
@@ -2332,7 +2360,7 @@ | |
else | |
cp = ent->name; | |
len = strlen(cp); | |
- if (out + 2 + len > outend) | |
+ if (outend - out < len + 2) | |
break; | |
*out++ = '&'; | |
memcpy(out, cp, len); | |
@@ -2838,6 +2866,10 @@ | |
out = &buffer[indx]; | |
} | |
c = CUR_CHAR(l); | |
+ if (ctxt->instate == XML_PARSER_EOF) { | |
+ xmlFree(buffer); | |
+ return(NULL); | |
+ } | |
if (c < 0x80) | |
{ *out++ = c; bits= -6; } | |
else if (c < 0x800) | |
@@ -2996,9 +3028,9 @@ | |
htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, | |
"Unfinished SystemLiteral\n", NULL, NULL); | |
} else { | |
- NEXT; | |
if (err == 0) | |
ret = xmlStrndup((BASE_PTR+startPosition), len); | |
+ NEXT; | |
} | |
return(ret); | |
@@ -3051,9 +3083,9 @@ | |
htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, | |
"Unfinished PubidLiteral\n", NULL, NULL); | |
} else { | |
- NEXT; | |
if (err == 0) | |
ret = xmlStrndup((BASE_PTR + startPosition), len); | |
+ NEXT; | |
} | |
return(ret); | |
@@ -3125,6 +3157,7 @@ | |
htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR, | |
"Invalid char in CDATA 0x%X\n", cur); | |
} | |
+ NEXTL(l); | |
if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) { | |
buf[nbchar] = 0; | |
if (ctxt->sax->cdataBlock!= NULL) { | |
@@ -3138,7 +3171,6 @@ | |
nbchar = 0; | |
} | |
GROW; | |
- NEXTL(l); | |
cur = CUR_CHAR(l); | |
} | |
@@ -3474,8 +3506,8 @@ | |
state = ctxt->instate; | |
ctxt->instate = XML_PARSER_COMMENT; | |
- SHRINK; | |
SKIP(4); | |
+ SHRINK; | |
buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar)); | |
if (buf == NULL) { | |
htmlErrMemory(ctxt, "buffer allocation failed\n"); | |
@@ -3801,7 +3833,12 @@ | |
"htmlCheckEncoding: wrong encoding meta\n", | |
NULL, NULL); | |
} else { | |
- xmlSwitchEncoding(ctxt, enc); | |
+ int ret = xmlSwitchEncoding(ctxt, enc); | |
+ if (ret < 0) { | |
+ htmlParseErr(ctxt, ctxt->errNo ? ctxt->errNo : XML_I18N_CONV_FAILED, | |
+ "htmlCheckEncoding: error switching to encoding '%s'\n", | |
+ encoding, NULL); | |
+ } | |
} | |
ctxt->charset = XML_CHAR_ENCODING_UTF8; | |
} else { | |
@@ -3810,7 +3847,12 @@ | |
*/ | |
handler = xmlFindCharEncodingHandler((const char *) encoding); | |
if (handler != NULL) { | |
- xmlSwitchToEncoding(ctxt, handler); | |
+ int ret = xmlSwitchToEncoding(ctxt, handler); | |
+ if (ret < 0) { | |
+ htmlParseErr(ctxt, ctxt->errNo ? ctxt->errNo : XML_I18N_CONV_FAILED, | |
+ "htmlCheckEncoding: error switching to encoding '%s'\n", | |
+ encoding, NULL); | |
+ } | |
ctxt->charset = XML_CHAR_ENCODING_UTF8; | |
} else { | |
htmlParseErr(ctxt, XML_ERR_UNSUPPORTED_ENCODING, | |
@@ -3824,7 +3866,7 @@ | |
(ctxt->input->buf->raw != NULL) && | |
(ctxt->input->buf->buffer != NULL)) { | |
int nbchars; | |
- int processed; | |
+ size_t processed; | |
/* | |
* convert as much as possible to the parser reading buffer. | |
@@ -4929,8 +4971,18 @@ | |
start[3] = NXT(3); | |
enc = xmlDetectCharEncoding(&start[0], 4); | |
if (enc != XML_CHAR_ENCODING_NONE) { | |
- xmlSwitchEncoding(ctxt, enc); | |
- } | |
+ int ret = xmlSwitchEncoding(ctxt, enc); | |
+ if (ret < 0) { | |
+ char buf[20]; | |
+ snprintf(&buf[0], 20, "0x%02X 0x%02X 0x%02X 0x%02X", | |
+ start[0], start[1], | |
+ start[2], start[3]); | |
+ buf[19] = 0; | |
+ htmlParseErr(ctxt, ctxt->errNo ? ctxt->errNo : XML_I18N_CONV_FAILED, | |
+ "htmlCheckEncoding: error switching to encoding, bytes %s\n", | |
+ (const xmlChar *)buf, NULL); | |
+ } | |
+ } | |
} | |
/* | |
@@ -5248,19 +5300,28 @@ | |
* registered set of known encodings | |
*/ | |
if (enc != XML_CHAR_ENCODING_ERROR) { | |
- xmlSwitchEncoding(ctxt, enc); | |
+ int ret = xmlSwitchEncoding(ctxt, enc); | |
if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) { | |
htmlParseErr(ctxt, XML_ERR_UNSUPPORTED_ENCODING, | |
"Unsupported encoding %s\n", | |
(const xmlChar *) encoding, NULL); | |
- } | |
+ } else if (ret < 0) { | |
+ htmlParseErr(ctxt, ctxt->errNo ? ctxt->errNo : XML_I18N_CONV_FAILED, | |
+ "htmlCheckEncoding: error switching to encoding '%s'\n", | |
+ (const xmlChar *)encoding, NULL); | |
+ } | |
} else { | |
/* | |
* fallback for unknown encodings | |
*/ | |
handler = xmlFindCharEncodingHandler((const char *) encoding); | |
if (handler != NULL) { | |
- xmlSwitchToEncoding(ctxt, handler); | |
+ int ret = xmlSwitchToEncoding(ctxt, handler); | |
+ if (ret < 0) { | |
+ htmlParseErr(ctxt, ctxt->errNo ? ctxt->errNo : XML_I18N_CONV_FAILED, | |
+ "htmlCheckEncoding: error switching to encoding '%s'\n", | |
+ (const xmlChar *)encoding, NULL); | |
+ } | |
} else { | |
htmlParseErr(ctxt, XML_ERR_UNSUPPORTED_ENCODING, | |
"Unsupported encoding %s\n", | |
@@ -5808,6 +5869,12 @@ | |
failed = htmlParseStartTag(ctxt); | |
+ /* <meta> tag with new charset can cause fatal encoding error in push mode. */ | |
+ if (ctxt->instate == XML_PARSER_EOF) { | |
+ if ((ctxt->sax) && (ctxt->sax->endDocument != NULL)) | |
+ ctxt->sax->endDocument(ctxt->userData); | |
+ goto done; | |
+ } | |
name = ctxt->name; | |
if ((failed == -1) || | |
(name == NULL)) { | |
@@ -6484,13 +6551,13 @@ | |
/* set encoding */ | |
if (encoding) { | |
- size_t l = strlen(encoding); | |
+ size_t encodingLength = strlen(encoding); | |
- if (l < 1000) { | |
- content = xmlMallocAtomic (xmlStrlen(content_line) + l + 1); | |
+ if (encodingLength < 1000) { | |
+ const size_t contentLength = xmlStrlen(content_line) + encodingLength + 1; | |
+ content = xmlMallocAtomic(contentLength); | |
if (content) { | |
- strcpy ((char *)content, (char *)content_line); | |
- strcat ((char *)content, (char *)encoding); | |
+ snprintf((char *)content, contentLength, "%s%s", (char *)content_line, (char *)encoding); | |
htmlCheckEncoding (ctxt, content); | |
xmlFree (content); | |
} | |
@@ -6746,6 +6813,8 @@ | |
ctxt->nameNr = 0; | |
ctxt->name = NULL; | |
+ ctxt->nsNr = 0; | |
+ | |
DICT_FREE(ctxt->version); | |
ctxt->version = NULL; | |
DICT_FREE(ctxt->encoding); | |
@@ -6773,6 +6842,7 @@ | |
ctxt->disableSAX = 0; | |
ctxt->valid = 1; | |
ctxt->vctxt.userData = ctxt; | |
+ ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_0; | |
ctxt->vctxt.error = xmlParserValidityError; | |
ctxt->vctxt.warning = xmlParserValidityWarning; | |
ctxt->record_info = 0; | |
@@ -6794,6 +6864,50 @@ | |
} | |
} | |
+#ifdef __APPLE__ | |
+#include <dispatch/dispatch.h> | |
+#include <mach-o/dyld_priv.h> | |
+ | |
+// libxml2 v2.9 changed the HTML parser's handling of whitespace in a way that broke | |
+// H&R Block at Home 2010. Detect H&R Block at Home 2010 and mimic the old parser behavior. | |
+static bool evaluteHTMLParserNeedsNoBlankQuirkCriteria(void) | |
+{ | |
+ const char* executablePath = _dyld_get_image_name(0); | |
+ if (!executablePath) | |
+ return false; | |
+ | |
+ // Find the base name portion of the path. | |
+ const char* executableName = strrchr(executablePath, '/'); | |
+ if (!executableName) | |
+ return false; | |
+ | |
+ // Move past the slash. | |
+ executableName++; | |
+ | |
+ if (strcmp(executableName, "TaxCut.real")) | |
+ return false; | |
+ | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wdeprecated-declarations" | |
+ // Apply the workaround if the application was linked against an SDK prior to where | |
+ // libxml2 v2.9 was present. | |
+ return dyld_get_program_sdk_version() < DYLD_MACOSX_VERSION_10_9; | |
+#pragma clang diagnostic pop | |
+} | |
+ | |
+static bool htmlParserNeedsNoBlankQuirk(void) | |
+{ | |
+ static bool needsQuirk; | |
+ static dispatch_once_t hasEvaluatedQuirk; | |
+ dispatch_once(&hasEvaluatedQuirk, ^{ | |
+ needsQuirk = evaluteHTMLParserNeedsNoBlankQuirkCriteria(); | |
+ }); | |
+ | |
+ return needsQuirk; | |
+} | |
+ | |
+#endif /* __APPLE__ */ | |
+ | |
/** | |
* htmlCtxtUseOptions: | |
* @ctxt: an HTML parser context | |
@@ -6810,6 +6924,11 @@ | |
if (ctxt == NULL) | |
return(-1); | |
+#if __APPLE__ | |
+ if (htmlParserNeedsNoBlankQuirk()) | |
+ options |= XML_PARSE_NOBLANKS; | |
+#endif | |
+ | |
if (options & HTML_PARSE_NOWARNING) { | |
ctxt->sax->warning = NULL; | |
ctxt->vctxt.warning = NULL; | |
@@ -6890,10 +7009,16 @@ | |
hdlr = xmlFindCharEncodingHandler(encoding); | |
if (hdlr != NULL) { | |
- xmlSwitchToEncoding(ctxt, hdlr); | |
- if (ctxt->input->encoding != NULL) | |
- xmlFree((xmlChar *) ctxt->input->encoding); | |
- ctxt->input->encoding = xmlStrdup((xmlChar *)encoding); | |
+ int retval = xmlSwitchToEncoding(ctxt, hdlr); | |
+ if (retval < 0) { | |
+ htmlParseErr(ctxt, ctxt->errNo ? ctxt->errNo : XML_I18N_CONV_FAILED, | |
+ "htmlCheckEncoding: error switching to encoding '%s'\n", | |
+ (const xmlChar *)encoding, NULL); | |
+ } else { | |
+ if (ctxt->input->encoding != NULL) | |
+ xmlFree((xmlChar *) ctxt->input->encoding); | |
+ ctxt->input->encoding = xmlStrdup((xmlChar *)encoding); | |
+ } | |
} | |
} | |
if ((URL != NULL) && (ctxt->input != NULL) && | |
diff -ru libxml2/HTMLtree.c libxml2-apple/libxml2/HTMLtree.c | |
--- libxml2/HTMLtree.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/HTMLtree.c 2025-06-26 01:54:56 | |
@@ -304,7 +304,7 @@ | |
* output as <option selected>, as per XSLT 1.0 16.2 "HTML Output Method" | |
* | |
*/ | |
-static const char* htmlBooleanAttrs[] = { | |
+static const char* const htmlBooleanAttrs[] = { | |
"checked", "compact", "declare", "defer", "disabled", "ismap", | |
"multiple", "nohref", "noresize", "noshade", "nowrap", "readonly", | |
"selected", NULL | |
@@ -384,7 +384,10 @@ | |
default: | |
msg = "unexpected error number\n"; | |
} | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlSimpleError(XML_FROM_OUTPUT, code, node, msg, extra); | |
+#pragma clang diagnostic pop | |
} | |
/************************************************************************ | |
@@ -992,7 +995,14 @@ | |
htmlDocContentDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr cur, | |
const char *encoding ATTRIBUTE_UNUSED, | |
int format) { | |
+ int type = 0; | |
+ if (cur) { | |
+ type = cur->type; | |
+ cur->type = XML_HTML_DOCUMENT_NODE; | |
+ } | |
htmlNodeDumpFormatOutput(buf, cur, (xmlNodePtr) cur, NULL, format); | |
+ if (cur) | |
+ cur->type = (xmlElementType) type; | |
} | |
/** | |
diff -ru libxml2/Makefile.am libxml2-apple/libxml2/Makefile.am | |
--- libxml2/Makefile.am 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/Makefile.am 2025-06-26 01:54:56 | |
@@ -55,7 +55,8 @@ | |
$(trio_sources) \ | |
xmlreader.c relaxng.c dict.c SAX2.c \ | |
xmlwriter.c legacy.c chvalid.c pattern.c xmlsave.c \ | |
- xmlmodule.c schematron.c xzlib.c | |
+ xmlmodule.c schematron.c xzlib.c \ | |
+ xmlversion.c | |
DEPS = $(top_builddir)/libxml2.la | |
LDADDS = $(STATIC_BINARIES) $(top_builddir)/libxml2.la $(THREAD_LIBS) $(Z_LIBS) $(LZMA_LIBS) $(ICONV_LIBS) $(M_LIBS) $(WIN32_EXTRA_LIBADD) | |
@@ -225,7 +226,7 @@ | |
testall : tests SVGtests SAXtests | |
-tests: XMLtests XMLenttests NStests IDtests Errtests APItests $(READER_TEST) $(TEST_SAX) $(TEST_PUSH) $(TEST_HTML) $(TEST_PHTML) $(TEST_VALID) URItests $(TEST_PATTERN) $(TEST_XPATH) $(TEST_XPTR) $(TEST_XINCLUDE) $(TEST_C14N) $(TEST_DEBUG) $(TEST_CATALOG) $(TEST_REGEXPS) $(TEST_SCHEMAS) $(TEST_SCHEMATRON) $(TEST_THREADS) Timingtests $(TEST_VTIME) $(PYTHON_TESTS) $(TEST_MODULES) | |
+tests: XMLtests XMLRecovertests XMLenttests NStests IDtests Errtests APItests $(READER_TEST) $(TEST_SAX) $(TEST_PUSH) $(TEST_HTML) $(TEST_PHTML) $(TEST_VALID) URItests $(TEST_PATTERN) $(TEST_XPATH) $(TEST_XPTR) $(TEST_XINCLUDE) $(TEST_C14N) $(TEST_DEBUG) $(TEST_CATALOG) $(TEST_REGEXPS) $(TEST_SCHEMAS) $(TEST_SCHEMATRON) $(TEST_THREADS) Timingtests $(TEST_VTIME) $(PYTHON_TESTS) $(TEST_MODULES) | |
@(if [ "$(PYTHON_SUBDIR)" != "" ] ; then cd python ; \ | |
$(MAKE) -s tests ; fi) | |
@(cd doc/examples ; $(MAKE) -s tests) | |
@@ -303,6 +304,25 @@ | |
rm result.$$name.sax ; \ | |
fi ; fi ; done) | |
+HTMLRecovertests : xmllint$(EXEEXT) | |
+ @(echo > .memdump) | |
+ @echo "## HTML recover regression tests" | |
+ -@(for i in $(srcdir)/test/recover/html/* ; do \ | |
+ name=`basename $$i`; \ | |
+ if [ ! -d $$i ] ; then \ | |
+ if [ ! -f $(srcdir)/result/recover/html/$$name ] ; then \ | |
+ echo New test file $$name ; \ | |
+ $(CHECKER) $(top_builddir)/xmllint --html --recover $$i > $(srcdir)/result/recover/html/$$name 2> $(srcdir)/result/recover/html/$$name.err ; \ | |
+ grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0"; \ | |
+ else \ | |
+ log=`$(CHECKER) $(top_builddir)/xmllint --html --recover $$i > result.$$name 2> error.$$name ; \ | |
+ grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0"; \ | |
+ diff $(srcdir)/result/recover/html/$$name result.$$name ; \ | |
+ diff -b $(srcdir)/result/recover/html/$$name.err error.$$name` ; \ | |
+ if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \ | |
+ rm -f result.$$name error.$$name ; \ | |
+ fi ; fi ; done) | |
+ | |
XMLtests : xmllint$(EXEEXT) | |
@(echo > .memdump) | |
@echo "## XML regression tests" | |
@@ -363,6 +383,25 @@ | |
rm result.$$name result2.$$name ; \ | |
fi ; fi ; done) | |
+XMLRecovertests: xmllint$(EXEEXT) | |
+ @(echo > .memdump) | |
+ @echo "## XML recover regression tests" | |
+ -@(for i in $(srcdir)/test/recover/xml/* ; do \ | |
+ name=`basename $$i`; \ | |
+ if [ ! -d $$i ] ; then \ | |
+ if [ ! -f $(srcdir)/result/recover/xml/$$name ] ; then \ | |
+ echo New test file $$name ; \ | |
+ $(CHECKER) $(top_builddir)/xmllint --recover $$i > $(srcdir)/result/recover/xml/$$name 2> $(srcdir)/result/recover/xml/$$name.err ; \ | |
+ grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0"; \ | |
+ else \ | |
+ log=`$(CHECKER) $(top_builddir)/xmllint --recover $$i > result.$$name 2> error.$$name ; \ | |
+ grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0"; \ | |
+ diff $(srcdir)/result/recover/xml/$$name result.$$name ; \ | |
+ diff -b $(srcdir)/result/recover/xml/$$name.err error.$$name` ; \ | |
+ if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \ | |
+ rm -f result.$$name error.$$name ; \ | |
+ fi ; fi ; done) | |
+ | |
NStests : xmllint$(EXEEXT) | |
@(echo > .memdump) | |
@echo "## XML Namespaces regression tests" | |
@@ -856,6 +895,21 @@ | |
if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \ | |
rm result.$$name ; \ | |
fi ; fi ; done) | |
+ @echo "## SAX2 stop on fatal error regression tests" | |
+ -@(for i in $(srcdir)/test/saxerrors/* ; do \ | |
+ name=`basename $$i`; \ | |
+ if [ ! -d $$i ] ; then \ | |
+ if [ ! -f $(srcdir)/result/saxerrors/$$name.sax2 ] ; then \ | |
+ echo New test file $$name ; \ | |
+ $(CHECKER) $(top_builddir)/xmllint --sax --sax-fatal-stop $$i > $(srcdir)/result/saxerrors/$$name.sax2 2> /dev/null ; \ | |
+ grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0";\ | |
+ else \ | |
+ log=`$(CHECKER) $(top_builddir)/xmllint --sax --sax-fatal-stop $$i > result.$$name 2> /dev/null ; \ | |
+ grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0";\ | |
+ diff $(srcdir)/result/saxerrors/$$name.sax2 result.$$name` ; \ | |
+ if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \ | |
+ rm result.$$name ; \ | |
+ fi ; fi ; done) | |
Validtests : xmllint$(EXEEXT) | |
@(echo > .memdump) | |
@@ -915,7 +969,7 @@ | |
grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0";\ | |
diff $(srcdir)/result/regexp/$$name result.$$name ; \ | |
if [ -s "$(srcdir)/result/regexp/$$name.err" -o -s "error.$$name" ] ; then diff $(srcdir)/result/regexp/$$name.err error.$$name ; fi` ; \ | |
- if [ -n "$$log" ] ; then echo $$name result ; echo $$log ; fi ; \ | |
+ if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \ | |
rm result.$$name error.$$name ; \ | |
fi ; fi ; done) | |
@@ -1047,6 +1101,33 @@ | |
rm res.$$name err.$$name ; \ | |
fi ; fi ;\ | |
done; done) | |
+ @echo "## Schemas streaming regression tests" | |
+ -@(for i in $(srcdir)/test/schemas/*_*.xsd ; do \ | |
+ name=`basename $$i | sed 's+_.*++'`; \ | |
+ sno=`basename $$i | sed 's+.*_\(.*\).xsd+\1+'`; \ | |
+ for j in $(srcdir)/test/schemas/"$$name"_*.xml ; do \ | |
+ if [ -f $$j ] ; then \ | |
+ xno=`basename $$j | sed 's+.*_\(.*\).xml+\1+'`; \ | |
+ if [ ! -f $(srcdir)/result/schemas/"$$name"_"$$sno"_"$$xno" ]; \ | |
+ then \ | |
+ echo New test file "$$name"_"$$sno"_"$$xno" ; \ | |
+ $(CHECKER) $(top_builddir)/testSchemas --stream $$i $$j \ | |
+ > $(srcdir)/result/schemas/"$$name"_"$$sno"_"$$xno" \ | |
+ 2> $(srcdir)/result/schemas/"$$name"_"$$sno"_"$$xno".err.rdr; \ | |
+ grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0";\ | |
+ else \ | |
+ log=`$(CHECKER) $(top_builddir)/testSchemas --stream $$i $$j \ | |
+ > res.$$name 2> err.$$name;\ | |
+ grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0";\ | |
+ diff $(srcdir)/result/schemas/"$$name"_"$$sno"_"$$xno" \ | |
+ res.$$name;\ | |
+ diff $(srcdir)/result/schemas/"$$name"_"$$sno"_"$$xno".err.rdr \ | |
+ err.$$name;\ | |
+ grep Unimplemented err.$$name`; \ | |
+ if [ -n "$$log" ] ; then echo "$$name"_"$$sno"_"$$xno" result ; echo "$$log" ; fi ; \ | |
+ rm res.$$name err.$$name ; \ | |
+ fi ; fi ;\ | |
+ done; done) | |
Relaxtests: xmllint$(EXEEXT) | |
@(echo > .memdump) | |
@@ -1259,7 +1340,8 @@ | |
dbgen.pl dbgenattr.pl regressions.py regressions.xml \ | |
README.tests Makefile.tests libxml2.syms timsort.h \ | |
README.zOS README.md \ | |
- CMakeLists.txt config.h.cmake.in libxml2-config.cmake.cmake.in | |
+ CMakeLists.txt config.h.cmake.in libxml2-config.cmake.cmake.in \ | |
+ xmlversionInternal.h | |
pkgconfigdir = $(libdir)/pkgconfig | |
diff -ru libxml2/SAX2.c libxml2-apple/libxml2/SAX2.c | |
--- libxml2/SAX2.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/SAX2.c 2025-06-26 01:54:56 | |
@@ -28,11 +28,6 @@ | |
#include <libxml/HTMLtree.h> | |
#include <libxml/globals.h> | |
-/* Define SIZE_T_MAX unless defined through <limits.h>. */ | |
-#ifndef SIZE_T_MAX | |
-# define SIZE_T_MAX ((size_t)-1) | |
-#endif /* !SIZE_T_MAX */ | |
- | |
/* #define DEBUG_SAX2 */ | |
/* #define DEBUG_SAX2_TREE */ | |
@@ -65,22 +60,28 @@ | |
ctxt->errNo = XML_ERR_NO_MEMORY; | |
if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC)) | |
schannel = ctxt->sax->serror; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, | |
ctxt->vctxt.error, ctxt->vctxt.userData, | |
ctxt, NULL, XML_FROM_PARSER, XML_ERR_NO_MEMORY, | |
XML_ERR_ERROR, NULL, 0, (const char *) str1, | |
NULL, NULL, 0, 0, | |
msg, (const char *) str1, NULL); | |
+#pragma clang diagnostic pop | |
ctxt->errNo = XML_ERR_NO_MEMORY; | |
ctxt->instate = XML_PARSER_EOF; | |
ctxt->disableSAX = 1; | |
} else { | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, | |
NULL, NULL, | |
ctxt, NULL, XML_FROM_PARSER, XML_ERR_NO_MEMORY, | |
XML_ERR_ERROR, NULL, 0, (const char *) str1, | |
NULL, NULL, 0, 0, | |
msg, (const char *) str1, NULL); | |
+#pragma clang diagnostic pop | |
} | |
} | |
@@ -107,20 +108,26 @@ | |
ctxt->errNo = error; | |
if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC)) | |
schannel = ctxt->sax->serror; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, | |
ctxt->vctxt.error, ctxt->vctxt.userData, | |
ctxt, NULL, XML_FROM_DTD, error, | |
XML_ERR_ERROR, NULL, 0, (const char *) str1, | |
(const char *) str2, NULL, 0, 0, | |
msg, (const char *) str1, (const char *) str2); | |
+#pragma clang diagnostic pop | |
ctxt->valid = 0; | |
} else { | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, | |
NULL, NULL, | |
ctxt, NULL, XML_FROM_DTD, error, | |
XML_ERR_ERROR, NULL, 0, (const char *) str1, | |
(const char *) str2, NULL, 0, 0, | |
msg, (const char *) str1, (const char *) str2); | |
+#pragma clang diagnostic pop | |
} | |
} | |
@@ -143,10 +150,13 @@ | |
return; | |
if (ctxt != NULL) | |
ctxt->errNo = error; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error, | |
XML_ERR_FATAL, NULL, 0, | |
(const char *) str1, (const char *) str2, | |
NULL, 0, 0, msg, str1, str2); | |
+#pragma clang diagnostic pop | |
if (ctxt != NULL) { | |
ctxt->wellFormed = 0; | |
ctxt->valid = 0; | |
@@ -174,10 +184,13 @@ | |
return; | |
if (ctxt != NULL) | |
ctxt->errNo = error; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error, | |
XML_ERR_WARNING, NULL, 0, | |
(const char *) str1, NULL, | |
NULL, 0, 0, msg, str1); | |
+#pragma clang diagnostic pop | |
} | |
/** | |
@@ -199,10 +212,13 @@ | |
return; | |
if (ctxt != NULL) | |
ctxt->errNo = error; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error, | |
XML_ERR_ERROR, NULL, 0, | |
(const char *) str1, (const char *) str2, | |
NULL, 0, 0, msg, str1, str2); | |
+#pragma clang diagnostic pop | |
} | |
/** | |
@@ -223,10 +239,13 @@ | |
return; | |
if (ctxt != NULL) | |
ctxt->errNo = error; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error, | |
XML_ERR_WARNING, NULL, 0, | |
(const char *) str1, (const char *) str2, | |
NULL, 0, 0, msg, str1, str2); | |
+#pragma clang diagnostic pop | |
} | |
/** | |
@@ -1787,13 +1806,6 @@ | |
xmlGenericError(xmlGenericErrorContext, "SAX.xmlSAX2EndElement(%s)\n", name); | |
#endif | |
- /* Capture end position and add node */ | |
- if (cur != NULL && ctxt->record_info) { | |
- ctxt->nodeInfo->end_pos = ctxt->input->cur - ctxt->input->base; | |
- ctxt->nodeInfo->end_line = ctxt->input->line; | |
- ctxt->nodeInfo->node = cur; | |
- xmlParserAddNodeInfo(ctxt, ctxt->nodeInfo); | |
- } | |
ctxt->nodemem = -1; | |
#ifdef LIBXML_VALID_ENABLED | |
@@ -2160,6 +2172,50 @@ | |
xmlFree(dup); | |
} | |
+#ifdef __APPLE__ | |
+#include <dispatch/dispatch.h> | |
+#include <mach-o/dyld_priv.h> | |
+ | |
+// libxml2 v2.9 changed how elements with undeclared namespace prefixes are handled, an error case that has undefined behavior, | |
+// in such a way that broke Microsoft Document Connection. Detect Microsoft Document Connection and mimic the old behavior. | |
+static bool evaluateStartElementNSNeedsUndeclaredPrefixQuirk(void) | |
+{ | |
+ const char* executablePath = _dyld_get_image_name(0); | |
+ if (!executablePath) | |
+ return false; | |
+ | |
+ // Find the base name portion of the path. | |
+ const char* executableName = strrchr(executablePath, '/'); | |
+ if (!executableName) | |
+ return false; | |
+ | |
+ // Move past the slash. | |
+ executableName++; | |
+ | |
+ if (strcmp(executableName, "Microsoft Document Connection")) | |
+ return false; | |
+ | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wdeprecated-declarations" | |
+ // Apply the workaround if the application was linked against an SDK prior to where | |
+ // libxml2 v2.9 was present. | |
+ return dyld_get_program_sdk_version() < DYLD_MACOSX_VERSION_10_9; | |
+#pragma clang diagnostic pop | |
+} | |
+ | |
+static bool startElementNSNeedsUndeclaredPrefixQuirk(void) | |
+{ | |
+ static bool needsQuirk; | |
+ static dispatch_once_t hasEvaluatedQuirk; | |
+ dispatch_once(&hasEvaluatedQuirk, ^{ | |
+ needsQuirk = evaluateStartElementNSNeedsUndeclaredPrefixQuirk(); | |
+ }); | |
+ | |
+ return needsQuirk; | |
+} | |
+ | |
+#endif /* __APPLE__ */ | |
+ | |
/** | |
* xmlSAX2StartElementNs: | |
* @ctx: the user data (XML parser context) | |
@@ -2212,6 +2268,9 @@ | |
ctxt->validate = 0; | |
} | |
+#ifdef __APPLE__ | |
+ if (!startElementNSNeedsUndeclaredPrefixQuirk()) { | |
+#endif | |
/* | |
* Take care of the rare case of an undefined namespace prefix | |
*/ | |
@@ -2226,6 +2285,9 @@ | |
lname = xmlBuildQName(localname, prefix, NULL, 0); | |
} | |
} | |
+#ifdef __APPLE__ | |
+ } | |
+#endif | |
/* | |
* allocate the node | |
*/ | |
@@ -2436,24 +2498,15 @@ | |
const xmlChar * URI ATTRIBUTE_UNUSED) | |
{ | |
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; | |
- xmlParserNodeInfo node_info; | |
- xmlNodePtr cur; | |
if (ctx == NULL) return; | |
- cur = ctxt->node; | |
- /* Capture end position and add node */ | |
- if ((ctxt->record_info) && (cur != NULL)) { | |
- node_info.end_pos = ctxt->input->cur - ctxt->input->base; | |
- node_info.end_line = ctxt->input->line; | |
- node_info.node = cur; | |
- xmlParserAddNodeInfo(ctxt, &node_info); | |
- } | |
ctxt->nodemem = -1; | |
#ifdef LIBXML_VALID_ENABLED | |
if (ctxt->validate && ctxt->wellFormed && | |
ctxt->myDoc && ctxt->myDoc->intSubset) | |
- ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, cur); | |
+ ctxt->valid &= xmlValidateOneElement(&ctxt->vctxt, ctxt->myDoc, | |
+ ctxt->node); | |
#endif /* LIBXML_VALID_ENABLED */ | |
/* | |
@@ -2576,22 +2629,23 @@ | |
xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: xmlStrdup returned NULL"); | |
return; | |
} | |
- if (((size_t)ctxt->nodelen + (size_t)len > XML_MAX_TEXT_LENGTH) && | |
+ if (ctxt->nodelen > INT_MAX - len) { | |
+ xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters overflow prevented"); | |
+ return; | |
+ } | |
+ if ((ctxt->nodelen + len > XML_MAX_TEXT_LENGTH) && | |
((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: huge text node"); | |
return; | |
} | |
- if ((size_t)ctxt->nodelen > SIZE_T_MAX - (size_t)len || | |
- (size_t)ctxt->nodemem + (size_t)len > SIZE_T_MAX / 2) { | |
- xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters overflow prevented"); | |
- return; | |
- } | |
if (ctxt->nodelen + len >= ctxt->nodemem) { | |
xmlChar *newbuf; | |
- size_t size; | |
+ int size; | |
- size = ctxt->nodemem + len; | |
- size *= 2; | |
+ size = ctxt->nodemem > INT_MAX - len ? | |
+ INT_MAX : | |
+ ctxt->nodemem + len; | |
+ size = size > INT_MAX / 2 ? INT_MAX : size * 2; | |
newbuf = (xmlChar *) xmlRealloc(lastChild->content,size); | |
if (newbuf == NULL) { | |
xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters"); | |
diff -ru libxml2/buf.c libxml2-apple/libxml2/buf.c | |
--- libxml2/buf.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/buf.c 2025-06-26 01:54:56 | |
@@ -30,6 +30,10 @@ | |
#include <libxml/parserInternals.h> /* for XML_MAX_TEXT_LENGTH */ | |
#include "buf.h" | |
+#ifndef SIZE_MAX | |
+#define SIZE_MAX ((size_t) -1) | |
+#endif | |
+ | |
#define WITH_BUFFER_COMPAT | |
/** | |
@@ -127,12 +131,11 @@ | |
xmlBufMemoryError(NULL, "creating buffer"); | |
return(NULL); | |
} | |
- ret->compat_use = 0; | |
ret->use = 0; | |
ret->error = 0; | |
ret->buffer = NULL; | |
ret->size = xmlDefaultBufferSize; | |
- ret->compat_size = xmlDefaultBufferSize; | |
+ UPDATE_COMPAT(ret); | |
ret->alloc = xmlBufferAllocScheme; | |
ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar)); | |
if (ret->content == NULL) { | |
@@ -140,7 +143,7 @@ | |
xmlFree(ret); | |
return(NULL); | |
} | |
- ret->content[0] = 0; | |
+ memset(ret->content, 0, (ret->size * sizeof(xmlChar))); | |
ret->contentIO = NULL; | |
return(ret); | |
} | |
@@ -156,18 +159,19 @@ | |
xmlBufCreateSize(size_t size) { | |
xmlBufPtr ret; | |
+ if (size == SIZE_MAX) | |
+ return(NULL); | |
ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf)); | |
if (ret == NULL) { | |
xmlBufMemoryError(NULL, "creating buffer"); | |
return(NULL); | |
} | |
- ret->compat_use = 0; | |
ret->use = 0; | |
ret->error = 0; | |
ret->buffer = NULL; | |
ret->alloc = xmlBufferAllocScheme; | |
- ret->size = (size ? size+2 : 0); /* +1 for ending null */ | |
- ret->compat_size = (int) ret->size; | |
+ ret->size = (size ? size + 1 : 0); /* +1 for ending null */ | |
+ UPDATE_COMPAT(ret); | |
if (ret->size){ | |
ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar)); | |
if (ret->content == NULL) { | |
@@ -175,7 +179,7 @@ | |
xmlFree(ret); | |
return(NULL); | |
} | |
- ret->content[0] = 0; | |
+ memset(ret->content, 0, (ret->size * sizeof(xmlChar))); | |
} else | |
ret->content = NULL; | |
ret->contentIO = NULL; | |
@@ -209,8 +213,7 @@ | |
buf->content = NULL; | |
buf->size = 0; | |
buf->use = 0; | |
- buf->compat_use = 0; | |
- buf->compat_size = 0; | |
+ UPDATE_COMPAT(buf); | |
return ret; | |
} | |
@@ -239,17 +242,19 @@ | |
xmlBufMemoryError(NULL, "creating buffer"); | |
return(NULL); | |
} | |
- if (size < INT_MAX) { | |
- ret->compat_use = size; | |
- ret->compat_size = size; | |
- } else { | |
- ret->compat_use = INT_MAX; | |
- ret->compat_size = INT_MAX; | |
- } | |
ret->use = size; | |
ret->size = size; | |
+ UPDATE_COMPAT(ret); | |
ret->alloc = XML_BUFFER_ALLOC_IMMUTABLE; | |
ret->content = (xmlChar *) mem; | |
+#if !defined(NDEBUG) && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) | |
+ /* Enable NUL terminator check on Debug builds when not fuzzing. */ | |
+ if (size != 0 && ret->content[size-1] != 0 && ret->content[size] != 0) { | |
+ xmlBufMemoryError(NULL, "buffer missing NUL terminator"); | |
+ xmlFree(ret); | |
+ return(NULL); | |
+ } | |
+#endif | |
ret->error = 0; | |
ret->buffer = NULL; | |
return(ret); | |
@@ -442,29 +447,27 @@ | |
CHECK_COMPAT(buf) | |
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0); | |
- if (buf->use + len < buf->size) | |
- return(buf->size - buf->use); | |
+ if (len < buf->size - buf->use) { | |
+ buf->content[buf->use + len] = 0; | |
+ return(buf->size - buf->use - 1); | |
+ } | |
+ if (len > SIZE_MAX - buf->use - 1) { | |
+ xmlBufMemoryError(buf, "growing buffer past SIZE_MAX"); | |
+ return(0); | |
+ } | |
- /* | |
- * Windows has a BIG problem on realloc timing, so we try to double | |
- * the buffer size (if that's enough) (bug 146697) | |
- * Apparently BSD too, and it's probably best for linux too | |
- * On an embedded system this may be something to change | |
- */ | |
-#if 1 | |
- if (buf->size > (size_t) len) | |
- size = buf->size * 2; | |
- else | |
- size = buf->use + len + 100; | |
-#else | |
- size = buf->use + len + 100; | |
-#endif | |
+ if (buf->size > (size_t) len) { | |
+ size = buf->size > SIZE_MAX / 2 ? SIZE_MAX : buf->size * 2; | |
+ } else { | |
+ size = buf->use + len; | |
+ size = size > SIZE_MAX - 100 ? SIZE_MAX : size + 100; | |
+ } | |
if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) { | |
/* | |
* Used to provide parsing limits | |
*/ | |
- if ((buf->use + len >= XML_MAX_TEXT_LENGTH) || | |
+ if ((buf->use + len + 1 >= XML_MAX_TEXT_LENGTH) || | |
(buf->size >= XML_MAX_TEXT_LENGTH)) { | |
xmlBufMemoryError(buf, "buffer error: text too long\n"); | |
return(0); | |
@@ -491,8 +494,10 @@ | |
buf->content = newbuf; | |
} | |
buf->size = size; | |
+ buf->content[buf->use] = 0; | |
+ buf->content[buf->use + len] = 0; | |
UPDATE_COMPAT(buf) | |
- return(buf->size - buf->use); | |
+ return(buf->size - buf->use - 1); | |
} | |
/** | |
@@ -622,14 +627,11 @@ | |
if ((buf == NULL) || (buf->error)) | |
return(-1); | |
CHECK_COMPAT(buf) | |
- if (len > (buf->size - buf->use)) | |
+ if (len >= (buf->size - buf->use)) | |
return(-1); | |
buf->use += len; | |
+ buf->content[buf->use] = 0; | |
UPDATE_COMPAT(buf) | |
- if (buf->size > buf->use) | |
- buf->content[buf->use] = 0; | |
- else | |
- return(-1); | |
return(0); | |
} | |
@@ -711,7 +713,7 @@ | |
return 0; | |
CHECK_COMPAT(buf) | |
- return(buf->size - buf->use); | |
+ return((buf->size > buf->use) ? (buf->size - 1) - buf->use : 0); | |
} | |
/** | |
@@ -744,7 +746,7 @@ | |
int | |
xmlBufResize(xmlBufPtr buf, size_t size) | |
{ | |
- unsigned int newSize; | |
+ size_t newSize; | |
xmlChar* rebuf = NULL; | |
size_t start_buf; | |
@@ -772,9 +774,13 @@ | |
case XML_BUFFER_ALLOC_IO: | |
case XML_BUFFER_ALLOC_DOUBLEIT: | |
/*take care of empty case*/ | |
- newSize = (buf->size ? buf->size*2 : size + 10); | |
+ if (buf->size == 0) { | |
+ newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10); | |
+ } else { | |
+ newSize = buf->size; | |
+ } | |
while (size > newSize) { | |
- if (newSize > UINT_MAX / 2) { | |
+ if (newSize > SIZE_MAX / 2) { | |
xmlBufMemoryError(buf, "growing buffer"); | |
return 0; | |
} | |
@@ -782,15 +788,15 @@ | |
} | |
break; | |
case XML_BUFFER_ALLOC_EXACT: | |
- newSize = size+10; | |
+ newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10); | |
break; | |
case XML_BUFFER_ALLOC_HYBRID: | |
if (buf->use < BASE_BUFFER_SIZE) | |
newSize = size; | |
else { | |
- newSize = buf->size * 2; | |
+ newSize = buf->size; | |
while (size > newSize) { | |
- if (newSize > UINT_MAX / 2) { | |
+ if (newSize > SIZE_MAX / 2) { | |
xmlBufMemoryError(buf, "growing buffer"); | |
return 0; | |
} | |
@@ -800,7 +806,7 @@ | |
break; | |
default: | |
- newSize = size+10; | |
+ newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10); | |
break; | |
} | |
@@ -811,7 +817,6 @@ | |
/* move data back to start */ | |
memmove(buf->contentIO, buf->content, buf->use); | |
buf->content = buf->contentIO; | |
- buf->content[buf->use] = 0; | |
buf->size += start_buf; | |
} else { | |
rebuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + newSize); | |
@@ -837,7 +842,6 @@ | |
if (rebuf != NULL) { | |
memcpy(rebuf, buf->content, buf->use); | |
xmlFree(buf->content); | |
- rebuf[buf->use] = 0; | |
} | |
} | |
if (rebuf == NULL) { | |
@@ -847,6 +851,7 @@ | |
buf->content = rebuf; | |
} | |
buf->size = newSize; | |
+ buf->content[buf->use] = 0; | |
UPDATE_COMPAT(buf) | |
return 1; | |
@@ -866,7 +871,7 @@ | |
*/ | |
int | |
xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) { | |
- unsigned int needSize; | |
+ size_t needSize; | |
if ((str == NULL) || (buf == NULL) || (buf->error)) | |
return -1; | |
@@ -888,8 +893,13 @@ | |
if (len < 0) return -1; | |
if (len == 0) return 0; | |
- needSize = buf->use + len + 2; | |
- if (needSize > buf->size){ | |
+ /* Note that both buf->size and buf->use can be zero here. */ | |
+ if ((size_t) len >= buf->size - buf->use) { | |
+ if ((size_t) len >= SIZE_MAX - buf->use) { | |
+ xmlBufMemoryError(buf, "growing buffer past SIZE_MAX"); | |
+ return(-1); | |
+ } | |
+ needSize = buf->use + len + 1; | |
if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) { | |
/* | |
* Used to provide parsing limits | |
@@ -964,12 +974,18 @@ | |
memmove(&buf->content[0], str, len); | |
buf->use += len; | |
buf->size += len; | |
+ buf->content[buf->use] = 0; | |
UPDATE_COMPAT(buf) | |
return(0); | |
} | |
} | |
- needSize = buf->use + len + 2; | |
- if (needSize > buf->size){ | |
+ /* Note that both buf->size and buf->use can be zero here. */ | |
+ if ((unsigned) len >= buf->size - buf->use) { | |
+ if ((unsigned) len >= UINT_MAX - buf->use) { | |
+ xmlBufMemoryError(buf, "growing buffer past UINT_MAX"); | |
+ return(-1); | |
+ } | |
+ needSize = buf->use + len + 1; | |
if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) { | |
/* | |
* Used to provide parsing limits | |
@@ -1025,31 +1041,7 @@ | |
*/ | |
int | |
xmlBufCCat(xmlBufPtr buf, const char *str) { | |
- const char *cur; | |
- | |
- if ((buf == NULL) || (buf->error)) | |
- return(-1); | |
- CHECK_COMPAT(buf) | |
- if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1; | |
- if (str == NULL) { | |
-#ifdef DEBUG_BUFFER | |
- xmlGenericError(xmlGenericErrorContext, | |
- "xmlBufCCat: str == NULL\n"); | |
-#endif | |
- return -1; | |
- } | |
- for (cur = str;*cur != 0;cur++) { | |
- if (buf->use + 10 >= buf->size) { | |
- if (!xmlBufResize(buf, buf->use+10)){ | |
- xmlBufMemoryError(buf, "growing buffer"); | |
- return XML_ERR_NO_MEMORY; | |
- } | |
- } | |
- buf->content[buf->use++] = *cur; | |
- } | |
- buf->content[buf->use] = 0; | |
- UPDATE_COMPAT(buf) | |
- return 0; | |
+ return xmlBufCat(buf, (const xmlChar *) str); | |
} | |
/** | |
@@ -1177,8 +1169,7 @@ | |
} | |
ret->use = buffer->use; | |
ret->size = buffer->size; | |
- ret->compat_use = buffer->use; | |
- ret->compat_size = buffer->size; | |
+ UPDATE_COMPAT(ret); | |
ret->error = 0; | |
ret->buffer = buffer; | |
ret->alloc = buffer->alloc; | |
@@ -1207,12 +1198,19 @@ | |
if (buf == NULL) | |
return(NULL); | |
CHECK_COMPAT(buf) | |
- if ((buf->error) || (buf->buffer == NULL)) { | |
+ ret = buf->buffer; | |
+ | |
+ if ((buf->error) || (ret == NULL)) { | |
xmlBufFree(buf); | |
+ if (ret != NULL) { | |
+ ret->content = NULL; | |
+ ret->contentIO = NULL; | |
+ ret->use = 0; | |
+ ret->size = 0; | |
+ } | |
return(NULL); | |
} | |
- ret = buf->buffer; | |
/* | |
* What to do in case of error in the buffer ??? | |
*/ | |
@@ -1283,8 +1281,12 @@ | |
*/ | |
int | |
xmlBufResetInput(xmlBufPtr buf, xmlParserInputPtr input) { | |
- if ((input == NULL) || (buf == NULL) || (buf->error)) | |
+ if (input == NULL) | |
return(-1); | |
+ if ((buf == NULL) || (buf->error)) { | |
+ input->base = input->cur = input->end = BAD_CAST ""; | |
+ return(-1); | |
+ } | |
CHECK_COMPAT(buf) | |
input->base = input->cur = buf->content; | |
input->end = &buf->content[buf->use]; | |
@@ -1305,7 +1307,7 @@ | |
size_t base; | |
if ((input == NULL) || (buf == NULL) || (buf->error)) | |
- return(-1); | |
+ return(0); | |
CHECK_COMPAT(buf) | |
base = input->base - buf->content; | |
/* | |
diff -ru libxml2/catalog.c libxml2-apple/libxml2/catalog.c | |
--- libxml2/catalog.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/catalog.c 2025-06-26 01:54:56 | |
@@ -15,6 +15,16 @@ | |
#define IN_LIBXML | |
#include "libxml.h" | |
+#ifdef LIBXML_THREAD_ENABLED | |
+#ifdef HAVE_PTHREAD_H | |
+#include <pthread.h> | |
+#elif defined(HAVE_WIN32_THREADS) | |
+#include <windows.h> | |
+#elif defined(HAVE_BEOS_THREADS) | |
+#include <OS.h> | |
+#endif | |
+#endif | |
+ | |
#ifdef LIBXML_CATALOG_ENABLED | |
#ifdef HAVE_SYS_TYPES_H | |
#include <sys/types.h> | |
@@ -204,10 +214,23 @@ | |
static xmlRMutexPtr xmlCatalogMutex = NULL; | |
/* | |
- * Whether the catalog support was initialized. | |
+ * Initialize catalog mutex only once. | |
*/ | |
-static int xmlCatalogInitialized = 0; | |
+#ifdef LIBXML_THREAD_ENABLED | |
+#ifdef HAVE_PTHREAD_H | |
+static pthread_once_t once_control = PTHREAD_ONCE_INIT; | |
+#elif defined(HAVE_WIN32_THREADS) | |
+static struct { | |
+ DWORD done; | |
+ DWORD control; | |
+} run_once = {0, 0}; | |
+#elif defined(HAVE_BEOS_THREADS) | |
+static int32 run_once_init = 0; | |
+#endif | |
+#endif | |
+static void _xmlInitializeCatalogData(void); | |
+ | |
/************************************************************************ | |
* * | |
* Catalog error handlers * | |
@@ -243,11 +266,14 @@ | |
const char *msg, const xmlChar *str1, const xmlChar *str2, | |
const xmlChar *str3) | |
{ | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, catal, node, XML_FROM_CATALOG, | |
error, XML_ERR_ERROR, NULL, 0, | |
(const char *) str1, (const char *) str2, | |
(const char *) str3, 0, 0, | |
msg, str1, str2, str3); | |
+#pragma clang diagnostic pop | |
} | |
@@ -3084,32 +3110,65 @@ | |
* | |
* Do the catalog initialization only of global data, doesn't try to load | |
* any catalog actually. | |
- * this function is not thread safe, catalog initialization should | |
+ * this function is thread safe, but catalog initialization should | |
* preferably be done once at startup | |
*/ | |
static void | |
xmlInitializeCatalogData(void) { | |
- if (xmlCatalogInitialized != 0) | |
- return; | |
+ if (xmlCatalogMutex) | |
+ return; | |
+#ifdef LIBXML_THREAD_ENABLED | |
+#ifdef HAVE_PTHREAD_H | |
+ pthread_once(&once_control, _xmlInitializeCatalogData); | |
+#elif defined(HAVE_WIN32_THREADS) | |
+ if (!run_once.done) { | |
+ if (InterlockedIncrement(&run_once.control) == 1) { | |
+ _xmlInitializeCatalogData(); | |
+ run_once.done = 1; | |
+ } else { | |
+ /* Another thread is working; give up our slice and | |
+ * wait until they're done. */ | |
+ while (!run_once.done) | |
+ Sleep(0); | |
+ } | |
+ } | |
+#elif defined(HAVE_BEOS_THREADS) | |
+ if (atomic_add(&run_once_init, 1) == 0) | |
+ _xmlInitializeCatalogData(); | |
+ else | |
+ atomic_add(&run_once_init, -1); | |
+#endif | |
+#else | |
+ _xmlInitializeCatalogData(); | |
+#endif | |
+} | |
+ | |
+/* | |
+ * _xmlInitializeCatalogData | |
+ * | |
+ * This function is not public. | |
+ * Called exactly once to initialize global xmlCatalogMutex and | |
+ * xmlDebugCatalogs. | |
+ */ | |
+static void _xmlInitializeCatalogData(void) | |
+{ | |
if (getenv("XML_DEBUG_CATALOG")) | |
xmlDebugCatalogs = 1; | |
- xmlCatalogMutex = xmlNewRMutex(); | |
- xmlCatalogInitialized = 1; | |
+ xmlCatalogMutex = xmlNewRMutex(); | |
} | |
+ | |
/** | |
* xmlInitializeCatalog: | |
* | |
* Do the catalog initialization. | |
- * this function is not thread safe, catalog initialization should | |
- * preferably be done once at startup | |
+ * This function is thread safe, but will only set up the | |
+ * default catalog once the first time it is called when | |
+ * LIBXML_THREAD_ENABLED is set. | |
*/ | |
void | |
xmlInitializeCatalog(void) { | |
- if (xmlCatalogInitialized != 0) | |
- return; | |
- | |
xmlInitializeCatalogData(); | |
xmlRMutexLock(xmlCatalogMutex); | |
@@ -3204,7 +3263,7 @@ | |
int ret; | |
xmlCatalogPtr catal; | |
- if (!xmlCatalogInitialized) | |
+ if (!xmlCatalogMutex) | |
xmlInitializeCatalogData(); | |
xmlRMutexLock(xmlCatalogMutex); | |
@@ -3277,10 +3336,12 @@ | |
* xmlCatalogCleanup: | |
* | |
* Free up all the memory associated with catalogs | |
+ * Does not free the catalog mutex if LIBXML_THREAD_ENABLED is | |
+ * set since that can not be done safely. | |
*/ | |
void | |
xmlCatalogCleanup(void) { | |
- if (xmlCatalogInitialized == 0) | |
+ if (!xmlCatalogMutex) | |
return; | |
xmlRMutexLock(xmlCatalogMutex); | |
@@ -3294,9 +3355,11 @@ | |
xmlFreeCatalog(xmlDefaultCatalog); | |
xmlDefaultCatalog = NULL; | |
xmlDebugCatalogs = 0; | |
- xmlCatalogInitialized = 0; | |
xmlRMutexUnlock(xmlCatalogMutex); | |
+#ifndef LIBXML_THREAD_ENABLED | |
xmlFreeRMutex(xmlCatalogMutex); | |
+ xmlCatalogMutex = NULL; | |
+#endif | |
} | |
/** | |
@@ -3312,7 +3375,7 @@ | |
xmlCatalogResolveSystem(const xmlChar *sysID) { | |
xmlChar *ret; | |
- if (!xmlCatalogInitialized) | |
+ if (!xmlCatalogMutex) | |
xmlInitializeCatalog(); | |
ret = xmlACatalogResolveSystem(xmlDefaultCatalog, sysID); | |
@@ -3332,7 +3395,7 @@ | |
xmlCatalogResolvePublic(const xmlChar *pubID) { | |
xmlChar *ret; | |
- if (!xmlCatalogInitialized) | |
+ if (!xmlCatalogMutex) | |
xmlInitializeCatalog(); | |
ret = xmlACatalogResolvePublic(xmlDefaultCatalog, pubID); | |
@@ -3353,7 +3416,7 @@ | |
xmlCatalogResolve(const xmlChar *pubID, const xmlChar *sysID) { | |
xmlChar *ret; | |
- if (!xmlCatalogInitialized) | |
+ if (!xmlCatalogMutex) | |
xmlInitializeCatalog(); | |
ret = xmlACatalogResolve(xmlDefaultCatalog, pubID, sysID); | |
@@ -3373,7 +3436,7 @@ | |
xmlCatalogResolveURI(const xmlChar *URI) { | |
xmlChar *ret; | |
- if (!xmlCatalogInitialized) | |
+ if (!xmlCatalogMutex) | |
xmlInitializeCatalog(); | |
ret = xmlACatalogResolveURI(xmlDefaultCatalog, URI); | |
@@ -3392,7 +3455,7 @@ | |
if (out == NULL) | |
return; | |
- if (!xmlCatalogInitialized) | |
+ if (!xmlCatalogMutex) | |
xmlInitializeCatalog(); | |
xmlACatalogDump(xmlDefaultCatalog, out); | |
@@ -3416,7 +3479,7 @@ | |
xmlCatalogAdd(const xmlChar *type, const xmlChar *orig, const xmlChar *replace) { | |
int res = -1; | |
- if (!xmlCatalogInitialized) | |
+ if (!xmlCatalogMutex) | |
xmlInitializeCatalogData(); | |
xmlRMutexLock(xmlCatalogMutex); | |
@@ -3453,7 +3516,7 @@ | |
xmlCatalogRemove(const xmlChar *value) { | |
int res; | |
- if (!xmlCatalogInitialized) | |
+ if (!xmlCatalogMutex) | |
xmlInitializeCatalog(); | |
xmlRMutexLock(xmlCatalogMutex); | |
@@ -3473,7 +3536,7 @@ | |
xmlCatalogConvert(void) { | |
int res = -1; | |
- if (!xmlCatalogInitialized) | |
+ if (!xmlCatalogMutex) | |
xmlInitializeCatalog(); | |
xmlRMutexLock(xmlCatalogMutex); | |
@@ -3604,7 +3667,7 @@ | |
xmlCatalogFreeLocal(void *catalogs) { | |
xmlCatalogEntryPtr catal; | |
- if (!xmlCatalogInitialized) | |
+ if (!xmlCatalogMutex) | |
xmlInitializeCatalog(); | |
catal = (xmlCatalogEntryPtr) catalogs; | |
@@ -3626,7 +3689,7 @@ | |
xmlCatalogAddLocal(void *catalogs, const xmlChar *URL) { | |
xmlCatalogEntryPtr catal, add; | |
- if (!xmlCatalogInitialized) | |
+ if (!xmlCatalogMutex) | |
xmlInitializeCatalog(); | |
if (URL == NULL) | |
@@ -3669,7 +3732,7 @@ | |
xmlCatalogEntryPtr catal; | |
xmlChar *ret; | |
- if (!xmlCatalogInitialized) | |
+ if (!xmlCatalogMutex) | |
xmlInitializeCatalog(); | |
if ((pubID == NULL) && (sysID == NULL)) | |
@@ -3713,7 +3776,7 @@ | |
xmlCatalogEntryPtr catal; | |
xmlChar *ret; | |
- if (!xmlCatalogInitialized) | |
+ if (!xmlCatalogMutex) | |
xmlInitializeCatalog(); | |
if (URI == NULL) | |
@@ -3752,7 +3815,7 @@ | |
static xmlChar result[1000]; | |
static int msg = 0; | |
- if (!xmlCatalogInitialized) | |
+ if (!xmlCatalogMutex) | |
xmlInitializeCatalog(); | |
if (msg == 0) { | |
@@ -3796,7 +3859,7 @@ | |
static xmlChar result[1000]; | |
static int msg = 0; | |
- if (!xmlCatalogInitialized) | |
+ if (!xmlCatalogMutex) | |
xmlInitializeCatalog(); | |
if (msg == 0) { | |
Only in libxml2-apple/libxml2: config.h.in | |
diff -ru libxml2/configure.ac libxml2-apple/libxml2/configure.ac | |
--- libxml2/configure.ac 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/configure.ac 2025-06-26 01:54:56 | |
@@ -63,6 +63,15 @@ | |
LT_INIT | |
+dnl #ifdef __APPLE__ | |
+dnl Disable -Wl,-undefined -Wl,dynamic_lookup when using libtool to link. | |
+case $host_os in | |
+ darwin*) | |
+ allow_undefined_flag= | |
+ ;; | |
+esac | |
+dnl #endif // defined(__APPLE__) | |
+ | |
dnl | |
dnl if the system support linker version scripts for symbol versioning | |
dnl then add it | |
@@ -126,6 +135,8 @@ | |
[ --with-iso8859x add ISO8859X support if no iconv (on)]) | |
AC_ARG_WITH(legacy, | |
[ --with-legacy add deprecated APIs for compatibility (on)]) | |
+AC_ARG_WITH(fuzzers, | |
+[ --with-fuzzers[[=LIB]] build libxml2 fuzzers (optionally using libFuzzer.a or AFL) (on)]) | |
AC_ARG_WITH(mem_debug, | |
[ --with-mem-debug add the memory debugging module (off)]) | |
AC_ARG_WITH(minimum, | |
@@ -177,6 +188,8 @@ | |
[ --with-xpath add the XPATH support (on)]) | |
AC_ARG_WITH(xptr, | |
[ --with-xptr add the XPointer support (on)]) | |
+AC_ARG_WITH(xptr-locs, | |
+[ --with-xptr-locs add support for XPointer locations (off)]) | |
AC_ARG_WITH(modules, | |
[ --with-modules add the dynamic modules support (on)]) | |
AC_ARG_WITH(zlib, | |
@@ -223,6 +236,10 @@ | |
then | |
with_push=yes | |
fi | |
+if test "$with_xptr_locs" = "yes" | |
+then | |
+ with_xptr=yes | |
+fi | |
if test "$with_xptr" = "yes" | |
then | |
with_xpath=yes | |
@@ -282,6 +299,10 @@ | |
then | |
with_legacy=no | |
fi | |
+ if test "$with_fuzzers" = "" | |
+ then | |
+ with_fuzzers=yes | |
+ fi | |
if test "$with_mem_debug" = "" | |
then | |
with_mem_debug=no | |
@@ -795,6 +816,67 @@ | |
dnl | |
+dnl Check for libFuzzer.a | |
+dnl | |
+ | |
+AC_PROG_CXX | |
+AC_LANG_SAVE | |
+AC_LANG_CPLUSPLUS | |
+dnl If not found, download these macros to a local ./m4/ directory: | |
+dnl https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html | |
+dnl https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html | |
+AX_CXX_COMPILE_STDCXX_11([noext], [mandatory]) | |
+ | |
+if test "$with_fuzzers" = "" | |
+then | |
+ with_fuzzers=yes | |
+fi | |
+ | |
+if test "$with_fuzzers" != "no" -a "$with_fuzzers" != "yes" | |
+then | |
+ AC_MSG_CHECKING(for fuzzing library) | |
+ _libs="${LIBS}" | |
+ LIBS="${LIBS} ${with_fuzzers}" | |
+ AC_TRY_LINK([ | |
+#include <stddef.h> | |
+#if defined(HAVE_STDINT_H) | |
+#include <stdint.h> | |
+#elif defined(HAVE_INTTYPES_H) | |
+#include <inttypes.h> | |
+#elif defined(WIN32) | |
+typedef unsigned char uint8_t; | |
+#endif | |
+int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);],[ | |
+ return 0; } /* main */ | |
+int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {],[ | |
+ AC_MSG_RESULT(yes) | |
+ LIBS="${_libs}"],[ | |
+ with_fuzzers=no | |
+ AC_MSG_RESULT(no) | |
+ LIBS="${_libs}"]) | |
+ | |
+fi | |
+ | |
+AC_LANG_RESTORE | |
+ | |
+if test "$with_fuzzers" = "yes" | |
+then | |
+ FUZZ_SUBDIR=fuzz | |
+ LIB_FUZZING_ENGINE= | |
+elif test "$with_fuzzers" != "no" | |
+then | |
+ FUZZ_SUBDIR=fuzz | |
+ LIB_FUZZING_ENGINE="${with_fuzzers}" | |
+else | |
+ FUZZ_SUBDIR= | |
+ LIB_FUZZING_ENGINE= | |
+fi | |
+AC_SUBST(FUZZ_SUBDIR) | |
+AC_SUBST(LIB_FUZZING_ENGINE) | |
+AM_CONDITIONAL(USE_STANDALONE_FUZZING_ENGINE, test "$with_fuzzers" = "yes") | |
+ | |
+ | |
+dnl | |
dnl check for python | |
dnl | |
@@ -1234,7 +1316,7 @@ | |
else | |
WITH_HTML=1 | |
HTML_OBJ="HTMLparser.o HTMLtree.o" | |
- TEST_HTML=HTMLtests | |
+ TEST_HTML="HTMLtests HTMLRecovertests" | |
if test "$with_push" != "no" ; then | |
TEST_PHTML=HTMLPushtests | |
else | |
@@ -1289,6 +1371,7 @@ | |
if test "$with_xptr" = "no" ; then | |
echo Disabling XPointer support | |
WITH_XPTR=0 | |
+ WITH_XPTR_LOCS=0 | |
XPTR_OBJ= | |
TEST_XPTR= | |
else | |
@@ -1299,8 +1382,14 @@ | |
echo XPointer requires XPath support - enabling it | |
with_xpath=yes | |
fi | |
+ if test "$with_xptr_locs" = "yes" ; then | |
+ WITH_XPTR_LOCS=1 | |
+ else | |
+ WITH_XPTR_LOCS=0 | |
+ fi | |
fi | |
AC_SUBST(WITH_XPTR) | |
+AC_SUBST(WITH_XPTR_LOCS) | |
AC_SUBST(XPTR_OBJ) | |
AC_SUBST(TEST_XPTR) | |
diff -ru libxml2/debugXML.c libxml2-apple/libxml2/debugXML.c | |
--- libxml2/debugXML.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/debugXML.c 2025-06-26 01:54:56 | |
@@ -168,21 +168,27 @@ | |
xmlDebugErr2(xmlDebugCtxtPtr ctxt, int error, const char *msg, int extra) | |
{ | |
ctxt->errors++; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, | |
NULL, ctxt->node, XML_FROM_CHECK, | |
error, XML_ERR_ERROR, NULL, 0, | |
NULL, NULL, NULL, 0, 0, | |
msg, extra); | |
+#pragma clang diagnostic pop | |
} | |
static void LIBXML_ATTR_FORMAT(3,0) | |
xmlDebugErr3(xmlDebugCtxtPtr ctxt, int error, const char *msg, const char *extra) | |
{ | |
ctxt->errors++; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, | |
NULL, ctxt->node, XML_FROM_CHECK, | |
error, XML_ERR_ERROR, NULL, 0, | |
NULL, NULL, NULL, 0, 0, | |
msg, extra); | |
+#pragma clang diagnostic pop | |
} | |
/** | |
@@ -1850,6 +1856,7 @@ | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a string\n", arg); | |
break; | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a point\n", arg); | |
@@ -1862,6 +1869,7 @@ | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a range\n", arg); | |
break; | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
case XPATH_USERS: | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is user-defined\n", arg); | |
@@ -2641,7 +2649,7 @@ | |
int res = -1; | |
if ((ctxt == NULL) || (ctxt->doc == NULL)) return(-1); | |
- vctxt.userData = NULL; | |
+ memset(&vctxt, 0, sizeof(vctxt)); | |
vctxt.error = xmlGenericError; | |
vctxt.warning = xmlGenericError; | |
@@ -3008,6 +3016,7 @@ | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a string\n", arg); | |
break; | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a point\n", arg); | |
@@ -3020,6 +3029,7 @@ | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a range\n", arg); | |
break; | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
case XPATH_USERS: | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is user-defined\n", arg); | |
@@ -3125,6 +3135,7 @@ | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a string\n", arg); | |
break; | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a point\n", arg); | |
@@ -3137,6 +3148,7 @@ | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a range\n", arg); | |
break; | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
case XPATH_USERS: | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is user-defined\n", arg); | |
@@ -3202,6 +3214,7 @@ | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a string\n", arg); | |
break; | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a point\n", arg); | |
@@ -3214,6 +3227,7 @@ | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a range\n", arg); | |
break; | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
case XPATH_USERS: | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is user-defined\n", arg); | |
@@ -3287,6 +3301,7 @@ | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a string\n", arg); | |
break; | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a point\n", arg); | |
@@ -3299,6 +3314,7 @@ | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a range\n", arg); | |
break; | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
case XPATH_USERS: | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is user-defined\n", arg); | |
@@ -3365,6 +3381,7 @@ | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a string\n", arg); | |
break; | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a point\n", arg); | |
@@ -3377,6 +3394,7 @@ | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is a range\n", arg); | |
break; | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
case XPATH_USERS: | |
xmlGenericError(xmlGenericErrorContext, | |
"%s is user-defined\n", arg); | |
diff -ru libxml2/dict.c libxml2-apple/libxml2/dict.c | |
--- libxml2/dict.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/dict.c 2025-06-26 01:54:56 | |
@@ -27,6 +27,16 @@ | |
#include <time.h> | |
#endif | |
+#ifdef LIBXML_THREAD_ENABLED | |
+#ifdef HAVE_PTHREAD_H | |
+#include <pthread.h> | |
+#elif defined(HAVE_WIN32_THREADS) | |
+#include <windows.h> | |
+#elif defined(HAVE_BEOS_THREADS) | |
+#include <OS.h> | |
+#endif | |
+#endif | |
+ | |
/* | |
* Following http://www.ocert.org/advisories/ocert-2011-003.html | |
* it seems that having hash randomization might be a good idea | |
@@ -135,9 +145,20 @@ | |
static xmlRMutexPtr xmlDictMutex = NULL; | |
/* | |
- * Whether the dictionary mutex was initialized. | |
+ * Initialize dictionary mutex only once. | |
*/ | |
-static int xmlDictInitialized = 0; | |
+#ifdef LIBXML_THREAD_ENABLED | |
+#ifdef HAVE_PTHREAD_H | |
+static pthread_once_t once_control = PTHREAD_ONCE_INIT; | |
+#elif defined(HAVE_WIN32_THREADS) | |
+static struct { | |
+ DWORD done; | |
+ DWORD control; | |
+} run_once = {0, 0}; | |
+#elif defined(HAVE_BEOS_THREADS) | |
+static int32 run_once_init = 0; | |
+#endif | |
+#endif | |
#ifdef DICT_RANDOMIZATION | |
#ifdef HAVE_RAND_R | |
@@ -162,23 +183,15 @@ | |
} | |
/** | |
- * __xmlInitializeDict: | |
+ * _xmlInitializeDictMutex: | |
* | |
- * This function is not public | |
- * Do the dictionary mutex initialization. | |
- * this function is not thread safe, initialization should | |
- * normally be done once at setup when called from xmlOnceInit() | |
- * we may also land in this code if thread support is not compiled in | |
- * | |
- * Returns 0 if initialization was already done, and 1 if that | |
- * call led to the initialization | |
+ * This function is not public. | |
+ * Called exactly once to initialize global xmlDictMutex and | |
+ * to seed psuedo-random number generator. | |
*/ | |
-int __xmlInitializeDict(void) { | |
- if (xmlDictInitialized) | |
- return(1); | |
+static void _xmlInitializeDictMutex(void) { | |
+ xmlDictMutex = xmlNewRMutex(); | |
- if ((xmlDictMutex = xmlNewRMutex()) == NULL) | |
- return(0); | |
xmlRMutexLock(xmlDictMutex); | |
#ifdef DICT_RANDOMIZATION | |
@@ -189,16 +202,58 @@ | |
srand(time(NULL)); | |
#endif | |
#endif | |
- xmlDictInitialized = 1; | |
+ | |
xmlRMutexUnlock(xmlDictMutex); | |
- return(1); | |
} | |
+/** | |
+ * __xmlInitializeDict: | |
+ * | |
+ * This function is not public | |
+ * Do the dictionary mutex initialization. | |
+ * this function is not thread safe, initialization should | |
+ * normally be done once at setup when called from xmlOnceInit() | |
+ * we may also land in this code if thread support is not compiled in | |
+ * | |
+ * Returns 0 if initialization failed, else returns 1. | |
+ */ | |
+int __xmlInitializeDict(void) { | |
+ if (xmlDictMutex) | |
+ return(1); | |
+ | |
+#ifdef LIBXML_THREAD_ENABLED | |
+#ifdef HAVE_PTHREAD_H | |
+ pthread_once(&once_control, _xmlInitializeDictMutex); | |
+#elif defined(HAVE_WIN32_THREADS) | |
+ if (!run_once.done) { | |
+ if (InterlockedIncrement(&run_once.control) == 1) { | |
+ _xmlInitializeDictMutex(); | |
+ run_once.done = 1; | |
+ } else { | |
+ /* Another thread is working; give up our slice and | |
+ * wait until they're done. */ | |
+ while (!run_once.done) | |
+ Sleep(0); | |
+ } | |
+ } | |
+#elif defined(HAVE_BEOS_THREADS) | |
+ if (atomic_add(&run_once_init, 1) == 0) | |
+ _xmlInitializeDictMutex(); | |
+ else | |
+ atomic_add(&run_once_init, -1); | |
+#endif | |
+#else | |
+ _xmlInitializeDictMutex(); | |
+#endif | |
+ | |
+ return(xmlDictMutex != NULL); | |
+} | |
+ | |
#ifdef DICT_RANDOMIZATION | |
int __xmlRandom(void) { | |
int ret; | |
- if (xmlDictInitialized == 0) | |
+ if (!xmlDictMutex) | |
__xmlInitializeDict(); | |
xmlRMutexLock(xmlDictMutex); | |
@@ -217,15 +272,18 @@ | |
* | |
* Free the dictionary mutex. Do not call unless sure the library | |
* is not in use anymore ! | |
+ * Does nothing when LIBXML_THREAD_ENABLED is set since the | |
+ * dictionary mutex can not be freed safely. | |
*/ | |
void | |
xmlDictCleanup(void) { | |
- if (!xmlDictInitialized) | |
+#ifndef LIBXML_THREAD_ENABLED | |
+ if (!xmlDictMutex) | |
return; | |
xmlFreeRMutex(xmlDictMutex); | |
- | |
- xmlDictInitialized = 0; | |
+ xmlDictMutex = NULL; | |
+#endif | |
} | |
/* | |
@@ -384,7 +442,7 @@ | |
hash = seed; | |
- for (i = 0;i < namelen; i++) { | |
+ for (i = 0; i < namelen; i++) { | |
hash += data[i]; | |
hash += (hash << 10); | |
hash ^= (hash >> 6); | |
@@ -451,7 +509,8 @@ | |
xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) { | |
unsigned long value = seed; | |
- if (name == NULL) return(0); | |
+ if ((name == NULL) || (namelen <= 0)) | |
+ return(value); | |
value += *name; | |
value <<= 5; | |
if (namelen > 10) { | |
@@ -575,7 +634,7 @@ | |
xmlDictCreate(void) { | |
xmlDictPtr dict; | |
- if (!xmlDictInitialized) | |
+ if (!xmlDictMutex) | |
if (!__xmlInitializeDict()) | |
return(NULL); | |
@@ -643,7 +702,7 @@ | |
*/ | |
int | |
xmlDictReference(xmlDictPtr dict) { | |
- if (!xmlDictInitialized) | |
+ if (!xmlDictMutex) | |
if (!__xmlInitializeDict()) | |
return(-1); | |
@@ -807,7 +866,7 @@ | |
if (dict == NULL) | |
return; | |
- if (!xmlDictInitialized) | |
+ if (!xmlDictMutex) | |
if (!__xmlInitializeDict()) | |
return; | |
@@ -867,7 +926,7 @@ | |
xmlDictEntryPtr entry; | |
xmlDictEntryPtr insert; | |
const xmlChar *ret; | |
- unsigned int l; | |
+ size_t l; | |
if ((dict == NULL) || (name == NULL)) | |
return(NULL); | |
@@ -1005,7 +1064,7 @@ | |
xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) { | |
unsigned long key, okey, nbi = 0; | |
xmlDictEntryPtr insert; | |
- unsigned int l; | |
+ size_t l; | |
if ((dict == NULL) || (name == NULL)) | |
return(NULL); | |
@@ -1115,7 +1174,7 @@ | |
xmlDictEntryPtr entry; | |
xmlDictEntryPtr insert; | |
const xmlChar *ret; | |
- unsigned int len, plen, l; | |
+ size_t len, plen, l; | |
if ((dict == NULL) || (name == NULL)) | |
return(NULL); | |
@@ -1124,6 +1183,8 @@ | |
l = len = strlen((const char *) name); | |
plen = strlen((const char *) prefix); | |
+ if ((len > INT_MAX / 2) || (plen > INT_MAX / 2)) | |
+ return(NULL); | |
len += 1 + plen; | |
/* | |
diff -ru libxml2/doc/examples/tree2.c libxml2-apple/libxml2/doc/examples/tree2.c | |
--- libxml2/doc/examples/tree2.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/doc/examples/tree2.c 2025-06-26 01:54:56 | |
@@ -27,7 +27,8 @@ | |
{ | |
xmlDocPtr doc = NULL; /* document pointer */ | |
xmlNodePtr root_node = NULL, node = NULL, node1 = NULL;/* node pointers */ | |
- char buff[256]; | |
+ const size_t buffLength = 256; | |
+ char buff[buffLength]; | |
int i, j; | |
LIBXML_TEST_VERSION; | |
@@ -80,10 +81,10 @@ | |
* A simple loop that "automates" nodes creation | |
*/ | |
for (i = 5; i < 7; i++) { | |
- sprintf(buff, "node%d", i); | |
+ snprintf(buff, buffLength, "node%d", i); | |
node = xmlNewChild(root_node, NULL, BAD_CAST buff, NULL); | |
for (j = 1; j < 4; j++) { | |
- sprintf(buff, "node%d%d", i, j); | |
+ snprintf(buff, buffLength, "node%d%d", i, j); | |
node1 = xmlNewChild(node, NULL, BAD_CAST buff, NULL); | |
xmlNewProp(node1, BAD_CAST "odd", BAD_CAST((j % 2) ? "no" : "yes")); | |
} | |
diff -ru libxml2/doc/libxml2-api.xml libxml2-apple/libxml2/doc/libxml2-api.xml | |
--- libxml2/doc/libxml2-api.xml 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/doc/libxml2-api.xml 2025-06-26 01:54:56 | |
@@ -4489,6 +4489,12 @@ | |
<macro name='XML_XPATH_NOVAR' file='xpath'> | |
<info>forbid variables in expression</info> | |
</macro> | |
+ <macro name='XPATH_LOCATIONSET' file='xpath'> | |
+ </macro> | |
+ <macro name='XPATH_POINT' file='xpath'> | |
+ </macro> | |
+ <macro name='XPATH_RANGE' file='xpath'> | |
+ </macro> | |
<macro name='XP_ERROR' file='xpathInternals'> | |
<info>Macro to raise an XPath error and return.</info> | |
<arg name='X' info='the error code'/> | |
@@ -18396,7 +18402,7 @@ | |
<arg name='no' type='int' info='the error number'/> | |
</function> | |
<function name='xmlXPtrBuildNodeList' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Build a node list tree copy of the XPointer result. This will drop Attributes and Namespace declarations.</info> | |
<return type='xmlNodePtr' info='an xmlNodePtr list or NULL. the caller has to free the node tree.'/> | |
<arg name='obj' type='xmlXPathObjectPtr' info='the XPointer result from the evaluation.'/> | |
@@ -18409,53 +18415,53 @@ | |
<arg name='ctx' type='xmlXPathContextPtr' info='the XPointer context'/> | |
</function> | |
<function name='xmlXPtrEvalRangePredicate' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>[8] Predicate ::= '[' PredicateExpr ']' [9] PredicateExpr ::= Expr Evaluate a predicate as in xmlXPathEvalPredicate() but for a Location Set instead of a node set</info> | |
<return type='void'/> | |
<arg name='ctxt' type='xmlXPathParserContextPtr' info='the XPointer Parser context'/> | |
</function> | |
<function name='xmlXPtrFreeLocationSet' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Free the LocationSet compound (not the actual ranges !).</info> | |
<return type='void'/> | |
<arg name='obj' type='xmlLocationSetPtr' info='the xmlLocationSetPtr to free'/> | |
</function> | |
<function name='xmlXPtrLocationSetAdd' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>add a new xmlXPathObjectPtr to an existing LocationSet If the location already exist in the set @val is freed.</info> | |
<return type='void'/> | |
<arg name='cur' type='xmlLocationSetPtr' info='the initial range set'/> | |
<arg name='val' type='xmlXPathObjectPtr' info='a new xmlXPathObjectPtr'/> | |
</function> | |
<function name='xmlXPtrLocationSetCreate' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Create a new xmlLocationSetPtr of type double and of value @val</info> | |
<return type='xmlLocationSetPtr' info='the newly created object.'/> | |
<arg name='val' type='xmlXPathObjectPtr' info='an initial xmlXPathObjectPtr, or NULL'/> | |
</function> | |
<function name='xmlXPtrLocationSetDel' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Removes an xmlXPathObjectPtr from an existing LocationSet</info> | |
<return type='void'/> | |
<arg name='cur' type='xmlLocationSetPtr' info='the initial range set'/> | |
<arg name='val' type='xmlXPathObjectPtr' info='an xmlXPathObjectPtr'/> | |
</function> | |
<function name='xmlXPtrLocationSetMerge' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Merges two rangesets, all ranges from @val2 are added to @val1</info> | |
<return type='xmlLocationSetPtr' info='val1 once extended or NULL in case of error.'/> | |
<arg name='val1' type='xmlLocationSetPtr' info='the first LocationSet'/> | |
<arg name='val2' type='xmlLocationSetPtr' info='the second LocationSet'/> | |
</function> | |
<function name='xmlXPtrLocationSetRemove' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Removes an entry from an existing LocationSet list.</info> | |
<return type='void'/> | |
<arg name='cur' type='xmlLocationSetPtr' info='the initial range set'/> | |
<arg name='val' type='int' info='the index to remove'/> | |
</function> | |
<function name='xmlXPtrNewCollapsedRange' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Create a new xmlXPathObjectPtr of type range using a single nodes</info> | |
<return type='xmlXPathObjectPtr' info='the newly created object.'/> | |
<arg name='start' type='xmlNodePtr' info='the starting and ending node'/> | |
@@ -18469,20 +18475,20 @@ | |
<arg name='origin' type='xmlNodePtr' info='the element from which a user or program initiated traversal of the link, or NULL.'/> | |
</function> | |
<function name='xmlXPtrNewLocationSetNodeSet' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Create a new xmlXPathObjectPtr of type LocationSet and initialize it with all the nodes from @set</info> | |
<return type='xmlXPathObjectPtr' info='the newly created object.'/> | |
<arg name='set' type='xmlNodeSetPtr' info='a node set'/> | |
</function> | |
<function name='xmlXPtrNewLocationSetNodes' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Create a new xmlXPathObjectPtr of type LocationSet and initialize it with the single range made of the two nodes @start and @end</info> | |
<return type='xmlXPathObjectPtr' info='the newly created object.'/> | |
<arg name='start' type='xmlNodePtr' info='the start NodePtr value'/> | |
<arg name='end' type='xmlNodePtr' info='the end NodePtr value or NULL'/> | |
</function> | |
<function name='xmlXPtrNewRange' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Create a new xmlXPathObjectPtr of type range</info> | |
<return type='xmlXPathObjectPtr' info='the newly created object.'/> | |
<arg name='start' type='xmlNodePtr' info='the starting node'/> | |
@@ -18491,49 +18497,49 @@ | |
<arg name='endindex' type='int' info='the ending index'/> | |
</function> | |
<function name='xmlXPtrNewRangeNodeObject' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Create a new xmlXPathObjectPtr of type range from a not to an object</info> | |
<return type='xmlXPathObjectPtr' info='the newly created object.'/> | |
<arg name='start' type='xmlNodePtr' info='the starting node'/> | |
<arg name='end' type='xmlXPathObjectPtr' info='the ending object'/> | |
</function> | |
<function name='xmlXPtrNewRangeNodePoint' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Create a new xmlXPathObjectPtr of type range from a node to a point</info> | |
<return type='xmlXPathObjectPtr' info='the newly created object.'/> | |
<arg name='start' type='xmlNodePtr' info='the starting node'/> | |
<arg name='end' type='xmlXPathObjectPtr' info='the ending point'/> | |
</function> | |
<function name='xmlXPtrNewRangeNodes' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Create a new xmlXPathObjectPtr of type range using 2 nodes</info> | |
<return type='xmlXPathObjectPtr' info='the newly created object.'/> | |
<arg name='start' type='xmlNodePtr' info='the starting node'/> | |
<arg name='end' type='xmlNodePtr' info='the ending node'/> | |
</function> | |
<function name='xmlXPtrNewRangePointNode' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Create a new xmlXPathObjectPtr of type range from a point to a node</info> | |
<return type='xmlXPathObjectPtr' info='the newly created object.'/> | |
<arg name='start' type='xmlXPathObjectPtr' info='the starting point'/> | |
<arg name='end' type='xmlNodePtr' info='the ending node'/> | |
</function> | |
<function name='xmlXPtrNewRangePoints' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Create a new xmlXPathObjectPtr of type range using 2 Points</info> | |
<return type='xmlXPathObjectPtr' info='the newly created object.'/> | |
<arg name='start' type='xmlXPathObjectPtr' info='the starting point'/> | |
<arg name='end' type='xmlXPathObjectPtr' info='the ending point'/> | |
</function> | |
<function name='xmlXPtrRangeToFunction' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Implement the range-to() XPointer function Obsolete. range-to is not a real function but a special type of location step which is handled in xpath.c.</info> | |
<return type='void'/> | |
<arg name='ctxt' type='xmlXPathParserContextPtr' info='the XPointer Parser context'/> | |
<arg name='nargs' type='int' info='the number of args'/> | |
</function> | |
<function name='xmlXPtrWrapLocationSet' file='xpointer' module='xpointer'> | |
- <cond>defined(LIBXML_XPTR_ENABLED)</cond> | |
+ <cond>defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED)</cond> | |
<info>Wrap the LocationSet @val in a new xmlXPathObjectPtr</info> | |
<return type='xmlXPathObjectPtr' info='the newly created object.'/> | |
<arg name='val' type='xmlLocationSetPtr' info='the LocationSet value'/> | |
diff -ru libxml2/encoding.c libxml2-apple/libxml2/encoding.c | |
--- libxml2/encoding.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/encoding.c 2025-06-26 01:54:56 | |
@@ -45,9 +45,17 @@ | |
#include <libxml/globals.h> | |
#include <libxml/xmlerror.h> | |
+#ifdef LIBXML_ICU_ENABLED | |
+#include <unicode/ucnv.h> | |
+#endif | |
+ | |
#include "buf.h" | |
#include "enc.h" | |
+#ifdef __APPLE__ | |
+#include "xmlversionInternal.h" | |
+#endif | |
+ | |
static xmlCharEncodingHandlerPtr xmlUTF16LEHandler = NULL; | |
static xmlCharEncodingHandlerPtr xmlUTF16BEHandler = NULL; | |
@@ -96,9 +104,12 @@ | |
static void LIBXML_ATTR_FORMAT(2,0) | |
xmlEncodingErr(xmlParserErrors error, const char *msg, const char *val) | |
{ | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, NULL, NULL, | |
XML_FROM_I18N, error, XML_ERR_FATAL, | |
NULL, 0, val, NULL, NULL, 0, 0, msg, val); | |
+#pragma clang diagnostic pop | |
} | |
#ifdef LIBXML_ICU_ENABLED | |
@@ -110,8 +121,12 @@ | |
if (conv == NULL) | |
return NULL; | |
- conv->pivot_source = conv->pivot_buf; | |
- conv->pivot_target = conv->pivot_buf; | |
+#ifdef LIBXML_HAS_ICU_PIVOT_BUFFER | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ conv->pivot_source = conv->pivot_buf; | |
+ conv->pivot_target = conv->pivot_buf; | |
+ } | |
+#endif /* LIBXML_HAS_ICU_PIVOT_BUFFER */ | |
conv->uconv = ucnv_open(name, &status); | |
if (U_FAILURE(status)) | |
@@ -193,7 +208,7 @@ | |
} else { | |
*outlen = out - outstart; | |
*inlen = processed - base; | |
- return(-1); | |
+ return(-2); | |
} | |
processed = (const unsigned char*) in; | |
@@ -1899,23 +1914,45 @@ | |
if (toUnicode) { | |
/* encoding => UTF-16 => UTF-8 */ | |
- ucnv_convertEx(cd->utf8, cd->uconv, &ucv_out, ucv_out + *outlen, | |
- &ucv_in, ucv_in + *inlen, cd->pivot_buf, | |
- &cd->pivot_source, &cd->pivot_target, | |
- cd->pivot_buf + ICU_PIVOT_BUF_SIZE, 0, flush, &err); | |
+#ifdef LIBXML_HAS_ICU_PIVOT_BUFFER | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ ucnv_convertEx(cd->utf8, cd->uconv, &ucv_out, ucv_out + *outlen, | |
+ &ucv_in, ucv_in + *inlen, cd->pivot_buf, | |
+ &cd->pivot_source, &cd->pivot_target, | |
+ cd->pivot_buf + ICU_PIVOT_BUF_SIZE, 0, flush, &err); | |
+ } else | |
+#endif /* LIBXML_HAS_ICU_PIVOT_BUFFER */ | |
+ { | |
+ ucnv_convertEx(cd->utf8, cd->uconv, &ucv_out, ucv_out + *outlen, | |
+ &ucv_in, ucv_in + *inlen, NULL, NULL, NULL, NULL, | |
+ 0, TRUE, &err); | |
+ } | |
} else { | |
/* UTF-8 => UTF-16 => encoding */ | |
- ucnv_convertEx(cd->uconv, cd->utf8, &ucv_out, ucv_out + *outlen, | |
- &ucv_in, ucv_in + *inlen, cd->pivot_buf, | |
- &cd->pivot_source, &cd->pivot_target, | |
- cd->pivot_buf + ICU_PIVOT_BUF_SIZE, 0, flush, &err); | |
+#ifdef LIBXML_HAS_ICU_PIVOT_BUFFER | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ ucnv_convertEx(cd->uconv, cd->utf8, &ucv_out, ucv_out + *outlen, | |
+ &ucv_in, ucv_in + *inlen, cd->pivot_buf, | |
+ &cd->pivot_source, &cd->pivot_target, | |
+ cd->pivot_buf + ICU_PIVOT_BUF_SIZE, 0, flush, &err); | |
+ } else | |
+#endif /* LIBXML_HAS_ICU_PIVOT_BUFFER */ | |
+ { | |
+ ucnv_convertEx(cd->uconv, cd->utf8, &ucv_out, ucv_out + *outlen, | |
+ &ucv_in, ucv_in + *inlen, NULL, NULL, NULL, NULL, | |
+ 0, TRUE, &err); | |
+ } | |
} | |
*inlen = ucv_in - (const char*) in; | |
*outlen = ucv_out - (char *) out; | |
if (U_SUCCESS(err)) { | |
- /* reset pivot buf if this is the last call for input (flush==TRUE) */ | |
- if (flush) | |
- cd->pivot_source = cd->pivot_target = cd->pivot_buf; | |
+#ifdef LIBXML_HAS_ICU_PIVOT_BUFFER | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ /* reset pivot buf if this is the last call for input (flush==TRUE) */ | |
+ if (flush) | |
+ cd->pivot_source = cd->pivot_target = cd->pivot_buf; | |
+ } | |
+#endif /* LIBXML_HAS_ICU_PIVOT_BUFFER */ | |
return 0; | |
} | |
if (err == U_BUFFER_OVERFLOW_ERROR) | |
@@ -2173,7 +2210,7 @@ | |
toconv = xmlBufUse(in); | |
if (toconv == 0) | |
return (0); | |
- written = xmlBufAvail(out) - 1; /* count '\0' */ | |
+ written = xmlBufAvail(out); | |
/* | |
* echo '<?xml version="1.0" encoding="UCS4"?>' | wc -c => 38 | |
* 45 chars should be sufficient to reach the end of the encoding | |
@@ -2191,7 +2228,7 @@ | |
} | |
if (toconv * 2 >= written) { | |
xmlBufGrow(out, toconv * 2); | |
- written = xmlBufAvail(out) - 1; | |
+ written = xmlBufAvail(out); | |
} | |
if (written > 360) | |
written = 360; | |
@@ -2283,13 +2320,9 @@ | |
if ((toconv > 64 * 1024) && (flush == 0)) | |
toconv = 64 * 1024; | |
written = xmlBufAvail(out); | |
- if (written > 0) | |
- written--; /* count '\0' */ | |
if (toconv * 2 >= written) { | |
xmlBufGrow(out, toconv * 2); | |
written = xmlBufAvail(out); | |
- if (written > 0) | |
- written--; /* count '\0' */ | |
} | |
if ((written > 128 * 1024) && (flush == 0)) | |
written = 128 * 1024; | |
@@ -2343,7 +2376,7 @@ | |
*/ | |
if (ret == -3) | |
ret = 0; | |
- return (c_out? c_out : ret); | |
+ return ((ret < 0) ? ret : c_out); | |
} | |
/** | |
@@ -2471,8 +2504,6 @@ | |
retry: | |
written = xmlBufAvail(out); | |
- if (written > 0) | |
- written--; /* count '\0' */ | |
/* | |
* First specific handling of the initialization call | |
@@ -2501,7 +2532,7 @@ | |
toconv = 64 * 1024; | |
if (toconv * 4 >= written) { | |
xmlBufGrow(out, toconv * 4); | |
- written = xmlBufAvail(out) - 1; | |
+ written = xmlBufAvail(out); | |
} | |
if (written > 256 * 1024) | |
written = 256 * 1024; | |
@@ -2576,7 +2607,7 @@ | |
"&#%d;", cur); | |
xmlBufShrink(in, len); | |
xmlBufGrow(out, charrefLen * 4); | |
- c_out = xmlBufAvail(out) - 1; | |
+ c_out = xmlBufAvail(out); | |
c_in = charrefLen; | |
ret = xmlEncOutputChunk(output->encoder, xmlBufEnd(out), &c_out, | |
charref, &c_in); | |
diff -ru libxml2/entities.c libxml2-apple/libxml2/entities.c | |
--- libxml2/entities.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/entities.c 2025-06-26 01:54:56 | |
@@ -112,36 +112,19 @@ | |
if ((entity->children) && (entity->owner == 1) && | |
(entity == (xmlEntityPtr) entity->children->parent)) | |
xmlFreeNodeList(entity->children); | |
- if (dict != NULL) { | |
- if ((entity->name != NULL) && (!xmlDictOwns(dict, entity->name))) | |
- xmlFree((char *) entity->name); | |
- if ((entity->ExternalID != NULL) && | |
- (!xmlDictOwns(dict, entity->ExternalID))) | |
- xmlFree((char *) entity->ExternalID); | |
- if ((entity->SystemID != NULL) && | |
- (!xmlDictOwns(dict, entity->SystemID))) | |
- xmlFree((char *) entity->SystemID); | |
- if ((entity->URI != NULL) && (!xmlDictOwns(dict, entity->URI))) | |
- xmlFree((char *) entity->URI); | |
- if ((entity->content != NULL) | |
- && (!xmlDictOwns(dict, entity->content))) | |
- xmlFree((char *) entity->content); | |
- if ((entity->orig != NULL) && (!xmlDictOwns(dict, entity->orig))) | |
- xmlFree((char *) entity->orig); | |
- } else { | |
- if (entity->name != NULL) | |
- xmlFree((char *) entity->name); | |
- if (entity->ExternalID != NULL) | |
- xmlFree((char *) entity->ExternalID); | |
- if (entity->SystemID != NULL) | |
- xmlFree((char *) entity->SystemID); | |
- if (entity->URI != NULL) | |
- xmlFree((char *) entity->URI); | |
- if (entity->content != NULL) | |
- xmlFree((char *) entity->content); | |
- if (entity->orig != NULL) | |
- xmlFree((char *) entity->orig); | |
- } | |
+ if ((entity->name != NULL) && | |
+ ((dict == NULL) || (!xmlDictOwns(dict, entity->name)))) | |
+ xmlFree((char *) entity->name); | |
+ if (entity->ExternalID != NULL) | |
+ xmlFree((char *) entity->ExternalID); | |
+ if (entity->SystemID != NULL) | |
+ xmlFree((char *) entity->SystemID); | |
+ if (entity->URI != NULL) | |
+ xmlFree((char *) entity->URI); | |
+ if (entity->content != NULL) | |
+ xmlFree((char *) entity->content); | |
+ if (entity->orig != NULL) | |
+ xmlFree((char *) entity->orig); | |
xmlFree(entity); | |
} | |
@@ -177,18 +160,12 @@ | |
ret->SystemID = xmlStrdup(SystemID); | |
} else { | |
ret->name = xmlDictLookup(dict, name, -1); | |
- if (ExternalID != NULL) | |
- ret->ExternalID = xmlDictLookup(dict, ExternalID, -1); | |
- if (SystemID != NULL) | |
- ret->SystemID = xmlDictLookup(dict, SystemID, -1); | |
+ ret->ExternalID = xmlStrdup(ExternalID); | |
+ ret->SystemID = xmlStrdup(SystemID); | |
} | |
if (content != NULL) { | |
ret->length = xmlStrlen(content); | |
- if ((dict != NULL) && (ret->length < 5)) | |
- ret->content = (xmlChar *) | |
- xmlDictLookup(dict, content, ret->length); | |
- else | |
- ret->content = xmlStrndup(content, ret->length); | |
+ ret->content = xmlStrndup(content, ret->length); | |
} else { | |
ret->length = 0; | |
ret->content = NULL; | |
diff -ru libxml2/error.c libxml2-apple/libxml2/error.c | |
--- libxml2/error.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/error.c 2025-06-26 01:54:56 | |
@@ -663,9 +663,12 @@ | |
XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL, | |
NULL, NULL, 0, 0, "Memory allocation failed\n"); | |
} else { | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, NULL, node, domain, | |
code, XML_ERR_ERROR, NULL, 0, extra, | |
NULL, NULL, 0, 0, msg, extra); | |
+#pragma clang diagnostic pop | |
} | |
} | |
/** | |
Only in libxml2/fuzz: .gitignore | |
diff -ru libxml2/fuzz/Makefile.am libxml2-apple/libxml2/fuzz/Makefile.am | |
--- libxml2/fuzz/Makefile.am 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/fuzz/Makefile.am 2025-06-26 01:54:56 | |
@@ -1,7 +1,8 @@ | |
AUTOMAKE_OPTIONS = -Wno-syntax | |
-EXTRA_PROGRAMS = genSeed html regexp schema uri xml xpath | |
+EXTRA_PROGRAMS = genSeed html reader regexp schema uri xml xpath | |
check_PROGRAMS = testFuzzer | |
-EXTRA_DIST = html.dict regexp.dict schema.dict xml.dict xpath.dict \ | |
+EXTRA_DIST = html.dict reader.dict regexp.dict schema.dict xml.dict xpath.dict \ | |
+ html.options reader.options regexp.options schema.options uri.options xml.options xpath.options \ | |
static_seed/uri static_seed/regexp fuzz.h | |
CLEANFILES = $(EXTRA_PROGRAMS) | |
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include | |
@@ -25,8 +26,8 @@ | |
.PHONY: tests corpus clean-corpus | |
-corpus: seed/html.stamp seed/regexp.stamp seed/schema.stamp seed/uri.stamp \ | |
- seed/xml.stamp seed/xpath.stamp | |
+corpus: seed/html.stamp seed/reader.stamp seed/regexp.stamp seed/schema.stamp \ | |
+ seed/uri.stamp seed/xml.stamp seed/xpath.stamp | |
tests: testFuzzer$(EXEEXT) corpus | |
@echo "## Running fuzzer tests" | |
@@ -76,6 +77,24 @@ | |
-max_len=1000000 \ | |
-timeout=10 \ | |
corpus/html seed/html | |
+ | |
+# Reader fuzzer | |
+ | |
+seed/reader.stamp: genSeed$(EXEEXT) | |
+ @mkdir -p seed/reader | |
+ ./genSeed$(EXEEXT) reader $(XML_SEED_CORPUS_SRC) | |
+ @touch seed/reader.stamp | |
+ | |
+reader_SOURCES = reader.c fuzz.c | |
+reader_LDFLAGS = -fsanitize=fuzzer | |
+ | |
+fuzz-reader: reader$(EXEEXT) seed/reader.stamp | |
+ @mkdir -p corpus/reader | |
+ ./reader$(EXEEXT) \ | |
+ -dict=reader.dict \ | |
+ -max_len=$(XML_MAX_LEN) \ | |
+ -timeout=20 \ | |
+ corpus/reader seed/reader | |
# Regexp fuzzer | |
diff -ru libxml2/fuzz/fuzz.c libxml2-apple/libxml2/fuzz/fuzz.c | |
--- libxml2/fuzz/fuzz.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/fuzz/fuzz.c 2025-06-26 01:54:56 | |
@@ -27,6 +27,9 @@ | |
const char *data; | |
size_t size; | |
+ /* Hash of data */ | |
+ unsigned long hash; | |
+ | |
/* Remaining data */ | |
const char *ptr; | |
size_t remaining; | |
@@ -52,6 +55,19 @@ | |
...) { | |
} | |
+static unsigned long dataHash(const char *data, size_t size) { | |
+ unsigned long value = 0L; | |
+ size_t i; | |
+ | |
+ value += 30 * (*data); | |
+ for (i = 0; i < size; ++i) { | |
+ char ch = data[i]; | |
+ value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); | |
+ } | |
+ | |
+ return value; | |
+} | |
+ | |
/** | |
* xmlFuzzDataInit: | |
* | |
@@ -61,6 +77,9 @@ | |
xmlFuzzDataInit(const char *data, size_t size) { | |
fuzzData.data = data; | |
fuzzData.size = size; | |
+ | |
+ fuzzData.hash = dataHash(data, size); | |
+ | |
fuzzData.ptr = data; | |
fuzzData.remaining = size; | |
@@ -72,6 +91,11 @@ | |
fuzzData.mainEntity = NULL; | |
} | |
+unsigned long | |
+xmlFuzzDataHash(void) { | |
+ return fuzzData.hash; | |
+} | |
+ | |
/** | |
* xmlFuzzDataFree: | |
* | |
@@ -84,13 +108,52 @@ | |
} | |
/** | |
+ * xmlFuzzReadBytes: | |
+ * @size: size of buffer in bytes | |
+ * @stopByte: stop value | |
+ * | |
+ * Read a random-length buffer from the fuzz data. | |
+ * | |
+ * The format is similar to libFuzzer's FuzzedDataProvider but treats | |
+ * @stopByte as the end of the buffer. | |
+ * | |
+ * Returns a buffer of length @size or NULL if the fuzz data is exhausted. | |
+ */ | |
+const char * | |
+xmlFuzzReadBytes(size_t *size, char stopByte) { | |
+ const char *out = fuzzData.outPtr; | |
+ | |
+ while (fuzzData.remaining > 0) { | |
+ int c = *fuzzData.ptr++; | |
+ fuzzData.remaining--; | |
+ | |
+ if ((c == stopByte) && (fuzzData.remaining > 0)) { | |
+ fuzzData.ptr++; | |
+ fuzzData.remaining--; | |
+ *size = fuzzData.outPtr - out; | |
+ return(out); | |
+ } | |
+ | |
+ *fuzzData.outPtr++ = c; | |
+ } | |
+ | |
+ if (fuzzData.outPtr > out) { | |
+ *size = fuzzData.outPtr - out; | |
+ return(out); | |
+ } | |
+ | |
+ *size = 0; | |
+ return(NULL); | |
+} | |
+ | |
+/** | |
* xmlFuzzReadInt: | |
* @size: size of string in bytes | |
* | |
* Read an integer from the fuzz data. | |
*/ | |
int | |
-xmlFuzzReadInt() { | |
+xmlFuzzReadInt(void) { | |
int ret; | |
if (fuzzData.remaining < sizeof(int)) | |
@@ -325,6 +388,18 @@ | |
return(ret); | |
} | |
+static unsigned int _rndSeed; | |
+ | |
+unsigned int | |
+xmlFuzzRnd(void) { | |
+ return _rndSeed = (unsigned int)((_rndSeed * 48271UL) % 2147483647UL); /* C++ std::minstd_rand */ | |
+} | |
+ | |
+void | |
+xmlFuzzRndSetSeed(unsigned int seed) { | |
+ _rndSeed = seed; | |
+} | |
+ | |
char * | |
xmlSlurpFile(const char *path, size_t *sizeRet) { | |
FILE *file; | |
@@ -353,4 +428,3 @@ | |
return(data); | |
} | |
- | |
diff -ru libxml2/fuzz/fuzz.h libxml2-apple/libxml2/fuzz/fuzz.h | |
--- libxml2/fuzz/fuzz.h 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/fuzz/fuzz.h 2025-06-26 01:54:56 | |
@@ -11,6 +11,9 @@ | |
#include <stdio.h> | |
#include <libxml/parser.h> | |
+#define xmlMin(a, b) ((a) < (b) ? (a) : (b)) | |
+#define xmlMax(a, b) ((a) > (b) ? (a) : (b)) | |
+ | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
@@ -18,6 +21,9 @@ | |
#if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_OUTPUT_ENABLED) | |
#define HAVE_HTML_FUZZER | |
#endif | |
+#if defined(LIBXML_READER_ENABLED) | |
+ #define HAVE_READER_FUZZER | |
+#endif | |
#if defined(LIBXML_REGEXP_ENABLED) | |
#define HAVE_REGEXP_FUZZER | |
#endif | |
@@ -49,9 +55,15 @@ | |
void | |
xmlFuzzDataInit(const char *data, size_t size); | |
+unsigned long | |
+xmlFuzzDataHash(void); | |
+ | |
void | |
xmlFuzzDataCleanup(void); | |
+const char * | |
+xmlFuzzReadBytes(size_t *size, char stopByte); | |
+ | |
int | |
xmlFuzzReadInt(void); | |
@@ -79,6 +91,12 @@ | |
size_t | |
xmlFuzzExtractStrings(const char *data, size_t size, char **strings, | |
size_t numStrings); | |
+ | |
+unsigned int | |
+xmlFuzzRnd(void); | |
+ | |
+void | |
+xmlFuzzRndSetSeed(unsigned int seed); | |
char * | |
xmlSlurpFile(const char *path, size_t *size); | |
diff -ru libxml2/fuzz/genSeed.c libxml2-apple/libxml2/fuzz/genSeed.c | |
--- libxml2/fuzz/genSeed.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/fuzz/genSeed.c 2025-06-26 01:54:56 | |
@@ -102,7 +102,7 @@ | |
globalData.oldLoader = NULL; | |
} | |
-#ifdef HAVE_XML_FUZZER | |
+#if defined(HAVE_READER_FUZZER) || defined(HAVE_XML_FUZZER) | |
static int | |
processXml(const char *docFile, FILE *out) { | |
int opts = XML_PARSE_NOENT | XML_PARSE_DTDLOAD; | |
@@ -392,6 +392,11 @@ | |
#ifdef HAVE_HTML_FUZZER | |
processArg = processPattern; | |
globalData.processFile = processHtml; | |
+#endif | |
+ } else if (strcmp(fuzzer, "reader") == 0) { | |
+#ifdef HAVE_READER_FUZZER | |
+ processArg = processPattern; | |
+ globalData.processFile = processXml; | |
#endif | |
} else if (strcmp(fuzzer, "schema") == 0) { | |
#ifdef HAVE_SCHEMA_FUZZER | |
diff -ru libxml2/fuzz/html.c libxml2-apple/libxml2/fuzz/html.c | |
--- libxml2/fuzz/html.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/fuzz/html.c 2025-06-26 01:54:56 | |
@@ -9,6 +9,24 @@ | |
#include <libxml/catalog.h> | |
#include "fuzz.h" | |
+extern size_t LLVMFuzzerMutate(uint8_t *data, size_t size, size_t maxSize); | |
+extern size_t LLVMFuzzerCustomMutator(uint8_t *data, size_t size, size_t maxSize, unsigned int seed); | |
+ | |
+size_t | |
+LLVMFuzzerCustomMutator(uint8_t *data, size_t size, size_t maxSize, unsigned int seed) { | |
+ xmlFuzzRndSetSeed(seed); | |
+ | |
+ const size_t optionsSize = sizeof(int); | |
+ if (size < optionsSize) | |
+ return LLVMFuzzerMutate(data, size, maxSize); | |
+ | |
+ // Mutate libxml2 parsing options in first byte of input (10% chance). | |
+ if (xmlFuzzRnd() % 10 == 1) | |
+ *((int *)&data[0]) = (int)xmlFuzzRnd(); | |
+ | |
+ return optionsSize + LLVMFuzzerMutate(data + optionsSize, size - optionsSize, maxSize - optionsSize); | |
+} | |
+ | |
int | |
LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED, | |
char ***argv ATTRIBUTE_UNUSED) { | |
@@ -24,6 +42,7 @@ | |
int | |
LLVMFuzzerTestOneInput(const char *data, size_t size) { | |
static const size_t maxChunkSize = 128; | |
+ xmlCharEncoding encoding; | |
htmlDocPtr doc; | |
htmlParserCtxtPtr ctxt; | |
xmlOutputBufferPtr out; | |
@@ -32,7 +51,8 @@ | |
int opts, outSize; | |
xmlFuzzDataInit(data, size); | |
- opts = xmlFuzzReadInt(); | |
+ encoding = (xmlCharEncoding)(xmlFuzzDataHash() % 23); /* See <libxml/encoding.h>. */ | |
+ opts = xmlFuzzReadInt() | XML_PARSE_NONET; | |
docBuffer = xmlFuzzReadRemaining(&docSize); | |
if (docBuffer == NULL) { | |
@@ -42,7 +62,8 @@ | |
/* Pull parser */ | |
- doc = htmlReadMemory(docBuffer, docSize, NULL, NULL, opts); | |
+ /* Recovery mode allows more input to be fuzzed. */ | |
+ doc = htmlReadMemory(docBuffer, docSize, NULL, xmlGetCharEncodingName(encoding), opts | XML_PARSE_RECOVER); | |
/* | |
* Also test the serializer. Call htmlDocContentDumpOutput with our | |
@@ -57,8 +78,7 @@ | |
/* Push parser */ | |
- ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL, | |
- XML_CHAR_ENCODING_NONE); | |
+ ctxt = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL, encoding); | |
htmlCtxtUseOptions(ctxt, opts); | |
for (consumed = 0; consumed < docSize; consumed += chunkSize) { | |
diff -ru libxml2/fuzz/html.options libxml2-apple/libxml2/fuzz/html.options | |
--- libxml2/fuzz/html.options 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/fuzz/html.options 2025-06-26 01:54:56 | |
@@ -1,2 +1,3 @@ | |
[libfuzzer] | |
+dict = html.dict | |
timeout = 10 | |
Only in libxml2-apple/libxml2/fuzz: reader.c | |
Only in libxml2-apple/libxml2/fuzz: reader.options | |
diff -ru libxml2/fuzz/regexp.options libxml2-apple/libxml2/fuzz/regexp.options | |
--- libxml2/fuzz/regexp.options 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/fuzz/regexp.options 2025-06-26 01:54:56 | |
@@ -1,2 +1,3 @@ | |
[libfuzzer] | |
+dict = regexp.dict | |
timeout = 5 | |
diff -ru libxml2/fuzz/schema.options libxml2-apple/libxml2/fuzz/schema.options | |
--- libxml2/fuzz/schema.options 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/fuzz/schema.options 2025-06-26 01:54:56 | |
@@ -1,2 +1,3 @@ | |
[libfuzzer] | |
+dict = schema.dict | |
timeout = 20 | |
diff -ru libxml2/fuzz/testFuzzer.c libxml2-apple/libxml2/fuzz/testFuzzer.c | |
--- libxml2/fuzz/testFuzzer.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/fuzz/testFuzzer.c 2025-06-26 01:54:56 | |
@@ -12,14 +12,31 @@ | |
#include <libxml/xmlstring.h> | |
#include "fuzz.h" | |
+size_t | |
+LLVMFuzzerMutate(uint8_t *data, size_t size, size_t maxSize) { | |
+ return size; | |
+} | |
+ | |
#ifdef HAVE_HTML_FUZZER | |
+ #define LLVMFuzzerCustomMutator fuzzHtmlMutator | |
#define LLVMFuzzerInitialize fuzzHtmlInit | |
#define LLVMFuzzerTestOneInput fuzzHtml | |
#include "html.c" | |
+ #undef LLVMFuzzerCustomMutator | |
#undef LLVMFuzzerInitialize | |
#undef LLVMFuzzerTestOneInput | |
#endif | |
+#ifdef HAVE_READER_FUZZER | |
+ #define LLVMFuzzerCustomMutator fuzzReaderMutator | |
+ #define LLVMFuzzerInitialize fuzzReaderInit | |
+ #define LLVMFuzzerTestOneInput fuzzReader | |
+ #include "reader.c" | |
+ #undef LLVMFuzzerCustomMutator | |
+ #undef LLVMFuzzerInitialize | |
+ #undef LLVMFuzzerTestOneInput | |
+#endif | |
+ | |
#ifdef HAVE_REGEXP_FUZZER | |
#define LLVMFuzzerInitialize fuzzRegexpInit | |
#define LLVMFuzzerTestOneInput fuzzRegexp | |
@@ -45,17 +62,21 @@ | |
#endif | |
#ifdef HAVE_XML_FUZZER | |
+ #define LLVMFuzzerCustomMutator fuzzXmlMutator | |
#define LLVMFuzzerInitialize fuzzXmlInit | |
#define LLVMFuzzerTestOneInput fuzzXml | |
#include "xml.c" | |
+ #undef LLVMFuzzerCustomMutator | |
#undef LLVMFuzzerInitialize | |
#undef LLVMFuzzerTestOneInput | |
#endif | |
#ifdef HAVE_XPATH_FUZZER | |
+ #define LLVMFuzzerCustomMutator fuzzXPathMutator | |
#define LLVMFuzzerInitialize fuzzXPathInit | |
#define LLVMFuzzerTestOneInput fuzzXPath | |
#include "xpath.c" | |
+ #undef LLVMFuzzerCustomMutator | |
#undef LLVMFuzzerInitialize | |
#undef LLVMFuzzerTestOneInput | |
#endif | |
@@ -103,7 +124,7 @@ | |
return(ret); | |
} | |
-#ifdef HAVE_XML_FUZZER | |
+#if defined(HAVE_READER_FUZZER) || defined(HAVE_XML_FUZZER) | |
static int | |
testEntityLoader() { | |
static const char data[] = | |
@@ -151,12 +172,16 @@ | |
main() { | |
int ret = 0; | |
-#ifdef HAVE_XML_FUZZER | |
+#if defined(HAVE_READER_FUZZER) || defined(HAVE_XML_FUZZER) | |
if (testEntityLoader() != 0) | |
ret = 1; | |
#endif | |
#ifdef HAVE_HTML_FUZZER | |
if (testFuzzer(fuzzHtmlInit, fuzzHtml, "seed/html/*") != 0) | |
+ ret = 1; | |
+#endif | |
+#ifdef HAVE_READER_FUZZER | |
+ if (testFuzzer(fuzzReaderInit, fuzzReader, "seed/xml/*") != 0) | |
ret = 1; | |
#endif | |
#ifdef HAVE_REGEXP_FUZZER | |
Only in libxml2-apple/libxml2/fuzz: uri.dict | |
diff -ru libxml2/fuzz/uri.options libxml2-apple/libxml2/fuzz/uri.options | |
--- libxml2/fuzz/uri.options 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/fuzz/uri.options 2025-06-26 01:54:56 | |
@@ -1,2 +1,3 @@ | |
[libfuzzer] | |
+dict = uri.dict | |
timeout = 2 | |
diff -ru libxml2/fuzz/xml.c libxml2-apple/libxml2/fuzz/xml.c | |
--- libxml2/fuzz/xml.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/fuzz/xml.c 2025-06-26 01:54:56 | |
@@ -6,12 +6,73 @@ | |
#include <libxml/catalog.h> | |
#include <libxml/parser.h> | |
+#include <libxml/parserInternals.h> | |
#include <libxml/tree.h> | |
#include <libxml/xmlerror.h> | |
#include <libxml/xinclude.h> | |
#include <libxml/xmlreader.h> | |
#include "fuzz.h" | |
+static void errorCallback(void* ctx, const char* msg ATTRIBUTE_UNUSED, ...) { | |
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; | |
+ xmlErrorPtr error = xmlCtxtGetLastError(ctxt); | |
+ if (error != NULL && error->level == XML_ERR_FATAL) | |
+ xmlStopParser(ctxt); | |
+} | |
+ | |
+static xmlSAXHandler xmlSAXHandlerStruct = { | |
+ NULL, /* internalSubset */ | |
+ NULL, /* isStandalone */ | |
+ NULL, /* hasInternalSubset */ | |
+ NULL, /* hasExternalSubset */ | |
+ NULL, /* resolveEntity */ | |
+ NULL, /* getEntity */ | |
+ NULL, /* entityDecl */ | |
+ NULL, /* notationDecl */ | |
+ NULL, /* attributeDecl */ | |
+ NULL, /* elementDecl */ | |
+ NULL, /* unparsedEntityDecl */ | |
+ NULL, /* setDocumentLocator */ | |
+ NULL, /* startDocument */ | |
+ NULL, /* endDocument */ | |
+ NULL, /* startElement */ | |
+ NULL, /* endElement */ | |
+ NULL, /* reference */ | |
+ NULL, /* characters */ | |
+ NULL, /* ignorableWhitespace */ | |
+ NULL, /* processingInstruction */ | |
+ NULL, /* comment */ | |
+ NULL, /* warning */ | |
+ NULL, /* error */ | |
+ NULL, /* fatalError */ | |
+ NULL, /* getParameterEntity */ | |
+ NULL, /* cdataBlock; */ | |
+ NULL, /* externalSubset; */ | |
+ XML_SAX2_MAGIC, | |
+ NULL, /* _private (unused) */ | |
+ NULL, /* startElementNs */ | |
+ NULL, /* endElementNs */ | |
+ NULL /* serror */ | |
+}; | |
+ | |
+extern size_t LLVMFuzzerMutate(uint8_t *data, size_t size, size_t maxSize); | |
+extern size_t LLVMFuzzerCustomMutator(uint8_t *data, size_t size, size_t maxSize, unsigned int seed); | |
+ | |
+size_t | |
+LLVMFuzzerCustomMutator(uint8_t *data, size_t size, size_t maxSize, unsigned int seed) { | |
+ xmlFuzzRndSetSeed(seed); | |
+ | |
+ const size_t optionsSize = sizeof(int); | |
+ if (size < optionsSize) | |
+ return LLVMFuzzerMutate(data, size, maxSize); | |
+ | |
+ // Mutate libxml2 parsing options in first byte of input (10% chance). | |
+ if (xmlFuzzRnd() % 10 == 1) | |
+ *((int *)&data[0]) = (int)xmlFuzzRnd(); | |
+ | |
+ return optionsSize + LLVMFuzzerMutate(data + optionsSize, size - optionsSize, maxSize - optionsSize); | |
+} | |
+ | |
int | |
LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED, | |
char ***argv ATTRIBUTE_UNUSED) { | |
@@ -27,17 +88,20 @@ | |
int | |
LLVMFuzzerTestOneInput(const char *data, size_t size) { | |
- static const size_t maxChunkSize = 128; | |
xmlDocPtr doc; | |
+ xmlDocPtr preservedReaderDoc = NULL; | |
xmlParserCtxtPtr ctxt; | |
+ xmlParserInputBufferPtr inputBuffer; | |
xmlTextReaderPtr reader; | |
xmlChar *out; | |
const char *docBuffer, *docUrl; | |
- size_t maxSize, docSize, consumed, chunkSize; | |
+ size_t maxSize, docSize, consumed, initialChunkSize, chunkSize, maxChunkSize; | |
int opts, outSize; | |
+ xmlCharEncoding encoding; | |
xmlFuzzDataInit(data, size); | |
- opts = xmlFuzzReadInt(); | |
+ encoding = (xmlCharEncoding)(xmlFuzzDataHash() % 23); /* See <libxml/encoding.h>. */ | |
+ opts = xmlFuzzReadInt() | XML_PARSE_NONET; | |
/* Lower maximum size when processing entities for now. */ | |
maxSize = opts & XML_PARSE_NOENT ? 50000 : 500000; | |
@@ -50,9 +114,13 @@ | |
if (docBuffer == NULL) | |
goto exit; | |
+ initialChunkSize = xmlMin(xmlFuzzDataHash() % 5, docSize); | |
+ maxChunkSize = xmlMax(128, xmlMin(xmlFuzzDataHash() % 1024, docSize)); | |
+ | |
/* Pull parser */ | |
- doc = xmlReadMemory(docBuffer, docSize, docUrl, NULL, opts); | |
+ /* Recovery mode allows more input to be fuzzed. */ | |
+ doc = xmlReadMemory(docBuffer, docSize, docUrl, xmlGetCharEncodingName(encoding), opts | XML_PARSE_RECOVER); | |
if (opts & XML_PARSE_XINCLUDE) | |
xmlXIncludeProcessFlags(doc, opts); | |
/* Also test the serializer. */ | |
@@ -62,12 +130,12 @@ | |
/* Push parser */ | |
- ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, docUrl); | |
+ ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, initialChunkSize, docUrl); | |
if (ctxt == NULL) | |
goto exit; | |
xmlCtxtUseOptions(ctxt, opts); | |
- for (consumed = 0; consumed < docSize; consumed += chunkSize) { | |
+ for (consumed = initialChunkSize; consumed < docSize; consumed += chunkSize) { | |
chunkSize = docSize - consumed; | |
if (chunkSize > maxChunkSize) | |
chunkSize = maxChunkSize; | |
@@ -75,6 +143,11 @@ | |
} | |
xmlParseChunk(ctxt, NULL, 0, 1); | |
+ | |
+ /* Also test the serializer. */ | |
+ xmlDocDumpMemory(ctxt->myDoc, &out, &outSize); | |
+ xmlFree(out); | |
+ | |
if (opts & XML_PARSE_XINCLUDE) | |
xmlXIncludeProcessFlags(ctxt->myDoc, opts); | |
xmlFreeDoc(ctxt->myDoc); | |
@@ -82,7 +155,7 @@ | |
/* Reader */ | |
- reader = xmlReaderForMemory(docBuffer, docSize, NULL, NULL, opts); | |
+ reader = xmlReaderForMemory(docBuffer, docSize, NULL, xmlGetCharEncodingName(encoding), opts); | |
if (reader == NULL) | |
goto exit; | |
while (xmlTextReaderRead(reader) == 1) { | |
@@ -94,7 +167,47 @@ | |
} | |
} | |
} | |
+ if (xmlFuzzDataHash() % 5 == 0) | |
+ preservedReaderDoc = xmlTextReaderCurrentDoc(reader); | |
+ if (xmlFuzzDataHash() % 3 == 0) | |
+ xmlTextReaderClose(reader); | |
xmlFreeTextReader(reader); | |
+ if (xmlFuzzDataHash() % 5 == 0 && preservedReaderDoc) { | |
+ xmlFreeDoc(preservedReaderDoc); | |
+ } | |
+ | |
+ /* SAX parser */ | |
+ | |
+ inputBuffer = xmlParserInputBufferCreateMem(docBuffer, (int)docSize, encoding); | |
+ if (inputBuffer) { | |
+ ctxt = xmlNewParserCtxt(); | |
+ if (ctxt) { | |
+ xmlCtxtUseOptions(ctxt, opts | XML_PARSE_NOENT); | |
+ xmlSAXHandlerPtr handler = &xmlSAXHandlerStruct; | |
+ if (xmlFuzzDataHash() % 5 == 0) | |
+ handler->error = &errorCallback; | |
+ xmlSAXHandlerPtr old_sax = ctxt->sax; | |
+ ctxt->sax = handler; | |
+ ctxt->userData = ctxt; | |
+ xmlParserInputPtr inputStream = xmlNewIOInputStream(ctxt, inputBuffer, encoding); | |
+ if (inputStream) { | |
+ inputPush(ctxt, inputStream); | |
+ xmlParseDocument(ctxt); | |
+ doc = ctxt->myDoc; | |
+ if (doc) { | |
+ ctxt->myDoc = NULL; | |
+ /* Also test the serializer. */ | |
+ xmlDocDumpMemory(doc, &out, &outSize); | |
+ xmlFree(out); | |
+ xmlFreeDoc(doc); | |
+ } | |
+ } | |
+ ctxt->sax = old_sax; | |
+ xmlFreeParserCtxt(ctxt); | |
+ if (xmlFuzzDataHash() % 5 == 0) | |
+ handler->error = NULL; | |
+ } | |
+ } | |
exit: | |
xmlFuzzDataCleanup(); | |
diff -ru libxml2/fuzz/xml.dict libxml2-apple/libxml2/fuzz/xml.dict | |
--- libxml2/fuzz/xml.dict 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/fuzz/xml.dict 2025-06-26 01:54:56 | |
@@ -1,5 +1,22 @@ | |
xml_decl="<?xml version='1.0'?>" | |
xml_decl_latin1="<?xml version='1.0' encoding='ISO-8859-1'?>" | |
+xml_decl_latin2="<?xml version='1.0' encoding='ISO-8859-2'?>" | |
+xml_decl_iso_8559_3="<?xml version='1.0' encoding='ISO-8859-3'?>" | |
+xml_decl_iso_8559_4="<?xml version='1.0' encoding='ISO-8859-4'?>" | |
+xml_decl_iso_8559_5="<?xml version='1.0' encoding='ISO-8859-5'?>" | |
+xml_decl_iso_8559_6="<?xml version='1.0' encoding='ISO-8859-6'?>" | |
+xml_decl_iso_8559_7="<?xml version='1.0' encoding='ISO-8859-7'?>" | |
+xml_decl_iso_8559_8="<?xml version='1.0' encoding='ISO-8859-8'?>" | |
+xml_decl_iso_8559_9="<?xml version='1.0' encoding='ISO-8859-9'?>" | |
+xml_decl_iso_2022_jp="<?xml version='1.0' encoding='ISO-2022-JP'?>" | |
+xml_decl_shift_jis="<?xml version='1.0' encoding='SHIFT_JIS'?>" | |
+xml_decl_euc_jp="<?xml version='1.0' encoding='EUC-JP'?>" | |
+xml_decl_ucs2="<?xml version='1.0' encoding='ISO-10646-UCS-2'?>" | |
+xml_decl_ucs4="<?xml version='1.0' encoding='ISO-10646-UCS-4'?>" | |
+xml_decl_utf8="<?xml version='1.0' encoding='UTF-8'?>" | |
+xml_decl_utf16="<?xml version='1.0' encoding='UTF-16'?>" | |
+xml_decl_start="<?xml version='1.0' encoding='" | |
+xml_decl_end="'?>" | |
elem_start_end="<a></a>" | |
elem_empty="<a/>" | |
@@ -13,8 +30,12 @@ | |
ns_prefix="a:" | |
cdata_section="<![CDATA[ ]]>" | |
+cdata_section_start="<![CDATA[ " | |
+cdata_section_end=" ]]>" | |
comment="<!-- -->" | |
+comment_start="<!-- " | |
+comment_end=" -->" | |
pi="<?a?>" | |
@@ -45,7 +66,9 @@ | |
attlist_decl_notation="<!ATTLIST a a NOTATION (a) #IMPLIED>" | |
include_sect="<![INCLUDE[ ]]>" | |
+include_sect_start="<![INCLUDE[ " | |
ignore_sect="<![IGNORE[ ]]>" | |
+ignore_sect_start="<![IGNORE[ " | |
ge_decl="<!ENTITY a 'a'>" | |
ge_decl_system="<!ENTITY a SYSTEM 'a'>" | |
@@ -82,8 +105,38 @@ | |
cs_ucs2="UCS-2" | |
cs_ucs4="UCS-4" | |
cs_latin1="ISO-8859-1" | |
+cs_latin2="ISO-8859-2" | |
+cs_iso_8559_3="ISO-8859-3" | |
+cs_iso_8559_4="ISO-8859-4" | |
+cs_iso_8559_5="ISO-8859-5" | |
+cs_iso_8559_6="ISO-8859-6" | |
+cs_iso_8559_7="ISO-8859-7" | |
+cs_iso_8559_8="ISO-8859-8" | |
+cs_iso_8559_9="ISO-8859-9" | |
+cs_iso_10646_ucs_2="ISO-10646-UCS-2" | |
+cs_iso_10646_ucs_4="ISO-10646-UCS-4" | |
cs_ascii="ASCII" | |
cs_ebcdic="EBCDIC" | |
cs_iso2022jp="ISO-2022-JP" | |
cs_shift_jis="SHIFT_JIS" | |
cs_euc_jp="EUC-JP" | |
+ | |
+# Unicode | |
+ | |
+utf8_2="\xC3\x84" | |
+utf8_3="\xE2\x80\x9C" | |
+utf8_4="\xF0\x9F\x98\x80" | |
+ | |
+# Byte order marks | |
+ | |
+bom_utf8="\xEF\xBB\xBF" | |
+bom_utf16_be="\xFE\xFF" | |
+bom_utf16_le="\xFF\xFE" | |
+bom_utf32_be="\x00\x00\xFE\xFF" | |
+bom_utf32_le="\xFF\xFE\x00\x00" | |
+bom_utf7="\x28\x2F\x76" | |
+bom_utf1="\xF7\x64\x4C" | |
+bom_utf_ebcdic="\xDD\x73\x66\x73" | |
+bom_scsu="\x0E\xFE\xFF" | |
+bom_bocu1="\xFB\xEE\x28" | |
+bom_gb18030="\x84\x31\x95\x33" | |
diff -ru libxml2/fuzz/xml.options libxml2-apple/libxml2/fuzz/xml.options | |
--- libxml2/fuzz/xml.options 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/fuzz/xml.options 2025-06-26 01:54:56 | |
@@ -1,2 +1,4 @@ | |
[libfuzzer] | |
+dict = xml.dict | |
timeout = 20 | |
+rss_limit_mb = 8192 | |
diff -ru libxml2/fuzz/xpath.c libxml2-apple/libxml2/fuzz/xpath.c | |
--- libxml2/fuzz/xpath.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/fuzz/xpath.c 2025-06-26 01:54:56 | |
@@ -8,6 +8,24 @@ | |
#include <libxml/xpointer.h> | |
#include "fuzz.h" | |
+extern size_t LLVMFuzzerMutate(uint8_t *data, size_t size, size_t maxSize); | |
+extern size_t LLVMFuzzerCustomMutator(uint8_t *data, size_t size, size_t maxSize, unsigned int seed); | |
+ | |
+size_t | |
+LLVMFuzzerCustomMutator(uint8_t *data, size_t size, size_t maxSize, unsigned int seed) { | |
+ xmlFuzzRndSetSeed(seed); | |
+ | |
+ const size_t optionsSize = sizeof(int); | |
+ if (size < optionsSize) | |
+ return LLVMFuzzerMutate(data, size, maxSize); | |
+ | |
+ // Mutate libxml2 parsing options in first byte of input (10% chance). | |
+ if (xmlFuzzRnd() % 10 == 1) | |
+ *((int *)&data[0]) = (int)xmlFuzzRnd(); | |
+ | |
+ return optionsSize + LLVMFuzzerMutate(data + optionsSize, size - optionsSize, maxSize - optionsSize); | |
+} | |
+ | |
int | |
LLVMFuzzerInitialize(int *argc ATTRIBUTE_UNUSED, | |
char ***argv ATTRIBUTE_UNUSED) { | |
@@ -22,17 +40,21 @@ | |
xmlDocPtr doc; | |
const char *expr, *xml; | |
size_t exprSize, xmlSize; | |
+ xmlCharEncoding encoding; | |
+ int opts; | |
if (size > 10000) | |
return(0); | |
xmlFuzzDataInit(data, size); | |
+ encoding = (xmlCharEncoding)(xmlFuzzDataHash() % 23); /* See <libxml/encoding.h>. */ | |
+ opts = xmlFuzzReadInt() | XML_PARSE_NONET; | |
expr = xmlFuzzReadString(&exprSize); | |
xml = xmlFuzzReadString(&xmlSize); | |
/* Recovery mode allows more input to be fuzzed. */ | |
- doc = xmlReadMemory(xml, xmlSize, NULL, NULL, XML_PARSE_RECOVER); | |
+ doc = xmlReadMemory(xml, xmlSize, NULL, xmlGetCharEncodingName(encoding), opts | XML_PARSE_RECOVER); | |
if (doc != NULL) { | |
xmlXPathContextPtr xpctxt = xmlXPathNewContext(doc); | |
diff -ru libxml2/fuzz/xpath.options libxml2-apple/libxml2/fuzz/xpath.options | |
--- libxml2/fuzz/xpath.options 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/fuzz/xpath.options 2025-06-26 01:54:56 | |
@@ -1,2 +1,3 @@ | |
[libfuzzer] | |
+dict = xpath.dict | |
timeout = 20 | |
Only in libxml2-apple/libxml2: fuzz-old | |
diff -ru libxml2/gentest.py libxml2-apple/libxml2/gentest.py | |
--- libxml2/gentest.py 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/gentest.py 2025-06-26 01:54:56 | |
@@ -161,6 +161,13 @@ | |
"xmlParseXMLDecl", "xmlParseTextDecl", "xmlParseMisc", | |
"xmlParseExternalSubset", "xmlParserHandlePEReference", | |
"xmlSkipBlankChars", | |
+# location sets | |
+"xmlXPtrLocationSetAdd", | |
+"xmlXPtrLocationSetCreate", | |
+"xmlXPtrLocationSetDel", | |
+"xmlXPtrLocationSetMerge", | |
+"xmlXPtrLocationSetRemove", | |
+"xmlXPtrWrapLocationSet", | |
] | |
# | |
@@ -204,6 +211,10 @@ | |
""", | |
"xmlParserInputBufferCreateFd": | |
"if (fd >= 0) fd = -1;", | |
+ "xmlSAXDefaultVersion": """ | |
+ { | |
+ int original_version = xmlSAXDefaultVersion(2); | |
+""", | |
} | |
extra_post_call = { | |
"xmlAddChild": | |
@@ -260,7 +271,11 @@ | |
"xmlParseChunk": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}", | |
"xmlParseExtParsedEnt": "if (ctxt != NULL) {xmlFreeDoc(ctxt->myDoc); ctxt->myDoc = NULL;}", | |
"xmlDOMWrapAdoptNode": "if ((node != NULL) && (node->parent == NULL)) {xmlUnlinkNode(node);xmlFreeNode(node);node = NULL;}", | |
- "xmlBufferSetAllocationScheme": "if ((buf != NULL) && (scheme == XML_BUFFER_ALLOC_IMMUTABLE) && (buf->content != NULL) && (buf->content != static_buf_content)) { xmlFree(buf->content); buf->content = NULL;}" | |
+ "xmlBufferSetAllocationScheme": "if ((buf != NULL) && (scheme == XML_BUFFER_ALLOC_IMMUTABLE) && (buf->content != NULL) && (buf->content != static_buf_content)) { xmlFree(buf->content); buf->content = NULL;}", | |
+ "xmlSAXDefaultVersion": """ | |
+ (void)xmlSAXDefaultVersion(original_version); | |
+ } | |
+""", | |
} | |
modules = [] | |
diff -ru libxml2/globals.c libxml2-apple/libxml2/globals.c | |
--- libxml2/globals.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/globals.c 2025-06-26 01:54:56 | |
@@ -14,6 +14,14 @@ | |
#define IN_LIBXML | |
#include "libxml.h" | |
+#ifdef HAVE_PTHREAD_H | |
+#include <pthread.h> | |
+#elif defined(HAVE_WIN32_THREADS) | |
+#include <windows.h> | |
+#elif defined(HAVE_BEOS_THREADS) | |
+#include <OS.h> | |
+#endif | |
+ | |
#ifdef HAVE_STDLIB_H | |
#include <stdlib.h> | |
#endif | |
@@ -39,6 +47,19 @@ | |
*/ | |
static xmlMutexPtr xmlThrDefMutex = NULL; | |
+#ifdef HAVE_PTHREAD_H | |
+static pthread_once_t once_control = PTHREAD_ONCE_INIT; | |
+#elif defined(HAVE_WIN32_THREADS) | |
+static struct { | |
+ DWORD done; | |
+ DWORD control; | |
+} run_once = {0, 0}; | |
+#elif defined(HAVE_BEOS_THREADS) | |
+static int32 run_once_init = 0; | |
+#endif | |
+ | |
+static void _xmlInitGlobalsOnce(void); | |
+ | |
/** | |
* xmlInitGlobals: | |
* | |
@@ -46,10 +67,38 @@ | |
*/ | |
void xmlInitGlobals(void) | |
{ | |
+#ifdef LIBXML_THREAD_ENABLED | |
+#ifdef HAVE_PTHREAD_H | |
+ pthread_once(&once_control, _xmlInitGlobalsOnce); | |
+#elif defined(HAVE_WIN32_THREADS) | |
+ if (!run_once.done) { | |
+ if (InterlockedIncrement(&run_once.control) == 1) { | |
+ _xmlInitGlobalsOnce(); | |
+ run_once.done = 1; | |
+ } else { | |
+ /* Another thread is working; give up our slice and | |
+ * wait until they're done. */ | |
+ while (!run_once.done) | |
+ Sleep(0); | |
+ } | |
+ } | |
+#elif defined(HAVE_BEOS_THREADS) | |
+ if (atomic_add(&run_once_init, 1) == 0) | |
+ _xmlInitGlobalsOnce(); | |
+ else | |
+ atomic_add(&run_once_init, -1); | |
+#endif | |
+#else | |
if (xmlThrDefMutex == NULL) | |
- xmlThrDefMutex = xmlNewMutex(); | |
+ _xmlInitGlobalsOnce(); | |
+#endif | |
} | |
+static void _xmlInitGlobalsOnce(void) | |
+{ | |
+ xmlThrDefMutex = xmlNewMutex(); | |
+} | |
+ | |
/** | |
* xmlCleanupGlobals: | |
* | |
@@ -70,6 +119,28 @@ | |
* * | |
************************************************************************/ | |
+#define LIKELY(x) __builtin_expect(!!(x), 1) | |
+ | |
+void *xmlMallocZero(size_t size); | |
+void *xmlMallocZero(size_t size) | |
+{ | |
+ void *result = calloc(1, size); | |
+ if (LIKELY(result)) | |
+ return result; | |
+ abort(); | |
+} | |
+ | |
+void *xmlReallocChecked(void *ptr, size_t size); | |
+void *xmlReallocChecked(void *ptr, size_t size) | |
+{ | |
+ void *result = realloc(ptr, size); | |
+ if (LIKELY(result)) | |
+ return result; | |
+ abort(); | |
+} | |
+ | |
+#undef LIKELY | |
+ | |
/* | |
* Memory allocation routines | |
*/ | |
@@ -101,7 +172,7 @@ | |
* | |
* Returns a pointer to the newly allocated block or NULL in case of error | |
*/ | |
-xmlMallocFunc xmlMalloc = malloc; | |
+xmlMallocFunc xmlMalloc = xmlMallocZero; | |
/** | |
* xmlMallocAtomic: | |
* @size: the size requested in bytes | |
@@ -112,7 +183,7 @@ | |
* | |
* Returns a pointer to the newly allocated block or NULL in case of error | |
*/ | |
-xmlMallocFunc xmlMallocAtomic = malloc; | |
+xmlMallocFunc xmlMallocAtomic = xmlMallocZero; | |
/** | |
* xmlRealloc: | |
* @mem: an already allocated block of memory | |
@@ -122,7 +193,7 @@ | |
* | |
* Returns a pointer to the newly reallocated block or NULL in case of error | |
*/ | |
-xmlReallocFunc xmlRealloc = realloc; | |
+xmlReallocFunc xmlRealloc = xmlReallocChecked; | |
/** | |
* xmlPosixStrdup | |
* @cur: the input char * | |
@@ -545,9 +616,9 @@ | |
gs->xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup; | |
#else | |
gs->xmlFree = (xmlFreeFunc) free; | |
- gs->xmlMalloc = (xmlMallocFunc) malloc; | |
- gs->xmlMallocAtomic = (xmlMallocFunc) malloc; | |
- gs->xmlRealloc = (xmlReallocFunc) realloc; | |
+ gs->xmlMalloc = (xmlMallocFunc) xmlMallocZero; | |
+ gs->xmlMallocAtomic = (xmlMallocFunc) xmlMallocZero; | |
+ gs->xmlRealloc = (xmlReallocFunc) xmlReallocChecked; | |
gs->xmlMemStrdup = (xmlStrdupFunc) xmlStrdup; | |
#endif | |
gs->xmlGetWarningsDefaultValue = xmlGetWarningsDefaultValueThrDef; | |
diff -ru libxml2/hash.c libxml2-apple/libxml2/hash.c | |
--- libxml2/hash.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/hash.c 2025-06-26 01:54:56 | |
@@ -540,7 +540,7 @@ | |
xmlHashEntryPtr entry; | |
xmlHashEntryPtr insert; | |
- if ((table == NULL) || (name == NULL)) | |
+ if ((table == NULL) || (name == NULL) || (table->nbElems == INT_MAX)) | |
return(-1); | |
/* | |
@@ -656,7 +656,7 @@ | |
xmlHashEntryPtr entry; | |
xmlHashEntryPtr insert; | |
- if ((table == NULL) || name == NULL) | |
+ if ((table == NULL) || (name == NULL) || (table->nbElems == INT_MAX)) | |
return(-1); | |
/* | |
diff -ru libxml2/include/libxml/DOCBparser.h libxml2-apple/libxml2/include/libxml/DOCBparser.h | |
--- libxml2/include/libxml/DOCBparser.h 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/include/libxml/DOCBparser.h 2025-06-26 01:54:56 | |
@@ -27,6 +27,15 @@ | |
extern "C" { | |
#endif | |
+#ifdef __APPLE__ | |
+#define LIBXML2_DOCB_DEPRECATED __OSX_DEPRECATED(10.4, 10.4, "Deprecated in libxml2 v2.6.0") \ | |
+ __IOS_DEPRECATED(2.0, 2.0, "Deprecated in libxml2 v2.6.0") \ | |
+ __TVOS_DEPRECATED(9.0, 9.0, "Deprecated in libxml2 v2.6.0") \ | |
+ __WATCHOS_DEPRECATED(1.0, 1.0, "Deprecated in libxml2 v2.6.0") | |
+#else | |
+#define LIBXML2_DOCB_DEPRECATED | |
+#endif | |
+ | |
/* | |
* Most of the back-end structures from XML and SGML are shared. | |
*/ | |
@@ -45,47 +54,49 @@ | |
docbEncodeEntities(unsigned char *out, | |
int *outlen, | |
const unsigned char *in, | |
- int *inlen, int quoteChar); | |
+ int *inlen, int quoteChar) LIBXML2_DOCB_DEPRECATED; | |
XMLPUBFUN docbDocPtr XMLCALL | |
docbSAXParseDoc (xmlChar *cur, | |
const char *encoding, | |
docbSAXHandlerPtr sax, | |
- void *userData); | |
+ void *userData) LIBXML2_DOCB_DEPRECATED; | |
XMLPUBFUN docbDocPtr XMLCALL | |
docbParseDoc (xmlChar *cur, | |
- const char *encoding); | |
+ const char *encoding) LIBXML2_DOCB_DEPRECATED; | |
XMLPUBFUN docbDocPtr XMLCALL | |
docbSAXParseFile (const char *filename, | |
const char *encoding, | |
docbSAXHandlerPtr sax, | |
- void *userData); | |
+ void *userData) LIBXML2_DOCB_DEPRECATED; | |
XMLPUBFUN docbDocPtr XMLCALL | |
docbParseFile (const char *filename, | |
- const char *encoding); | |
+ const char *encoding) LIBXML2_DOCB_DEPRECATED; | |
/** | |
* Interfaces for the Push mode. | |
*/ | |
XMLPUBFUN void XMLCALL | |
- docbFreeParserCtxt (docbParserCtxtPtr ctxt); | |
+ docbFreeParserCtxt (docbParserCtxtPtr ctxt) LIBXML2_DOCB_DEPRECATED; | |
XMLPUBFUN docbParserCtxtPtr XMLCALL | |
docbCreatePushParserCtxt(docbSAXHandlerPtr sax, | |
void *user_data, | |
const char *chunk, | |
int size, | |
const char *filename, | |
- xmlCharEncoding enc); | |
+ xmlCharEncoding enc) LIBXML2_DOCB_DEPRECATED; | |
XMLPUBFUN int XMLCALL | |
docbParseChunk (docbParserCtxtPtr ctxt, | |
const char *chunk, | |
int size, | |
- int terminate); | |
+ int terminate) LIBXML2_DOCB_DEPRECATED; | |
XMLPUBFUN docbParserCtxtPtr XMLCALL | |
docbCreateFileParserCtxt(const char *filename, | |
- const char *encoding); | |
+ const char *encoding) LIBXML2_DOCB_DEPRECATED; | |
XMLPUBFUN int XMLCALL | |
- docbParseDocument (docbParserCtxtPtr ctxt); | |
+ docbParseDocument (docbParserCtxtPtr ctxt) LIBXML2_DOCB_DEPRECATED; | |
+ | |
+#undef LIBXML2_DOCB_DEPRECATED | |
#ifdef __cplusplus | |
} | |
diff -ru libxml2/include/libxml/HTMLparser.h libxml2-apple/libxml2/include/libxml/HTMLparser.h | |
--- libxml2/include/libxml/HTMLparser.h 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/include/libxml/HTMLparser.h 2025-06-26 01:54:56 | |
@@ -13,7 +13,10 @@ | |
#ifndef __HTML_PARSER_H__ | |
#define __HTML_PARSER_H__ | |
#include <libxml/xmlversion.h> | |
+#include <libxml/encoding.h> | |
#include <libxml/parser.h> | |
+#include <libxml/xmlIO.h> | |
+#include <libxml/xmlstring.h> | |
#ifdef LIBXML_HTML_ENABLED | |
diff -ru libxml2/include/libxml/dict.h libxml2-apple/libxml2/include/libxml/dict.h | |
--- libxml2/include/libxml/dict.h 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/include/libxml/dict.h 2025-06-26 01:54:56 | |
@@ -12,6 +12,7 @@ | |
#define __XML_DICT_H__ | |
#include <stddef.h> | |
+#include <libxml/xmlstring.h> | |
#include <libxml/xmlversion.h> | |
#ifdef __cplusplus | |
diff -ru libxml2/include/libxml/encoding.h libxml2-apple/libxml2/include/libxml/encoding.h | |
--- libxml2/include/libxml/encoding.h 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/include/libxml/encoding.h 2025-06-26 01:54:56 | |
@@ -28,7 +28,8 @@ | |
#include <iconv.h> | |
#endif | |
#ifdef LIBXML_ICU_ENABLED | |
-#include <unicode/ucnv.h> | |
+struct UConverter; | |
+typedef struct UConverter UConverter; | |
#endif | |
#ifdef __cplusplus | |
extern "C" { | |
@@ -129,14 +130,23 @@ | |
* If iconv is supported, there are two extra fields. | |
*/ | |
#ifdef LIBXML_ICU_ENABLED | |
+#ifdef __cplusplus | |
+} | |
+#endif | |
/* Size of pivot buffer, same as icu/source/common/ucnv.cpp CHUNK_SIZE */ | |
+#include <stdint.h> | |
+#ifdef __cplusplus | |
+extern "C" { | |
+#endif | |
#define ICU_PIVOT_BUF_SIZE 1024 | |
struct _uconv_t { | |
UConverter *uconv; /* for conversion between an encoding and UTF-16 */ | |
UConverter *utf8; /* for conversion between UTF-8 and UTF-16 */ | |
- UChar pivot_buf[ICU_PIVOT_BUF_SIZE]; | |
- UChar *pivot_source; | |
- UChar *pivot_target; | |
+#ifdef LIBXML_HAS_ICU_PIVOT_BUFFER | |
+ uint16_t /*UChar*/ pivot_buf[ICU_PIVOT_BUF_SIZE]; | |
+ uint16_t /*UChar*/ *pivot_source; | |
+ uint16_t /*UChar*/ *pivot_target; | |
+#endif | |
}; | |
typedef struct _uconv_t uconv_t; | |
#endif | |
diff -ru libxml2/include/libxml/globals.h libxml2-apple/libxml2/include/libxml/globals.h | |
--- libxml2/include/libxml/globals.h 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/include/libxml/globals.h 2025-06-26 01:54:56 | |
@@ -19,6 +19,7 @@ | |
#include <libxml/xmlerror.h> | |
#include <libxml/SAX2.h> | |
#include <libxml/xmlmemory.h> | |
+#include <libxml/encoding.h> | |
#ifdef __cplusplus | |
extern "C" { | |
diff -ru libxml2/include/libxml/hash.h libxml2-apple/libxml2/include/libxml/hash.h | |
--- libxml2/include/libxml/hash.h 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/include/libxml/hash.h 2025-06-26 01:54:56 | |
@@ -113,7 +113,7 @@ | |
xmlHashDeallocator f); | |
XMLPUBFUN void XMLCALL | |
xmlHashDefaultDeallocator(void *entry, | |
- const xmlChar *name); | |
+ const xmlChar *name) LIBXML_API_AVAILABLE_MACOS13_IOS16_WATCHOS9_TVOS16; | |
/* | |
* Add a new entry to the hash table. | |
diff -ru libxml2/include/libxml/xmlIO.h libxml2-apple/libxml2/include/libxml/xmlIO.h | |
--- libxml2/include/libxml/xmlIO.h 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/include/libxml/xmlIO.h 2025-06-26 01:54:56 | |
@@ -218,7 +218,7 @@ | |
XMLPUBFUN void XMLCALL | |
xmlCleanupOutputCallbacks (void); | |
XMLPUBFUN int XMLCALL | |
- xmlPopOutputCallbacks (void); | |
+ xmlPopOutputCallbacks (void) LIBXML_API_AVAILABLE_MACOS13_IOS16_WATCHOS9_TVOS16; | |
XMLPUBFUN void XMLCALL | |
xmlRegisterDefaultOutputCallbacks(void); | |
XMLPUBFUN xmlOutputBufferPtr XMLCALL | |
diff -ru libxml2/include/libxml/xmlmemory.h libxml2-apple/libxml2/include/libxml/xmlmemory.h | |
--- libxml2/include/libxml/xmlmemory.h 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/include/libxml/xmlmemory.h 2025-06-26 01:54:56 | |
@@ -137,6 +137,8 @@ | |
/* | |
* These are specific to the XML debug memory wrapper. | |
*/ | |
+XMLPUBFUN size_t XMLCALL | |
+ xmlMemSize (void *ptr) LIBXML_API_AVAILABLE_MACOS14_IOS17_WATCHOS10_TVOS17; | |
XMLPUBFUN int XMLCALL | |
xmlMemUsed (void); | |
XMLPUBFUN int XMLCALL | |
diff -ru libxml2/include/libxml/xmlversion.h.in libxml2-apple/libxml2/include/libxml/xmlversion.h.in | |
--- libxml2/include/libxml/xmlversion.h.in 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/include/libxml/xmlversion.h.in 2025-06-26 01:54:56 | |
@@ -12,6 +12,11 @@ | |
#include <libxml/xmlexports.h> | |
+#ifdef __APPLE__ | |
+#include <Availability.h> | |
+#include <TargetConditionals.h> | |
+#endif | |
+ | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
@@ -257,6 +262,15 @@ | |
#endif | |
/** | |
+ * LIBXML_XPTR_LOCS_ENABLED: | |
+ * | |
+ * Whether support for XPointer locations is configured in | |
+ */ | |
+#if @WITH_XPTR_LOCS@ | |
+#define LIBXML_XPTR_LOCS_ENABLED | |
+#endif | |
+ | |
+/** | |
* LIBXML_XINCLUDE_ENABLED: | |
* | |
* Whether XInclude is configured in | |
@@ -437,6 +451,7 @@ | |
# define LIBXML_ATTR_ALLOC_SIZE(x) | |
# endif | |
#else | |
+# undef LIBXML_ATTR_ALLOC_SIZE(x) | |
# define LIBXML_ATTR_ALLOC_SIZE(x) | |
#endif | |
@@ -453,9 +468,22 @@ | |
# define LIBXML_ATTR_FORMAT(fmt,args) | |
# endif | |
#else | |
+# undef LIBXML_ATTR_FORMAT(fmt,args) | |
# define LIBXML_ATTR_FORMAT(fmt,args) | |
#endif | |
+#ifndef XML_DEPRECATED | |
+# ifdef IN_LIBXML | |
+# define XML_DEPRECATED | |
+# elif defined(__APPLE__) | |
+/* Apple has its own deprecation macros that include OS versions. */ | |
+# define XML_DEPRECATED | |
+# else | |
+/* Available since at least GCC 3.1 */ | |
+# define XML_DEPRECATED __attribute__((deprecated)) | |
+# endif | |
+#endif | |
+ | |
#else /* ! __GNUC__ */ | |
/** | |
* ATTRIBUTE_UNUSED: | |
@@ -475,7 +503,66 @@ | |
* Macro used to indicate to GCC the parameter are printf like | |
*/ | |
#define LIBXML_ATTR_FORMAT(fmt,args) | |
+/** | |
+ * XML_DEPRECATED: | |
+ * | |
+ * Macro used to indicate that a function, variable, type or struct member | |
+ * is deprecated. | |
+ */ | |
+#ifndef XML_DEPRECATED | |
+#define XML_DEPRECATED | |
+#endif | |
#endif /* __GNUC__ */ | |
+ | |
+/** | |
+ * LIBXML_API_AVAILABLE_MACOS13_IOS16_WATCHOS9_TVOS16: | |
+ * LIBXML_HAS_XPATH_RESOURCE_LIMITS: | |
+ * | |
+ * Macros used for binary compatibility between Apple's v2.9.4 and v2.9.12+. | |
+ */ | |
+ | |
+#ifdef __APPLE__ | |
+ | |
+#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 160000 \ | |
+ || defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 130000 \ | |
+ || defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED >= 160000 \ | |
+ || defined(__WATCH_OS_VERSION_MIN_REQUIRED) && __WATCH_OS_VERSION_MIN_REQUIRED >= 90000 | |
+#define LIBXML_API_AVAILABLE_MACOS13_IOS16_WATCHOS9_TVOS16 \ | |
+ __IOS_AVAILABLE(16.0) __OSX_AVAILABLE(13.0) __TVOS_AVAILABLE(16.0) __WATCHOS_AVAILABLE(9.0) | |
+#define LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(libxml2_version) \ | |
+ __OSX_DEPRECATED(10.4, 13.0, "Also deprecated in libxml2 " # libxml2_version) \ | |
+ __IOS_DEPRECATED(2.0, 16.0, "Also deprecated in libxml2 " # libxml2_version) \ | |
+ __TVOS_DEPRECATED(9.0, 16.0, "Also deprecated in libxml2 " # libxml2_version) \ | |
+ __WATCHOS_DEPRECATED(1.0, 9.0, "Also deprecated in libxml2 " # libxml2_version) | |
+#define LIBXML_HAS_ICU_PIVOT_BUFFER | |
+#define LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+#else | |
+#define LIBXML_API_AVAILABLE_MACOS13_IOS16_WATCHOS9_TVOS16 | |
+#define LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(libxml2_version) | |
+#undef LIBXML_HAS_ICU_PIVOT_BUFFER | |
+#undef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+#endif | |
+ | |
+#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 170000 \ | |
+ || defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 140000 \ | |
+ || defined(__TV_OS_VERSION_MIN_REQUIRED) && __TV_OS_VERSION_MIN_REQUIRED >= 170000 \ | |
+ || defined(__WATCH_OS_VERSION_MIN_REQUIRED) && __WATCH_OS_VERSION_MIN_REQUIRED >= 100000 | |
+#define LIBXML_API_AVAILABLE_MACOS14_IOS17_WATCHOS10_TVOS17 \ | |
+ __IOS_AVAILABLE(17.0) __OSX_AVAILABLE(14.0) __TVOS_AVAILABLE(17.0) __WATCHOS_AVAILABLE(10.0) | |
+#else | |
+#define LIBXML_API_AVAILABLE_MACOS14_IOS17_WATCHOS10_TVOS17 | |
+#endif | |
+ | |
+#else /* !defined(__APPLE__) */ | |
+ | |
+#define LIBXML_API_AVAILABLE_MACOS13_IOS16_WATCHOS9_TVOS16 | |
+#define LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(libxml2_version) | |
+#define LIBXML_HAS_ICU_PIVOT_BUFFER | |
+#define LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ | |
+#define LIBXML_API_AVAILABLE_MACOS14_IOS17_WATCHOS10_TVOS17 | |
+ | |
+#endif /* defined(__APPLE__) */ | |
#ifdef __cplusplus | |
} | |
diff -ru libxml2/include/libxml/xpath.h libxml2-apple/libxml2/include/libxml/xpath.h | |
--- libxml2/include/libxml/xpath.h 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/include/libxml/xpath.h 2025-06-26 01:54:56 | |
@@ -70,9 +70,11 @@ | |
XPATH_INVALID_CHAR_ERROR, | |
XPATH_INVALID_CTXT, | |
XPATH_STACK_ERROR, | |
- XPATH_FORBID_VARIABLE_ERROR, | |
- XPATH_OP_LIMIT_EXCEEDED, | |
- XPATH_RECURSION_LIMIT_EXCEEDED | |
+ XPATH_FORBID_VARIABLE_ERROR | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ ,XPATH_OP_LIMIT_EXCEEDED | |
+ ,XPATH_RECURSION_LIMIT_EXCEEDED | |
+#endif | |
} xmlXPathError; | |
/* | |
@@ -104,13 +106,23 @@ | |
XPATH_BOOLEAN = 2, | |
XPATH_NUMBER = 3, | |
XPATH_STRING = 4, | |
- XPATH_POINT = 5, | |
- XPATH_RANGE = 6, | |
- XPATH_LOCATIONSET = 7, | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
+ XPATH_POINT = 5, /* LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14) */ | |
+ XPATH_RANGE = 6, /* LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14) */ | |
+ XPATH_LOCATIONSET = 7, /* LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14) */ | |
+#endif | |
XPATH_USERS = 8, | |
XPATH_XSLT_TREE = 9 /* An XSLT value tree, non modifiable */ | |
} xmlXPathObjectType; | |
+#ifndef LIBXML_XPTR_LOCS_ENABLED | |
+/** DOC_DISABLE */ | |
+#define XPATH_POINT 5 | |
+#define XPATH_RANGE 6 | |
+#define XPATH_LOCATIONSET 7 | |
+/** DOC_ENABLE */ | |
+#endif | |
+ | |
typedef struct _xmlXPathObject xmlXPathObject; | |
typedef xmlXPathObject *xmlXPathObjectPtr; | |
struct _xmlXPathObject { | |
@@ -355,10 +367,12 @@ | |
/* Cache for reusal of XPath objects */ | |
void *cache; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
/* Resource limits */ | |
unsigned long opLimit; | |
unsigned long opCount; | |
int depth; | |
+#endif | |
}; | |
/* | |
@@ -390,7 +404,7 @@ | |
int xptr; /* it this an XPointer expression */ | |
xmlNodePtr ancestor; /* used for walking preceding axis */ | |
- int valueFrame; /* used to limit Pop on the stack */ | |
+ int valueFrame; /* always zero for compatibility */ | |
}; | |
/************************************************************************ | |
diff -ru libxml2/include/libxml/xpathInternals.h libxml2-apple/libxml2/include/libxml/xpathInternals.h | |
--- libxml2/include/libxml/xpathInternals.h 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/include/libxml/xpathInternals.h 2025-06-26 01:54:56 | |
@@ -297,7 +297,7 @@ | |
if (ctxt == NULL) return; \ | |
if (nargs != (x)) \ | |
XP_ERROR(XPATH_INVALID_ARITY); \ | |
- if (ctxt->valueNr < ctxt->valueFrame + (x)) \ | |
+ if (ctxt->valueNr < (x)) \ | |
XP_ERROR(XPATH_STACK_ERROR); | |
/** | |
diff -ru libxml2/include/libxml/xpointer.h libxml2-apple/libxml2/include/libxml/xpointer.h | |
--- libxml2/include/libxml/xpointer.h 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/include/libxml/xpointer.h 2025-06-26 01:54:56 | |
@@ -28,6 +28,7 @@ | |
extern "C" { | |
#endif | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
/* | |
* A Location Set | |
*/ | |
@@ -43,51 +44,68 @@ | |
* Handling of location sets. | |
*/ | |
+XML_DEPRECATED | |
XMLPUBFUN xmlLocationSetPtr XMLCALL | |
- xmlXPtrLocationSetCreate (xmlXPathObjectPtr val); | |
+ xmlXPtrLocationSetCreate (xmlXPathObjectPtr val) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN void XMLCALL | |
- xmlXPtrFreeLocationSet (xmlLocationSetPtr obj); | |
+ xmlXPtrFreeLocationSet (xmlLocationSetPtr obj) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN xmlLocationSetPtr XMLCALL | |
xmlXPtrLocationSetMerge (xmlLocationSetPtr val1, | |
- xmlLocationSetPtr val2); | |
+ xmlLocationSetPtr val2) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN xmlXPathObjectPtr XMLCALL | |
xmlXPtrNewRange (xmlNodePtr start, | |
int startindex, | |
xmlNodePtr end, | |
- int endindex); | |
+ int endindex) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN xmlXPathObjectPtr XMLCALL | |
xmlXPtrNewRangePoints (xmlXPathObjectPtr start, | |
- xmlXPathObjectPtr end); | |
+ xmlXPathObjectPtr end) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN xmlXPathObjectPtr XMLCALL | |
xmlXPtrNewRangeNodePoint (xmlNodePtr start, | |
- xmlXPathObjectPtr end); | |
+ xmlXPathObjectPtr end) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN xmlXPathObjectPtr XMLCALL | |
xmlXPtrNewRangePointNode (xmlXPathObjectPtr start, | |
- xmlNodePtr end); | |
+ xmlNodePtr end) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN xmlXPathObjectPtr XMLCALL | |
xmlXPtrNewRangeNodes (xmlNodePtr start, | |
- xmlNodePtr end); | |
+ xmlNodePtr end) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN xmlXPathObjectPtr XMLCALL | |
xmlXPtrNewLocationSetNodes (xmlNodePtr start, | |
- xmlNodePtr end); | |
+ xmlNodePtr end) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN xmlXPathObjectPtr XMLCALL | |
- xmlXPtrNewLocationSetNodeSet(xmlNodeSetPtr set); | |
+ xmlXPtrNewLocationSetNodeSet(xmlNodeSetPtr set) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN xmlXPathObjectPtr XMLCALL | |
xmlXPtrNewRangeNodeObject (xmlNodePtr start, | |
- xmlXPathObjectPtr end); | |
+ xmlXPathObjectPtr end) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN xmlXPathObjectPtr XMLCALL | |
- xmlXPtrNewCollapsedRange (xmlNodePtr start); | |
+ xmlXPtrNewCollapsedRange (xmlNodePtr start) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN void XMLCALL | |
xmlXPtrLocationSetAdd (xmlLocationSetPtr cur, | |
- xmlXPathObjectPtr val); | |
+ xmlXPathObjectPtr val) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN xmlXPathObjectPtr XMLCALL | |
- xmlXPtrWrapLocationSet (xmlLocationSetPtr val); | |
+ xmlXPtrWrapLocationSet (xmlLocationSetPtr val) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN void XMLCALL | |
xmlXPtrLocationSetDel (xmlLocationSetPtr cur, | |
- xmlXPathObjectPtr val); | |
+ xmlXPathObjectPtr val) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN void XMLCALL | |
xmlXPtrLocationSetRemove (xmlLocationSetPtr cur, | |
- int val); | |
+ int val) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
/* | |
* Functions. | |
@@ -99,13 +117,18 @@ | |
XMLPUBFUN xmlXPathObjectPtr XMLCALL | |
xmlXPtrEval (const xmlChar *str, | |
xmlXPathContextPtr ctx); | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
+XML_DEPRECATED | |
XMLPUBFUN void XMLCALL | |
xmlXPtrRangeToFunction (xmlXPathParserContextPtr ctxt, | |
- int nargs); | |
+ int nargs) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN xmlNodePtr XMLCALL | |
- xmlXPtrBuildNodeList (xmlXPathObjectPtr obj); | |
+ xmlXPtrBuildNodeList (xmlXPathObjectPtr obj) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+XML_DEPRECATED | |
XMLPUBFUN void XMLCALL | |
- xmlXPtrEvalRangePredicate (xmlXPathParserContextPtr ctxt); | |
+ xmlXPtrEvalRangePredicate (xmlXPathParserContextPtr ctxt) LIBXML_API_DEPRECATED_MACOS13_IOS16_WATCHOS9_TVOS16(v2.9.14); | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
#ifdef __cplusplus | |
} | |
#endif | |
Only in libxml2-apple/libxml2/include: private | |
diff -ru libxml2/legacy.c libxml2-apple/libxml2/legacy.c | |
--- libxml2/legacy.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/legacy.c 2025-06-26 01:54:56 | |
@@ -85,7 +85,7 @@ | |
{ | |
} | |
-static const char *xmlFeaturesList[] = { | |
+static const char * const xmlFeaturesList[] = { | |
"validate", | |
"load subset", | |
"keep blanks", | |
diff -ru libxml2/libxml.h libxml2-apple/libxml2/libxml.h | |
--- libxml2/libxml.h 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/libxml.h 2025-06-26 01:54:56 | |
@@ -60,6 +60,15 @@ | |
#include "trio.h" | |
#endif | |
+#if !defined(_WIN32) && \ | |
+ !defined(__CYGWIN__) && \ | |
+ (defined(__clang__) || \ | |
+ (defined(__GNUC__) && (__GNUC__ >= 4))) | |
+#define XML_HIDDEN __attribute__((visibility("hidden"))) | |
+#else | |
+#define XML_HIDDEN | |
+#endif | |
+ | |
#if defined(__clang__) || \ | |
(defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) | |
#define XML_IGNORE_PEDANTIC_WARNINGS \ | |
diff -ru libxml2/nanohttp.c libxml2-apple/libxml2/nanohttp.c | |
--- libxml2/nanohttp.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/nanohttp.c 2025-06-26 01:54:56 | |
@@ -1448,7 +1448,7 @@ | |
if (ctxt->port != 80) { | |
p += snprintf( p, blen - (p - bp), "%s http://%s:%d%s", | |
method, ctxt->hostname, | |
- ctxt->port, ctxt->path ); | |
+ (ctxt->port & INT_MAX), ctxt->path ); | |
} | |
else | |
p += snprintf( p, blen - (p - bp), "%s http://%s%s", method, | |
@@ -1465,7 +1465,7 @@ | |
ctxt->hostname); | |
} else { | |
p += snprintf( p, blen - (p - bp), " HTTP/1.0\r\nHost: %s:%d\r\n", | |
- ctxt->hostname, ctxt->port); | |
+ ctxt->hostname, (ctxt->port & INT_MAX)); | |
} | |
#ifdef LIBXML_ZLIB_ENABLED | |
diff -ru libxml2/parser.c libxml2-apple/libxml2/parser.c | |
--- libxml2/parser.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/parser.c 2025-06-26 01:54:56 | |
@@ -61,6 +61,7 @@ | |
#include <libxml/encoding.h> | |
#include <libxml/xmlIO.h> | |
#include <libxml/uri.h> | |
+#include <libxml/xmlversion.h> | |
#ifdef LIBXML_CATALOG_ENABLED | |
#include <libxml/catalog.h> | |
#endif | |
@@ -84,9 +85,17 @@ | |
#include <unistd.h> | |
#endif | |
+#ifdef __APPLE__ | |
+#include <os/log.h> | |
+#endif | |
+ | |
#include "buf.h" | |
#include "enc.h" | |
+#include "private/parser.h" | |
+const int xmlEntityDecodingDepthMax = 40; | |
+const int xmlEntityDecodingDepthHugeMax = 1024; | |
+ | |
struct _xmlStartTag { | |
const xmlChar *prefix; | |
const xmlChar *URI; | |
@@ -101,8 +110,6 @@ | |
xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID, | |
const xmlChar *base, xmlParserCtxtPtr pctx); | |
-static void xmlHaltParser(xmlParserCtxtPtr ctxt); | |
- | |
static int | |
xmlParseElementStart(xmlParserCtxtPtr ctxt); | |
@@ -115,6 +122,8 @@ | |
* * | |
************************************************************************/ | |
+#define XML_MAX_HUGE_LENGTH 1000000000 | |
+ | |
#define XML_PARSER_BIG_ENTITY 1000 | |
#define XML_PARSER_LOT_ENTITY 5000 | |
@@ -302,7 +311,7 @@ | |
* List of XML prefixed PI allowed by W3C specs | |
*/ | |
-static const char *xmlW3CPIs[] = { | |
+static const char * const xmlW3CPIs[] = { | |
"xml-stylesheet", | |
"xml-model", | |
NULL | |
@@ -565,7 +574,7 @@ | |
errmsg = "Malformed declaration expecting version"; | |
break; | |
case XML_ERR_NAME_TOO_LONG: | |
- errmsg = "Name too long use XML_PARSE_HUGE option"; | |
+ errmsg = "Name too long"; | |
break; | |
#if 0 | |
case: | |
@@ -642,6 +651,8 @@ | |
(ctxt->sax->initialized == XML_SAX2_MAGIC)) | |
schannel = ctxt->sax->serror; | |
if (ctxt != NULL) { | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, | |
(ctxt->sax) ? ctxt->sax->warning : NULL, | |
ctxt->userData, | |
@@ -649,12 +660,16 @@ | |
XML_ERR_WARNING, NULL, 0, | |
(const char *) str1, (const char *) str2, NULL, 0, 0, | |
msg, (const char *) str1, (const char *) str2); | |
+#pragma clang diagnostic pop | |
} else { | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, NULL, NULL, | |
ctxt, NULL, XML_FROM_PARSER, error, | |
XML_ERR_WARNING, NULL, 0, | |
(const char *) str1, (const char *) str2, NULL, 0, 0, | |
msg, (const char *) str1, (const char *) str2); | |
+#pragma clang diagnostic pop | |
} | |
} | |
@@ -682,19 +697,25 @@ | |
schannel = ctxt->sax->serror; | |
} | |
if (ctxt != NULL) { | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, | |
ctxt->vctxt.error, ctxt->vctxt.userData, | |
ctxt, NULL, XML_FROM_DTD, error, | |
XML_ERR_ERROR, NULL, 0, (const char *) str1, | |
(const char *) str2, NULL, 0, 0, | |
msg, (const char *) str1, (const char *) str2); | |
+#pragma clang diagnostic pop | |
ctxt->valid = 0; | |
} else { | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, NULL, NULL, | |
ctxt, NULL, XML_FROM_DTD, error, | |
XML_ERR_ERROR, NULL, 0, (const char *) str1, | |
(const char *) str2, NULL, 0, 0, | |
msg, (const char *) str1, (const char *) str2); | |
+#pragma clang diagnostic pop | |
} | |
} | |
@@ -716,9 +737,12 @@ | |
return; | |
if (ctxt != NULL) | |
ctxt->errNo = error; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, | |
ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL, | |
NULL, 0, NULL, NULL, NULL, val, 0, msg, val); | |
+#pragma clang diagnostic pop | |
if (ctxt != NULL) { | |
ctxt->wellFormed = 0; | |
if (ctxt->recovery == 0) | |
@@ -747,10 +771,13 @@ | |
return; | |
if (ctxt != NULL) | |
ctxt->errNo = error; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, | |
ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL, | |
NULL, 0, (const char *) str1, (const char *) str2, | |
NULL, val, 0, msg, str1, val, str2); | |
+#pragma clang diagnostic pop | |
if (ctxt != NULL) { | |
ctxt->wellFormed = 0; | |
if (ctxt->recovery == 0) | |
@@ -776,10 +803,13 @@ | |
return; | |
if (ctxt != NULL) | |
ctxt->errNo = error; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, | |
XML_FROM_PARSER, error, XML_ERR_FATAL, | |
NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg, | |
val); | |
+#pragma clang diagnostic pop | |
if (ctxt != NULL) { | |
ctxt->wellFormed = 0; | |
if (ctxt->recovery == 0) | |
@@ -805,10 +835,13 @@ | |
return; | |
if (ctxt != NULL) | |
ctxt->errNo = error; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, | |
XML_FROM_PARSER, error, XML_ERR_ERROR, | |
NULL, 0, (const char *) val, NULL, NULL, 0, 0, msg, | |
val); | |
+#pragma clang diagnostic pop | |
} | |
/** | |
@@ -832,10 +865,13 @@ | |
return; | |
if (ctxt != NULL) | |
ctxt->errNo = error; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error, | |
XML_ERR_ERROR, NULL, 0, (const char *) info1, | |
(const char *) info2, (const char *) info3, 0, 0, msg, | |
info1, info2, info3); | |
+#pragma clang diagnostic pop | |
if (ctxt != NULL) | |
ctxt->nsWellFormed = 0; | |
} | |
@@ -859,10 +895,13 @@ | |
if ((ctxt != NULL) && (ctxt->disableSAX != 0) && | |
(ctxt->instate == XML_PARSER_EOF)) | |
return; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error, | |
XML_ERR_WARNING, NULL, 0, (const char *) info1, | |
(const char *) info2, (const char *) info3, 0, 0, msg, | |
info1, info2, info3); | |
+#pragma clang diagnostic pop | |
} | |
/************************************************************************ | |
@@ -1107,6 +1146,15 @@ | |
if (ctxt == NULL) return; | |
sax = ctxt->sax; | |
#ifdef LIBXML_SAX1_ENABLED | |
+#ifdef __APPLE__ | |
+ if ((sax) && (sax->initialized == XML_SAX2_MAGIC) && | |
+ (((sax->startElementNs == NULL) && (sax->startElement != NULL)) || | |
+ ((sax->endElementNs == NULL) && (sax->endElement != NULL))) && | |
+ (ctxt->html == 0)) { | |
+ os_log_fault(OS_LOG_DEFAULT, | |
+ "XML SAX2 parser requested but SAX1 used due to startElement/endElement handlers--switch to startElementNs/endElementNs"); | |
+ } | |
+#endif /* __APPLE__ */ | |
if ((sax) && (sax->initialized == XML_SAX2_MAGIC) && | |
((sax->startElementNs != NULL) || | |
(sax->endElementNs != NULL) || | |
@@ -1711,25 +1759,25 @@ | |
int *attallocs; | |
int maxatts; | |
- if (ctxt->atts == NULL) { | |
- maxatts = 55; /* allow for 10 attrs by default */ | |
- atts = (const xmlChar **) | |
- xmlMalloc(maxatts * sizeof(xmlChar *)); | |
- if (atts == NULL) goto mem_error; | |
- ctxt->atts = atts; | |
- attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int)); | |
- if (attallocs == NULL) goto mem_error; | |
- ctxt->attallocs = attallocs; | |
- ctxt->maxatts = maxatts; | |
- } else if (nr + 5 > ctxt->maxatts) { | |
- maxatts = (nr + 5) * 2; | |
- atts = (const xmlChar **) xmlRealloc((void *) ctxt->atts, | |
+ if (nr + 5 > ctxt->maxatts) { | |
+ maxatts = ctxt->maxatts == 0 ? 55 : (nr + 5) * 2; | |
+ atts = (const xmlChar **) xmlMalloc( | |
maxatts * sizeof(const xmlChar *)); | |
if (atts == NULL) goto mem_error; | |
+ /* Workaround <rdar://105882275> due to broken custom xmlRealloc() in Canon printer drivers. */ | |
+ if (ctxt->attallocs == NULL) | |
+ attallocs = (int *) xmlMalloc((maxatts / 5) * sizeof(int)); | |
+ else | |
+ attallocs = (int *) xmlRealloc((void *) ctxt->attallocs, | |
+ (maxatts / 5) * sizeof(int)); | |
+ if (attallocs == NULL) { | |
+ xmlFree(atts); | |
+ goto mem_error; | |
+ } | |
+ if (ctxt->maxatts > 0) | |
+ memcpy(atts, ctxt->atts, ctxt->maxatts * sizeof(const xmlChar *)); | |
+ xmlFree(ctxt->atts); | |
ctxt->atts = atts; | |
- attallocs = (int *) xmlRealloc((void *) ctxt->attallocs, | |
- (maxatts / 5) * sizeof(int)); | |
- if (attallocs == NULL) goto mem_error; | |
ctxt->attallocs = attallocs; | |
ctxt->maxatts = maxatts; | |
} | |
@@ -1754,18 +1802,17 @@ | |
if ((ctxt == NULL) || (value == NULL)) | |
return(-1); | |
if (ctxt->inputNr >= ctxt->inputMax) { | |
- ctxt->inputMax *= 2; | |
- ctxt->inputTab = | |
- (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab, | |
- ctxt->inputMax * | |
- sizeof(ctxt->inputTab[0])); | |
- if (ctxt->inputTab == NULL) { | |
+ size_t newSize = ctxt->inputMax * 2; | |
+ xmlParserInputPtr *tmp; | |
+ | |
+ tmp = (xmlParserInputPtr *) xmlRealloc(ctxt->inputTab, | |
+ newSize * sizeof(*tmp)); | |
+ if (tmp == NULL) { | |
xmlErrMemory(ctxt, NULL); | |
- xmlFreeInputStream(value); | |
- ctxt->inputMax /= 2; | |
- value = NULL; | |
return (-1); | |
} | |
+ ctxt->inputTab = tmp; | |
+ ctxt->inputMax = newSize; | |
} | |
ctxt->inputTab[ctxt->inputNr] = value; | |
ctxt->input = value; | |
@@ -2163,10 +2210,12 @@ | |
} | |
#define NEXTL(l) do { \ | |
- if (*(ctxt->input->cur) == '\n') { \ | |
- ctxt->input->line++; ctxt->input->col = 1; \ | |
- } else ctxt->input->col++; \ | |
- ctxt->input->cur += l; \ | |
+ if (ctxt->input->cur + l <= ctxt->input->end) { \ | |
+ if (*(ctxt->input->cur) == '\n') { \ | |
+ ctxt->input->line++; ctxt->input->col = 1; \ | |
+ } else ctxt->input->col++; \ | |
+ ctxt->input->cur += l; \ | |
+ } \ | |
} while (0) | |
#define CUR_CHAR(l) xmlCurrentChar(ctxt, &l) | |
@@ -2188,7 +2237,7 @@ | |
int | |
xmlSkipBlankChars(xmlParserCtxtPtr ctxt) { | |
- int res = 0; | |
+ size_t res = 0; | |
/* | |
* It's Okay to use CUR/NEXT here since all the blanks are on | |
@@ -2219,7 +2268,7 @@ | |
} else { | |
int expandPE = ((ctxt->external != 0) || (ctxt->inputNr != 1)); | |
- while (1) { | |
+ while (ctxt->instate != XML_PARSER_EOF) { | |
if (IS_BLANK_CH(CUR)) { /* CHECKED tstblanks.xml */ | |
NEXT; | |
} else if (CUR == '%') { | |
@@ -2247,7 +2296,7 @@ | |
res++; | |
} | |
} | |
- return(res); | |
+ return(res > INT_MAX ? INT_MAX : (int)res); | |
} | |
/************************************************************************ | |
@@ -2303,16 +2352,16 @@ | |
xmlGenericError(xmlGenericErrorContext, | |
"Pushing input %d : %.30s\n", ctxt->inputNr+1, input->cur); | |
} | |
- if (((ctxt->inputNr > 40) && ((ctxt->options & XML_PARSE_HUGE) == 0)) || | |
- (ctxt->inputNr > 1024)) { | |
+ if (((ctxt->inputNr > xmlEntityDecodingDepthMax) && ((ctxt->options & XML_PARSE_HUGE) == 0)) || | |
+ (ctxt->inputNr > xmlEntityDecodingDepthHugeMax)) { | |
xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL); | |
while (ctxt->inputNr > 1) | |
xmlFreeInputStream(inputPop(ctxt)); | |
return(-1); | |
} | |
- ret = inputPush(ctxt, input); | |
if (ctxt->instate == XML_PARSER_EOF) | |
return(-1); | |
+ ret = inputPush(ctxt, input); | |
GROW; | |
return(ret); | |
} | |
@@ -2654,15 +2703,15 @@ | |
xmlChar *rep = NULL; | |
const xmlChar *last; | |
xmlEntityPtr ent; | |
- int c,l; | |
+ int c, l = 0; | |
if ((ctxt == NULL) || (str == NULL) || (len < 0)) | |
return(NULL); | |
last = str + len; | |
- if (((ctxt->depth > 40) && | |
+ if (((ctxt->depth > xmlEntityDecodingDepthMax) && | |
((ctxt->options & XML_PARSE_HUGE) == 0)) || | |
- (ctxt->depth > 1024)) { | |
+ (ctxt->depth > xmlEntityDecodingDepthHugeMax)) { | |
xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL); | |
return(NULL); | |
} | |
@@ -3208,6 +3257,9 @@ | |
int len = 0, l; | |
int c; | |
int count = 0; | |
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ? | |
+ XML_MAX_TEXT_LENGTH : | |
+ XML_MAX_NAME_LENGTH; | |
#ifdef DEBUG | |
nbParseNameComplex++; | |
@@ -3273,9 +3325,12 @@ | |
if (ctxt->instate == XML_PARSER_EOF) | |
return(NULL); | |
} | |
- len += l; | |
+ if (len <= INT_MAX - l) | |
+ len += l; | |
NEXTL(l); | |
c = CUR_CHAR(l); | |
+ if (c == 0 && ctxt->instate == XML_PARSER_EOF) | |
+ return(NULL); | |
} | |
} else { | |
if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */ | |
@@ -3299,13 +3354,13 @@ | |
if (ctxt->instate == XML_PARSER_EOF) | |
return(NULL); | |
} | |
- len += l; | |
+ if (len <= INT_MAX - l) | |
+ len += l; | |
NEXTL(l); | |
c = CUR_CHAR(l); | |
} | |
} | |
- if ((len > XML_MAX_NAME_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
+ if (len > maxLength) { | |
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name"); | |
return(NULL); | |
} | |
@@ -3344,7 +3399,10 @@ | |
xmlParseName(xmlParserCtxtPtr ctxt) { | |
const xmlChar *in; | |
const xmlChar *ret; | |
- int count = 0; | |
+ size_t count = 0; | |
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ? | |
+ XML_MAX_TEXT_LENGTH : | |
+ XML_MAX_NAME_LENGTH; | |
GROW; | |
@@ -3368,8 +3426,7 @@ | |
in++; | |
if ((*in > 0) && (*in < 0x80)) { | |
count = in - ctxt->input->cur; | |
- if ((count > XML_MAX_NAME_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
+ if (count > maxLength) { | |
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name"); | |
return(NULL); | |
} | |
@@ -3390,6 +3447,9 @@ | |
int len = 0, l; | |
int c; | |
int count = 0; | |
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ? | |
+ XML_MAX_TEXT_LENGTH : | |
+ XML_MAX_NAME_LENGTH; | |
size_t startPosition = 0; | |
#ifdef DEBUG | |
@@ -3410,20 +3470,22 @@ | |
while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */ | |
(xmlIsNameChar(ctxt, c) && (c != ':'))) { | |
if (count++ > XML_PARSER_CHUNK_SIZE) { | |
- if ((len > XML_MAX_NAME_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName"); | |
- return(NULL); | |
- } | |
count = 0; | |
GROW; | |
if (ctxt->instate == XML_PARSER_EOF) | |
return(NULL); | |
} | |
- len += l; | |
+ if (len <= INT_MAX - l) | |
+ len += l; | |
NEXTL(l); | |
c = CUR_CHAR(l); | |
if (c == 0) { | |
+ /* | |
+ * A xmlStructuredErrorFunc could call xmlStopParser(), so | |
+ * return early if that happens. | |
+ */ | |
+ if (ctxt->instate == XML_PARSER_EOF) | |
+ return(NULL); | |
count = 0; | |
/* | |
* when shrinking to extend the buffer we really need to preserve | |
@@ -3438,8 +3500,7 @@ | |
c = CUR_CHAR(l); | |
} | |
} | |
- if ((len > XML_MAX_NAME_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
+ if (len > maxLength) { | |
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName"); | |
return(NULL); | |
} | |
@@ -3465,7 +3526,10 @@ | |
xmlParseNCName(xmlParserCtxtPtr ctxt) { | |
const xmlChar *in, *e; | |
const xmlChar *ret; | |
- int count = 0; | |
+ size_t count = 0; | |
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ? | |
+ XML_MAX_TEXT_LENGTH : | |
+ XML_MAX_NAME_LENGTH; | |
#ifdef DEBUG | |
nbParseNCName++; | |
@@ -3490,8 +3554,7 @@ | |
goto complex; | |
if ((*in > 0) && (*in < 0x80)) { | |
count = in - ctxt->input->cur; | |
- if ((count > XML_MAX_NAME_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
+ if (count > maxLength) { | |
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName"); | |
return(NULL); | |
} | |
@@ -3573,6 +3636,9 @@ | |
const xmlChar *cur = *str; | |
int len = 0, l; | |
int c; | |
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ? | |
+ XML_MAX_TEXT_LENGTH : | |
+ XML_MAX_NAME_LENGTH; | |
#ifdef DEBUG | |
nbParseStringName++; | |
@@ -3608,12 +3674,6 @@ | |
if (len + 10 > max) { | |
xmlChar *tmp; | |
- if ((len > XML_MAX_NAME_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName"); | |
- xmlFree(buffer); | |
- return(NULL); | |
- } | |
max *= 2; | |
tmp = (xmlChar *) xmlRealloc(buffer, | |
max * sizeof(xmlChar)); | |
@@ -3627,14 +3687,18 @@ | |
COPY_BUF(l,buffer,len,c); | |
cur += l; | |
c = CUR_SCHAR(cur, l); | |
+ if (len > maxLength) { | |
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName"); | |
+ xmlFree(buffer); | |
+ return(NULL); | |
+ } | |
} | |
buffer[len] = 0; | |
*str = cur; | |
return(buffer); | |
} | |
} | |
- if ((len > XML_MAX_NAME_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
+ if (len > maxLength) { | |
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName"); | |
return(NULL); | |
} | |
@@ -3661,6 +3725,9 @@ | |
int len = 0, l; | |
int c; | |
int count = 0; | |
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ? | |
+ XML_MAX_TEXT_LENGTH : | |
+ XML_MAX_NAME_LENGTH; | |
#ifdef DEBUG | |
nbParseNmToken++; | |
@@ -3712,12 +3779,6 @@ | |
if (len + 10 > max) { | |
xmlChar *tmp; | |
- if ((max > XML_MAX_NAME_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken"); | |
- xmlFree(buffer); | |
- return(NULL); | |
- } | |
max *= 2; | |
tmp = (xmlChar *) xmlRealloc(buffer, | |
max * sizeof(xmlChar)); | |
@@ -3731,6 +3792,11 @@ | |
COPY_BUF(l,buffer,len,c); | |
NEXTL(l); | |
c = CUR_CHAR(l); | |
+ if (len > maxLength) { | |
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken"); | |
+ xmlFree(buffer); | |
+ return(NULL); | |
+ } | |
} | |
buffer[len] = 0; | |
return(buffer); | |
@@ -3738,8 +3804,7 @@ | |
} | |
if (len == 0) | |
return(NULL); | |
- if ((len > XML_MAX_NAME_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
+ if (len > maxLength) { | |
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken"); | |
return(NULL); | |
} | |
@@ -3765,6 +3830,9 @@ | |
int len = 0; | |
int size = XML_PARSER_BUFFER_SIZE; | |
int c, l; | |
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ? | |
+ XML_MAX_HUGE_LENGTH : | |
+ XML_MAX_TEXT_LENGTH; | |
xmlChar stop; | |
xmlChar *ret = NULL; | |
const xmlChar *cur = NULL; | |
@@ -3824,6 +3892,12 @@ | |
GROW; | |
c = CUR_CHAR(l); | |
} | |
+ | |
+ if (len > maxLength) { | |
+ xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_NOT_FINISHED, | |
+ "entity value too long\n"); | |
+ goto error; | |
+ } | |
} | |
buf[len] = 0; | |
if (ctxt->instate == XML_PARSER_EOF) | |
@@ -3911,6 +3985,9 @@ | |
xmlChar *rep = NULL; | |
size_t len = 0; | |
size_t buf_size = 0; | |
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ? | |
+ XML_MAX_HUGE_LENGTH : | |
+ XML_MAX_TEXT_LENGTH; | |
int c, l, in_space = 0; | |
xmlChar *current = NULL; | |
xmlEntityPtr ent; | |
@@ -3942,16 +4019,6 @@ | |
while (((NXT(0) != limit) && /* checked */ | |
(IS_CHAR(c)) && (c != '<')) && | |
(ctxt->instate != XML_PARSER_EOF)) { | |
- /* | |
- * Impose a reasonable limit on attribute size, unless XML_PARSE_HUGE | |
- * special option is given | |
- */ | |
- if ((len > XML_MAX_TEXT_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
- xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED, | |
- "AttValue length too long\n"); | |
- goto mem_error; | |
- } | |
if (c == '&') { | |
in_space = 0; | |
if (NXT(1) == '#') { | |
@@ -4099,6 +4166,11 @@ | |
} | |
GROW; | |
c = CUR_CHAR(l); | |
+ if (len > maxLength) { | |
+ xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED, | |
+ "AttValue length too long\n"); | |
+ goto mem_error; | |
+ } | |
} | |
if (ctxt->instate == XML_PARSER_EOF) | |
goto error; | |
@@ -4120,16 +4192,6 @@ | |
} else | |
NEXT; | |
- /* | |
- * There we potentially risk an overflow, don't allow attribute value of | |
- * length more than INT_MAX it is a very reasonable assumption ! | |
- */ | |
- if (len >= INT_MAX) { | |
- xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED, | |
- "AttValue length too long\n"); | |
- goto mem_error; | |
- } | |
- | |
if (attlen != NULL) *attlen = (int) len; | |
return(buf); | |
@@ -4200,6 +4262,9 @@ | |
int len = 0; | |
int size = XML_PARSER_BUFFER_SIZE; | |
int cur, l; | |
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ? | |
+ XML_MAX_TEXT_LENGTH : | |
+ XML_MAX_NAME_LENGTH; | |
xmlChar stop; | |
int state = ctxt->instate; | |
int count = 0; | |
@@ -4227,13 +4292,6 @@ | |
if (len + 5 >= size) { | |
xmlChar *tmp; | |
- if ((size > XML_MAX_NAME_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral"); | |
- xmlFree(buf); | |
- ctxt->instate = (xmlParserInputState) state; | |
- return(NULL); | |
- } | |
size *= 2; | |
tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar)); | |
if (tmp == NULL) { | |
@@ -4262,6 +4320,12 @@ | |
SHRINK; | |
cur = CUR_CHAR(l); | |
} | |
+ if (len > maxLength) { | |
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral"); | |
+ xmlFree(buf); | |
+ ctxt->instate = (xmlParserInputState) state; | |
+ return(NULL); | |
+ } | |
} | |
buf[len] = 0; | |
ctxt->instate = (xmlParserInputState) state; | |
@@ -4289,6 +4353,9 @@ | |
xmlChar *buf = NULL; | |
int len = 0; | |
int size = XML_PARSER_BUFFER_SIZE; | |
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ? | |
+ XML_MAX_TEXT_LENGTH : | |
+ XML_MAX_NAME_LENGTH; | |
xmlChar cur; | |
xmlChar stop; | |
int count = 0; | |
@@ -4316,12 +4383,6 @@ | |
if (len + 1 >= size) { | |
xmlChar *tmp; | |
- if ((size > XML_MAX_NAME_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID"); | |
- xmlFree(buf); | |
- return(NULL); | |
- } | |
size *= 2; | |
tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar)); | |
if (tmp == NULL) { | |
@@ -4349,6 +4410,11 @@ | |
SHRINK; | |
cur = CUR; | |
} | |
+ if (len > maxLength) { | |
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID"); | |
+ xmlFree(buf); | |
+ return(NULL); | |
+ } | |
} | |
buf[len] = 0; | |
if (cur != stop) { | |
@@ -4488,7 +4554,8 @@ | |
if (*in == ']') { | |
if ((in[1] == ']') && (in[2] == '>')) { | |
xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL); | |
- ctxt->input->cur = in + 1; | |
+ if (ctxt->instate != XML_PARSER_EOF) | |
+ ctxt->input->cur = in + 1; | |
return; | |
} | |
in++; | |
@@ -4524,8 +4591,7 @@ | |
line = ctxt->input->line; | |
col = ctxt->input->col; | |
} | |
- /* something really bad happened in the SAX callback */ | |
- if (ctxt->instate != XML_PARSER_CONTENT) | |
+ if (ctxt->instate == XML_PARSER_EOF) | |
return; | |
} | |
ctxt->input->cur = in; | |
@@ -4748,6 +4814,9 @@ | |
int r, rl; | |
int cur, l; | |
size_t count = 0; | |
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ? | |
+ XML_MAX_HUGE_LENGTH : | |
+ XML_MAX_TEXT_LENGTH; | |
int inputid; | |
inputid = ctxt->input->id; | |
@@ -4793,13 +4862,6 @@ | |
if ((r == '-') && (q == '-')) { | |
xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL); | |
} | |
- if ((len > XML_MAX_TEXT_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
- xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED, | |
- "Comment too big found", NULL); | |
- xmlFree (buf); | |
- return; | |
- } | |
if (len + 5 >= size) { | |
xmlChar *new_buf; | |
size_t new_size; | |
@@ -4837,6 +4899,13 @@ | |
GROW; | |
cur = CUR_CHAR(l); | |
} | |
+ | |
+ if (len > maxLength) { | |
+ xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED, | |
+ "Comment too big found", NULL); | |
+ xmlFree (buf); | |
+ return; | |
+ } | |
} | |
buf[len] = 0; | |
if (cur == 0) { | |
@@ -4881,6 +4950,9 @@ | |
xmlChar *buf = NULL; | |
size_t size = XML_PARSER_BUFFER_SIZE; | |
size_t len = 0; | |
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ? | |
+ XML_MAX_HUGE_LENGTH : | |
+ XML_MAX_TEXT_LENGTH; | |
xmlParserInputState state; | |
const xmlChar *in; | |
size_t nbchar = 0; | |
@@ -4964,8 +5036,7 @@ | |
buf[len] = 0; | |
} | |
} | |
- if ((len > XML_MAX_TEXT_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
+ if (len > maxLength) { | |
xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED, | |
"Comment too big found", NULL); | |
xmlFree (buf); | |
@@ -5036,7 +5107,8 @@ | |
} | |
} while (((*in >= 0x20) && (*in <= 0x7F)) || (*in == 0x09) || (*in == 0x0a)); | |
xmlParseCommentComplex(ctxt, buf, len, size); | |
- ctxt->instate = state; | |
+ if (ctxt->instate != XML_PARSER_EOF) | |
+ ctxt->instate = state; | |
return; | |
} | |
@@ -5165,6 +5237,9 @@ | |
xmlChar *buf = NULL; | |
size_t len = 0; | |
size_t size = XML_PARSER_BUFFER_SIZE; | |
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ? | |
+ XML_MAX_HUGE_LENGTH : | |
+ XML_MAX_TEXT_LENGTH; | |
int cur, l; | |
const xmlChar *target; | |
xmlParserInputState state; | |
@@ -5240,14 +5315,6 @@ | |
return; | |
} | |
count = 0; | |
- if ((len > XML_MAX_TEXT_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
- xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED, | |
- "PI %s too big found", target); | |
- xmlFree(buf); | |
- ctxt->instate = state; | |
- return; | |
- } | |
} | |
COPY_BUF(l,buf,len,cur); | |
NEXTL(l); | |
@@ -5257,15 +5324,14 @@ | |
GROW; | |
cur = CUR_CHAR(l); | |
} | |
+ if (len > maxLength) { | |
+ xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED, | |
+ "PI %s too big found", target); | |
+ xmlFree(buf); | |
+ ctxt->instate = state; | |
+ return; | |
+ } | |
} | |
- if ((len > XML_MAX_TEXT_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
- xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED, | |
- "PI %s too big found", target); | |
- xmlFree(buf); | |
- ctxt->instate = state; | |
- return; | |
- } | |
buf[len] = 0; | |
if (cur != '?') { | |
xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED, | |
@@ -5331,8 +5397,8 @@ | |
if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) { | |
int inputid = ctxt->input->id; | |
- SHRINK; | |
SKIP(10); | |
+ SHRINK; | |
if (SKIP_BLANKS == 0) { | |
xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, | |
"Space required after '<!NOTATION'\n"); | |
@@ -5413,8 +5479,8 @@ | |
/* GROW; done in the caller */ | |
if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) { | |
int inputid = ctxt->input->id; | |
- SHRINK; | |
SKIP(8); | |
+ SHRINK; | |
if (SKIP_BLANKS == 0) { | |
xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, | |
"Space required after '<!ENTITY'\n"); | |
@@ -5928,33 +5994,36 @@ | |
*/ | |
int | |
xmlParseAttributeType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) { | |
- SHRINK; | |
+ int ret = 0; | |
if (CMP5(CUR_PTR, 'C', 'D', 'A', 'T', 'A')) { | |
SKIP(5); | |
- return(XML_ATTRIBUTE_CDATA); | |
+ ret = XML_ATTRIBUTE_CDATA; | |
} else if (CMP6(CUR_PTR, 'I', 'D', 'R', 'E', 'F', 'S')) { | |
SKIP(6); | |
- return(XML_ATTRIBUTE_IDREFS); | |
+ ret = XML_ATTRIBUTE_IDREFS; | |
} else if (CMP5(CUR_PTR, 'I', 'D', 'R', 'E', 'F')) { | |
SKIP(5); | |
- return(XML_ATTRIBUTE_IDREF); | |
+ ret = XML_ATTRIBUTE_IDREF; | |
} else if ((RAW == 'I') && (NXT(1) == 'D')) { | |
SKIP(2); | |
- return(XML_ATTRIBUTE_ID); | |
+ ret = XML_ATTRIBUTE_ID; | |
} else if (CMP6(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'Y')) { | |
SKIP(6); | |
- return(XML_ATTRIBUTE_ENTITY); | |
+ ret = XML_ATTRIBUTE_ENTITY; | |
} else if (CMP8(CUR_PTR, 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S')) { | |
SKIP(8); | |
- return(XML_ATTRIBUTE_ENTITIES); | |
+ ret = XML_ATTRIBUTE_ENTITIES; | |
} else if (CMP8(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S')) { | |
SKIP(8); | |
- return(XML_ATTRIBUTE_NMTOKENS); | |
+ ret = XML_ATTRIBUTE_NMTOKENS; | |
} else if (CMP7(CUR_PTR, 'N', 'M', 'T', 'O', 'K', 'E', 'N')) { | |
SKIP(7); | |
- return(XML_ATTRIBUTE_NMTOKEN); | |
+ ret = XML_ATTRIBUTE_NMTOKEN; | |
+ } else { | |
+ ret = xmlParseEnumeratedType(ctxt, tree); | |
} | |
- return(xmlParseEnumeratedType(ctxt, tree)); | |
+ SHRINK; | |
+ return(ret); | |
} | |
/** | |
@@ -7211,8 +7280,8 @@ | |
ent->checked = diff * 2; | |
if ((ent->content != NULL) && (xmlStrchr(ent->content, '<'))) | |
ent->checked |= 1; | |
- if (ret == XML_ERR_ENTITY_LOOP) { | |
- xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL); | |
+ if (ret == XML_ERR_ENTITY_LOOP || ret == XML_ERR_USER_STOP) { | |
+ xmlFatalErr(ctxt, ret, NULL); | |
xmlHaltParser(ctxt); | |
xmlFreeNodeList(list); | |
return; | |
@@ -8957,6 +9026,9 @@ | |
const xmlChar *in = NULL, *start, *end, *last; | |
xmlChar *ret = NULL; | |
int line, col; | |
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ? | |
+ XML_MAX_HUGE_LENGTH : | |
+ XML_MAX_TEXT_LENGTH; | |
GROW; | |
in = (xmlChar *) CUR_PTR; | |
@@ -8996,8 +9068,7 @@ | |
start = in; | |
if (in >= end) { | |
GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end) | |
- if (((in - start) > XML_MAX_TEXT_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
+ if ((in - start) > maxLength) { | |
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED, | |
"AttValue length too long\n"); | |
return(NULL); | |
@@ -9010,8 +9081,7 @@ | |
if ((*in++ == 0x20) && (*in == 0x20)) break; | |
if (in >= end) { | |
GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end) | |
- if (((in - start) > XML_MAX_TEXT_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
+ if ((in - start) > maxLength) { | |
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED, | |
"AttValue length too long\n"); | |
return(NULL); | |
@@ -9044,16 +9114,14 @@ | |
last = last + delta; | |
} | |
end = ctxt->input->end; | |
- if (((in - start) > XML_MAX_TEXT_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
+ if ((in - start) > maxLength) { | |
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED, | |
"AttValue length too long\n"); | |
return(NULL); | |
} | |
} | |
} | |
- if (((in - start) > XML_MAX_TEXT_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
+ if ((in - start) > maxLength) { | |
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED, | |
"AttValue length too long\n"); | |
return(NULL); | |
@@ -9066,8 +9134,7 @@ | |
col++; | |
if (in >= end) { | |
GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end) | |
- if (((in - start) > XML_MAX_TEXT_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
+ if ((in - start) > maxLength) { | |
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED, | |
"AttValue length too long\n"); | |
return(NULL); | |
@@ -9075,8 +9142,7 @@ | |
} | |
} | |
last = in; | |
- if (((in - start) > XML_MAX_TEXT_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
+ if ((in - start) > maxLength) { | |
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED, | |
"AttValue length too long\n"); | |
return(NULL); | |
@@ -9261,7 +9327,7 @@ | |
int maxatts = ctxt->maxatts; | |
int nratts, nbatts, nbdef, inputid; | |
int i, j, nbNs, attval; | |
- unsigned long cur; | |
+ size_t cur; | |
int nsNr = ctxt->nsNr; | |
if (RAW != '<') return(NULL); | |
@@ -9509,10 +9575,10 @@ | |
* Arithmetic on dangling pointers is technically undefined | |
* behavior, but well... | |
*/ | |
- ptrdiff_t offset = ctxt->input->base - atts[i+2]; | |
+ const xmlChar *old = atts[i+2]; | |
atts[i+2] = NULL; /* Reset repurposed namespace URI */ | |
- atts[i+3] += offset; /* value */ | |
- atts[i+4] += offset; /* valuend */ | |
+ atts[i+3] = ctxt->input->base + (atts[i+3] - old); /* value */ | |
+ atts[i+4] = ctxt->input->base + (atts[i+4] - old); /* valuend */ | |
} | |
} | |
@@ -9766,6 +9832,9 @@ | |
int s, sl; | |
int cur, l; | |
int count = 0; | |
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ? | |
+ XML_MAX_HUGE_LENGTH : | |
+ XML_MAX_TEXT_LENGTH; | |
/* Check 2.6.0 was NXT(0) not RAW */ | |
if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) { | |
@@ -9799,13 +9868,6 @@ | |
if (len + 5 >= size) { | |
xmlChar *tmp; | |
- if ((size > XML_MAX_TEXT_LENGTH) && | |
- ((ctxt->options & XML_PARSE_HUGE) == 0)) { | |
- xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED, | |
- "CData section too big found", NULL); | |
- xmlFree (buf); | |
- return; | |
- } | |
tmp = (xmlChar *) xmlRealloc(buf, size * 2 * sizeof(xmlChar)); | |
if (tmp == NULL) { | |
xmlFree(buf); | |
@@ -9832,6 +9894,12 @@ | |
} | |
NEXTL(l); | |
cur = CUR_CHAR(l); | |
+ if (len > maxLength) { | |
+ xmlFatalErrMsg(ctxt, XML_ERR_CDATA_NOT_FINISHED, | |
+ "CData section too big found\n"); | |
+ xmlFree(buf); | |
+ return; | |
+ } | |
} | |
buf[len] = 0; | |
ctxt->instate = XML_PARSER_CONTENT; | |
@@ -9895,7 +9963,8 @@ | |
else if ((*cur == '<') && (NXT(1) == '!') && | |
(NXT(2) == '-') && (NXT(3) == '-')) { | |
xmlParseComment(ctxt); | |
- ctxt->instate = XML_PARSER_CONTENT; | |
+ if (ctxt->instate != XML_PARSER_EOF) | |
+ ctxt->instate = XML_PARSER_CONTENT; | |
} | |
/* | |
@@ -10012,7 +10081,7 @@ | |
const xmlChar *URI = NULL; | |
xmlParserNodeInfo node_info; | |
int line, tlen = 0; | |
- xmlNodePtr ret; | |
+ xmlNodePtr cur; | |
int nsNr = ctxt->nsNr; | |
if (((unsigned int) ctxt->nameNr > xmlParserMaxDepth) && | |
@@ -10054,7 +10123,7 @@ | |
return(-1); | |
} | |
nameNsPush(ctxt, name, prefix, URI, line, ctxt->nsNr - nsNr); | |
- ret = ctxt->node; | |
+ cur = ctxt->node; | |
#ifdef LIBXML_VALID_ENABLED | |
/* | |
@@ -10087,17 +10156,23 @@ | |
spacePop(ctxt); | |
if (nsNr != ctxt->nsNr) | |
nsPop(ctxt, ctxt->nsNr - nsNr); | |
- if ( ret != NULL && ctxt->record_info ) { | |
- node_info.end_pos = ctxt->input->consumed + | |
- (CUR_PTR - ctxt->input->base); | |
- node_info.end_line = ctxt->input->line; | |
- node_info.node = ret; | |
- xmlParserAddNodeInfo(ctxt, &node_info); | |
+ if (cur != NULL && ctxt->record_info) { | |
+ node_info.node = cur; | |
+ node_info.end_pos = ctxt->input->consumed + | |
+ (CUR_PTR - ctxt->input->base); | |
+ node_info.end_line = ctxt->input->line; | |
+ xmlParserAddNodeInfo(ctxt, &node_info); | |
} | |
return(1); | |
} | |
if (RAW == '>') { | |
NEXT1; | |
+ if (cur != NULL && ctxt->record_info) { | |
+ node_info.node = cur; | |
+ node_info.end_pos = 0; | |
+ node_info.end_line = 0; | |
+ xmlParserAddNodeInfo(ctxt, &node_info); | |
+ } | |
} else { | |
xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_GT_REQUIRED, | |
"Couldn't find end of Start Tag %s line %d\n", | |
@@ -10111,17 +10186,6 @@ | |
spacePop(ctxt); | |
if (nsNr != ctxt->nsNr) | |
nsPop(ctxt, ctxt->nsNr - nsNr); | |
- | |
- /* | |
- * Capture end position and add node | |
- */ | |
- if ( ret != NULL && ctxt->record_info ) { | |
- node_info.end_pos = ctxt->input->consumed + | |
- (CUR_PTR - ctxt->input->base); | |
- node_info.end_line = ctxt->input->line; | |
- node_info.node = ret; | |
- xmlParserAddNodeInfo(ctxt, &node_info); | |
- } | |
return(-1); | |
} | |
@@ -10136,8 +10200,7 @@ | |
*/ | |
static void | |
xmlParseElementEnd(xmlParserCtxtPtr ctxt) { | |
- xmlParserNodeInfo node_info; | |
- xmlNodePtr ret = ctxt->node; | |
+ xmlNodePtr cur = ctxt->node; | |
if (ctxt->nameNr <= 0) | |
return; | |
@@ -10155,14 +10218,17 @@ | |
#endif /* LIBXML_SAX1_ENABLED */ | |
/* | |
- * Capture end position and add node | |
+ * Capture end position | |
*/ | |
- if ( ret != NULL && ctxt->record_info ) { | |
- node_info.end_pos = ctxt->input->consumed + | |
- (CUR_PTR - ctxt->input->base); | |
- node_info.end_line = ctxt->input->line; | |
- node_info.node = ret; | |
- xmlParserAddNodeInfo(ctxt, &node_info); | |
+ if (cur != NULL && ctxt->record_info) { | |
+ xmlParserNodeInfoPtr node_info; | |
+ | |
+ node_info = (xmlParserNodeInfoPtr) xmlParserFindNodeInfo(ctxt, cur); | |
+ if (node_info != NULL) { | |
+ node_info->end_pos = ctxt->input->consumed + | |
+ (CUR_PTR - ctxt->input->base); | |
+ node_info->end_line = ctxt->input->line; | |
+ } | |
} | |
} | |
@@ -11197,7 +11263,8 @@ | |
static int | |
xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) { | |
int ret = 0; | |
- int avail, tlen; | |
+ int tlen; | |
+ size_t avail; | |
xmlChar cur, next; | |
const xmlChar *lastlt, *lastgt; | |
@@ -11265,7 +11332,7 @@ | |
xmlParseGetLasts(ctxt, &lastlt, &lastgt); | |
while (ctxt->instate != XML_PARSER_EOF) { | |
- if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1)) | |
+ if ((ctxt->wellFormed != 1) && (ctxt->disableSAX == 1)) | |
return(0); | |
if (ctxt->input == NULL) break; | |
@@ -12157,7 +12224,11 @@ | |
#endif | |
return(ret); | |
encoding_error: | |
- { | |
+ if (ctxt->input->end - ctxt->input->cur < 4) { | |
+ __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR, | |
+ "Input is not proper UTF-8, indicate encoding !\n", | |
+ NULL, NULL); | |
+ } else { | |
char buffer[150]; | |
snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n", | |
@@ -12240,7 +12311,7 @@ | |
if (ctxt == NULL) | |
return(XML_ERR_INTERNAL_ERROR); | |
- if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1)) | |
+ if ((ctxt->wellFormed != 1) && (ctxt->disableSAX == 1)) | |
return(ctxt->errNo); | |
if (ctxt->instate == XML_PARSER_EOF) | |
return(-1); | |
@@ -12356,7 +12427,7 @@ | |
xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup"); | |
xmlHaltParser(ctxt); | |
} | |
- if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1)) | |
+ if ((ctxt->wellFormed != 1) && (ctxt->disableSAX == 1)) | |
return(ctxt->errNo); | |
if (remain != 0) { | |
@@ -12535,41 +12606,6 @@ | |
#endif /* LIBXML_PUSH_ENABLED */ | |
/** | |
- * xmlHaltParser: | |
- * @ctxt: an XML parser context | |
- * | |
- * Blocks further parser processing don't override error | |
- * for internal use | |
- */ | |
-static void | |
-xmlHaltParser(xmlParserCtxtPtr ctxt) { | |
- if (ctxt == NULL) | |
- return; | |
- ctxt->instate = XML_PARSER_EOF; | |
- ctxt->disableSAX = 1; | |
- while (ctxt->inputNr > 1) | |
- xmlFreeInputStream(inputPop(ctxt)); | |
- if (ctxt->input != NULL) { | |
- /* | |
- * in case there was a specific allocation deallocate before | |
- * overriding base | |
- */ | |
- if (ctxt->input->free != NULL) { | |
- ctxt->input->free((xmlChar *) ctxt->input->base); | |
- ctxt->input->free = NULL; | |
- } | |
- if (ctxt->input->buf != NULL) { | |
- xmlFreeParserInputBuffer(ctxt->input->buf); | |
- ctxt->input->buf = NULL; | |
- } | |
- ctxt->input->cur = BAD_CAST""; | |
- ctxt->input->length = 0; | |
- ctxt->input->base = ctxt->input->cur; | |
- ctxt->input->end = ctxt->input->cur; | |
- } | |
-} | |
- | |
-/** | |
* xmlStopParser: | |
* @ctxt: an XML parser context | |
* | |
@@ -13010,9 +13046,9 @@ | |
xmlChar start[4]; | |
xmlCharEncoding enc; | |
- if (((depth > 40) && | |
+ if (((depth > xmlEntityDecodingDepthMax) && | |
((oldctxt == NULL) || (oldctxt->options & XML_PARSE_HUGE) == 0)) || | |
- (depth > 1024)) { | |
+ (depth > xmlEntityDecodingDepthHugeMax)) { | |
return(XML_ERR_ENTITY_LOOP); | |
} | |
@@ -13114,6 +13150,7 @@ | |
ctxt->vctxt.error = oldctxt->vctxt.error; | |
ctxt->vctxt.warning = oldctxt->vctxt.warning; | |
ctxt->vctxt.userData = oldctxt->vctxt.userData; | |
+ ctxt->vctxt.finishDtd = oldctxt->vctxt.finishDtd; | |
} | |
ctxt->external = oldctxt->external; | |
if (ctxt->dict) xmlDictFree(ctxt->dict); | |
@@ -13310,8 +13347,8 @@ | |
int i; | |
#endif | |
- if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) || | |
- (oldctxt->depth > 1024)) { | |
+ if (((oldctxt->depth > xmlEntityDecodingDepthMax) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) || | |
+ (oldctxt->depth > xmlEntityDecodingDepthHugeMax)) { | |
return(XML_ERR_ENTITY_LOOP); | |
} | |
@@ -13734,7 +13771,7 @@ | |
int size; | |
int ret = 0; | |
- if (depth > 40) { | |
+ if (depth > xmlEntityDecodingDepthMax) { | |
return(XML_ERR_ENTITY_LOOP); | |
} | |
@@ -14825,6 +14862,8 @@ | |
ctxt->nameNr = 0; | |
ctxt->name = NULL; | |
+ | |
+ ctxt->nsNr = 0; | |
DICT_FREE(ctxt->version); | |
ctxt->version = NULL; | |
diff -ru libxml2/parserInternals.c libxml2-apple/libxml2/parserInternals.c | |
--- libxml2/parserInternals.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/parserInternals.c 2025-06-26 01:54:56 | |
@@ -61,6 +61,7 @@ | |
#include "buf.h" | |
#include "enc.h" | |
+#include "private/parser.h" | |
/* | |
* Various global defaults for parsing | |
@@ -150,10 +151,13 @@ | |
return; | |
if (ctxt != NULL) | |
ctxt->errNo = xmlerr; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, | |
ctxt, NULL, XML_FROM_PARSER, xmlerr, XML_ERR_FATAL, | |
NULL, 0, (const char *) str1, (const char *) str2, | |
NULL, 0, 0, msg, str1, str2); | |
+#pragma clang diagnostic pop | |
if (ctxt != NULL) { | |
ctxt->wellFormed = 0; | |
if (ctxt->recovery == 0) | |
@@ -177,10 +181,13 @@ | |
return; | |
if (ctxt != NULL) | |
ctxt->errNo = XML_ERR_INTERNAL_ERROR; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, | |
ctxt, NULL, XML_FROM_PARSER, XML_ERR_INTERNAL_ERROR, | |
XML_ERR_FATAL, NULL, 0, (const char *) str, NULL, NULL, | |
0, 0, msg, str); | |
+#pragma clang diagnostic pop | |
if (ctxt != NULL) { | |
ctxt->wellFormed = 0; | |
if (ctxt->recovery == 0) | |
@@ -206,9 +213,12 @@ | |
return; | |
if (ctxt != NULL) | |
ctxt->errNo = error; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, | |
ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL, | |
NULL, 0, NULL, NULL, NULL, val, 0, msg, val); | |
+#pragma clang diagnostic pop | |
if (ctxt != NULL) { | |
ctxt->wellFormed = 0; | |
if (ctxt->recovery == 0) | |
@@ -272,6 +282,41 @@ | |
/** | |
+ * xmlHaltParser: | |
+ * @ctxt: an XML parser context | |
+ * | |
+ * Blocks further parser processing don't override error | |
+ * for internal use | |
+ */ | |
+void | |
+xmlHaltParser(xmlParserCtxtPtr ctxt) { | |
+ if (ctxt == NULL) | |
+ return; | |
+ ctxt->instate = XML_PARSER_EOF; | |
+ ctxt->disableSAX = 1; | |
+ while (ctxt->inputNr > 1) | |
+ xmlFreeInputStream(inputPop(ctxt)); | |
+ if (ctxt->input != NULL) { | |
+ /* | |
+ * in case there was a specific allocation deallocate before | |
+ * overriding base | |
+ */ | |
+ if (ctxt->input->free != NULL) { | |
+ ctxt->input->free((xmlChar *) ctxt->input->base); | |
+ ctxt->input->free = NULL; | |
+ } | |
+ if (ctxt->input->buf != NULL) { | |
+ xmlFreeParserInputBuffer(ctxt->input->buf); | |
+ ctxt->input->buf = NULL; | |
+ } | |
+ ctxt->input->cur = BAD_CAST""; | |
+ ctxt->input->length = 0; | |
+ ctxt->input->base = ctxt->input->cur; | |
+ ctxt->input->end = ctxt->input->cur; | |
+ } | |
+} | |
+ | |
+/** | |
* xmlParserInputRead: | |
* @in: an XML parser input | |
* @len: an indicative size for the lookahead | |
@@ -300,7 +345,6 @@ | |
xmlParserInputGrow(xmlParserInputPtr in, int len) { | |
int ret; | |
size_t indx; | |
- const xmlChar *content; | |
if ((in == NULL) || (len < 0)) return(-1); | |
#ifdef DEBUG_INPUT | |
@@ -325,22 +369,8 @@ | |
} else | |
return(0); | |
- /* | |
- * NOTE : in->base may be a "dangling" i.e. freed pointer in this | |
- * block, but we use it really as an integer to do some | |
- * pointer arithmetic. Insure will raise it as a bug but in | |
- * that specific case, that's not ! | |
- */ | |
- | |
- content = xmlBufContent(in->buf->buffer); | |
- if (in->base != content) { | |
- /* | |
- * the buffer has been reallocated | |
- */ | |
- indx = in->cur - in->base; | |
- in->base = content; | |
- in->cur = &content[indx]; | |
- } | |
+ in->base = xmlBufContent(in->buf->buffer); | |
+ in->cur = in->base + indx; | |
in->end = xmlBufEnd(in->buf->buffer); | |
CHECK_BUFFER(in); | |
@@ -358,8 +388,6 @@ | |
xmlParserInputShrink(xmlParserInputPtr in) { | |
size_t used; | |
size_t ret; | |
- size_t indx; | |
- const xmlChar *content; | |
#ifdef DEBUG_INPUT | |
xmlGenericError(xmlGenericErrorContext, "Shrink\n"); | |
@@ -372,7 +400,7 @@ | |
CHECK_BUFFER(in); | |
- used = in->cur - xmlBufContent(in->buf->buffer); | |
+ used = in->cur - in->base; | |
/* | |
* Do not shrink on large buffers whose only a tiny fraction | |
* was consumed | |
@@ -380,27 +408,17 @@ | |
if (used > INPUT_CHUNK) { | |
ret = xmlBufShrink(in->buf->buffer, used - LINE_LEN); | |
if (ret > 0) { | |
- in->cur -= ret; | |
+ used -= ret; | |
in->consumed += ret; | |
} | |
- in->end = xmlBufEnd(in->buf->buffer); | |
} | |
- CHECK_BUFFER(in); | |
- | |
- if (xmlBufUse(in->buf->buffer) > INPUT_CHUNK) { | |
- return; | |
+ if (xmlBufUse(in->buf->buffer) <= INPUT_CHUNK) { | |
+ xmlParserInputBufferRead(in->buf, 2 * INPUT_CHUNK); | |
} | |
- xmlParserInputBufferRead(in->buf, 2 * INPUT_CHUNK); | |
- content = xmlBufContent(in->buf->buffer); | |
- if (in->base != content) { | |
- /* | |
- * the buffer has been reallocated | |
- */ | |
- indx = in->cur - in->base; | |
- in->base = content; | |
- in->cur = &content[indx]; | |
- } | |
+ | |
+ in->base = xmlBufContent(in->buf->buffer); | |
+ in->cur = in->base + used; | |
in->end = xmlBufEnd(in->buf->buffer); | |
CHECK_BUFFER(in); | |
@@ -433,7 +451,7 @@ | |
return; | |
} | |
- if ((*ctxt->input->cur == 0) && | |
+ if ((ctxt->input->end - ctxt->input->cur < 1) && | |
(xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) { | |
return; | |
} | |
@@ -468,30 +486,38 @@ | |
c = *cur; | |
if (c & 0x80) { | |
+ size_t avail; | |
+ | |
if (c == 0xC0) | |
goto encoding_error; | |
- if (cur[1] == 0) { | |
+ | |
+ avail = ctxt->input->end - ctxt->input->cur; | |
+ | |
+ if (avail < 2) { | |
xmlParserInputGrow(ctxt->input, INPUT_CHUNK); | |
cur = ctxt->input->cur; | |
+ avail = ctxt->input->end - ctxt->input->cur; | |
} | |
- if ((cur[1] & 0xc0) != 0x80) | |
+ if ((avail < 2) || (cur[1] & 0xc0) != 0x80) | |
goto encoding_error; | |
if ((c & 0xe0) == 0xe0) { | |
unsigned int val; | |
- if (cur[2] == 0) { | |
+ if (avail < 3) { | |
xmlParserInputGrow(ctxt->input, INPUT_CHUNK); | |
cur = ctxt->input->cur; | |
+ avail = ctxt->input->end - ctxt->input->cur; | |
} | |
- if ((cur[2] & 0xc0) != 0x80) | |
+ if ((avail < 3) || (cur[2] & 0xc0) != 0x80) | |
goto encoding_error; | |
if ((c & 0xf0) == 0xf0) { | |
- if (cur[3] == 0) { | |
+ if (avail < 4) { | |
xmlParserInputGrow(ctxt->input, INPUT_CHUNK); | |
cur = ctxt->input->cur; | |
+ avail = ctxt->input->end - ctxt->input->cur; | |
} | |
if (((c & 0xf8) != 0xf0) || | |
- ((cur[3] & 0xc0) != 0x80)) | |
+ (avail < 4) || ((cur[3] & 0xc0) != 0x80)) | |
goto encoding_error; | |
/* 4-byte code */ | |
ctxt->input->cur += 4; | |
@@ -532,7 +558,7 @@ | |
ctxt->input->col++; | |
ctxt->input->cur++; | |
} | |
- if (*ctxt->input->cur == 0) | |
+ if (ctxt->input->end - ctxt->input->cur < 1) | |
xmlParserInputGrow(ctxt->input, INPUT_CHUNK); | |
return; | |
encoding_error: | |
@@ -609,28 +635,36 @@ | |
c = *cur; | |
if (c & 0x80) { | |
+ size_t avail; | |
+ | |
if (((c & 0x40) == 0) || (c == 0xC0)) | |
goto encoding_error; | |
- if (cur[1] == 0) { | |
+ | |
+ avail = ctxt->input->end - ctxt->input->cur; | |
+ | |
+ if (avail < 2) { | |
xmlParserInputGrow(ctxt->input, INPUT_CHUNK); | |
cur = ctxt->input->cur; | |
+ avail = ctxt->input->end - ctxt->input->cur; | |
} | |
- if ((cur[1] & 0xc0) != 0x80) | |
+ if ((avail < 2) || (cur[1] & 0xc0) != 0x80) | |
goto encoding_error; | |
if ((c & 0xe0) == 0xe0) { | |
- if (cur[2] == 0) { | |
+ if (avail < 3) { | |
xmlParserInputGrow(ctxt->input, INPUT_CHUNK); | |
cur = ctxt->input->cur; | |
+ avail = ctxt->input->end - ctxt->input->cur; | |
} | |
- if ((cur[2] & 0xc0) != 0x80) | |
+ if ((avail < 3) || (cur[2] & 0xc0) != 0x80) | |
goto encoding_error; | |
if ((c & 0xf0) == 0xf0) { | |
- if (cur[3] == 0) { | |
+ if (avail < 4) { | |
xmlParserInputGrow(ctxt->input, INPUT_CHUNK); | |
cur = ctxt->input->cur; | |
+ avail = ctxt->input->end - ctxt->input->cur; | |
} | |
if (((c & 0xf8) != 0xf0) || | |
- ((cur[3] & 0xc0) != 0x80)) | |
+ (avail < 4) || ((cur[3] & 0xc0) != 0x80)) | |
goto encoding_error; | |
/* 4-byte code */ | |
*len = 4; | |
@@ -660,17 +694,21 @@ | |
if (!IS_CHAR(val)) { | |
xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR, | |
"Char 0x%X out of allowed range\n", val); | |
+ if (ctxt->instate == XML_PARSER_EOF) | |
+ goto encoding_error; | |
} | |
return(val); | |
} else { | |
/* 1-byte code */ | |
*len = 1; | |
- if (*ctxt->input->cur == 0) | |
+ if (ctxt->input->end - ctxt->input->cur < 1) | |
xmlParserInputGrow(ctxt->input, INPUT_CHUNK); | |
if ((*ctxt->input->cur == 0) && | |
(ctxt->input->end > ctxt->input->cur)) { | |
xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR, | |
"Char 0x0 out of allowed range\n", 0); | |
+ if (ctxt->instate == XML_PARSER_EOF) | |
+ goto encoding_error; | |
} | |
if (*ctxt->input->cur == 0xD) { | |
if (ctxt->input->cur[1] == 0xA) { | |
@@ -1098,9 +1136,9 @@ | |
} | |
ctxt->charset = XML_CHAR_ENCODING_UTF8; | |
ret = xmlSwitchToEncodingInt(ctxt, handler, len); | |
- if ((ret < 0) || (ctxt->errNo == XML_I18N_CONV_FAILED)) { | |
+ if (((ret < 0) || (ctxt->errNo == XML_I18N_CONV_FAILED)) && !(ctxt->html)) { | |
/* | |
- * on encoding conversion errors, stop the parser | |
+ * on XML encoding conversion errors, stop the parser | |
*/ | |
xmlStopParser(ctxt); | |
ctxt->errNo = XML_I18N_CONV_FAILED; | |
@@ -1169,9 +1207,16 @@ | |
* Is there already some content down the pipe to convert ? | |
*/ | |
if (xmlBufIsEmpty(input->buf->buffer) == 0) { | |
+ xmlBufPtr buf; | |
int processed; | |
unsigned int use; | |
+ buf = xmlBufCreate(); | |
+ if (buf == NULL) { | |
+ xmlErrMemory(ctxt, NULL); | |
+ return(-1); | |
+ } | |
+ | |
/* | |
* Specific handling of the Byte Order Mark for | |
* UTF-16 | |
@@ -1206,7 +1251,7 @@ | |
processed = input->cur - input->base; | |
xmlBufShrink(input->buf->buffer, processed); | |
input->buf->raw = input->buf->buffer; | |
- input->buf->buffer = xmlBufCreate(); | |
+ input->buf->buffer = buf; | |
input->buf->rawconsumed = processed; | |
use = xmlBufUse(input->buf->raw); | |
@@ -1226,9 +1271,13 @@ | |
} | |
xmlBufResetInput(input->buf->buffer, input); | |
if (nbchars < 0) { | |
- xmlErrInternal(ctxt, | |
- "switching encoding: encoder error\n", | |
- NULL); | |
+ /* TODO: This could be an out of memory or an encoding error. */ | |
+ if (!ctxt->html) { | |
+ xmlErrInternal(ctxt, | |
+ "switching encoding: encoder error\n", | |
+ NULL); | |
+ xmlHaltParser(ctxt); | |
+ } | |
return (-1); | |
} | |
input->buf->rawconsumed += use - xmlBufUse(input->buf->raw); | |
@@ -1377,8 +1426,13 @@ | |
* should not happen while parsing which is the situation where | |
* the id is actually needed. | |
*/ | |
- if (ctxt != NULL) | |
+ if (ctxt != NULL) { | |
+ if (input->id >= INT_MAX) { | |
+ xmlErrMemory(ctxt, "Input ID overflow\n"); | |
+ return(NULL); | |
+ } | |
input->id = ctxt->input_id++; | |
+ } | |
return(input); | |
} | |
diff -ru libxml2/python/generator.py libxml2-apple/libxml2/python/generator.py | |
--- libxml2/python/generator.py 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/python/generator.py 2025-06-26 01:54:56 | |
@@ -289,6 +289,15 @@ | |
'xmlSaveFormatFileTo', | |
) | |
+deprecated_funcs = { | |
+ 'xmlXPtrEvalRangePredicate': True, | |
+ 'xmlXPtrNewCollapsedRange': True, | |
+ 'xmlXPtrNewLocationSetNodes': True, | |
+ 'xmlXPtrNewRange': True, | |
+ 'xmlXPtrNewRangeNodes': True, | |
+ 'xmlXPtrRangeToFunction': True, | |
+} | |
+ | |
def skip_function(name): | |
if name[0:12] == "xmlXPathWrap": | |
return 1 | |
Only in libxml2-apple/libxml2/python: libxml2class.txt | |
diff -ru libxml2/python/types.c libxml2-apple/libxml2/python/types.c | |
--- libxml2/python/types.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/python/types.c 2025-06-26 01:54:56 | |
@@ -603,6 +603,7 @@ | |
case XPATH_STRING: | |
ret = PY_IMPORT_STRING((char *) obj->stringval); | |
break; | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
{ | |
PyObject *node; | |
@@ -704,6 +705,7 @@ | |
} | |
break; | |
} | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
default: | |
#ifdef DEBUG | |
printf("Unable to convert XPath object type %d\n", obj->type); | |
diff -ru libxml2/relaxng.c libxml2-apple/libxml2/relaxng.c | |
--- libxml2/relaxng.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/relaxng.c 2025-06-26 01:54:56 | |
@@ -524,11 +524,14 @@ | |
data = ctxt->userData; | |
ctxt->nbErrors++; | |
} | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, channel, data, | |
NULL, node, XML_FROM_RELAXNGP, | |
error, XML_ERR_ERROR, NULL, 0, | |
(const char *) str1, (const char *) str2, NULL, 0, 0, | |
msg, str1, str2); | |
+#pragma clang diagnostic pop | |
} | |
/** | |
@@ -558,11 +561,14 @@ | |
data = ctxt->userData; | |
ctxt->nbErrors++; | |
} | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, channel, data, | |
NULL, node, XML_FROM_RELAXNGV, | |
error, XML_ERR_ERROR, NULL, 0, | |
(const char *) str1, (const char *) str2, NULL, 0, 0, | |
msg, str1, str2); | |
+#pragma clang diagnostic pop | |
} | |
/************************************************************************ | |
@@ -2266,8 +2272,11 @@ | |
if (ctxt->errNo == XML_RELAXNG_OK) | |
ctxt->errNo = err; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
xmlRngVErr(ctxt, (child == NULL ? node : child), err, | |
(const char *) msg, arg1, arg2); | |
+#pragma clang diagnostic pop | |
xmlFree(msg); | |
} | |
@@ -5388,7 +5397,7 @@ | |
if (tmp != NULL) { | |
if (last == NULL) { | |
last = tmp; | |
- } else { | |
+ } else if (tmp != ret) { | |
last->next = tmp; | |
last = tmp; | |
} | |
Only in libxml2-apple/libxml2/result/HTML: apple_760263-2.html | |
Only in libxml2-apple/libxml2/result/HTML: apple_760263-2.html.err | |
Only in libxml2-apple/libxml2/result/HTML: apple_760263-2.html.sax | |
Only in libxml2-apple/libxml2/result/HTML: apple_760263.html | |
Only in libxml2-apple/libxml2/result/HTML: apple_760263.html.err | |
Only in libxml2-apple/libxml2/result/HTML: apple_760263.html.sax | |
Only in libxml2-apple/libxml2/result/HTML: apple_765468.html | |
Only in libxml2-apple/libxml2/result/HTML: apple_765468.html.err | |
Only in libxml2-apple/libxml2/result/HTML: apple_765468.html.sax | |
Only in libxml2-apple/libxml2/result/HTML: encoding-incorrect-shift_jis.html | |
Only in libxml2-apple/libxml2/result/HTML: encoding-incorrect-shift_jis.html.err | |
Only in libxml2-apple/libxml2/result/HTML: encoding-incorrect-shift_jis.html.sax | |
Only in libxml2-apple/libxml2/result/HTML: encoding-shift_jis.html | |
Only in libxml2-apple/libxml2/result/HTML: encoding-shift_jis.html.err | |
Only in libxml2-apple/libxml2/result/HTML: encoding-shift_jis.html.sax | |
Only in libxml2-apple/libxml2/result/HTML: encoding-utf-8.html | |
Only in libxml2-apple/libxml2/result/HTML: encoding-utf-8.html.err | |
Only in libxml2-apple/libxml2/result/HTML: encoding-utf-8.html.sax | |
Only in libxml2-apple/libxml2/result/XInclude: coalesce.xml | |
Only in libxml2-apple/libxml2/result/XInclude: coalesce.xml.rdr | |
Only in libxml2-apple/libxml2/result/XInclude: fallback5.xml.err | |
Only in libxml2-apple/libxml2/result/XInclude: fallback6.xml.err | |
Only in libxml2-apple/libxml2/result/XInclude: ns1.xml.err | |
Only in libxml2-apple/libxml2/result: encoding-shift_jis.xhtml | |
Only in libxml2-apple/libxml2/result: encoding-shift_jis.xhtml.rde | |
Only in libxml2-apple/libxml2/result: encoding-shift_jis.xhtml.rdr | |
Only in libxml2-apple/libxml2/result: encoding-shift_jis.xhtml.sax | |
Only in libxml2-apple/libxml2/result: encoding-shift_jis.xhtml.sax2 | |
Only in libxml2-apple/libxml2/result: encoding-utf-8.xhtml | |
Only in libxml2-apple/libxml2/result: encoding-utf-8.xhtml.rde | |
Only in libxml2-apple/libxml2/result: encoding-utf-8.xhtml.rdr | |
Only in libxml2-apple/libxml2/result: encoding-utf-8.xhtml.sax | |
Only in libxml2-apple/libxml2/result: encoding-utf-8.xhtml.sax2 | |
Only in libxml2-apple/libxml2/result/errors: 766956-1.xml | |
Only in libxml2-apple/libxml2/result/errors: 766956-1.xml.ent | |
Only in libxml2-apple/libxml2/result/errors: 766956-1.xml.err | |
Only in libxml2-apple/libxml2/result/errors: 766956-1.xml.str | |
Only in libxml2-apple/libxml2/result/errors: 766956-2.xml | |
Only in libxml2-apple/libxml2/result/errors: 766956-2.xml.ent | |
Only in libxml2-apple/libxml2/result/errors: 766956-2.xml.err | |
Only in libxml2-apple/libxml2/result/errors: 766956-2.xml.str | |
Only in libxml2-apple/libxml2/result/errors: 769855-1.xml | |
Only in libxml2-apple/libxml2/result/errors: 769855-1.xml.ent | |
Only in libxml2-apple/libxml2/result/errors: 769855-1.xml.err | |
Only in libxml2-apple/libxml2/result/errors: 769855-1.xml.str | |
Only in libxml2-apple/libxml2/result/errors: 769855-2.xml | |
Only in libxml2-apple/libxml2/result/errors: 769855-2.xml.ent | |
Only in libxml2-apple/libxml2/result/errors: 769855-2.xml.err | |
Only in libxml2-apple/libxml2/result/errors: 769855-2.xml.str | |
Only in libxml2-apple/libxml2/result/errors: crbug-602280.xml | |
Only in libxml2-apple/libxml2/result/errors: crbug-602280.xml.ent | |
Only in libxml2-apple/libxml2/result/errors: crbug-602280.xml.err | |
Only in libxml2-apple/libxml2/result/errors: crbug-602280.xml.str | |
Only in libxml2-apple/libxml2/result/errors: encoding-incorrect-shift_jis.xml | |
Only in libxml2-apple/libxml2/result/errors: encoding-incorrect-shift_jis.xml.ent | |
Only in libxml2-apple/libxml2/result/errors: encoding-incorrect-shift_jis.xml.err | |
Only in libxml2-apple/libxml2/result/errors: encoding-incorrect-shift_jis.xml.str | |
Only in libxml2-apple/libxml2/result/noent: encoding-shift_jis.xhtml | |
Only in libxml2-apple/libxml2/result/noent: encoding-shift_jis.xhtml.sax2 | |
Only in libxml2-apple/libxml2/result/noent: encoding-utf-8.xhtml | |
Only in libxml2-apple/libxml2/result/noent: encoding-utf-8.xhtml.sax2 | |
Only in libxml2-apple/libxml2/result: recover | |
Only in libxml2-apple/libxml2/result: recover-huge | |
Only in libxml2-apple/libxml2/result/regexp: apple_bug757711 | |
Only in libxml2-apple/libxml2/result/regexp: apple_bug757711.err | |
Only in libxml2-apple/libxml2/result/regexp: oss-fuzz-2142 | |
Only in libxml2-apple/libxml2/result/regexp: oss-fuzz-2142.err | |
Only in libxml2-apple/libxml2/result/regexp: oss-fuzz-949 | |
Only in libxml2-apple/libxml2/result/regexp: oss-fuzz-949.err | |
Only in libxml2-apple/libxml2/result/relaxng: anyName1_0 | |
Only in libxml2-apple/libxml2/result/relaxng: anyName1_0.err | |
Only in libxml2-apple/libxml2/result: saxerrors | |
Only in libxml2-apple/libxml2/result/schemas: 570702_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: 579746_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: 579746_0_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: 579746_0_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: 579746_0_3.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: 579746_0_4.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: 579746_0_5.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: 579746_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: 579746_1_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: 579746_1_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: 579746_1_3.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: 579746_1_4.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: 579746_1_5.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: 582887_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: 582906-1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: 582906-2_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_0_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_0_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_0_3.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_0_4.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_0_5.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_0_6.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_0_7.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_1_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_1_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_1_3.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_1_4.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_1_5.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_1_6.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_1_7.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_2_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_2_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_2_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_2_3.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_2_4.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_2_5.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_2_6.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: all_2_7.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: allsg_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: allsg_0_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: allsg_0_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: allsg_0_3.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: allsg_0_4.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: allsg_0_5.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: annot-err_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any2_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any3_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any4_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any5_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any5_0_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any5_0_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any5_0_3.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any5_0_4.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any5_0_5.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any5_0_6.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any5_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any5_1_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any5_1_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any5_1_3.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any5_1_4.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any5_1_5.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any5_1_6.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any6_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any6_2_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any7_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any7_1_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any7_1_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any7_2_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any7_2_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any7_2_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: any8_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: anyAttr-derive-errors1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: anyAttr-derive1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: anyAttr-derive2_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: anyAttr-processContents-err1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: anyAttr-processContents1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: anyAttr1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: attr0_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: attruse_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: attruse_0_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: attruse_0_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug141312_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug141333_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug143951_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug145246_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug152470_1_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug167754_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug303566_1_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug306806_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug309338_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug310264_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug312957_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug313982_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug321475_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug322411_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug323510_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: bug455953_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: changelog093_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_0_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_0_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_0_3.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_0_4.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_0_5.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_0_6.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_1_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_1_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_1_3.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_1_4.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_1_5.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_1_6.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_2_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_2_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_2_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_2_3.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_2_4.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_2_5.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: choice_2_6.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: complex-type-extension_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: cos-ct-extends-1-3_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: cos-st-restricts-1-2-err_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: ct-sc-nobase_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: date_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: decimal-1_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: decimal-2_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: decimal-3_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: derivation-ok-extension-err_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: derivation-ok-extension_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: derivation-ok-restriction-2-1-1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: derivation-ok-restriction-4-1-err_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: derivation-restriction-anyAttr_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: deter0_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: dur_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: elem0_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: element-err_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: element-minmax-err_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: empty-value_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: empty-value_1_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: empty_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: empty_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: extension0_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: extension1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: extension1_0_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: extension1_0_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: extension2_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: facet-unionST-err1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: facet-whiteSpace_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: group0_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: hexbinary_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: hexbinary_0_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: idc-keyref-err1_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: import0_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: import1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: import2_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: include1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: include2_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: include3_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: issue303_0_0.err | |
Only in libxml2-apple/libxml2/result/schemas: issue303_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: issue40_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: issue491_0_0 | |
Only in libxml2-apple/libxml2/result/schemas: issue491_0_0.err | |
Only in libxml2-apple/libxml2/result/schemas: issue491_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: item_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: item_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: length1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: length2_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: length3_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: list0_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: list0_0_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: list0_0_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: list0_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: list0_1_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: list0_1_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: mixed0_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: mixed1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: ns0_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: ns0_0_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: ns0_0_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: ns0_0_3.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: ns0_0_4.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: ns0_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: ns0_1_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: ns0_1_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: ns0_1_3.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: ns0_1_4.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: ns1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: ns2_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: nvdcve_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: oss-fuzz-51295_0_0 | |
Only in libxml2-apple/libxml2/result/schemas: oss-fuzz-51295_0_0.err | |
Only in libxml2-apple/libxml2/result/schemas: oss-fuzz-51295_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: po0_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: po1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: poschargrp0_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: regexp-char-ref_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: regexp-char-ref_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: restrict-CT-attr-ref_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: restriction-attr1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: restriction-enum-1_1_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: restriction0_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: scc-no-xmlns_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: scc-no-xsi_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: seq-dubl-elem1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: seq0_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: src-attribute1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: src-attribute2_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: src-attribute3-1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: src-attribute3-2-form_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: src-attribute3-2-st_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: src-attribute3-2-type_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: src-attribute4_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: src-element1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: src-element2-1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: src-element2-2_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: src-element3_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: subst-group-1_0_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: union2_1_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: union_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: vdv-first0_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: vdv-first1_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: vdv-first2_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: vdv-first3_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: vdv-first4_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: vdv-first4_0_1.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: vdv-first4_0_2.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: vdv-first5_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: xsd-list-itemType_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/schemas: xsd-simpleType-varieties_0_0.err.rdr | |
Only in libxml2-apple/libxml2/result/valid: 780228.xml | |
Only in libxml2-apple/libxml2/result/valid: 780228.xml.err | |
Only in libxml2-apple/libxml2/result/valid: 780228.xml.err.rdr | |
diff -ru libxml2/result/valid/781333.xml.err libxml2-apple/libxml2/result/valid/781333.xml.err | |
--- libxml2/result/valid/781333.xml.err 2025-06-26 01:55:23 | |
+++ libxml2-apple/libxml2/result/valid/781333.xml.err 2025-06-26 01:54:56 | |
@@ -1,3 +1,3 @@ | |
-./test/valid/781333.xml:4: element a: validity error : Element a content does not follow the DTD, expecting ( ..., got | |
+./test/valid/781333.xml:4: element a: validity error : Element a content does not follow the DTD, expecting (pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp: ..., got | |
<a/> | |
^ | |
diff -ru libxml2/result/valid/781333.xml.err.rdr libxml2-apple/libxml2/result/valid/781333.xml.err.rdr | |
--- libxml2/result/valid/781333.xml.err.rdr 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/result/valid/781333.xml.err.rdr 2025-06-26 01:54:56 | |
@@ -1,4 +1,4 @@ | |
-./test/valid/781333.xml:4: element a: validity error : Element a content does not follow the DTD, expecting ( ..., got | |
+./test/valid/781333.xml:4: element a: validity error : Element a content does not follow the DTD, expecting (pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp: ..., got | |
<a/> | |
^ | |
./test/valid/781333.xml:5: element a: validity error : Element a content does not follow the DTD, Expecting more child | |
diff -ru libxml2/runtest.c libxml2-apple/libxml2/runtest.c | |
--- libxml2/runtest.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/runtest.c 2025-06-26 01:54:56 | |
@@ -108,6 +108,10 @@ | |
static char* temp_directory = NULL; | |
static int checkTestFile(const char *filename); | |
+#ifdef __APPLE__ | |
+#include "xmlversionInternal.h" | |
+#endif | |
+ | |
#if defined(_WIN32) && !defined(__CYGWIN__) | |
#include <windows.h> | |
@@ -247,8 +251,9 @@ | |
static char testErrors[32769]; | |
static int testErrorsSize = 0; | |
-static void XMLCDECL | |
-testErrorHandler(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) { | |
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) | |
+testErrorHandler(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) | |
+{ | |
va_list args; | |
int res; | |
@@ -269,8 +274,9 @@ | |
testErrors[testErrorsSize] = 0; | |
} | |
-static void XMLCDECL | |
-channel(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) { | |
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) | |
+channel(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) | |
+{ | |
va_list args; | |
int res; | |
@@ -813,6 +819,7 @@ | |
static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct; | |
static int callbacks = 0; | |
static int quiet = 0; | |
+static int saxFatalStop = 0; | |
/** | |
* isStandaloneDebug: | |
@@ -1345,7 +1352,7 @@ | |
* Display and format a warning messages, gives file, line, position and | |
* extra parameters. | |
*/ | |
-static void XMLCDECL | |
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) | |
warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) | |
{ | |
va_list args; | |
@@ -1368,8 +1375,8 @@ | |
* Display and format a error messages, gives file, line, position and | |
* extra parameters. | |
*/ | |
-static void XMLCDECL | |
-errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) | |
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) | |
+errorDebug(void *ctx, const char *msg, ...) | |
{ | |
va_list args; | |
@@ -1380,6 +1387,13 @@ | |
fprintf(SAXdebug, "SAX.error: "); | |
vfprintf(SAXdebug, msg, args); | |
va_end(args); | |
+ | |
+ if (saxFatalStop) { | |
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; | |
+ xmlErrorPtr error = xmlCtxtGetLastError(ctxt); | |
+ if (error != NULL && error->level == XML_ERR_FATAL) | |
+ xmlStopParser(ctxt); | |
+ } | |
} | |
/** | |
@@ -1391,7 +1405,7 @@ | |
* Display and format a fatalError messages, gives file, line, position and | |
* extra parameters. | |
*/ | |
-static void XMLCDECL | |
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) | |
fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) | |
{ | |
va_list args; | |
@@ -1735,7 +1749,7 @@ | |
fprintf(SAXdebug, "xmlSAXUserParseFile returned error %d\n", ret); | |
ret = 0; | |
} | |
- if (ret != 0) { | |
+ if (ret != 0 && !saxFatalStop) { | |
fprintf(stderr, "Failed to parse %s\n", filename); | |
ret = 1; | |
goto done; | |
@@ -1764,6 +1778,9 @@ | |
fprintf(SAXdebug, "xmlSAXUserParseFile returned error %d\n", ret); | |
ret = 0; | |
} | |
+ if (ret == XML_ERR_USER_STOP && saxFatalStop) { | |
+ ret = 0; | |
+ } | |
fclose(SAXdebug); | |
if (compareFiles(temp, result)) { | |
fprintf(stderr, "Got a difference for %s\n", filename); | |
@@ -1783,6 +1800,17 @@ | |
return(ret); | |
} | |
+static int | |
+saxFatalStopParseTest(const char *filename, const char *result, | |
+ const char *err, int options) { | |
+ int ret; | |
+ int oldSAXFatalStop = saxFatalStop; | |
+ saxFatalStop = 1; | |
+ ret = saxParseTest(filename, result, err, options); | |
+ saxFatalStop = oldSAXFatalStop; | |
+ return ret; | |
+} | |
+ | |
/************************************************************************ | |
* * | |
* Parse to tree based tests * | |
@@ -2234,13 +2262,24 @@ | |
fprintf(out, " %s\n", value); | |
} | |
} | |
+ | |
+typedef enum { | |
+ STREAM_TEST_OUTPUT_STDOUT = 1, | |
+ STREAM_TEST_OUTPUT_STDERR = 2, | |
+ STREAM_TEST_OUTPUT_DEFAULT = STREAM_TEST_OUTPUT_STDERR | |
+} streamTestOutput; | |
+ | |
static int | |
streamProcessTest(const char *filename, const char *result, const char *err, | |
- xmlTextReaderPtr reader, const char *rng, | |
- int options ATTRIBUTE_UNUSED) { | |
- int ret; | |
+ xmlTextReaderPtr reader, const char *rngPath, | |
+ const char* schemaPath, int options ATTRIBUTE_UNUSED, | |
+ streamTestOutput output) { | |
+ int ret = 0; | |
char *temp = NULL; | |
FILE *t = NULL; | |
+#ifdef LIBXML_SCHEMAS_ENABLED | |
+ int schemaValidationFailed = 0; | |
+#endif | |
if (reader == NULL) | |
return(-1); | |
@@ -2260,37 +2299,46 @@ | |
} | |
} | |
#ifdef LIBXML_SCHEMAS_ENABLED | |
- if (rng != NULL) { | |
- ret = xmlTextReaderRelaxNGValidate(reader, rng); | |
- if (ret < 0) { | |
- testErrorHandler(NULL, "Relax-NG schema %s failed to compile\n", | |
- rng); | |
- fclose(t); | |
- if (temp != NULL) { | |
- unlink(temp); | |
- free(temp); | |
- } | |
- return(0); | |
- } | |
+ if (rngPath != NULL) { | |
+ ret = xmlTextReaderRelaxNGValidate(reader, rngPath); | |
+ if (ret < 0) { | |
+ testErrorHandler(NULL, "Relax-NG schema %s failed to compile\n", | |
+ rngPath); | |
+ } | |
} | |
+ if (schemaPath != NULL) | |
+ ret = xmlTextReaderSchemaValidate(reader, schemaPath); | |
+ | |
+ if (ret < 0) | |
+ schemaValidationFailed = 1; | |
#endif | |
- xmlGetWarningsDefaultValue = 1; | |
- ret = xmlTextReaderRead(reader); | |
- while (ret == 1) { | |
- if ((t != NULL) && (rng == NULL)) | |
- processNode(t, reader); | |
+ if (ret == 0) { | |
+ xmlGetWarningsDefaultValue = 1; | |
ret = xmlTextReaderRead(reader); | |
+ while (ret == 1) { | |
+ if ((t != NULL) && (rngPath == NULL) && (schemaPath == NULL)) | |
+ processNode(t, reader); | |
+ ret = xmlTextReaderRead(reader); | |
+ } | |
+ if (ret != 0) { | |
+ testErrorHandler(NULL, "%s : failed to parse\n", filename); | |
+ } | |
} | |
- if (ret != 0) { | |
- testErrorHandler(NULL, "%s : failed to parse\n", filename); | |
- } | |
- if (rng != NULL) { | |
+#ifdef LIBXML_SCHEMAS_ENABLED | |
+ if (((rngPath != NULL) || (schemaPath != NULL)) && !schemaValidationFailed) { | |
if (xmlTextReaderIsValid(reader) != 1) { | |
- testErrorHandler(NULL, "%s fails to validate\n", filename); | |
+ if (output == STREAM_TEST_OUTPUT_STDOUT) | |
+ fprintf(t, "%s fails to validate\n", filename); | |
+ else | |
+ testErrorHandler(NULL, "%s fails to validate\n", filename); | |
} else { | |
- testErrorHandler(NULL, "%s validates\n", filename); | |
+ if (output == STREAM_TEST_OUTPUT_STDOUT) | |
+ fprintf(t, "%s validates\n", filename); | |
+ else | |
+ testErrorHandler(NULL, "%s validates\n", filename); | |
} | |
} | |
+#endif | |
xmlGetWarningsDefaultValue = 0; | |
if (t != NULL) { | |
fclose(t); | |
@@ -2333,7 +2381,8 @@ | |
int ret; | |
reader = xmlReaderForFile(filename, NULL, options); | |
- ret = streamProcessTest(filename, result, err, reader, NULL, options); | |
+ ret = streamProcessTest(filename, result, err, reader, NULL, NULL, | |
+ options, STREAM_TEST_OUTPUT_DEFAULT); | |
xmlFreeTextReader(reader); | |
return(ret); | |
} | |
@@ -2361,7 +2410,8 @@ | |
return(-1); | |
} | |
reader = xmlReaderWalker(doc); | |
- ret = streamProcessTest(filename, result, err, reader, NULL, options); | |
+ ret = streamProcessTest(filename, result, err, reader, NULL, NULL, | |
+ options, STREAM_TEST_OUTPUT_DEFAULT); | |
xmlFreeTextReader(reader); | |
xmlFreeDoc(doc); | |
return(ret); | |
@@ -2393,7 +2443,8 @@ | |
return(-1); | |
} | |
reader = xmlReaderForMemory(base, size, filename, NULL, options); | |
- ret = streamProcessTest(filename, result, err, reader, NULL, options); | |
+ ret = streamProcessTest(filename, result, err, reader, NULL, NULL, | |
+ options, STREAM_TEST_OUTPUT_DEFAULT); | |
free((char *)base); | |
xmlFreeTextReader(reader); | |
return(ret); | |
@@ -2594,7 +2645,8 @@ | |
return(ret); | |
} | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifndef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
/** | |
* xptrDocTest: | |
* @filename: the file to parse | |
@@ -2646,6 +2698,7 @@ | |
return(ret); | |
} | |
#endif /* LIBXML_XPTR_ENABLED */ | |
+#endif /* !defined(LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME) */ | |
/** | |
* xmlidDocTest: | |
@@ -3113,7 +3166,7 @@ | |
free(temp); | |
} | |
- if ((validResult != 0) && (err != NULL)) { | |
+ if (err != NULL) { | |
if (compareFileMem(err, testErrors, testErrorsSize)) { | |
fprintf(stderr, "Error for %s on %s failed\n", filename, sch); | |
ret = 1; | |
@@ -3124,6 +3177,33 @@ | |
xmlFreeDoc(doc); | |
return(ret); | |
} | |
+ | |
+static void | |
+schemasCreatePatternAndPrefix(const char *base, | |
+ size_t baseLen, | |
+ char *pattern, | |
+ char *prefix) | |
+{ | |
+ baseLen -= 4; /* remove trailing .xsd */ | |
+ if (base[baseLen - 2] == '_') { | |
+ baseLen -= 2; /* remove subtest number */ | |
+ } | |
+ if (base[baseLen - 2] == '_') { | |
+ baseLen -= 2; /* remove subtest number */ | |
+ } | |
+ memcpy(prefix, base, baseLen); | |
+ prefix[baseLen] = '\0'; | |
+ | |
+ snprintf(pattern, 499, "./test/schemas/%s_?.xml", prefix); | |
+ pattern[499] = '\0'; | |
+ | |
+ if (base[baseLen] == '_') { | |
+ baseLen += 2; | |
+ memcpy(prefix, base, baseLen); | |
+ prefix[baseLen] = '\0'; | |
+ } | |
+} | |
+ | |
/** | |
* schemasTest: | |
* @filename: the schemas file | |
@@ -3143,9 +3223,11 @@ | |
const char *base = baseFilename(filename); | |
const char *base2; | |
const char *instance; | |
+ const char *schemaValidityErrors = NULL; | |
xmlSchemaParserCtxtPtr ctxt; | |
xmlSchemaPtr schemas; | |
- int res = 0, len, ret; | |
+ size_t len; | |
+ int res = 0, ret; | |
char pattern[500]; | |
char prefix[500]; | |
char result[500]; | |
@@ -3155,43 +3237,41 @@ | |
char count = 0; | |
/* first compile the schemas if possible */ | |
+ xmlGetWarningsDefaultValue = 1; | |
ctxt = xmlSchemaNewParserCtxt(filename); | |
xmlSchemaSetParserErrors(ctxt, testErrorHandler, testErrorHandler, ctxt); | |
schemas = xmlSchemaParse(ctxt); | |
xmlSchemaFreeParserCtxt(ctxt); | |
+ xmlGetWarningsDefaultValue = 0; | |
+ if (testErrorsSize > 0) { | |
+ schemaValidityErrors = strdup(testErrors); | |
+ if (schemaValidityErrors == NULL) { | |
+ xmlSchemaFree(schemas); | |
+ return(-1); | |
+ } | |
+ } | |
+ | |
/* | |
* most of the mess is about the output filenames generated by the Makefile | |
*/ | |
len = strlen(base); | |
if ((len > 499) || (len < 5)) { | |
xmlSchemaFree(schemas); | |
+ if (schemaValidityErrors) | |
+ free((void *)schemaValidityErrors); | |
return(-1); | |
} | |
- len -= 4; /* remove trailing .xsd */ | |
- if (base[len - 2] == '_') { | |
- len -= 2; /* remove subtest number */ | |
- } | |
- if (base[len - 2] == '_') { | |
- len -= 2; /* remove subtest number */ | |
- } | |
- memcpy(prefix, base, len); | |
- prefix[len] = 0; | |
- if (snprintf(pattern, 499, "./test/schemas/%s_?.xml", prefix) >= 499) | |
- pattern[499] = 0; | |
+ schemasCreatePatternAndPrefix(base, len, pattern, prefix); | |
- if (base[len] == '_') { | |
- len += 2; | |
- memcpy(prefix, base, len); | |
- prefix[len] = 0; | |
- } | |
- | |
globbuf.gl_offs = 0; | |
glob(pattern, GLOB_DOOFFS, NULL, &globbuf); | |
for (i = 0;i < globbuf.gl_pathc;i++) { | |
testErrorsSize = 0; | |
testErrors[0] = 0; | |
+ if (schemaValidityErrors) | |
+ testErrorHandler(NULL, "%s", schemaValidityErrors); | |
instance = globbuf.gl_pathv[i]; | |
base2 = baseFilename(instance); | |
len = strlen(base2); | |
@@ -3220,10 +3300,93 @@ | |
} | |
globfree(&globbuf); | |
xmlSchemaFree(schemas); | |
+ if (schemaValidityErrors) | |
+ free((void *)schemaValidityErrors); | |
return(res); | |
} | |
+#ifdef LIBXML_READER_ENABLED | |
+/** | |
+ * schemasStreamTest: | |
+ * @filename: the schemas file | |
+ * @result: the file with expected result | |
+ * @err: the file with error messages | |
+ * | |
+ * Parse a set of files with streaming, applying W3C XSD schemas | |
+ * | |
+ * Returns 0 in case of success, an error code otherwise | |
+ */ | |
+static int | |
+schemasStreamTest(const char *filename, | |
+ const char *resul ATTRIBUTE_UNUSED, | |
+ const char *errr ATTRIBUTE_UNUSED, | |
+ int options) { | |
+ const char *base = baseFilename(filename); | |
+ const char *base2; | |
+ const char *instance; | |
+ size_t len; | |
+ int res = 0, ret; | |
+ char pattern[500]; | |
+ char prefix[500]; | |
+ char result[500]; | |
+ char err[500]; | |
+ glob_t globbuf; | |
+ size_t i; | |
+ char count = 0; | |
+ xmlTextReaderPtr reader; | |
+ | |
+ /* | |
+ * most of the mess is about the output filenames generated by the Makefile | |
+ */ | |
+ len = strlen(base); | |
+ if ((len > 499) || (len < 5)) { | |
+ fprintf(stderr, "len(base) == %lu !\n", (unsigned long)len); | |
+ return(-1); | |
+ } | |
+ | |
+ schemasCreatePatternAndPrefix(base, len, pattern, prefix); | |
+ | |
+ xmlGetWarningsDefaultValue = 1; | |
+ globbuf.gl_offs = 0; | |
+ glob(pattern, GLOB_DOOFFS, NULL, &globbuf); | |
+ for (i = 0;i < globbuf.gl_pathc;i++) { | |
+ testErrorsSize = 0; | |
+ testErrors[0] = 0; | |
+ instance = globbuf.gl_pathv[i]; | |
+ base2 = baseFilename(instance); | |
+ len = strlen(base2); | |
+ if ((len > 6) && (base2[len - 6] == '_')) { | |
+ count = base2[len - 5]; | |
+ snprintf(result, 499, "result/schemas/%s_%c", | |
+ prefix, count); | |
+ result[499] = 0; | |
+ snprintf(err, 499, "result/schemas/%s_%c.err.rdr", | |
+ prefix, count); | |
+ err[499] = 0; | |
+ } else { | |
+ fprintf(stderr, "don't know how to process %s\n", instance); | |
+ continue; | |
+ } | |
+ reader = xmlReaderForFile(instance, NULL, options); | |
+ if (reader == NULL) { | |
+ fprintf(stderr, "Failed to build reder for %s\n", instance); | |
+ } | |
+ ret = streamProcessTest(instance, result, err, reader, NULL, | |
+ filename, options, STREAM_TEST_OUTPUT_STDOUT); | |
+ xmlFreeTextReader(reader); | |
+ if (ret != 0) { | |
+ fprintf(stderr, "instance %s failed\n", instance); | |
+ res = ret; | |
+ } | |
+ } | |
+ globfree(&globbuf); | |
+ xmlGetWarningsDefaultValue = 0; | |
+ | |
+ return(res); | |
+} | |
+#endif /* LIBXML_READER_ENABLED */ | |
+ | |
/************************************************************************ | |
* * | |
* Schemas tests * | |
@@ -3467,10 +3630,10 @@ | |
} | |
if (disable_err == 1) | |
ret = streamProcessTest(instance, result, NULL, reader, filename, | |
- options); | |
+ NULL, options, STREAM_TEST_OUTPUT_DEFAULT); | |
else | |
ret = streamProcessTest(instance, result, err, reader, filename, | |
- options); | |
+ NULL, options, STREAM_TEST_OUTPUT_DEFAULT); | |
xmlFreeTextReader(reader); | |
if (ret != 0) { | |
fprintf(stderr, "instance %s failed\n", instance); | |
@@ -3481,7 +3644,7 @@ | |
return(res); | |
} | |
-#endif /* READER */ | |
+#endif /* LIBXML_READER_ENABLED */ | |
#endif | |
@@ -4309,6 +4472,12 @@ | |
{ "XML regression tests on memory" , | |
memParseTest, "./test/*", "result/", "", NULL, | |
0 }, | |
+ { "XML recover regression tests" , | |
+ errParseTest, "./test/recover/xml/*", "result/recover/xml/", "", ".err", | |
+ XML_PARSE_RECOVER }, | |
+ { "XML recover huge regression tests" , | |
+ errParseTest, "./test/recover-huge/xml/*", "result/recover-huge/xml/", "", ".err", | |
+ XML_PARSE_HUGE | XML_PARSE_RECOVER }, | |
{ "XML entity subst regression tests" , | |
noentParseTest, "./test/*", "result/noent/", "", NULL, | |
XML_PARSE_NOENT }, | |
@@ -4355,6 +4524,9 @@ | |
{ "SAX2 callbacks regression tests with entity substitution" , | |
saxParseTest, "./test/*", "result/noent/", ".sax2", NULL, | |
XML_PARSE_NOENT }, | |
+ { "SAX2 stop on fatal error regression tests" , | |
+ saxFatalStopParseTest, "./test/saxerrors/*", "result/saxerrors/", ".sax2", NULL, | |
+ 0 }, | |
#ifdef LIBXML_PUSH_ENABLED | |
{ "XML push regression tests" , | |
pushParseTest, "./test/*", "result/", "", NULL, | |
@@ -4372,6 +4544,9 @@ | |
pushParseTest, "./test/HTML/*", "result/HTML/", "", ".err", | |
XML_PARSE_HTML }, | |
#endif | |
+ { "HTML recover regression tests" , | |
+ errParseTest, "./test/recover/html/*", "result/recover/html/", "", ".err", | |
+ XML_PARSE_HTML | XML_PARSE_RECOVER }, | |
{ "HTML SAX regression tests" , | |
saxParseTest, "./test/HTML/*", "result/HTML/", ".sax", NULL, | |
XML_PARSE_HTML }, | |
@@ -4425,11 +4600,13 @@ | |
{ "XPath document queries regression tests" , | |
xpathDocTest, "./test/XPath/docs/*", NULL, NULL, NULL, | |
0 }, | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifndef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
{ "XPointer document queries regression tests" , | |
xptrDocTest, "./test/XPath/docs/*", NULL, NULL, NULL, | |
0 }, | |
#endif | |
+#endif /* !defined(LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME) */ | |
{ "xml:id regression tests" , | |
xmlidDocTest, "./test/xmlid/*", "result/xmlid/", "", ".err", | |
0 }, | |
@@ -4448,6 +4625,11 @@ | |
{ "Schemas regression tests" , | |
schemasTest, "./test/schemas/*_*.xsd", NULL, NULL, NULL, | |
0 }, | |
+#ifdef LIBXML_READER_ENABLED | |
+ { "Schemas streaming regression tests" , | |
+ schemasStreamTest, "./test/schemas/*_*.xsd", NULL, NULL, NULL, | |
+ 0 }, | |
+#endif | |
{ "Relax-NG regression tests" , | |
rngTest, "./test/relaxng/*.rng", NULL, NULL, NULL, | |
XML_PARSE_DTDATTR | XML_PARSE_NOENT }, | |
diff -ru libxml2/runxmlconf.c libxml2-apple/libxml2/runxmlconf.c | |
--- libxml2/runxmlconf.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/runxmlconf.c 2025-06-26 01:54:56 | |
@@ -108,7 +108,8 @@ | |
static int nbError = 0; | |
static int nbFatal = 0; | |
-static void test_log(const char *msg, ...) { | |
+static void LIBXML_ATTR_FORMAT(1,2) | |
+test_log(const char *msg, ...) { | |
va_list args; | |
if (logfile != NULL) { | |
fprintf(logfile, "\n------------\n"); | |
diff -ru libxml2/schematron.c libxml2-apple/libxml2/schematron.c | |
--- libxml2/schematron.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/schematron.c 2025-06-26 01:54:56 | |
@@ -259,10 +259,13 @@ | |
data = ctxt->userData; | |
schannel = ctxt->serror; | |
} | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, | |
error, XML_ERR_ERROR, NULL, 0, | |
(const char *) str1, (const char *) str2, NULL, 0, 0, | |
msg, str1, str2); | |
+#pragma clang diagnostic pop | |
} | |
/** | |
@@ -1384,8 +1387,8 @@ | |
long line; | |
const xmlChar *report = NULL; | |
- if (((test->type == XML_SCHEMATRON_REPORT) & (!success)) || | |
- ((test->type == XML_SCHEMATRON_ASSERT) & (success))) | |
+ if (((test->type == XML_SCHEMATRON_REPORT) && (!success)) || | |
+ ((test->type == XML_SCHEMATRON_ASSERT) && (success))) | |
return; | |
line = xmlGetLineNo(cur); | |
path = xmlGetNodePath(cur); | |
@@ -1633,9 +1636,11 @@ | |
failed = 1; | |
break; | |
case XPATH_UNDEFINED: | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
case XPATH_RANGE: | |
case XPATH_LOCATIONSET: | |
+#endif | |
case XPATH_USERS: | |
failed = 1; | |
break; | |
Only in libxml2-apple/libxml2/test/HTML: apple_760263-2.html | |
Only in libxml2-apple/libxml2/test/HTML: apple_760263.html | |
Only in libxml2-apple/libxml2/test/HTML: apple_765468.html | |
Only in libxml2-apple/libxml2/test/HTML: encoding-incorrect-shift_jis.html | |
Only in libxml2-apple/libxml2/test/HTML: encoding-shift_jis.html | |
Only in libxml2-apple/libxml2/test/HTML: encoding-utf-8.html | |
Only in libxml2-apple/libxml2/test/XInclude/docs: coalesce.xml | |
Only in libxml2-apple/libxml2/test/XInclude/ents: coalesce1.xml | |
Only in libxml2-apple/libxml2/test: encoding-shift_jis.xhtml | |
Only in libxml2-apple/libxml2/test: encoding-utf-8.xhtml | |
Only in libxml2-apple/libxml2/test/errors: 766956-1.xml | |
Only in libxml2-apple/libxml2/test/errors: 766956-2.xml | |
Only in libxml2-apple/libxml2/test/errors: 769855-1.xml | |
Only in libxml2-apple/libxml2/test/errors: 769855-2.xml | |
Only in libxml2-apple/libxml2/test/errors: crbug-602280.xml | |
Only in libxml2-apple/libxml2/test/errors: encoding-incorrect-shift_jis.xml | |
Only in libxml2-apple/libxml2/test: recover | |
Only in libxml2-apple/libxml2/test: recover-huge | |
Only in libxml2-apple/libxml2/test/recurse: lol_param.xml | |
Only in libxml2-apple/libxml2/test/regexp: apple_bug757711 | |
Only in libxml2-apple/libxml2/test/regexp: oss-fuzz-2142 | |
Only in libxml2-apple/libxml2/test/regexp: oss-fuzz-949 | |
Only in libxml2/test/relaxng: ambig_name-class.rng | |
Only in libxml2/test/relaxng: ambig_name-class2.rng | |
Only in libxml2-apple/libxml2/test/relaxng: anyName1.rng | |
Only in libxml2-apple/libxml2/test/relaxng: anyName1_0.xml | |
Only in libxml2-apple/libxml2/test: saxerrors | |
Only in libxml2-apple/libxml2/test/schemas: issue491_0.xml | |
Only in libxml2-apple/libxml2/test/schemas: issue491_0.xsd | |
Only in libxml2-apple/libxml2/test/schemas: oss-fuzz-51295_0.xml | |
Only in libxml2-apple/libxml2/test/schemas: oss-fuzz-51295_0.xsd | |
Only in libxml2-apple/libxml2/test/valid: 780228.xml | |
diff -ru libxml2/testOOM.c libxml2-apple/libxml2/testOOM.c | |
--- libxml2/testOOM.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/testOOM.c 2025-06-26 01:54:56 | |
@@ -137,7 +137,7 @@ | |
printf ("binary data [0x%02x]?\n", (unsigned char)s[ix]); | |
} | |
buffer_expand (b, size); | |
- strcpy (b->str + b->len, s); | |
+ strncpy(b->str + b->len, s, size); | |
b->str[b->len+size-1] = '\n'; /* replace string term with newline */ | |
b->len += size; | |
} | |
diff -ru libxml2/testSchemas.c libxml2-apple/libxml2/testSchemas.c | |
--- libxml2/testSchemas.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/testSchemas.c 2025-06-26 01:54:56 | |
@@ -11,6 +11,7 @@ | |
#include <libxml/xmlversion.h> | |
#include <libxml/parser.h> | |
+#include <libxml/xmlreader.h> | |
#include <stdio.h> | |
#include <string.h> | |
@@ -52,12 +53,16 @@ | |
#ifdef HAVE_MMAP | |
static int memory = 0; | |
#endif | |
+#ifdef LIBXML_READER_ENABLED | |
+static int stream = 0; | |
+#endif | |
int main(int argc, char **argv) { | |
int i; | |
int files = 0; | |
xmlSchemaPtr schema = NULL; | |
+ const char *schemaPath = NULL; | |
for (i = 1; i < argc ; i++) { | |
#ifdef LIBXML_DEBUG_ENABLED | |
@@ -70,6 +75,11 @@ | |
memory++; | |
} else | |
#endif | |
+#ifdef LIBXML_READER_ENABLED | |
+ if ((!strcmp(argv[i], "-stream")) || (!strcmp(argv[i], "--stream"))) { | |
+ stream++; | |
+ } else | |
+#endif | |
if ((!strcmp(argv[i], "-noout")) || (!strcmp(argv[i], "--noout"))) { | |
noout++; | |
} | |
@@ -80,6 +90,10 @@ | |
if (schema == NULL) { | |
xmlSchemaParserCtxtPtr ctxt; | |
+ schemaPath = argv[i]; | |
+ | |
+ xmlGetWarningsDefaultValue = 1; | |
+ | |
#ifdef HAVE_MMAP | |
if (memory) { | |
int fd; | |
@@ -116,8 +130,63 @@ | |
xmlSchemaDump(stdout, schema); | |
#endif | |
#endif /* LIBXML_OUTPUT_ENABLED */ | |
+ xmlGetWarningsDefaultValue = 0; | |
+ | |
if (schema == NULL) | |
goto failed_schemas; | |
+#ifdef LIBXML_READER_ENABLED | |
+ } else if (stream) { | |
+ xmlTextReaderPtr reader = NULL; | |
+ int ret = 0; | |
+#ifdef HAVE_MMAP | |
+ int fd = -1; | |
+ struct stat info; | |
+ const char *base = NULL; | |
+ | |
+ if (memory) { | |
+ if (stat(argv[i], &info) < 0) | |
+ break; | |
+ if ((fd = open(argv[i], O_RDONLY)) < 0) | |
+ break; | |
+ base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0); | |
+ if (base == (void *)MAP_FAILED) { | |
+ close(fd); | |
+ break; | |
+ } | |
+ | |
+ reader = xmlReaderForMemory(base, info.st_size, argv[i], NULL, 0); | |
+ } else | |
+#endif | |
+ { | |
+ reader = xmlReaderForFile(argv[i], NULL, 0); | |
+ } | |
+ | |
+ ret = xmlTextReaderSchemaValidate(reader, schemaPath); | |
+ if (ret < 0) | |
+ break; | |
+ | |
+ do { | |
+ ret = xmlTextReaderRead(reader); | |
+ } while (ret == 1); | |
+ | |
+ ret = xmlTextReaderIsValid(reader); | |
+ if (ret == 1) { | |
+ fprintf(stdout, "%s validates\n", argv[i]); | |
+ } else if (ret == 0) { | |
+ fprintf(stdout, "%s fails to validate\n", argv[i]); | |
+ } else { | |
+ fprintf(stdout, "%s validation generated an internal error\n", | |
+ argv[i]); | |
+ } | |
+ | |
+ xmlFreeTextReader(reader); | |
+#ifdef HAVE_MMAP | |
+ if (memory) { | |
+ munmap((char *) base, info.st_size); | |
+ close(fd); | |
+ } | |
+#endif | |
+#endif | |
} else { | |
xmlDocPtr doc; | |
@@ -134,11 +203,11 @@ | |
xmlGenericError, xmlGenericError, NULL); | |
ret = xmlSchemaValidateDoc(ctxt, doc); | |
if (ret == 0) { | |
- printf("%s validates\n", argv[i]); | |
+ fprintf(stdout, "%s validates\n", argv[i]); | |
} else if (ret > 0) { | |
- printf("%s fails to validate\n", argv[i]); | |
+ fprintf(stdout, "%s fails to validate\n", argv[i]); | |
} else { | |
- printf("%s validation generated an internal error\n", | |
+ fprintf(stdout, "%s validation generated an internal error\n", | |
argv[i]); | |
} | |
xmlSchemaFreeValidCtxt(ctxt); | |
@@ -157,9 +226,12 @@ | |
#ifdef LIBXML_DEBUG_ENABLED | |
printf("\t--debug : dump a debug tree of the in-memory document\n"); | |
#endif | |
- printf("\t--noout : do not print the result\n"); | |
#ifdef HAVE_MMAP | |
printf("\t--memory : test the schemas in memory parsing\n"); | |
+#endif | |
+ printf("\t--noout : do not print the result\n"); | |
+#ifdef LIBXML_READER_ENABLED | |
+ printf("\t--stream : use the streaming interface to process very large files\n"); | |
#endif | |
} | |
failed_schemas: | |
diff -ru libxml2/testapi.c libxml2-apple/libxml2/testapi.c | |
--- libxml2/testapi.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/testapi.c 2025-06-26 01:54:56 | |
@@ -8,6 +8,9 @@ | |
* [email protected] | |
*/ | |
+/* Disable deprecation warnings */ | |
+#define XML_DEPRECATED | |
+ | |
#include "libxml.h" | |
#include <stdio.h> | |
@@ -5256,7 +5259,14 @@ | |
mem_base = xmlMemBlocks(); | |
version = gen_int(n_version, 0); | |
+ { | |
+ int original_version = xmlSAXDefaultVersion(2); | |
+ | |
+ | |
ret_val = xmlSAXDefaultVersion(version); | |
+ (void)xmlSAXDefaultVersion(original_version); | |
+ } | |
+ | |
desret_int(ret_val); | |
call_tests++; | |
des_int(n_version, version, 0); | |
@@ -37480,11 +37490,112 @@ | |
return(test_ret); | |
} | |
+ | |
static int | |
+test_xmlEscapeFormatString(void) { | |
+ int test_ret = 0; | |
+ | |
+#if defined(LIBXML_SCHEMAS_ENABLED) | |
+ xmlChar *actual = NULL; | |
+ xmlChar *expected = NULL; | |
+ xmlChar *input = NULL; | |
+ | |
+ call_tests++; | |
+ if (xmlEscapeFormatString(NULL) != NULL) | |
+ test_ret++; | |
+ | |
+ call_tests++; | |
+ input = xmlCharStrdup(""); | |
+ expected = xmlStrdup(input); | |
+ actual = xmlEscapeFormatString(&input); | |
+ if ((xmlStrcmp(actual, expected) != 0) || (input != actual)) | |
+ test_ret++; | |
+ xmlFree(expected); | |
+ xmlFree(actual); | |
+ | |
+ call_tests++; | |
+ input = xmlCharStrdup("str"); | |
+ expected = xmlStrdup(input); | |
+ actual = xmlEscapeFormatString(&input); | |
+ if ((xmlStrcmp(actual, expected) != 0) || (input != actual)) | |
+ test_ret++; | |
+ xmlFree(expected); | |
+ xmlFree(actual); | |
+ | |
+ call_tests++; | |
+ input = xmlCharStrdup("%"); | |
+ expected = xmlCharStrdup("%%"); | |
+ actual = xmlEscapeFormatString(&input); | |
+ if ((xmlStrcmp(actual, expected) != 0) || (input != actual)) | |
+ test_ret++; | |
+ xmlFree(expected); | |
+ xmlFree(actual); | |
+ | |
+ call_tests++; | |
+ input = xmlCharStrdup("%%"); | |
+ expected = xmlCharStrdup("%%%%"); | |
+ actual = xmlEscapeFormatString(&input); | |
+ if ((xmlStrcmp(actual, expected) != 0) || (input != actual)) | |
+ test_ret++; | |
+ xmlFree(expected); | |
+ xmlFree(actual); | |
+ | |
+ call_tests++; | |
+ input = xmlCharStrdup("%%%"); | |
+ expected = xmlCharStrdup("%%%%%%"); | |
+ actual = xmlEscapeFormatString(&input); | |
+ if ((xmlStrcmp(actual, expected) != 0) || (input != actual)) | |
+ test_ret++; | |
+ xmlFree(expected); | |
+ xmlFree(actual); | |
+ | |
+ call_tests++; | |
+ input = xmlCharStrdup("%str"); | |
+ expected = xmlCharStrdup("%%str"); | |
+ actual = xmlEscapeFormatString(&input); | |
+ if ((xmlStrcmp(actual, expected) != 0) || (input != actual)) | |
+ test_ret++; | |
+ xmlFree(expected); | |
+ xmlFree(actual); | |
+ | |
+ call_tests++; | |
+ input = xmlCharStrdup("str%str"); | |
+ expected = xmlCharStrdup("str%%str"); | |
+ actual = xmlEscapeFormatString(&input); | |
+ if ((xmlStrcmp(actual, expected) != 0) || (input != actual)) | |
+ test_ret++; | |
+ xmlFree(expected); | |
+ xmlFree(actual); | |
+ | |
+ call_tests++; | |
+ input = xmlCharStrdup("str%"); | |
+ expected = xmlCharStrdup("str%%"); | |
+ actual = xmlEscapeFormatString(&input); | |
+ if ((xmlStrcmp(actual, expected) != 0) || (input != actual)) | |
+ test_ret++; | |
+ xmlFree(expected); | |
+ xmlFree(actual); | |
+ | |
+ call_tests++; | |
+ input = xmlCharStrdup("%s%t%r%i%n%g%"); | |
+ expected = xmlCharStrdup("%%s%%t%%r%%i%%n%%g%%"); | |
+ actual = xmlEscapeFormatString(&input); | |
+ if ((xmlStrcmp(actual, expected) != 0) || (input != actual)) | |
+ test_ret++; | |
+ xmlFree(expected); | |
+ xmlFree(actual); | |
+ | |
+ function_tests++; | |
+#endif | |
+ | |
+ return(test_ret); | |
+} | |
+ | |
+static int | |
test_xmlstring(void) { | |
int test_ret = 0; | |
- if (quiet == 0) printf("Testing xmlstring : 26 of 30 functions ...\n"); | |
+ if (quiet == 0) printf("Testing xmlstring : 27 of 31 functions ...\n"); | |
test_ret += test_xmlCharStrdup(); | |
test_ret += test_xmlCharStrndup(); | |
test_ret += test_xmlCheckUTF8(); | |
@@ -37513,6 +37624,7 @@ | |
test_ret += test_xmlUTF8Strpos(); | |
test_ret += test_xmlUTF8Strsize(); | |
test_ret += test_xmlUTF8Strsub(); | |
+ test_ret += test_xmlEscapeFormatString(); | |
if (test_ret != 0) | |
printf("Module xmlstring: %d errors\n", test_ret); | |
@@ -51602,7 +51714,7 @@ | |
test_xmlXPtrBuildNodeList(void) { | |
int test_ret = 0; | |
-#if defined(LIBXML_XPTR_ENABLED) | |
+#if defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED) | |
int mem_base; | |
xmlNodePtr ret_val; | |
xmlXPathObjectPtr obj; /* the XPointer result from the evaluation. */ | |
@@ -51677,7 +51789,7 @@ | |
test_xmlXPtrEvalRangePredicate(void) { | |
int test_ret = 0; | |
-#if defined(LIBXML_XPTR_ENABLED) | |
+#if defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED) | |
int mem_base; | |
xmlXPathParserContextPtr ctxt; /* the XPointer Parser context */ | |
int n_ctxt; | |
@@ -51704,159 +51816,12 @@ | |
return(test_ret); | |
} | |
-#ifdef LIBXML_XPTR_ENABLED | |
-#define gen_nb_xmlLocationSetPtr 1 | |
-static xmlLocationSetPtr gen_xmlLocationSetPtr(int no ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) { | |
- return(NULL); | |
-} | |
-static void des_xmlLocationSetPtr(int no ATTRIBUTE_UNUSED, xmlLocationSetPtr val ATTRIBUTE_UNUSED, int nr ATTRIBUTE_UNUSED) { | |
-} | |
-#endif | |
- | |
- | |
static int | |
-test_xmlXPtrLocationSetAdd(void) { | |
- int test_ret = 0; | |
- | |
-#if defined(LIBXML_XPTR_ENABLED) | |
- int mem_base; | |
- xmlLocationSetPtr cur; /* the initial range set */ | |
- int n_cur; | |
- xmlXPathObjectPtr val; /* a new xmlXPathObjectPtr */ | |
- int n_val; | |
- | |
- for (n_cur = 0;n_cur < gen_nb_xmlLocationSetPtr;n_cur++) { | |
- for (n_val = 0;n_val < gen_nb_xmlXPathObjectPtr;n_val++) { | |
- mem_base = xmlMemBlocks(); | |
- cur = gen_xmlLocationSetPtr(n_cur, 0); | |
- val = gen_xmlXPathObjectPtr(n_val, 1); | |
- | |
- xmlXPtrLocationSetAdd(cur, val); | |
- call_tests++; | |
- des_xmlLocationSetPtr(n_cur, cur, 0); | |
- des_xmlXPathObjectPtr(n_val, val, 1); | |
- xmlResetLastError(); | |
- if (mem_base != xmlMemBlocks()) { | |
- printf("Leak of %d blocks found in xmlXPtrLocationSetAdd", | |
- xmlMemBlocks() - mem_base); | |
- test_ret++; | |
- printf(" %d", n_cur); | |
- printf(" %d", n_val); | |
- printf("\n"); | |
- } | |
- } | |
- } | |
- function_tests++; | |
-#endif | |
- | |
- return(test_ret); | |
-} | |
- | |
- | |
-static int | |
-test_xmlXPtrLocationSetCreate(void) { | |
- int test_ret = 0; | |
- | |
- | |
- /* missing type support */ | |
- return(test_ret); | |
-} | |
- | |
- | |
-static int | |
-test_xmlXPtrLocationSetDel(void) { | |
- int test_ret = 0; | |
- | |
-#if defined(LIBXML_XPTR_ENABLED) | |
- int mem_base; | |
- xmlLocationSetPtr cur; /* the initial range set */ | |
- int n_cur; | |
- xmlXPathObjectPtr val; /* an xmlXPathObjectPtr */ | |
- int n_val; | |
- | |
- for (n_cur = 0;n_cur < gen_nb_xmlLocationSetPtr;n_cur++) { | |
- for (n_val = 0;n_val < gen_nb_xmlXPathObjectPtr;n_val++) { | |
- mem_base = xmlMemBlocks(); | |
- cur = gen_xmlLocationSetPtr(n_cur, 0); | |
- val = gen_xmlXPathObjectPtr(n_val, 1); | |
- | |
- xmlXPtrLocationSetDel(cur, val); | |
- call_tests++; | |
- des_xmlLocationSetPtr(n_cur, cur, 0); | |
- des_xmlXPathObjectPtr(n_val, val, 1); | |
- xmlResetLastError(); | |
- if (mem_base != xmlMemBlocks()) { | |
- printf("Leak of %d blocks found in xmlXPtrLocationSetDel", | |
- xmlMemBlocks() - mem_base); | |
- test_ret++; | |
- printf(" %d", n_cur); | |
- printf(" %d", n_val); | |
- printf("\n"); | |
- } | |
- } | |
- } | |
- function_tests++; | |
-#endif | |
- | |
- return(test_ret); | |
-} | |
- | |
- | |
-static int | |
-test_xmlXPtrLocationSetMerge(void) { | |
- int test_ret = 0; | |
- | |
- | |
- /* missing type support */ | |
- return(test_ret); | |
-} | |
- | |
- | |
-static int | |
-test_xmlXPtrLocationSetRemove(void) { | |
- int test_ret = 0; | |
- | |
-#if defined(LIBXML_XPTR_ENABLED) | |
- int mem_base; | |
- xmlLocationSetPtr cur; /* the initial range set */ | |
- int n_cur; | |
- int val; /* the index to remove */ | |
- int n_val; | |
- | |
- for (n_cur = 0;n_cur < gen_nb_xmlLocationSetPtr;n_cur++) { | |
- for (n_val = 0;n_val < gen_nb_int;n_val++) { | |
- mem_base = xmlMemBlocks(); | |
- cur = gen_xmlLocationSetPtr(n_cur, 0); | |
- val = gen_int(n_val, 1); | |
- | |
- xmlXPtrLocationSetRemove(cur, val); | |
- call_tests++; | |
- des_xmlLocationSetPtr(n_cur, cur, 0); | |
- des_int(n_val, val, 1); | |
- xmlResetLastError(); | |
- if (mem_base != xmlMemBlocks()) { | |
- printf("Leak of %d blocks found in xmlXPtrLocationSetRemove", | |
- xmlMemBlocks() - mem_base); | |
- test_ret++; | |
- printf(" %d", n_cur); | |
- printf(" %d", n_val); | |
- printf("\n"); | |
- } | |
- } | |
- } | |
- function_tests++; | |
-#endif | |
- | |
- return(test_ret); | |
-} | |
- | |
- | |
-static int | |
test_xmlXPtrNewCollapsedRange(void) { | |
int test_ret = 0; | |
-#if defined(LIBXML_XPTR_ENABLED) | |
+#if defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED) | |
int mem_base; | |
xmlXPathObjectPtr ret_val; | |
xmlNodePtr start; /* the starting and ending node */ | |
@@ -51900,7 +51865,7 @@ | |
test_xmlXPtrNewLocationSetNodeSet(void) { | |
int test_ret = 0; | |
-#if defined(LIBXML_XPTR_ENABLED) | |
+#if defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED) | |
int mem_base; | |
xmlXPathObjectPtr ret_val; | |
xmlNodeSetPtr set; /* a node set */ | |
@@ -51934,7 +51899,7 @@ | |
test_xmlXPtrNewLocationSetNodes(void) { | |
int test_ret = 0; | |
-#if defined(LIBXML_XPTR_ENABLED) | |
+#if defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED) | |
int mem_base; | |
xmlXPathObjectPtr ret_val; | |
xmlNodePtr start; /* the start NodePtr value */ | |
@@ -51975,7 +51940,7 @@ | |
test_xmlXPtrNewRange(void) { | |
int test_ret = 0; | |
-#if defined(LIBXML_XPTR_ENABLED) | |
+#if defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED) | |
int mem_base; | |
xmlXPathObjectPtr ret_val; | |
xmlNodePtr start; /* the starting node */ | |
@@ -52030,7 +51995,7 @@ | |
test_xmlXPtrNewRangeNodeObject(void) { | |
int test_ret = 0; | |
-#if defined(LIBXML_XPTR_ENABLED) | |
+#if defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED) | |
int mem_base; | |
xmlXPathObjectPtr ret_val; | |
xmlNodePtr start; /* the starting node */ | |
@@ -52071,7 +52036,7 @@ | |
test_xmlXPtrNewRangeNodePoint(void) { | |
int test_ret = 0; | |
-#if defined(LIBXML_XPTR_ENABLED) | |
+#if defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED) | |
int mem_base; | |
xmlXPathObjectPtr ret_val; | |
xmlNodePtr start; /* the starting node */ | |
@@ -52112,7 +52077,7 @@ | |
test_xmlXPtrNewRangeNodes(void) { | |
int test_ret = 0; | |
-#if defined(LIBXML_XPTR_ENABLED) | |
+#if defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED) | |
int mem_base; | |
xmlXPathObjectPtr ret_val; | |
xmlNodePtr start; /* the starting node */ | |
@@ -52153,7 +52118,7 @@ | |
test_xmlXPtrNewRangePointNode(void) { | |
int test_ret = 0; | |
-#if defined(LIBXML_XPTR_ENABLED) | |
+#if defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED) | |
int mem_base; | |
xmlXPathObjectPtr ret_val; | |
xmlXPathObjectPtr start; /* the starting point */ | |
@@ -52194,7 +52159,7 @@ | |
test_xmlXPtrNewRangePoints(void) { | |
int test_ret = 0; | |
-#if defined(LIBXML_XPTR_ENABLED) | |
+#if defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED) | |
int mem_base; | |
xmlXPathObjectPtr ret_val; | |
xmlXPathObjectPtr start; /* the starting point */ | |
@@ -52235,7 +52200,7 @@ | |
test_xmlXPtrRangeToFunction(void) { | |
int test_ret = 0; | |
-#if defined(LIBXML_XPTR_ENABLED) | |
+#if defined(LIBXML_XPTR_ENABLED) && defined(LIBXML_XPTR_LOCS_ENABLED) | |
int mem_base; | |
xmlXPathParserContextPtr ctxt; /* the XPointer Parser context */ | |
int n_ctxt; | |
@@ -52269,53 +52234,14 @@ | |
return(test_ret); | |
} | |
- | |
static int | |
-test_xmlXPtrWrapLocationSet(void) { | |
- int test_ret = 0; | |
- | |
-#if defined(LIBXML_XPTR_ENABLED) | |
- int mem_base; | |
- xmlXPathObjectPtr ret_val; | |
- xmlLocationSetPtr val; /* the LocationSet value */ | |
- int n_val; | |
- | |
- for (n_val = 0;n_val < gen_nb_xmlLocationSetPtr;n_val++) { | |
- mem_base = xmlMemBlocks(); | |
- val = gen_xmlLocationSetPtr(n_val, 0); | |
- | |
- ret_val = xmlXPtrWrapLocationSet(val); | |
- desret_xmlXPathObjectPtr(ret_val); | |
- call_tests++; | |
- des_xmlLocationSetPtr(n_val, val, 0); | |
- xmlResetLastError(); | |
- if (mem_base != xmlMemBlocks()) { | |
- printf("Leak of %d blocks found in xmlXPtrWrapLocationSet", | |
- xmlMemBlocks() - mem_base); | |
- test_ret++; | |
- printf(" %d", n_val); | |
- printf("\n"); | |
- } | |
- } | |
- function_tests++; | |
-#endif | |
- | |
- return(test_ret); | |
-} | |
- | |
-static int | |
test_xpointer(void) { | |
int test_ret = 0; | |
- if (quiet == 0) printf("Testing xpointer : 17 of 21 functions ...\n"); | |
+ if (quiet == 0) printf("Testing xpointer : 13 of 21 functions ...\n"); | |
test_ret += test_xmlXPtrBuildNodeList(); | |
test_ret += test_xmlXPtrEval(); | |
test_ret += test_xmlXPtrEvalRangePredicate(); | |
- test_ret += test_xmlXPtrLocationSetAdd(); | |
- test_ret += test_xmlXPtrLocationSetCreate(); | |
- test_ret += test_xmlXPtrLocationSetDel(); | |
- test_ret += test_xmlXPtrLocationSetMerge(); | |
- test_ret += test_xmlXPtrLocationSetRemove(); | |
test_ret += test_xmlXPtrNewCollapsedRange(); | |
test_ret += test_xmlXPtrNewContext(); | |
test_ret += test_xmlXPtrNewLocationSetNodeSet(); | |
@@ -52327,7 +52253,6 @@ | |
test_ret += test_xmlXPtrNewRangePointNode(); | |
test_ret += test_xmlXPtrNewRangePoints(); | |
test_ret += test_xmlXPtrRangeToFunction(); | |
- test_ret += test_xmlXPtrWrapLocationSet(); | |
if (test_ret != 0) | |
printf("Module xpointer: %d errors\n", test_ret); | |
diff -ru libxml2/testchar.c libxml2-apple/libxml2/testchar.c | |
--- libxml2/testchar.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/testchar.c 2025-06-26 01:54:56 | |
@@ -23,7 +23,7 @@ | |
char document1[100] = "<doc>XXXX</doc>"; | |
char document2[100] = "<doc foo='XXXX'/>"; | |
-static void testDocumentRangeByte1(xmlParserCtxtPtr ctxt, char *document, | |
+static int testDocumentRangeByte1(xmlParserCtxtPtr ctxt, char *document, | |
int len, char *data, int forbid1, int forbid2) { | |
int i; | |
xmlDocPtr res; | |
@@ -37,33 +37,41 @@ | |
res = xmlReadMemory(document, len, "test", NULL, 0); | |
if ((i == forbid1) || (i == forbid2)) { | |
- if ((lastError == 0) || (res != NULL)) | |
+ if ((lastError == 0) || (res != NULL)) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Byte 0x%02X: %c\n", | |
i, i); | |
+ return(1); | |
+ } | |
} | |
else if ((i == '<') || (i == '&')) { | |
- if ((lastError == 0) || (res != NULL)) | |
+ if ((lastError == 0) || (res != NULL)) { | |
fprintf(stderr, | |
"Failed to detect illegal char %c for Byte 0x%02X\n", i, i); | |
+ return(1); | |
+ } | |
} | |
else if (((i < 0x20) || (i >= 0x80)) && | |
(i != 0x9) && (i != 0xA) && (i != 0xD)) { | |
- if ((lastError != XML_ERR_INVALID_CHAR) && (res != NULL)) | |
+ if ((lastError != XML_ERR_INVALID_CHAR) && (res != NULL)) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Byte 0x%02X\n", i); | |
+ return(1); | |
+ } | |
} | |
else if (res == NULL) { | |
fprintf(stderr, | |
"Failed to parse valid char for Byte 0x%02X : %c\n", i, i); | |
+ return(1); | |
} | |
if (res != NULL) | |
xmlFreeDoc(res); | |
} | |
+ return(0); | |
} | |
-static void testDocumentRangeByte2(xmlParserCtxtPtr ctxt, char *document, | |
+static int testDocumentRangeByte2(xmlParserCtxtPtr ctxt, char *document, | |
int len, char *data) { | |
int i, j; | |
xmlDocPtr res; | |
@@ -80,10 +88,12 @@ | |
/* if first bit of first char is set, then second bit must too */ | |
if ((i & 0x80) && ((i & 0x40) == 0)) { | |
- if ((lastError == 0) || (res != NULL)) | |
+ if ((lastError == 0) || (res != NULL)) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Bytes 0x%02X 0x%02X\n", | |
i, j); | |
+ return(1); | |
+ } | |
} | |
/* | |
@@ -91,10 +101,12 @@ | |
* bits must be 10 | |
*/ | |
else if ((i & 0x80) && ((j & 0xC0) != 0x80)) { | |
- if ((lastError == 0) || (res != NULL)) | |
+ if ((lastError == 0) || (res != NULL)) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Bytes 0x%02X 0x%02X\n", | |
i, j); | |
+ return(1); | |
+ } | |
} | |
/* | |
@@ -102,10 +114,12 @@ | |
* than 0x80, i.e. one of bits 5 to 1 of i must be set | |
*/ | |
else if ((i & 0x80) && ((i & 0x1E) == 0)) { | |
- if ((lastError == 0) || (res != NULL)) | |
+ if ((lastError == 0) || (res != NULL)) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Bytes 0x%02X 0x%02X\n", | |
i, j); | |
+ return(1); | |
+ } | |
} | |
/* | |
@@ -113,10 +127,12 @@ | |
* at least 3 bytes, but we give only 2 ! | |
*/ | |
else if ((i & 0xE0) == 0xE0) { | |
- if ((lastError == 0) || (res != NULL)) | |
+ if ((lastError == 0) || (res != NULL)) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x00\n", | |
i, j); | |
+ return(1); | |
+ } | |
} | |
/* | |
@@ -125,11 +141,13 @@ | |
else if ((lastError != 0) || (res == NULL)) { | |
fprintf(stderr, | |
"Failed to parse document for Bytes 0x%02X 0x%02X\n", i, j); | |
+ return(1); | |
} | |
if (res != NULL) | |
xmlFreeDoc(res); | |
} | |
} | |
+ return(0); | |
} | |
/** | |
@@ -141,9 +159,10 @@ | |
* CDATA in text or in attribute values. | |
*/ | |
-static void testDocumentRanges(void) { | |
+static int testDocumentRanges(void) { | |
xmlParserCtxtPtr ctxt; | |
char *data; | |
+ int test_ret = 0; | |
/* | |
* Set up a parsing context using the first document as | |
@@ -152,7 +171,7 @@ | |
ctxt = xmlNewParserCtxt(); | |
if (ctxt == NULL) { | |
fprintf(stderr, "Failed to allocate parser context\n"); | |
- return; | |
+ return(1); | |
} | |
printf("testing 1 byte char in document: 1"); | |
@@ -163,7 +182,7 @@ | |
data[2] = ' '; | |
data[3] = ' '; | |
/* test 1 byte injection at beginning of area */ | |
- testDocumentRangeByte1(ctxt, &document1[0], strlen(document1), | |
+ test_ret += testDocumentRangeByte1(ctxt, &document1[0], strlen(document1), | |
data, -1, -1); | |
printf(" 2"); | |
fflush(stdout); | |
@@ -172,7 +191,7 @@ | |
data[2] = ' '; | |
data[3] = ' '; | |
/* test 1 byte injection at end of area */ | |
- testDocumentRangeByte1(ctxt, &document1[0], strlen(document1), | |
+ test_ret += testDocumentRangeByte1(ctxt, &document1[0], strlen(document1), | |
data + 3, -1, -1); | |
printf(" 3"); | |
@@ -183,7 +202,7 @@ | |
data[2] = ' '; | |
data[3] = ' '; | |
/* test 1 byte injection at beginning of area */ | |
- testDocumentRangeByte1(ctxt, &document2[0], strlen(document2), | |
+ test_ret += testDocumentRangeByte1(ctxt, &document2[0], strlen(document2), | |
data, '\'', -1); | |
printf(" 4"); | |
fflush(stdout); | |
@@ -192,7 +211,7 @@ | |
data[2] = ' '; | |
data[3] = ' '; | |
/* test 1 byte injection at end of area */ | |
- testDocumentRangeByte1(ctxt, &document2[0], strlen(document2), | |
+ test_ret += testDocumentRangeByte1(ctxt, &document2[0], strlen(document2), | |
data + 3, '\'', -1); | |
printf(" done\n"); | |
@@ -204,7 +223,7 @@ | |
data[2] = ' '; | |
data[3] = ' '; | |
/* test 2 byte injection at beginning of area */ | |
- testDocumentRangeByte2(ctxt, &document1[0], strlen(document1), | |
+ test_ret += testDocumentRangeByte2(ctxt, &document1[0], strlen(document1), | |
data); | |
printf(" 2"); | |
fflush(stdout); | |
@@ -213,7 +232,7 @@ | |
data[2] = ' '; | |
data[3] = ' '; | |
/* test 2 byte injection at end of area */ | |
- testDocumentRangeByte2(ctxt, &document1[0], strlen(document1), | |
+ test_ret += testDocumentRangeByte2(ctxt, &document1[0], strlen(document1), | |
data + 2); | |
printf(" 3"); | |
@@ -224,7 +243,7 @@ | |
data[2] = ' '; | |
data[3] = ' '; | |
/* test 2 byte injection at beginning of area */ | |
- testDocumentRangeByte2(ctxt, &document2[0], strlen(document2), | |
+ test_ret += testDocumentRangeByte2(ctxt, &document2[0], strlen(document2), | |
data); | |
printf(" 4"); | |
fflush(stdout); | |
@@ -233,14 +252,15 @@ | |
data[2] = ' '; | |
data[3] = ' '; | |
/* test 2 byte injection at end of area */ | |
- testDocumentRangeByte2(ctxt, &document2[0], strlen(document2), | |
+ test_ret += testDocumentRangeByte2(ctxt, &document2[0], strlen(document2), | |
data + 2); | |
printf(" done\n"); | |
xmlFreeParserCtxt(ctxt); | |
+ return(test_ret); | |
} | |
-static void testCharRangeByte1(xmlParserCtxtPtr ctxt, char *data) { | |
+static int testCharRangeByte1(xmlParserCtxtPtr ctxt, char *data) { | |
int i = 0; | |
int len, c; | |
@@ -255,19 +275,25 @@ | |
c = xmlCurrentChar(ctxt, &len); | |
if ((i == 0) || (i >= 0x80)) { | |
/* we must see an error there */ | |
- if (lastError != XML_ERR_INVALID_CHAR) | |
+ if (lastError != XML_ERR_INVALID_CHAR) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Byte 0x%02X\n", i); | |
+ return(1); | |
+ } | |
} else if (i == 0xD) { | |
- if ((c != 0xA) || (len != 1)) | |
+ if ((c != 0xA) || (len != 1)) { | |
fprintf(stderr, "Failed to convert char for Byte 0x%02X\n", i); | |
+ return(1); | |
+ } | |
} else if ((c != i) || (len != 1)) { | |
fprintf(stderr, "Failed to parse char for Byte 0x%02X\n", i); | |
+ return(1); | |
} | |
} | |
+ return(0); | |
} | |
-static void testCharRangeByte2(xmlParserCtxtPtr ctxt, char *data) { | |
+static int testCharRangeByte2(xmlParserCtxtPtr ctxt, char *data) { | |
int i, j; | |
int len, c; | |
@@ -284,10 +310,12 @@ | |
/* if first bit of first char is set, then second bit must too */ | |
if ((i & 0x80) && ((i & 0x40) == 0)) { | |
- if (lastError != XML_ERR_INVALID_CHAR) | |
+ if (lastError != XML_ERR_INVALID_CHAR) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Bytes 0x%02X 0x%02X\n", | |
i, j); | |
+ return(1); | |
+ } | |
} | |
/* | |
@@ -295,10 +323,12 @@ | |
* bits must be 10 | |
*/ | |
else if ((i & 0x80) && ((j & 0xC0) != 0x80)) { | |
- if (lastError != XML_ERR_INVALID_CHAR) | |
+ if (lastError != XML_ERR_INVALID_CHAR) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Bytes 0x%02X 0x%02X: %d\n", | |
i, j, c); | |
+ return(1); | |
+ } | |
} | |
/* | |
@@ -306,10 +336,12 @@ | |
* than 0x80, i.e. one of bits 5 to 1 of i must be set | |
*/ | |
else if ((i & 0x80) && ((i & 0x1E) == 0)) { | |
- if (lastError != XML_ERR_INVALID_CHAR) | |
+ if (lastError != XML_ERR_INVALID_CHAR) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Bytes 0x%02X 0x%02X: %d\n", | |
i, j, c); | |
+ return(1); | |
+ } | |
} | |
/* | |
@@ -317,10 +349,12 @@ | |
* at least 3 bytes, but we give only 2 ! | |
*/ | |
else if ((i & 0xE0) == 0xE0) { | |
- if (lastError != XML_ERR_INVALID_CHAR) | |
+ if (lastError != XML_ERR_INVALID_CHAR) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x00\n", | |
i, j); | |
+ return(1); | |
+ } | |
} | |
/* | |
@@ -329,6 +363,7 @@ | |
else if ((lastError != 0) || (len != 2)) { | |
fprintf(stderr, | |
"Failed to parse char for Bytes 0x%02X 0x%02X\n", i, j); | |
+ return(1); | |
} | |
/* | |
@@ -338,12 +373,14 @@ | |
fprintf(stderr, | |
"Failed to parse char for Bytes 0x%02X 0x%02X: expect %d got %d\n", | |
i, j, ((j & 0x3F) + ((i & 0x1F) << 6)), c); | |
+ return(1); | |
} | |
} | |
} | |
+ return(0); | |
} | |
-static void testCharRangeByte3(xmlParserCtxtPtr ctxt, char *data) { | |
+static int testCharRangeByte3(xmlParserCtxtPtr ctxt, char *data) { | |
int i, j, k, K; | |
int len, c; | |
unsigned char lows[6] = {0, 0x80, 0x81, 0xC1, 0xFF, 0xBF}; | |
@@ -368,20 +405,24 @@ | |
* at least 4 bytes, but we give only 3 ! | |
*/ | |
if ((i & 0xF0) == 0xF0) { | |
- if (lastError != XML_ERR_INVALID_CHAR) | |
+ if (lastError != XML_ERR_INVALID_CHAR) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X 0x%02X\n", | |
i, j, K, data[3]); | |
+ return(1); | |
+ } | |
} | |
/* | |
* The second and the third bytes must start with 10 | |
*/ | |
else if (((j & 0xC0) != 0x80) || ((K & 0xC0) != 0x80)) { | |
- if (lastError != XML_ERR_INVALID_CHAR) | |
+ if (lastError != XML_ERR_INVALID_CHAR) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X\n", | |
i, j, K); | |
+ return(1); | |
+ } | |
} | |
/* | |
@@ -390,10 +431,12 @@ | |
* the 6th byte of data[1] must be set | |
*/ | |
else if (((i & 0xF) == 0) && ((j & 0x20) == 0)) { | |
- if (lastError != XML_ERR_INVALID_CHAR) | |
+ if (lastError != XML_ERR_INVALID_CHAR) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X\n", | |
i, j, K); | |
+ return(1); | |
+ } | |
} | |
/* | |
@@ -401,10 +444,12 @@ | |
*/ | |
else if (((value > 0xD7FF) && (value <0xE000)) || | |
((value > 0xFFFD) && (value <0x10000))) { | |
- if (lastError != XML_ERR_INVALID_CHAR) | |
+ if (lastError != XML_ERR_INVALID_CHAR) { | |
fprintf(stderr, | |
"Failed to detect invalid char 0x%04X for Bytes 0x%02X 0x%02X 0x%02X\n", | |
value, i, j, K); | |
+ return(1); | |
+ } | |
} | |
/* | |
@@ -414,6 +459,7 @@ | |
fprintf(stderr, | |
"Failed to parse char for Bytes 0x%02X 0x%02X 0x%02X\n", | |
i, j, K); | |
+ return(1); | |
} | |
/* | |
@@ -423,13 +469,15 @@ | |
fprintf(stderr, | |
"Failed to parse char for Bytes 0x%02X 0x%02X 0x%02X: expect %d got %d\n", | |
i, j, data[2], value, c); | |
+ return(1); | |
} | |
} | |
} | |
} | |
+ return(0); | |
} | |
-static void testCharRangeByte4(xmlParserCtxtPtr ctxt, char *data) { | |
+static int testCharRangeByte4(xmlParserCtxtPtr ctxt, char *data) { | |
int i, j, k, K, l, L; | |
int len, c; | |
unsigned char lows[6] = {0, 0x80, 0x81, 0xC1, 0xFF, 0xBF}; | |
@@ -458,10 +506,12 @@ | |
* at least 5 bytes, but we give only 4 ! | |
*/ | |
if ((i & 0xF8) == 0xF8) { | |
- if (lastError != XML_ERR_INVALID_CHAR) | |
+ if (lastError != XML_ERR_INVALID_CHAR) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X 0x%02X\n", | |
i, j, K, data[3]); | |
+ return(1); | |
+ } | |
} | |
/* | |
@@ -469,10 +519,12 @@ | |
*/ | |
else if (((j & 0xC0) != 0x80) || ((K & 0xC0) != 0x80) || | |
((L & 0xC0) != 0x80)) { | |
- if (lastError != XML_ERR_INVALID_CHAR) | |
+ if (lastError != XML_ERR_INVALID_CHAR) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X 0x%02X\n", | |
i, j, K, L); | |
+ return(1); | |
+ } | |
} | |
/* | |
@@ -481,10 +533,12 @@ | |
* the 6 or 5th byte of j must be set | |
*/ | |
else if (((i & 0x7) == 0) && ((j & 0x30) == 0)) { | |
- if (lastError != XML_ERR_INVALID_CHAR) | |
+ if (lastError != XML_ERR_INVALID_CHAR) { | |
fprintf(stderr, | |
"Failed to detect invalid char for Bytes 0x%02X 0x%02X 0x%02X 0x%02X\n", | |
i, j, K, L); | |
+ return(1); | |
+ } | |
} | |
/* | |
@@ -493,10 +547,12 @@ | |
else if (((value > 0xD7FF) && (value <0xE000)) || | |
((value > 0xFFFD) && (value <0x10000)) || | |
(value > 0x10FFFF)) { | |
- if (lastError != XML_ERR_INVALID_CHAR) | |
+ if (lastError != XML_ERR_INVALID_CHAR) { | |
fprintf(stderr, | |
"Failed to detect invalid char 0x%04X for Bytes 0x%02X 0x%02X 0x%02X 0x%02X\n", | |
value, i, j, K, L); | |
+ return(1); | |
+ } | |
} | |
/* | |
@@ -506,6 +562,7 @@ | |
fprintf(stderr, | |
"Failed to parse char for Bytes 0x%02X 0x%02X 0x%02X\n", | |
i, j, K); | |
+ return(1); | |
} | |
/* | |
@@ -515,11 +572,13 @@ | |
fprintf(stderr, | |
"Failed to parse char for Bytes 0x%02X 0x%02X 0x%02X: expect %d got %d\n", | |
i, j, data[2], value, c); | |
+ return(1); | |
} | |
} | |
} | |
} | |
} | |
+ return(0); | |
} | |
/** | |
@@ -530,11 +589,12 @@ | |
* cover the full range of UTF-8 chars accepted by XML-1.0 | |
*/ | |
-static void testCharRanges(void) { | |
+static int testCharRanges(void) { | |
char data[5]; | |
xmlParserCtxtPtr ctxt; | |
xmlParserInputBufferPtr buf; | |
xmlParserInputPtr input; | |
+ int test_ret = 0; | |
memset(data, 0, 5); | |
@@ -545,17 +605,19 @@ | |
ctxt = xmlNewParserCtxt(); | |
if (ctxt == NULL) { | |
fprintf(stderr, "Failed to allocate parser context\n"); | |
- return; | |
+ return(1); | |
} | |
- buf = xmlParserInputBufferCreateStatic(data, sizeof(data), | |
+ buf = xmlParserInputBufferCreateStatic(data, sizeof(data) - 1, | |
XML_CHAR_ENCODING_NONE); | |
if (buf == NULL) { | |
fprintf(stderr, "Failed to allocate input buffer\n"); | |
+ test_ret = 1; | |
goto error; | |
} | |
input = xmlNewInputStream(ctxt); | |
if (input == NULL) { | |
xmlFreeParserInputBuffer(buf); | |
+ test_ret = 1; | |
goto error; | |
} | |
input->filename = NULL; | |
@@ -567,25 +629,163 @@ | |
printf("testing char range: 1"); | |
fflush(stdout); | |
- testCharRangeByte1(ctxt, data); | |
+ test_ret += testCharRangeByte1(ctxt, data); | |
printf(" 2"); | |
fflush(stdout); | |
- testCharRangeByte2(ctxt, data); | |
+ test_ret += testCharRangeByte2(ctxt, data); | |
printf(" 3"); | |
fflush(stdout); | |
- testCharRangeByte3(ctxt, data); | |
+ test_ret += testCharRangeByte3(ctxt, data); | |
printf(" 4"); | |
fflush(stdout); | |
- testCharRangeByte4(ctxt, data); | |
+ test_ret += testCharRangeByte4(ctxt, data); | |
printf(" done\n"); | |
fflush(stdout); | |
error: | |
xmlFreeParserCtxt(ctxt); | |
+ return(test_ret); | |
} | |
+static int | |
+testUserEncoding(void) { | |
+ /* | |
+ * Create a document encoded as UTF-16LE with an ISO-8859-1 encoding | |
+ * declaration, then parse it with xmlReadMemory and the encoding | |
+ * argument set to UTF-16LE. | |
+ */ | |
+ xmlDocPtr doc = NULL; | |
+ const char *start = "<?xml version='1.0' encoding='ISO-8859-1'?><d>"; | |
+ const char *end = "</d>"; | |
+ char *buf = NULL; | |
+ xmlChar *text; | |
+ int startSize = strlen(start); | |
+ int textSize = 100000; /* Make sure to exceed internal buffer sizes. */ | |
+ int endSize = strlen(end); | |
+ int totalSize = startSize + textSize + endSize; | |
+ int k = 0; | |
+ int i; | |
+ int ret = 1; | |
+ | |
+ buf = xmlMalloc(2 * totalSize); | |
+ for (i = 0; start[i] != 0; i++) { | |
+ buf[k++] = start[i]; | |
+ buf[k++] = 0; | |
+ } | |
+ for (i = 0; i < textSize; i++) { | |
+ buf[k++] = 'x'; | |
+ buf[k++] = 0; | |
+ } | |
+ for (i = 0; end[i] != 0; i++) { | |
+ buf[k++] = end[i]; | |
+ buf[k++] = 0; | |
+ } | |
+ | |
+ doc = xmlReadMemory(buf, 2 * totalSize, NULL, "UTF-16LE", 0); | |
+ if (doc == NULL) { | |
+ fprintf(stderr, "failed to parse document\n"); | |
+ goto error; | |
+ } | |
+ | |
+ text = doc->children->children->content; | |
+ for (i = 0; i < textSize; i++) { | |
+ if (text[i] != 'x') { | |
+ fprintf(stderr, "text node has wrong content at offset %d\n", k); | |
+ goto error; | |
+ } | |
+ } | |
+ | |
+ ret = 0; | |
+ | |
+error: | |
+ xmlFreeDoc(doc); | |
+ xmlFree(buf); | |
+ | |
+ return ret; | |
+} | |
+ | |
+static int | |
+testUTF8Chunks(void) { | |
+#if defined(LIBXML_PUSH_ENABLED) && defined(LIBXML_OUTPUT_ENABLED) | |
+ xmlParserCtxtPtr ctxt; | |
+ xmlChar *out; | |
+ int outSize; | |
+ char *buf; | |
+ int i; | |
+ int ret = 0; | |
+ | |
+ ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL); | |
+ | |
+ xmlParseChunk(ctxt, "<d>", 3, 0); | |
+ xmlParseChunk(ctxt, "\xF0", 1, 0); | |
+ xmlParseChunk(ctxt, "\x9F", 1, 0); | |
+ xmlParseChunk(ctxt, "\x98", 1, 0); | |
+ xmlParseChunk(ctxt, "\x8A", 1, 0); | |
+ xmlParseChunk(ctxt, "</d>", 4, 1); | |
+ | |
+ xmlDocDumpMemory(ctxt->myDoc, &out, &outSize); | |
+ if (strcmp((char *) out, | |
+ "<?xml version=\"1.0\"?>\n<d>😊</d>\n") != 0) { | |
+ fprintf(stderr, "failed UTF-8 chunk test 1\n"); | |
+ ret += 1; | |
+ } | |
+ | |
+ xmlFree(out); | |
+ xmlFreeDoc(ctxt->myDoc); | |
+ xmlFreeParserCtxt(ctxt); | |
+ | |
+ ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL); | |
+ | |
+ xmlParseChunk(ctxt, "<d>", 3, 0); | |
+ | |
+ /* | |
+ * Create a chunk longer than XML_PARSER_BIG_BUFFER_SIZE (300) ending | |
+ * with an incomplete UTF-8 sequence. | |
+ */ | |
+ buf = xmlMalloc(1000 * 2 + 1); | |
+ for (i = 0; i < 2000; i += 2) | |
+ memcpy(buf + i, "\xCE\xB1", 2); | |
+ buf[i] = '\xCE'; | |
+ xmlParseChunk(ctxt, buf, 2001, 0); | |
+ xmlFree(buf); | |
+ | |
+ xmlParseChunk(ctxt, "\xB1</d>", 4, 0); | |
+ xmlParseChunk(ctxt, NULL, 0, 0); | |
+ | |
+ xmlDocDumpMemory(ctxt->myDoc, &out, &outSize); | |
+ if (strncmp((char *) out, "<?xml version=\"1.0\"?>\n<d>", 25) != 0) { | |
+ fprintf(stderr, "failed UTF-8 chunk test 2-1\n"); | |
+ ret += 1; | |
+ goto error; | |
+ } | |
+ for (i = 25; i < 25 + 1001 * 7; i += 7) { | |
+ if (memcmp(out + i, "α", 7) != 0) { | |
+ fprintf(stderr, "failed UTF-8 chunk test 2-2 %d\n", i); | |
+ ret += 1; | |
+ goto error; | |
+ } | |
+ } | |
+ if (strcmp((char *) out + i, "</d>\n") != 0) { | |
+ fprintf(stderr, "failed UTF-8 chunk test 2-3\n"); | |
+ ret += 1; | |
+ goto error; | |
+ } | |
+ | |
+error: | |
+ xmlFree(out); | |
+ xmlFreeDoc(ctxt->myDoc); | |
+ xmlFreeParserCtxt(ctxt); | |
+ | |
+ return(ret); | |
+#else | |
+ return(0); | |
+#endif | |
+} | |
+ | |
int main(void) { | |
+ int ret = 0; | |
+ | |
/* | |
* this initialize the library and check potential ABI mismatches | |
* between the version it was compiled for and the actual shared | |
@@ -602,8 +802,10 @@ | |
/* | |
* Run the tests | |
*/ | |
- testCharRanges(); | |
- testDocumentRanges(); | |
+ ret += testCharRanges(); | |
+ ret += testDocumentRanges(); | |
+ ret += testUserEncoding(); | |
+ ret += testUTF8Chunks(); | |
/* | |
* Cleanup function for the XML library. | |
@@ -613,5 +815,5 @@ | |
* this is to debug memory for regression tests | |
*/ | |
xmlMemoryDump(); | |
- return(0); | |
+ return(ret ? 1 : 0); | |
} | |
diff -ru libxml2/testrecurse.c libxml2-apple/libxml2/testrecurse.c | |
--- libxml2/testrecurse.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/testrecurse.c 2025-06-26 01:54:56 | |
@@ -310,8 +310,8 @@ | |
static char testErrors[32769]; | |
static int testErrorsSize = 0; | |
-static void XMLCDECL | |
-channel(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) { | |
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) | |
+channel(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) { | |
va_list args; | |
int res; | |
diff -ru libxml2/threads.c libxml2-apple/libxml2/threads.c | |
--- libxml2/threads.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/threads.c 2025-06-26 01:54:56 | |
@@ -74,7 +74,7 @@ | |
#else /* __GNUC__, __GLIBC__, __linux__ */ | |
-static int libxml_is_threaded = 1; | |
+const int libxml_is_threaded = 1; | |
#endif /* __GNUC__, __GLIBC__, __linux__ */ | |
@@ -132,9 +132,13 @@ | |
#ifdef HAVE_PTHREAD_H | |
static pthread_key_t globalkey; | |
+#ifndef __APPLE__ | |
static pthread_t mainthread; | |
+#endif | |
static pthread_once_t once_control = PTHREAD_ONCE_INIT; | |
+#ifndef __APPLE__ | |
static pthread_once_t once_control_init = PTHREAD_ONCE_INIT; | |
+#endif | |
static pthread_mutex_t global_init_lock = PTHREAD_MUTEX_INITIALIZER; | |
#elif defined HAVE_WIN32_THREADS | |
#if defined(HAVE_COMPILER_TLS) | |
@@ -808,7 +812,11 @@ | |
xmlGenericError(xmlGenericErrorContext, "xmlIsMainThread()\n"); | |
#endif | |
#ifdef HAVE_PTHREAD_H | |
+#ifndef __APPLE__ | |
return (pthread_equal(mainthread,pthread_self())); | |
+#else | |
+ return (pthread_main_np() == 1); | |
+#endif /* !defined(__APPLE__) */ | |
#elif defined HAVE_WIN32_THREADS | |
return (mainthread == GetCurrentThreadId()); | |
#elif defined HAVE_BEOS_THREADS | |
@@ -909,9 +917,22 @@ | |
xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n"); | |
#endif | |
#ifdef HAVE_PTHREAD_H | |
+/* | |
+ * Third-party applications are calling xmlCleanupParser() (and | |
+ * thus xmlCleanupThreads()) inappropriately--sometimes multiple | |
+ * times--causing the pthread key for libxml2 to be released. Because | |
+ * xmlCleanupThreads() was only meant to be called when the libxml2 | |
+ * dylib was unloaded (which never happens on iOS or OS X), it caused | |
+ * libxml2 to continue to use the same pthread key after it had been | |
+ * released--and sometimes after the same key had been assigned to | |
+ * another framework or dylib--causing mysterious crashes. | |
+ * See <rdar://problem/6768256&6814031> for details. | |
+ */ | |
+#ifndef __APPLE__ | |
if (libxml_is_threaded != 0) | |
pthread_key_delete(globalkey); | |
once_control = once_control_init; | |
+#endif /* !defined(__APPLE__) */ | |
#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) | |
if (globalkey != TLS_OUT_OF_INDEXES) { | |
xmlGlobalStateCleanupHelperParams *p; | |
@@ -950,7 +971,9 @@ | |
{ | |
#ifdef HAVE_PTHREAD_H | |
(void) pthread_key_create(&globalkey, xmlFreeGlobalState); | |
+#ifndef __APPLE__ | |
mainthread = pthread_self(); | |
+#endif | |
__xmlInitializeDict(); | |
#elif defined(HAVE_WIN32_THREADS) | |
if (!run_once.done) { | |
diff -ru libxml2/tree.c libxml2-apple/libxml2/tree.c | |
--- libxml2/tree.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/tree.c 2025-06-26 01:54:56 | |
@@ -18,6 +18,7 @@ | |
#define IN_LIBXML | |
#include "libxml.h" | |
+#include <assert.h> | |
#include <string.h> /* for memset() only ! */ | |
#include <stddef.h> | |
#include <limits.h> | |
@@ -47,6 +48,10 @@ | |
#include <libxml/debugXML.h> | |
#endif | |
+#ifdef __APPLE__ | |
+#include <os/log.h> | |
+#endif | |
+ | |
#include "buf.h" | |
#include "save.h" | |
@@ -58,6 +63,8 @@ | |
* * | |
************************************************************************/ | |
+extern const int xmlEntityDecodingDepthMax; | |
+ | |
static xmlNsPtr | |
xmlNewReconciledNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns); | |
@@ -108,7 +115,10 @@ | |
default: | |
msg = "unexpected error number\n"; | |
} | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlSimpleError(XML_FROM_TREE, code, node, msg, extra); | |
+#pragma clang diagnostic pop | |
} | |
/************************************************************************ | |
@@ -1332,6 +1342,8 @@ | |
charval = 0; | |
break; | |
} | |
+ if (charval > 0x110000) | |
+ charval = 0x110000; | |
cur++; | |
if (cur < end) | |
tmp = *cur; | |
@@ -1348,7 +1360,6 @@ | |
else | |
tmp = 0; | |
while (tmp != ';') { /* Non input consuming loops */ | |
- /* Don't check for integer overflow, see above. */ | |
if ((tmp >= '0') && (tmp <= '9')) | |
charval = charval * 10 + (tmp - '0'); | |
else { | |
@@ -1357,6 +1368,8 @@ | |
charval = 0; | |
break; | |
} | |
+ if (charval > 0x110000) | |
+ charval = 0x110000; | |
cur++; | |
if (cur < end) | |
tmp = *cur; | |
@@ -1447,12 +1460,14 @@ | |
xmlChar buffer[10]; | |
int l; | |
+ if (charval >= 0x110000) | |
+ charval = 0xFFFD; /* replacement character */ | |
+ | |
l = xmlCopyCharMultiByte(buffer, charval); | |
buffer[l] = 0; | |
if (xmlBufCat(buf, buffer)) | |
goto out; | |
- charval = 0; | |
} | |
} else | |
cur++; | |
@@ -1541,6 +1556,8 @@ | |
charval = 0; | |
break; | |
} | |
+ if (charval > 0x110000) | |
+ charval = 0x110000; | |
cur++; | |
tmp = *cur; | |
} | |
@@ -1551,7 +1568,6 @@ | |
cur += 2; | |
tmp = *cur; | |
while (tmp != ';') { /* Non input consuming loops */ | |
- /* Don't check for integer overflow, see above. */ | |
if ((tmp >= '0') && (tmp <= '9')) | |
charval = charval * 10 + (tmp - '0'); | |
else { | |
@@ -1560,6 +1576,8 @@ | |
charval = 0; | |
break; | |
} | |
+ if (charval > 0x110000) | |
+ charval = 0x110000; | |
cur++; | |
tmp = *cur; | |
} | |
@@ -1647,12 +1665,14 @@ | |
xmlChar buffer[10]; | |
int len; | |
+ if (charval >= 0x110000) | |
+ charval = 0xFFFD; /* replacement character */ | |
+ | |
len = xmlCopyCharMultiByte(buffer, charval); | |
buffer[len] = 0; | |
if (xmlBufCat(buf, buffer)) | |
goto out; | |
- charval = 0; | |
} | |
} else | |
cur++; | |
@@ -1684,6 +1704,9 @@ | |
return(ret); | |
} | |
+static xmlChar * | |
+xmlNodeListGetStringInternal(xmlDocPtr doc, const xmlNode *list, int inLine, int depth); | |
+ | |
/** | |
* xmlNodeListGetString: | |
* @doc: the document | |
@@ -1698,11 +1721,21 @@ | |
xmlChar * | |
xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine) | |
{ | |
+ return xmlNodeListGetStringInternal(doc, list, inLine, 0); | |
+} | |
+ | |
+static xmlChar * | |
+xmlNodeListGetStringInternal(xmlDocPtr doc, const xmlNode *list, int inLine, int depth) | |
+{ | |
const xmlNode *node = list; | |
xmlChar *ret = NULL; | |
xmlEntityPtr ent; | |
int attr; | |
+ if (depth > xmlEntityDecodingDepthMax) { | |
+ return(NULL); /* Avoid stack overflow due to previous XML_ERR_ENTITY_LOOP. */ | |
+ } | |
+ | |
if (list == NULL) | |
return (NULL); | |
if ((list->parent != NULL) && (list->parent->type == XML_ATTRIBUTE_NODE)) | |
@@ -1740,7 +1773,7 @@ | |
* entity reference nodes (among others). | |
* -> we recursive call xmlNodeListGetString() | |
* which handles these types */ | |
- buffer = xmlNodeListGetString(doc, ent->children, 1); | |
+ buffer = xmlNodeListGetStringInternal(doc, ent->children, 1, depth + 1); | |
if (buffer != NULL) { | |
ret = xmlStrcat(ret, buffer); | |
xmlFree(buffer); | |
@@ -2815,6 +2848,20 @@ | |
return(cur); | |
} | |
+static const xmlChar *_copyStringForNewDictIfNeeded(xmlDictPtr oldDict, xmlDictPtr newDict, const xmlChar *oldValue) { | |
+ const xmlChar *newValue = oldValue; | |
+ if (oldValue) { | |
+ int oldDictOwnsOldValue = oldDict && (xmlDictOwns(oldDict, oldValue) == 1); | |
+ if (oldDictOwnsOldValue) { | |
+ if (newDict) | |
+ newValue = xmlDictLookup(newDict, oldValue, -1); | |
+ else | |
+ newValue = xmlStrdup(oldValue); | |
+ } | |
+ } | |
+ return newValue; | |
+} | |
+ | |
/** | |
* xmlSetTreeDoc: | |
* @tree: the top element | |
@@ -2829,6 +2876,9 @@ | |
if ((tree == NULL) || (tree->type == XML_NAMESPACE_DECL)) | |
return; | |
if (tree->doc != doc) { | |
+ xmlDictPtr oldTreeDict = tree->doc ? tree->doc->dict : NULL; | |
+ xmlDictPtr newDict = doc ? doc->dict : NULL; | |
+ | |
if(tree->type == XML_ELEMENT_NODE) { | |
prop = tree->properties; | |
while (prop != NULL) { | |
@@ -2836,7 +2886,15 @@ | |
xmlRemoveID(tree->doc, prop); | |
} | |
- prop->doc = doc; | |
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | |
+ if (prop->doc) | |
+ assert(xmlDictOwns(prop->doc->dict, prop->name) != 1); | |
+#endif | |
+ if (prop->doc != doc) { | |
+ xmlDictPtr oldPropDict = prop->doc ? prop->doc->dict : NULL; | |
+ prop->name = _copyStringForNewDictIfNeeded(oldPropDict, newDict, prop->name); | |
+ prop->doc = doc; | |
+ } | |
xmlSetListDoc(prop->children, doc); | |
/* | |
@@ -2865,6 +2923,17 @@ | |
} else if (tree->children != NULL) { | |
xmlSetListDoc(tree->children, doc); | |
} | |
+ | |
+#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | |
+ if (tree->doc) { | |
+ assert(xmlDictOwns(tree->doc->dict, tree->name) != 1); | |
+ assert(xmlDictOwns(tree->doc->dict, tree->content) != 1); | |
+ } | |
+ assert(tree->ns == NULL); | |
+#endif | |
+ tree->name = _copyStringForNewDictIfNeeded(oldTreeDict, newDict, tree->name); | |
+ tree->content = (xmlChar *)_copyStringForNewDictIfNeeded(oldTreeDict, NULL, tree->content); | |
+ /* FIXME: tree->ns should be updated as in xmlStaticCopyNode(). */ | |
tree->doc = doc; | |
} | |
} | |
@@ -4299,6 +4368,14 @@ | |
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue)) | |
xmlRegisterNodeDefaultValue((xmlNodePtr)ret); | |
+ /* | |
+ * Note that since ret->parent is already set, xmlAddChild will | |
+ * return early and not actually insert the node. It will only | |
+ * coalesce text nodes and unnecessarily call xmlSetTreeDoc. | |
+ * Assuming that the subtree to be copied always has its text | |
+ * nodes coalesced, the somewhat confusing call to xmlAddChild | |
+ * could be removed. | |
+ */ | |
tmp = xmlAddChild(parent, ret); | |
/* node could have coalesced */ | |
if (tmp != ret) | |
@@ -4354,8 +4431,49 @@ | |
} | |
ret->last = ret->children; | |
} else if ((node->children != NULL) && (extended != 2)) { | |
- ret->children = xmlStaticCopyNodeList(node->children, doc, ret); | |
- UPDATE_LAST_CHILD_AND_PARENT(ret) | |
+ xmlNodePtr cur, insert; | |
+ | |
+ cur = node->children; | |
+ insert = ret; | |
+ while (cur != NULL) { | |
+ xmlNodePtr copy = xmlStaticCopyNode(cur, doc, insert, 2); | |
+ if (copy == NULL) { | |
+ xmlFreeNode(ret); | |
+ return(NULL); | |
+ } | |
+ | |
+ /* Check for coalesced text nodes */ | |
+ if (insert->last != copy) { | |
+ if (insert->last == NULL) { | |
+ insert->children = copy; | |
+ } else { | |
+ copy->prev = insert->last; | |
+ insert->last->next = copy; | |
+ } | |
+ insert->last = copy; | |
+ } | |
+ | |
+ if ((cur->type != XML_ENTITY_REF_NODE) && | |
+ (cur->children != NULL)) { | |
+ cur = cur->children; | |
+ insert = copy; | |
+ continue; | |
+ } | |
+ | |
+ while (1) { | |
+ if (cur->next != NULL) { | |
+ cur = cur->next; | |
+ break; | |
+ } | |
+ | |
+ cur = cur->parent; | |
+ insert = insert->parent; | |
+ if (cur == node) { | |
+ cur = NULL; | |
+ break; | |
+ } | |
+ } | |
+ } | |
} | |
out: | |
@@ -4370,29 +4488,28 @@ | |
xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) { | |
xmlNodePtr ret = NULL; | |
xmlNodePtr p = NULL,q; | |
+ xmlDtdPtr newSubset = NULL; | |
while (node != NULL) { | |
-#ifdef LIBXML_TREE_ENABLED | |
if (node->type == XML_DTD_NODE ) { | |
- if (doc == NULL) { | |
+#ifdef LIBXML_TREE_ENABLED | |
+ if ((doc == NULL) || (doc->intSubset != NULL)) { | |
node = node->next; | |
continue; | |
} | |
- if (doc->intSubset == NULL) { | |
- q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node ); | |
- if (q == NULL) return(NULL); | |
- q->doc = doc; | |
- q->parent = parent; | |
- doc->intSubset = (xmlDtdPtr) q; | |
- xmlAddChild(parent, q); | |
- } else { | |
- q = (xmlNodePtr) doc->intSubset; | |
- xmlAddChild(parent, q); | |
- } | |
- } else | |
+ q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node ); | |
+ if (q == NULL) goto error; | |
+ q->doc = doc; | |
+ q->parent = parent; | |
+ newSubset = (xmlDtdPtr) q; | |
+#else | |
+ node = node->next; | |
+ continue; | |
#endif /* LIBXML_TREE_ENABLED */ | |
+ } else { | |
q = xmlStaticCopyNode(node, doc, parent, 1); | |
- if (q == NULL) return(NULL); | |
+ if (q == NULL) goto error; | |
+ } | |
if (ret == NULL) { | |
q->prev = NULL; | |
ret = p = q; | |
@@ -4404,7 +4521,12 @@ | |
} | |
node = node->next; | |
} | |
+ if (newSubset != NULL) | |
+ doc->intSubset = newSubset; | |
return(ret); | |
+error: | |
+ xmlFreeNodeList(ret); | |
+ return(NULL); | |
} | |
/** | |
@@ -7088,7 +7210,7 @@ | |
xmlFree(ret); | |
return(NULL); | |
} | |
- ret->content[0] = 0; | |
+ memset(ret->content, 0, (ret->size * sizeof(xmlChar))); | |
ret->contentIO = NULL; | |
return(ret); | |
} | |
@@ -7104,6 +7226,8 @@ | |
xmlBufferCreateSize(size_t size) { | |
xmlBufferPtr ret; | |
+ if (size >= INT_MAX) | |
+ return(NULL); | |
ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer)); | |
if (ret == NULL) { | |
xmlTreeErrMemory("creating buffer"); | |
@@ -7111,7 +7235,7 @@ | |
} | |
ret->use = 0; | |
ret->alloc = xmlBufferAllocScheme; | |
- ret->size = (size ? size+2 : 0); /* +1 for ending null */ | |
+ ret->size = (size ? size + 1 : 0); /* +1 for ending null */ | |
if (ret->size){ | |
ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar)); | |
if (ret->content == NULL) { | |
@@ -7119,7 +7243,7 @@ | |
xmlFree(ret); | |
return(NULL); | |
} | |
- ret->content[0] = 0; | |
+ memset(ret->content, 0, (ret->size * sizeof(xmlChar))); | |
} else | |
ret->content = NULL; | |
ret->contentIO = NULL; | |
@@ -7171,6 +7295,8 @@ | |
if ((mem == NULL) || (size == 0)) | |
return(NULL); | |
+ if (size > INT_MAX) | |
+ return(NULL); | |
ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer)); | |
if (ret == NULL) { | |
@@ -7181,6 +7307,14 @@ | |
ret->size = size; | |
ret->alloc = XML_BUFFER_ALLOC_IMMUTABLE; | |
ret->content = (xmlChar *) mem; | |
+#if !defined(NDEBUG) && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) | |
+ /* Enable NUL terminator check on Debug builds when not fuzzing. */ | |
+ if (size != 0 && ret->content[size-1] != 0 && ret->content[size] != 0) { | |
+ xmlTreeErrMemory("buffer missing NUL terminator"); | |
+ xmlFree(ret); | |
+ return(NULL); | |
+ } | |
+#endif | |
return(ret); | |
} | |
@@ -7318,28 +7452,27 @@ | |
*/ | |
int | |
xmlBufferGrow(xmlBufferPtr buf, unsigned int len) { | |
- int size; | |
+ unsigned int size; | |
xmlChar *newbuf; | |
if (buf == NULL) return(-1); | |
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0); | |
- if (len + buf->use < buf->size) return(0); | |
+ if (len < buf->size - buf->use) { | |
+ buf->content[buf->use + len] = 0; | |
+ return(0); | |
+ } | |
+ if (len > INT_MAX - buf->use - 1) { | |
+ xmlTreeErrMemory("growing buffer past INT_MAX"); | |
+ return(-1); | |
+ } | |
- /* | |
- * Windows has a BIG problem on realloc timing, so we try to double | |
- * the buffer size (if that's enough) (bug 146697) | |
- * Apparently BSD too, and it's probably best for linux too | |
- * On an embedded system this may be something to change | |
- */ | |
-#if 1 | |
- if (buf->size > len) | |
- size = buf->size * 2; | |
- else | |
- size = buf->use + len + 100; | |
-#else | |
- size = buf->use + len + 100; | |
-#endif | |
+ if (buf->size > (size_t) len) { | |
+ size = buf->size > INT_MAX / 2 ? INT_MAX : buf->size * 2; | |
+ } else { | |
+ size = buf->use + len; | |
+ size = size > INT_MAX - 100 ? INT_MAX : size + 100; | |
+ } | |
if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) { | |
size_t start_buf = buf->content - buf->contentIO; | |
@@ -7360,7 +7493,9 @@ | |
buf->content = newbuf; | |
} | |
buf->size = size; | |
- return(buf->size - buf->use); | |
+ buf->content[buf->use] = 0; | |
+ buf->content[buf->use + len] = 0; | |
+ return(buf->size - buf->use - 1); | |
} | |
/** | |
@@ -7373,7 +7508,7 @@ | |
*/ | |
int | |
xmlBufferDump(FILE *file, xmlBufferPtr buf) { | |
- int ret; | |
+ size_t ret; | |
if (buf == NULL) { | |
#ifdef DEBUG_BUFFER | |
@@ -7392,7 +7527,7 @@ | |
if (file == NULL) | |
file = stdout; | |
ret = fwrite(buf->content, sizeof(xmlChar), buf->use, file); | |
- return(ret); | |
+ return(ret > INT_MAX ? INT_MAX : (int)ret); | |
} | |
/** | |
@@ -7428,7 +7563,14 @@ | |
if(!buf) | |
return 0; | |
- return buf->use; | |
+ if (buf->use >= INT_MAX) { | |
+#ifdef __APPLE__ | |
+ os_log_error(OS_LOG_DEFAULT, "xmlBufferLength() int overflow: %{public}u", buf->use); | |
+#endif | |
+ return (INT_MAX - 1); | |
+ } | |
+ | |
+ return (int)buf->use; | |
} | |
/** | |
@@ -7456,8 +7598,8 @@ | |
if (size < buf->size) | |
return 1; | |
- if (size > UINT_MAX - 10) { | |
- xmlTreeErrMemory("growing buffer"); | |
+ if (size > INT_MAX - 10) { | |
+ xmlTreeErrMemory("growing buffer past INT_MAX"); | |
return 0; | |
} | |
@@ -7466,9 +7608,12 @@ | |
case XML_BUFFER_ALLOC_IO: | |
case XML_BUFFER_ALLOC_DOUBLEIT: | |
/*take care of empty case*/ | |
- newSize = (buf->size ? buf->size : size + 10); | |
+ if (buf->size == 0) | |
+ newSize = (size > INT_MAX - 10 ? INT_MAX : size + 10); | |
+ else | |
+ newSize = buf->size; | |
while (size > newSize) { | |
- if (newSize > UINT_MAX / 2) { | |
+ if (newSize > INT_MAX / 2) { | |
xmlTreeErrMemory("growing buffer"); | |
return 0; | |
} | |
@@ -7476,7 +7621,7 @@ | |
} | |
break; | |
case XML_BUFFER_ALLOC_EXACT: | |
- newSize = size+10; | |
+ newSize = (size > INT_MAX - 10 ? INT_MAX : size + 10); | |
break; | |
case XML_BUFFER_ALLOC_HYBRID: | |
if (buf->use < BASE_BUFFER_SIZE) | |
@@ -7484,7 +7629,7 @@ | |
else { | |
newSize = buf->size; | |
while (size > newSize) { | |
- if (newSize > UINT_MAX / 2) { | |
+ if (newSize > INT_MAX / 2) { | |
xmlTreeErrMemory("growing buffer"); | |
return 0; | |
} | |
@@ -7494,7 +7639,7 @@ | |
break; | |
default: | |
- newSize = size+10; | |
+ newSize = (size > INT_MAX - 10 ? INT_MAX : size + 10); | |
break; | |
} | |
@@ -7505,7 +7650,6 @@ | |
/* move data back to start */ | |
memmove(buf->contentIO, buf->content, buf->use); | |
buf->content = buf->contentIO; | |
- buf->content[buf->use] = 0; | |
buf->size += start_buf; | |
} else { | |
rebuf = (xmlChar *) xmlRealloc(buf->contentIO, start_buf + newSize); | |
@@ -7531,7 +7675,6 @@ | |
if (rebuf != NULL) { | |
memcpy(rebuf, buf->content, buf->use); | |
xmlFree(buf->content); | |
- rebuf[buf->use] = 0; | |
} | |
} | |
if (rebuf == NULL) { | |
@@ -7541,6 +7684,7 @@ | |
buf->content = rebuf; | |
} | |
buf->size = newSize; | |
+ buf->content[buf->use] = 0; | |
return 1; | |
} | |
@@ -7580,8 +7724,13 @@ | |
if (len < 0) return -1; | |
if (len == 0) return 0; | |
- needSize = buf->use + len + 2; | |
- if (needSize > buf->size){ | |
+ /* Note that both buf->size and buf->use can be zero here. */ | |
+ if ((unsigned) len >= buf->size - buf->use) { | |
+ if ((unsigned) len >= INT_MAX - buf->use) { | |
+ xmlTreeErrMemory("growing buffer past INT_MAX"); | |
+ return XML_ERR_NO_MEMORY; | |
+ } | |
+ needSize = buf->use + len + 1; | |
if (!xmlBufferResize(buf, needSize)){ | |
xmlTreeErrMemory("growing buffer"); | |
return XML_ERR_NO_MEMORY; | |
@@ -7645,11 +7794,17 @@ | |
memmove(&buf->content[0], str, len); | |
buf->use += len; | |
buf->size += len; | |
+ buf->content[buf->use] = 0; | |
return(0); | |
} | |
} | |
- needSize = buf->use + len + 2; | |
- if (needSize > buf->size){ | |
+ /* Note that both buf->size and buf->use can be zero here. */ | |
+ if ((unsigned) len >= buf->size - buf->use) { | |
+ if ((unsigned) len >= INT_MAX - buf->use) { | |
+ xmlTreeErrMemory("growing buffer past INT_MAX"); | |
+ return(-1); | |
+ } | |
+ needSize = buf->use + len + 1; | |
if (!xmlBufferResize(buf, needSize)){ | |
xmlTreeErrMemory("growing buffer"); | |
return XML_ERR_NO_MEMORY; | |
@@ -7694,29 +7849,7 @@ | |
*/ | |
int | |
xmlBufferCCat(xmlBufferPtr buf, const char *str) { | |
- const char *cur; | |
- | |
- if (buf == NULL) | |
- return(-1); | |
- if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1; | |
- if (str == NULL) { | |
-#ifdef DEBUG_BUFFER | |
- xmlGenericError(xmlGenericErrorContext, | |
- "xmlBufferCCat: str == NULL\n"); | |
-#endif | |
- return -1; | |
- } | |
- for (cur = str;*cur != 0;cur++) { | |
- if (buf->use + 10 >= buf->size) { | |
- if (!xmlBufferResize(buf, buf->use+10)){ | |
- xmlTreeErrMemory("growing buffer"); | |
- return XML_ERR_NO_MEMORY; | |
- } | |
- } | |
- buf->content[buf->use++] = *cur; | |
- } | |
- buf->content[buf->use] = 0; | |
- return 0; | |
+ return xmlBufferCat(buf, (const xmlChar *) str); | |
} | |
/** | |
@@ -8234,23 +8367,20 @@ | |
xmlDOMWrapNSNormAddNsMapItem2(xmlNsPtr **list, int *size, int *number, | |
xmlNsPtr oldNs, xmlNsPtr newNs) | |
{ | |
- if (*list == NULL) { | |
- *list = (xmlNsPtr *) xmlMalloc(6 * sizeof(xmlNsPtr)); | |
- if (*list == NULL) { | |
- xmlTreeErrMemory("alloc ns map item"); | |
- return(-1); | |
- } | |
- *size = 3; | |
- *number = 0; | |
- } else if ((*number) >= (*size)) { | |
- *size *= 2; | |
- *list = (xmlNsPtr *) xmlRealloc(*list, | |
- (*size) * 2 * sizeof(xmlNsPtr)); | |
- if (*list == NULL) { | |
- xmlTreeErrMemory("realloc ns map item"); | |
- return(-1); | |
- } | |
+ if (*number >= *size) { | |
+ xmlNsPtr *tmp; | |
+ size_t newSize; | |
+ | |
+ newSize = *size ? *size * 2 : 3; | |
+ tmp = xmlRealloc(*list, newSize * 2 * sizeof(tmp[0])); | |
+ if (tmp == NULL) { | |
+ xmlTreeErrMemory("realloc ns map item"); | |
+ return(-1); | |
+ } | |
+ *list = tmp; | |
+ *size = newSize; | |
} | |
+ | |
(*list)[2 * (*number)] = oldNs; | |
(*list)[2 * (*number) +1] = newNs; | |
(*number)++; | |
@@ -8279,7 +8409,7 @@ | |
xmlNodePtr node, int options ATTRIBUTE_UNUSED) | |
{ | |
xmlNsPtr *list = NULL; | |
- int sizeList, nbList, i, j; | |
+ int sizeList = 0, nbList = 0, ret = 0, i, j; | |
xmlNsPtr ns; | |
if ((node == NULL) || (doc == NULL) || (node->doc != doc)) | |
@@ -8315,7 +8445,7 @@ | |
do { | |
if (xmlDOMWrapNSNormAddNsMapItem2(&list, &sizeList, | |
&nbList, ns, ns) == -1) | |
- goto internal_error; | |
+ ret = -1; | |
ns = ns->next; | |
} while (ns != NULL); | |
} | |
@@ -8345,7 +8475,7 @@ | |
ns = xmlDOMWrapStoreNs(doc, node->ns->href, | |
node->ns->prefix); | |
if (ns == NULL) | |
- goto internal_error; | |
+ ret = -1; | |
} | |
if (ns != NULL) { | |
/* | |
@@ -8353,7 +8483,7 @@ | |
*/ | |
if (xmlDOMWrapNSNormAddNsMapItem2(&list, &sizeList, | |
&nbList, node->ns, ns) == -1) | |
- goto internal_error; | |
+ ret = -1; | |
} | |
node->ns = ns; | |
} | |
@@ -8385,12 +8515,7 @@ | |
if (list != NULL) | |
xmlFree(list); | |
- return (0); | |
- | |
-internal_error: | |
- if (list != NULL) | |
- xmlFree(list); | |
- return (-1); | |
+ return (ret); | |
} | |
/* | |
@@ -8811,7 +8936,7 @@ | |
int optRemoveRedundantNS = | |
((xmlDOMReconcileNSOptions) options & XML_DOM_RECONNS_REMOVEREDUND) ? 1 : 0; | |
xmlNsPtr *listRedund = NULL; | |
- int sizeRedund = 0, nbRedund = 0, ret, i, j; | |
+ int sizeRedund = 0, nbRedund = 0, ret = 0, i, j; | |
if ((elem == NULL) || (elem->doc == NULL) || | |
(elem->type != XML_ELEMENT_NODE)) | |
@@ -8840,7 +8965,7 @@ | |
*/ | |
if (xmlDOMWrapNSNormGatherInScopeNs(&nsMap, | |
elem->parent) == -1) | |
- goto internal_error; | |
+ ret = -1; | |
} | |
parnsdone = 1; | |
} | |
@@ -8862,16 +8987,18 @@ | |
* Add it to the list of redundant ns-decls. | |
*/ | |
if (xmlDOMWrapNSNormAddNsMapItem2(&listRedund, | |
- &sizeRedund, &nbRedund, ns, mi->newNs) == -1) | |
- goto internal_error; | |
- /* | |
- * Remove the ns-decl from the element-node. | |
- */ | |
- if (prevns) | |
- prevns->next = ns->next; | |
- else | |
- cur->nsDef = ns->next; | |
- goto next_ns_decl; | |
+ &sizeRedund, &nbRedund, ns, mi->newNs) == -1) { | |
+ ret = -1; | |
+ } else { | |
+ /* | |
+ * Remove the ns-decl from the element-node. | |
+ */ | |
+ if (prevns) | |
+ prevns->next = ns->next; | |
+ else | |
+ cur->nsDef = ns->next; | |
+ goto next_ns_decl; | |
+ } | |
} | |
} | |
} | |
@@ -8901,7 +9028,7 @@ | |
*/ | |
if (xmlDOMWrapNsMapAddItem(&nsMap, -1, ns, ns, | |
depth) == NULL) | |
- goto internal_error; | |
+ ret = -1; | |
prevns = ns; | |
next_ns_decl: | |
@@ -8921,7 +9048,7 @@ | |
((xmlNodePtr) elem->parent->doc != elem->parent)) { | |
if (xmlDOMWrapNSNormGatherInScopeNs(&nsMap, | |
elem->parent) == -1) | |
- goto internal_error; | |
+ ret = -1; | |
} | |
parnsdone = 1; | |
} | |
@@ -8960,7 +9087,7 @@ | |
&nsMap, depth, | |
ancestorsOnly, | |
(cur->type == XML_ATTRIBUTE_NODE) ? 1 : 0) == -1) | |
- goto internal_error; | |
+ ret = -1; | |
cur->ns = ns; | |
ns_end: | |
@@ -9020,11 +9147,6 @@ | |
} | |
} while (cur != NULL); | |
- ret = 0; | |
- goto exit; | |
-internal_error: | |
- ret = -1; | |
-exit: | |
if (listRedund) { | |
for (i = 0, j = 0; i < nbRedund; i++, j += 2) { | |
xmlFreeNs(listRedund[j]); | |
@@ -9105,8 +9227,6 @@ | |
parnsdone = 0; | |
cur = node; | |
- if ((cur != NULL) && (cur->type == XML_NAMESPACE_DECL)) | |
- goto internal_error; | |
while (cur != NULL) { | |
/* | |
@@ -9138,7 +9258,8 @@ | |
/* | |
* TODO | |
*/ | |
- return (-1); | |
+ ret = -1; | |
+ goto leave_node; | |
case XML_ELEMENT_NODE: | |
curElem = cur; | |
depth++; | |
@@ -9159,7 +9280,7 @@ | |
*/ | |
if (xmlDOMWrapNSNormGatherInScopeNs(&nsMap, | |
destParent) == -1) | |
- goto internal_error; | |
+ ret = -1; | |
parnsdone = 1; | |
} | |
for (ns = cur->nsDef; ns != NULL; ns = ns->next) { | |
@@ -9188,7 +9309,7 @@ | |
*/ | |
if (xmlDOMWrapNsMapAddItem(&nsMap, -1, | |
ns, ns, depth) == NULL) | |
- goto internal_error; | |
+ ret = -1; | |
} | |
} | |
/* Falls through. */ | |
@@ -9200,7 +9321,7 @@ | |
if (! parnsdone) { | |
if (xmlDOMWrapNSNormGatherInScopeNs(&nsMap, | |
destParent) == -1) | |
- goto internal_error; | |
+ ret = -1; | |
parnsdone = 1; | |
} | |
/* | |
@@ -9234,7 +9355,7 @@ | |
*/ | |
if (xmlDOMWrapNsMapAddItem(&nsMap, -1, | |
cur->ns, ns, XML_TREE_NSMAP_CUSTOM) == NULL) | |
- goto internal_error; | |
+ ret = -1; | |
cur->ns = ns; | |
} else { | |
/* | |
@@ -9248,7 +9369,7 @@ | |
ancestorsOnly, | |
/* ns-decls must be prefixed for attributes. */ | |
(cur->type == XML_ATTRIBUTE_NODE) ? 1 : 0) == -1) | |
- goto internal_error; | |
+ ret = -1; | |
cur->ns = ns; | |
} | |
ns_end: | |
@@ -9319,7 +9440,7 @@ | |
case XML_COMMENT_NODE: | |
break; | |
default: | |
- goto internal_error; | |
+ ret = -1; | |
} | |
/* | |
* Walk the tree. | |
@@ -9370,12 +9491,6 @@ | |
} | |
} | |
- goto exit; | |
- | |
-internal_error: | |
- ret = -1; | |
- | |
-exit: | |
/* | |
* Cleanup. | |
*/ | |
@@ -9455,7 +9570,8 @@ | |
xmlNsPtr cloneNs = NULL, *cloneNsDefSlot = NULL; | |
xmlDictPtr dict; /* The destination dict */ | |
- if ((node == NULL) || (resNode == NULL) || (destDoc == NULL)) | |
+ if ((node == NULL) || (resNode == NULL) || (destDoc == NULL) || | |
+ ((destParent != NULL) && (destParent->doc != destDoc))) | |
return(-1); | |
/* | |
* TODO: Initially we support only element-nodes. | |
@@ -9962,7 +10078,7 @@ | |
int options ATTRIBUTE_UNUSED) | |
{ | |
xmlNodePtr cur; | |
- int adoptStr = 1; | |
+ int adoptStr = 1, ret = 0; | |
if ((attr == NULL) || (destDoc == NULL)) | |
return (-1); | |
@@ -9988,14 +10104,14 @@ | |
*/ | |
if (xmlSearchNsByNamespaceStrict(destDoc, destParent, attr->ns->href, | |
&ns, 1) == -1) | |
- goto internal_error; | |
+ ret = -1; | |
if (ns == NULL) { | |
ns = xmlDOMWrapNSNormDeclareNsForced(destDoc, destParent, | |
attr->ns->href, attr->ns->prefix, 1); | |
} | |
} | |
if (ns == NULL) | |
- goto internal_error; | |
+ ret = -1; | |
attr->ns = ns; | |
} | |
@@ -10006,10 +10122,10 @@ | |
* Walk content. | |
*/ | |
if (attr->children == NULL) | |
- return (0); | |
+ return (ret); | |
cur = attr->children; | |
if ((cur != NULL) && (cur->type == XML_NAMESPACE_DECL)) | |
- goto internal_error; | |
+ ret = -1; | |
while (cur != NULL) { | |
cur->doc = destDoc; | |
switch (cur->type) { | |
@@ -10054,9 +10170,8 @@ | |
goto next_sibling; | |
} | |
} | |
- return (0); | |
-internal_error: | |
- return (-1); | |
+ | |
+ return (ret); | |
} | |
/* | |
diff -ru libxml2/trionan.c libxml2-apple/libxml2/trionan.c | |
--- libxml2/trionan.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/trionan.c 2025-06-26 01:54:56 | |
@@ -178,7 +178,7 @@ | |
TRIO_ARGS1((values), | |
TRIO_CONST unsigned char *values) | |
{ | |
- TRIO_VOLATILE double result; | |
+ TRIO_VOLATILE double result = 0.0; | |
int i; | |
for (i = 0; i < (int)sizeof(double); i++) { | |
diff -ru libxml2/valid.c libxml2-apple/libxml2/valid.c | |
--- libxml2/valid.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/valid.c 2025-06-26 01:54:56 | |
@@ -10,6 +10,7 @@ | |
#define IN_LIBXML | |
#include "libxml.h" | |
+#include <assert.h> | |
#include <string.h> | |
#ifdef HAVE_STDLIB_H | |
@@ -68,9 +69,7 @@ | |
context */ | |
if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || | |
(ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) { | |
- long delta = (char *) ctxt - (char *) ctxt->userData; | |
- if ((delta > 0) && (delta < 250)) | |
- pctxt = ctxt->userData; | |
+ pctxt = ctxt->userData; | |
} | |
} | |
if (extra) | |
@@ -108,16 +107,17 @@ | |
context */ | |
if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || | |
(ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) { | |
- long delta = (char *) ctxt - (char *) ctxt->userData; | |
- if ((delta > 0) && (delta < 250)) | |
- pctxt = ctxt->userData; | |
+ pctxt = ctxt->userData; | |
} | |
} | |
if (extra) | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, channel, data, | |
pctxt, NULL, XML_FROM_VALID, error, | |
XML_ERR_ERROR, NULL, 0, extra, NULL, NULL, 0, 0, | |
msg, extra); | |
+#pragma clang diagnostic pop | |
else | |
__xmlRaiseError(NULL, channel, data, | |
pctxt, NULL, XML_FROM_VALID, error, | |
@@ -155,16 +155,17 @@ | |
context */ | |
if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || | |
(ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) { | |
- long delta = (char *) ctxt - (char *) ctxt->userData; | |
- if ((delta > 0) && (delta < 250)) | |
- pctxt = ctxt->userData; | |
+ pctxt = ctxt->userData; | |
} | |
} | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error, | |
XML_ERR_ERROR, NULL, 0, | |
(const char *) str1, | |
(const char *) str2, | |
(const char *) str3, 0, 0, msg, str1, str2, str3); | |
+#pragma clang diagnostic pop | |
} | |
#endif /* LIBXML_VALID_ENABLED or LIBXML_SCHEMAS_ENABLED */ | |
@@ -198,16 +199,17 @@ | |
context */ | |
if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || | |
(ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) { | |
- long delta = (char *) ctxt - (char *) ctxt->userData; | |
- if ((delta > 0) && (delta < 250)) | |
- pctxt = ctxt->userData; | |
+ pctxt = ctxt->userData; | |
} | |
} | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error, | |
XML_ERR_ERROR, NULL, 0, | |
(const char *) str1, | |
(const char *) str3, | |
NULL, int2, 0, msg, str1, int2, str3); | |
+#pragma clang diagnostic pop | |
} | |
/** | |
@@ -239,16 +241,17 @@ | |
context */ | |
if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) || | |
(ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) { | |
- long delta = (char *) ctxt - (char *) ctxt->userData; | |
- if ((delta > 0) && (delta < 250)) | |
- pctxt = ctxt->userData; | |
+ pctxt = ctxt->userData; | |
} | |
} | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error, | |
XML_ERR_WARNING, NULL, 0, | |
(const char *) str1, | |
(const char *) str2, | |
(const char *) str3, 0, 0, msg, str1, str2, str3); | |
+#pragma clang diagnostic pop | |
} | |
@@ -1081,6 +1084,7 @@ | |
tmp->type = cur->type; | |
tmp->ocur = cur->ocur; | |
prev->c2 = tmp; | |
+ tmp->parent = prev; | |
if (cur->name != NULL) { | |
if (dict) | |
tmp->name = xmlDictLookup(dict, cur->name, -1); | |
@@ -1312,6 +1316,14 @@ | |
} | |
#endif /* LIBXML_OUTPUT_ENABLED */ | |
+static void | |
+terminateBufferTooSmall(char *buf, int size) { | |
+ int len = strlen(buf); | |
+ if ((size - len > 4) && (buf[len - 1] != '.')) | |
+ strncat(buf, " ...", size - len); | |
+ buf[size - 1] = '\0'; | |
+} | |
+ | |
/** | |
* xmlSnprintfElementContent: | |
* @buf: an output buffer | |
@@ -1325,34 +1337,49 @@ | |
void | |
xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int englob) { | |
int len; | |
+ int trailingLength; | |
if (content == NULL) return; | |
+ assert(buf); | |
+ if (size < 1) return; | |
len = strlen(buf); | |
if (size - len < 50) { | |
- if ((size - len > 4) && (buf[len - 1] != '.')) | |
- strcat(buf, " ..."); | |
+ terminateBufferTooSmall(buf, size); | |
return; | |
} | |
- if (englob) strcat(buf, "("); | |
+ if (englob) { | |
+ assert(size - len > 1); | |
+ strncat(buf, "(", size - len); | |
+ len += 1; | |
+ } | |
+ trailingLength = (englob ? 1 : 0) + (content->ocur != XML_ELEMENT_CONTENT_ONCE ? 1 : 0); | |
switch (content->type) { | |
case XML_ELEMENT_CONTENT_PCDATA: | |
- strcat(buf, "#PCDATA"); | |
+ assert(size - len > 7); | |
+ strncat(buf, "#PCDATA", size - len); | |
+ len += 7; | |
break; | |
case XML_ELEMENT_CONTENT_ELEMENT: { | |
- int qnameLen = xmlStrlen(content->name); | |
- | |
- if (content->prefix != NULL) | |
- qnameLen += xmlStrlen(content->prefix) + 1; | |
- if (size - len < qnameLen + 10) { | |
- strcat(buf, " ..."); | |
- return; | |
- } | |
if (content->prefix != NULL) { | |
- strcat(buf, (char *) content->prefix); | |
- strcat(buf, ":"); | |
+ int prefixLength = xmlStrlen(content->prefix); | |
+ if (size - len < prefixLength + 1 + trailingLength + 1) { | |
+ terminateBufferTooSmall(buf, size); | |
+ return; | |
+ } | |
+ strncat(buf, (char *)content->prefix, size - len); | |
+ len += prefixLength; | |
+ strncat(buf, ":", size - len); | |
+ len += 1; | |
} | |
- if (content->name != NULL) | |
- strcat(buf, (char *) content->name); | |
+ if (content->name != NULL) { | |
+ int nameLength = xmlStrlen(content->name); | |
+ if (size - len < nameLength + trailingLength + 1) { | |
+ terminateBufferTooSmall(buf, size); | |
+ return; | |
+ } | |
+ strncat(buf, (char *)content->name, size - len); | |
+ len += nameLength; | |
+ } | |
break; | |
} | |
case XML_ELEMENT_CONTENT_SEQ: | |
@@ -1363,17 +1390,18 @@ | |
xmlSnprintfElementContent(buf, size, content->c1, 0); | |
len = strlen(buf); | |
if (size - len < 50) { | |
- if ((size - len > 4) && (buf[len - 1] != '.')) | |
- strcat(buf, " ..."); | |
+ terminateBufferTooSmall(buf, size); | |
return; | |
} | |
- strcat(buf, " , "); | |
+ strncat(buf, " , ", size - len); | |
+ len += 3; | |
if (((content->c2->type == XML_ELEMENT_CONTENT_OR) || | |
(content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)) && | |
(content->c2->type != XML_ELEMENT_CONTENT_ELEMENT)) | |
xmlSnprintfElementContent(buf, size, content->c2, 1); | |
else | |
xmlSnprintfElementContent(buf, size, content->c2, 0); | |
+ len = strlen(buf); | |
break; | |
case XML_ELEMENT_CONTENT_OR: | |
if ((content->c1->type == XML_ELEMENT_CONTENT_OR) || | |
@@ -1383,35 +1411,46 @@ | |
xmlSnprintfElementContent(buf, size, content->c1, 0); | |
len = strlen(buf); | |
if (size - len < 50) { | |
- if ((size - len > 4) && (buf[len - 1] != '.')) | |
- strcat(buf, " ..."); | |
+ terminateBufferTooSmall(buf, size); | |
return; | |
} | |
- strcat(buf, " | "); | |
+ strncat(buf, " | ", size - len); | |
+ len += 3; | |
if (((content->c2->type == XML_ELEMENT_CONTENT_SEQ) || | |
(content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)) && | |
(content->c2->type != XML_ELEMENT_CONTENT_ELEMENT)) | |
xmlSnprintfElementContent(buf, size, content->c2, 1); | |
else | |
xmlSnprintfElementContent(buf, size, content->c2, 0); | |
+ len = strlen(buf); | |
break; | |
} | |
- if (size - strlen(buf) <= 2) return; | |
- if (englob) | |
- strcat(buf, ")"); | |
+ if (size - len < trailingLength + 1) { | |
+ terminateBufferTooSmall(buf, size); | |
+ return; | |
+ } | |
+ if (englob) { | |
+ strncat(buf, ")", size - len); | |
+ len += 1; | |
+ } | |
switch (content->ocur) { | |
case XML_ELEMENT_CONTENT_ONCE: | |
break; | |
case XML_ELEMENT_CONTENT_OPT: | |
- strcat(buf, "?"); | |
+ strncat(buf, "?", size - len); | |
+ len += 1; | |
break; | |
case XML_ELEMENT_CONTENT_MULT: | |
- strcat(buf, "*"); | |
+ strncat(buf, "*", size - len); | |
+ len += 1; | |
break; | |
case XML_ELEMENT_CONTENT_PLUS: | |
- strcat(buf, "+"); | |
+ strncat(buf, "+", size - len); | |
+ len += 1; | |
break; | |
} | |
+ assert(size - len > 0); | |
+ buf[size - 1] = '\0'; | |
} | |
/**************************************************************** | |
@@ -5246,47 +5285,72 @@ | |
xmlSnprintfElements(char *buf, int size, xmlNodePtr node, int glob) { | |
xmlNodePtr cur; | |
int len; | |
+ int trailingLength = (glob ? 1 : 0); | |
if (node == NULL) return; | |
- if (glob) strcat(buf, "("); | |
+ assert(buf); | |
+ if (size < 1) return; | |
+ len = strlen(buf); | |
+ if (glob) { | |
+ if (size - len < 1 + trailingLength + 1) { | |
+ terminateBufferTooSmall(buf, size); | |
+ return; | |
+ } | |
+ strncat(buf, "(", size - len); | |
+ len += 1; | |
+ } | |
cur = node; | |
while (cur != NULL) { | |
- len = strlen(buf); | |
if (size - len < 50) { | |
- if ((size - len > 4) && (buf[len - 1] != '.')) | |
- strcat(buf, " ..."); | |
+ terminateBufferTooSmall(buf, size); | |
return; | |
} | |
switch (cur->type) { | |
case XML_ELEMENT_NODE: | |
+ { | |
+ int nameLength; | |
+ int nextLength = (cur->next != NULL ? 1 : 0); | |
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) { | |
- if (size - len < xmlStrlen(cur->ns->prefix) + 10) { | |
- if ((size - len > 4) && (buf[len - 1] != '.')) | |
- strcat(buf, " ..."); | |
+ int prefixLength = xmlStrlen(cur->ns->prefix); | |
+ if (size - len < prefixLength + 1 + nextLength + trailingLength + 1) { | |
+ terminateBufferTooSmall(buf, size); | |
return; | |
} | |
- strcat(buf, (char *) cur->ns->prefix); | |
- strcat(buf, ":"); | |
+ strncat(buf, (char *)cur->ns->prefix, size - len); | |
+ len += prefixLength; | |
+ strncat(buf, ":", size - len); | |
+ len += 1; | |
} | |
- if (size - len < xmlStrlen(cur->name) + 10) { | |
- if ((size - len > 4) && (buf[len - 1] != '.')) | |
- strcat(buf, " ..."); | |
+ nameLength = xmlStrlen(cur->name); | |
+ if (size - len < nameLength + nextLength + trailingLength + 1) { | |
+ terminateBufferTooSmall(buf, size); | |
return; | |
} | |
- strcat(buf, (char *) cur->name); | |
- if (cur->next != NULL) | |
- strcat(buf, " "); | |
+ strncat(buf, (char *)cur->name, size - len); | |
+ len += nameLength; | |
+ if (cur->next != NULL) { | |
+ strncat(buf, " ", size - len); | |
+ len += nextLength; | |
+ } | |
break; | |
+ } | |
case XML_TEXT_NODE: | |
if (xmlIsBlankNode(cur)) | |
break; | |
/* Falls through. */ | |
case XML_CDATA_SECTION_NODE: | |
case XML_ENTITY_REF_NODE: | |
- strcat(buf, "CDATA"); | |
- if (cur->next != NULL) | |
- strcat(buf, " "); | |
+ { | |
+ int nextLength = (cur->next != NULL ? 1 : 0); | |
+ assert(size - len > 5 + nextLength + trailingLength); | |
+ strncat(buf, "CDATA", size - len); | |
+ len += 5; | |
+ if (cur->next != NULL) { | |
+ strncat(buf, " ", size - len); | |
+ len += nextLength; | |
+ } | |
break; | |
+ } | |
case XML_ATTRIBUTE_NODE: | |
case XML_DOCUMENT_NODE: | |
#ifdef LIBXML_DOCB_ENABLED | |
@@ -5297,10 +5361,17 @@ | |
case XML_DOCUMENT_FRAG_NODE: | |
case XML_NOTATION_NODE: | |
case XML_NAMESPACE_DECL: | |
- strcat(buf, "???"); | |
- if (cur->next != NULL) | |
- strcat(buf, " "); | |
+ { | |
+ int nextLength = (cur->next != NULL ? 1 : 0); | |
+ assert(size - len > 3 + nextLength + trailingLength); | |
+ strncat(buf, "???", size - len); | |
+ len += 3; | |
+ if (cur->next != NULL) { | |
+ strncat(buf, " ", size - len); | |
+ len += nextLength; | |
+ } | |
break; | |
+ } | |
case XML_ENTITY_NODE: | |
case XML_PI_NODE: | |
case XML_DTD_NODE: | |
@@ -5314,7 +5385,13 @@ | |
} | |
cur = cur->next; | |
} | |
- if (glob) strcat(buf, ")"); | |
+ if (glob) { | |
+ assert(size - len > trailingLength); | |
+ strncat(buf, ")", size - len); | |
+ len += trailingLength; | |
+ } | |
+ assert(size - len > 0); | |
+ buf[size - 1] = '\0'; | |
} | |
/** | |
@@ -6470,60 +6547,60 @@ | |
*/ | |
int | |
-xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) { | |
- xmlNodePtr child; | |
+xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr root) { | |
+ xmlNodePtr elem; | |
xmlAttrPtr attr; | |
xmlNsPtr ns; | |
const xmlChar *value; | |
int ret = 1; | |
- if (elem == NULL) return(0); | |
+ if (root == NULL) return(0); | |
- /* | |
- * XInclude elements were added after parsing in the infoset, | |
- * they don't really mean anything validation wise. | |
- */ | |
- if ((elem->type == XML_XINCLUDE_START) || | |
- (elem->type == XML_XINCLUDE_END) || | |
- (elem->type == XML_NAMESPACE_DECL)) | |
- return(1); | |
- | |
CHECK_DTD; | |
- /* | |
- * Entities references have to be handled separately | |
- */ | |
- if (elem->type == XML_ENTITY_REF_NODE) { | |
- return(1); | |
- } | |
+ elem = root; | |
+ while (1) { | |
+ ret &= xmlValidateOneElement(ctxt, doc, elem); | |
- ret &= xmlValidateOneElement(ctxt, doc, elem); | |
- if (elem->type == XML_ELEMENT_NODE) { | |
- attr = elem->properties; | |
- while (attr != NULL) { | |
- value = xmlNodeListGetString(doc, attr->children, 0); | |
- ret &= xmlValidateOneAttribute(ctxt, doc, elem, attr, value); | |
- if (value != NULL) | |
- xmlFree((char *)value); | |
- attr= attr->next; | |
- } | |
- ns = elem->nsDef; | |
- while (ns != NULL) { | |
- if (elem->ns == NULL) | |
- ret &= xmlValidateOneNamespace(ctxt, doc, elem, NULL, | |
- ns, ns->href); | |
- else | |
- ret &= xmlValidateOneNamespace(ctxt, doc, elem, | |
- elem->ns->prefix, ns, ns->href); | |
- ns = ns->next; | |
- } | |
+ if (elem->type == XML_ELEMENT_NODE) { | |
+ attr = elem->properties; | |
+ while (attr != NULL) { | |
+ value = xmlNodeListGetString(doc, attr->children, 0); | |
+ ret &= xmlValidateOneAttribute(ctxt, doc, elem, attr, value); | |
+ if (value != NULL) | |
+ xmlFree((char *)value); | |
+ attr= attr->next; | |
+ } | |
+ | |
+ ns = elem->nsDef; | |
+ while (ns != NULL) { | |
+ if (elem->ns == NULL) | |
+ ret &= xmlValidateOneNamespace(ctxt, doc, elem, NULL, | |
+ ns, ns->href); | |
+ else | |
+ ret &= xmlValidateOneNamespace(ctxt, doc, elem, | |
+ elem->ns->prefix, ns, | |
+ ns->href); | |
+ ns = ns->next; | |
+ } | |
+ | |
+ if (elem->children != NULL) { | |
+ elem = elem->children; | |
+ continue; | |
+ } | |
+ } | |
+ | |
+ while (1) { | |
+ if (elem == root) | |
+ goto done; | |
+ if (elem->next != NULL) | |
+ break; | |
+ elem = elem->parent; | |
+ } | |
+ elem = elem->next; | |
} | |
- child = elem->children; | |
- while (child != NULL) { | |
- ret &= xmlValidateElement(ctxt, doc, child); | |
- child = child->next; | |
- } | |
+done: | |
return(ret); | |
} | |
Only in libxml2-apple/libxml2: version.rc | |
diff -ru libxml2/win32/Makefile.msvc libxml2-apple/libxml2/win32/Makefile.msvc | |
--- libxml2/win32/Makefile.msvc 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/win32/Makefile.msvc 2025-06-26 01:54:56 | |
@@ -19,7 +19,11 @@ | |
!include $(AUTOCONF) | |
# Names of various input and output components. | |
+!if "$(DEBUG)" == "1" | |
+XML_NAME = xml2_debug | |
+!else | |
XML_NAME = xml2 | |
+!endif | |
XML_BASENAME = lib$(XML_NAME) | |
XML_SO = $(XML_BASENAME).dll | |
XML_RES = $(XML_BASENAME).res | |
@@ -29,11 +33,11 @@ | |
XML_A_DLL = $(XML_BASENAME)_a_dll.lib | |
# Place where we let the compiler put its output. | |
-BINDIR = bin.msvc | |
-XML_INTDIR = int.msvc | |
-XML_INTDIR_A = int.a.msvc | |
-XML_INTDIR_A_DLL = int.a.dll.msvc | |
-UTILS_INTDIR = int.utils.msvc | |
+BINDIR = $(ARCH)\bin.msvc | |
+XML_INTDIR = $(ARCH)\int.msvc | |
+XML_INTDIR_A = $(ARCH)\int.a.msvc | |
+XML_INTDIR_A_DLL = $(ARCH)\int.a.dll.msvc | |
+UTILS_INTDIR = $(ARCH)\int.utils.msvc | |
# The preprocessor and its options. | |
CPP = cl.exe /EP | |
@@ -44,7 +48,7 @@ | |
# The compiler and its options. | |
CC = cl.exe | |
-CFLAGS = /nologo /D "_WINDOWS" /D "_MBCS" /D "NOLIBTOOL" /W3 /wd4244 /wd4267 $(CRUNTIME) | |
+CFLAGS = /nologo /D "_WINDOWS" /D "_MBCS" /D "HAVE_CONFIG_H" /D "NOLIBTOOL" /W3 $(CRUNTIME) | |
CFLAGS = $(CFLAGS) /I$(XML_SRCDIR) /I$(XML_SRCDIR)\include /I$(INCPREFIX) | |
!if "$(WITH_THREADS)" != "no" | |
CFLAGS = $(CFLAGS) /D "_REENTRANT" | |
@@ -56,30 +60,39 @@ | |
!else if "$(WITH_THREADS)" == "posix" | |
CFLAGS = $(CFLAGS) /D "HAVE_PTHREAD_H" | |
!endif | |
-CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE | |
+CFLAGS = $(CFLAGS) /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES | |
# The linker and its options. | |
LD = link.exe | |
LDFLAGS = /nologo /VERSION:$(LIBXML_MAJOR_VERSION).$(LIBXML_MINOR_VERSION) | |
LDFLAGS = $(LDFLAGS) /LIBPATH:$(BINDIR) /LIBPATH:$(LIBPREFIX) | |
+LDFLAGS = $(LDFLAGS) /NXCOMPAT /DYNAMICBASE | |
+!if "$(ARCH)" == "32" | |
+LDFLAGS = $(LDFLAGS) /SAFESEH | |
+!endif | |
LIBS = | |
!if "$(WITH_FTP)" == "1" || "$(WITH_HTTP)" == "1" | |
LIBS = $(LIBS) wsock32.lib ws2_32.lib | |
!endif | |
!if "$(WITH_ICONV)" == "1" | |
+!if "$(DEBUG)" == "1" | |
+LIBS = $(LIBS) iconv_debug.lib | |
+!else | |
LIBS = $(LIBS) iconv.lib | |
+!endif | |
!endif | |
!if "$(WITH_ICU)" == "1" | |
-!if "$(STATIC)" == "1" | |
-LIBS = $(LIBS) advapi32.lib sicuuc.lib sicuin.lib sicudt.lib | |
+CFLAGS = $(CFLAGS) /DU_DISABLE_RENAMING=1 | |
+!if "$(DEBUG)" == "1" | |
+LIBS = $(LIBS) libicuuc_debug.lib | |
!else | |
-LIBS = $(LIBS) icuuc.lib icuin.lib icudt.lib | |
+LIBS = $(LIBS) libicuuc.lib | |
!endif | |
!endif | |
!if "$(WITH_ZLIB)" == "1" | |
# could be named differently zdll or zlib | |
-# LIBS = $(LIBS) zdll.lib | |
-LIBS = $(LIBS) zlib.lib | |
+LIBS = $(LIBS) zdll.lib | |
+# LIBS = $(LIBS) zlib.lib | |
!endif | |
!if "$(WITH_LZMA)" == "1" | |
LIBS = $(LIBS) liblzma.lib | |
@@ -155,7 +168,8 @@ | |
$(XML_INTDIR)\xmlwriter.obj\ | |
$(XML_INTDIR)\xpath.obj\ | |
$(XML_INTDIR)\xpointer.obj\ | |
- $(XML_INTDIR)\xmlstring.obj | |
+ $(XML_INTDIR)\xmlstring.obj\ | |
+ $(XML_INTDIR)\version.res | |
# Static libxml object files. | |
XML_OBJS_A = $(XML_INTDIR_A)\buf.obj\ | |
@@ -371,6 +385,10 @@ | |
# An implicit rule for static for dll libxml compilation. | |
{$(XML_SRCDIR)}.c{$(XML_INTDIR_A_DLL)}.obj:: | |
$(CC) $(CFLAGS) /D "LIBXML_STATIC" /D "LIBXML_STATIC_FOR_DLL" /Fo$(XML_INTDIR_A_DLL)\ /c $< | |
+ | |
+# Compiles libxml resource files. | |
+{$(XML_SRCDIR)}.rc{$(XML_INTDIR)}.res: | |
+ rc.exe /i $(RINCLUDE) /fo $@ $< | |
# Compiles libxml source. Uses the implicit rule for commands. | |
$(XML_OBJS) : $(XML_INTDIR) | |
diff -ru libxml2/win32/configure.js libxml2-apple/libxml2/win32/configure.js | |
--- libxml2/win32/configure.js 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/win32/configure.js 2025-06-26 01:54:56 | |
@@ -167,6 +167,7 @@ | |
txt += " (" + buildSoPrefix + ")\n"; | |
txt += " include: Additional search path for the compiler, particularly\n"; | |
txt += " where iconv headers can be found (" + buildInclude + ")\n"; | |
+ txt += " rinclude: Additional search path for the resource compiler\n"; | |
txt += " lib: Additional search path for the linker, particularly\n"; | |
txt += " where iconv library can be found (" + buildLib + ")\n"; | |
WScript.Echo(txt); | |
@@ -265,6 +266,7 @@ | |
vf.WriteLine("LIB=" + buildLib); | |
vf.WriteLine("DYNRUNTIME=" + (dynruntime? "1" : "0")); | |
} | |
+ vf.WriteLine("RINCLUDE=" + resourceInclude); | |
vf.Close(); | |
versionFile = "rcVersion.h"; | |
vf = fso.CreateTextFile(versionFile, true); | |
@@ -548,6 +550,8 @@ | |
buildIncPrefix = arg.substring(opt.length + 1, arg.length); | |
else if (opt == "include") | |
buildInclude = arg.substring(opt.length + 1, arg.length); | |
+ else if (opt == "rinclude") | |
+ resourceInclude = arg.substring(opt.length + 1, arg.length); | |
else if (opt == "lib") | |
buildLib = arg.substring(opt.length + 1, arg.length); | |
else if (opt == "release") | |
@@ -705,6 +709,7 @@ | |
txtOut += "Put static libs in: " + buildLibPrefix + "\n"; | |
txtOut += "Put shared libs in: " + buildSoPrefix + "\n"; | |
txtOut += " Include path: " + buildInclude + "\n"; | |
+txtOut += " RInclude path: " + resourceInclude + "\n"; | |
txtOut += " Lib path: " + buildLib + "\n"; | |
WScript.Echo(txtOut); | |
Only in libxml2-apple/libxml2/win32: libxml2_debug.def.src | |
diff -ru libxml2/xinclude.c libxml2-apple/libxml2/xinclude.c | |
--- libxml2/xinclude.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xinclude.c 2025-06-26 01:54:56 | |
@@ -134,10 +134,13 @@ | |
{ | |
if (ctxt != NULL) | |
ctxt->nbErrors++; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE, | |
error, XML_ERR_ERROR, NULL, 0, | |
(const char *) extra, NULL, NULL, 0, 0, | |
msg, (const char *) extra); | |
+#pragma clang diagnostic pop | |
} | |
#if 0 | |
@@ -154,10 +157,13 @@ | |
xmlXIncludeWarn(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error, | |
const char *msg, const xmlChar *extra) | |
{ | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, ctxt, node, XML_FROM_XINCLUDE, | |
error, XML_ERR_WARNING, NULL, 0, | |
(const char *) extra, NULL, NULL, 0, 0, | |
msg, (const char *) extra); | |
+#pragma clang diagnostic pop | |
} | |
#endif | |
@@ -614,14 +620,15 @@ | |
} | |
URL = xmlSaveUri(uri); | |
xmlFreeURI(uri); | |
- xmlFree(URI); | |
if (URL == NULL) { | |
xmlXIncludeErr(ctxt, cur, XML_XINCLUDE_HREF_URI, | |
"invalid value URI %s\n", URI); | |
if (fragment != NULL) | |
xmlFree(fragment); | |
+ xmlFree(URI); | |
return(-1); | |
} | |
+ xmlFree(URI); | |
/* | |
* If local and xml then we need a fragment | |
@@ -880,6 +887,7 @@ | |
return(result); | |
} | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
/** | |
* xmlXIncludeGetNthChild: | |
* @cur: the node | |
@@ -986,7 +994,7 @@ | |
int len; | |
if (content == NULL) { | |
- tmp = xmlNewTextLen(NULL, 0); | |
+ tmp = xmlNewDocTextLen(target, NULL, 0); | |
} else { | |
len = index2; | |
if ((cur == start) && (index1 > 1)) { | |
@@ -995,7 +1003,7 @@ | |
} else { | |
len = index2; | |
} | |
- tmp = xmlNewTextLen(content, len); | |
+ tmp = xmlNewDocTextLen(target, content, len); | |
} | |
/* single sub text node selection */ | |
if (list == NULL) | |
@@ -1046,13 +1054,13 @@ | |
const xmlChar *content = cur->content; | |
if (content == NULL) { | |
- tmp = xmlNewTextLen(NULL, 0); | |
+ tmp = xmlNewDocTextLen(target, NULL, 0); | |
} else { | |
if (index1 > 1) { | |
content += (index1 - 1); | |
index1 = 0; | |
} | |
- tmp = xmlNewText(content); | |
+ tmp = xmlNewDocText(target, content); | |
} | |
last = list = tmp; | |
listParent = cur->parent; | |
@@ -1119,6 +1127,7 @@ | |
} | |
return(list); | |
} | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
/** | |
* xmlXIncludeBuildNodeList: | |
@@ -1220,7 +1229,7 @@ | |
} | |
break; | |
} | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_LOCATIONSET: { | |
xmlLocationSetPtr set = (xmlLocationSetPtr) obj->user; | |
if (set == NULL) | |
@@ -1242,10 +1251,10 @@ | |
} | |
case XPATH_RANGE: | |
return(xmlXIncludeCopyRange(ctxt, target, source, obj)); | |
-#endif | |
case XPATH_POINT: | |
/* points are ignored in XInclude */ | |
break; | |
+#endif | |
default: | |
break; | |
} | |
@@ -1597,7 +1606,9 @@ | |
case XPATH_BOOLEAN: | |
case XPATH_NUMBER: | |
case XPATH_STRING: | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
+#endif | |
case XPATH_USERS: | |
case XPATH_XSLT_TREE: | |
xmlXIncludeErr(ctxt, ctxt->incTab[nr]->ref, | |
@@ -1619,9 +1630,11 @@ | |
return(-1); | |
} | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_RANGE: | |
case XPATH_LOCATIONSET: | |
break; | |
+#endif | |
} | |
set = xptr->nodesetval; | |
if (set != NULL) { | |
@@ -2237,6 +2250,9 @@ | |
xmlAddPrevSibling(cur, end); | |
} | |
+ /* | |
+ * FIXME: xmlUnlinkNode doesn't coalesce text nodes. | |
+ */ | |
xmlUnlinkNode(cur); | |
xmlFreeNode(cur); | |
} else { | |
diff -ru libxml2/xml2-config.1 libxml2-apple/libxml2/xml2-config.1 | |
--- libxml2/xml2-config.1 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xml2-config.1 2025-06-26 01:54:56 | |
@@ -1,15 +1,15 @@ | |
.TH GNOME-XML 1 "3 July 1999" Version 1.1.0 | |
.SH NAME | |
-xml-config - script to get information about the installed version of GNOME-XML | |
+xml2-config - script to get information about the installed version of GNOME-XML | |
.SH SYNOPSIS | |
-.B xml-config | |
+.B xml2-config | |
[\-\-prefix\fI[=DIR]\fP] [\-\-libs] [\-\-cflags] [\-\-version] [\-\-help] | |
.SH DESCRIPTION | |
-\fIxml-config\fP is a tool that is used to determine the compile and | |
+\fIxml2-config\fP is a tool that is used to determine the compile and | |
linker flags that should be used to compile and link programs that use | |
\fIGNOME-XML\fP. | |
.SH OPTIONS | |
-\fIxml-config\fP accepts the following options: | |
+\fIxml2-config\fP accepts the following options: | |
.TP 8 | |
.B \-\-version | |
Print the currently installed version of \fIGNOME-XML\fP on the standard output. | |
diff -ru libxml2/xmlIO.c libxml2-apple/libxml2/xmlIO.c | |
--- libxml2/xmlIO.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xmlIO.c 2025-06-26 01:54:56 | |
@@ -130,7 +130,7 @@ | |
* * | |
************************************************************************/ | |
-static const char *IOerr[] = { | |
+static const char * const IOerr[] = { | |
"Unknown IO error", /* UNKNOWN */ | |
"Permission denied", /* EACCES */ | |
"Resource temporarily unavailable",/* EAGAIN */ | |
@@ -410,7 +410,10 @@ | |
if (code >= XML_IO_UNKNOWN) idx = code - XML_IO_UNKNOWN; | |
if (idx >= (sizeof(IOerr) / sizeof(IOerr[0]))) idx = 0; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlSimpleError(domain, code, NULL, IOerr[idx], extra); | |
+#pragma clang diagnostic pop | |
} | |
/** | |
@@ -457,11 +460,13 @@ | |
schannel = ctxt->sax->serror; | |
data = ctxt->userData; | |
} | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, channel, data, ctxt, NULL, XML_FROM_IO, | |
XML_IO_LOAD_ERROR, level, NULL, 0, | |
filename, NULL, NULL, 0, 0, | |
msg, filename); | |
- | |
+#pragma clang diagnostic pop | |
} | |
/************************************************************************ | |
@@ -3247,12 +3252,6 @@ | |
if ((len <= MINLEN) && (len != 4)) | |
len = MINLEN; | |
- if (xmlBufAvail(in->buffer) <= 0) { | |
- xmlIOErr(XML_IO_BUFFER_FULL, NULL); | |
- in->error = XML_IO_BUFFER_FULL; | |
- return(-1); | |
- } | |
- | |
if (xmlBufGrow(in->buffer, len + 1) < 0) { | |
xmlIOErrMemory("growing input buffer"); | |
in->error = XML_ERR_NO_MEMORY; | |
@@ -3560,7 +3559,7 @@ | |
* how many bytes to consume and how many bytes to store. | |
*/ | |
cons = len; | |
- chunk = xmlBufAvail(out->buffer) - 1; | |
+ chunk = xmlBufAvail(out->buffer); | |
/* | |
* make sure we have enough room to save first, if this is | |
diff -ru libxml2/xmlcatalog.c libxml2-apple/libxml2/xmlcatalog.c | |
--- libxml2/xmlcatalog.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xmlcatalog.c 2025-06-26 01:54:56 | |
@@ -76,7 +76,7 @@ | |
#else | |
char line_read[501]; | |
char *ret; | |
- int len; | |
+ size_t len; | |
if (prompt != NULL) | |
fprintf(stdout, "%s", prompt); | |
@@ -409,8 +409,13 @@ | |
break; | |
} | |
- if (convert) | |
+ if (convert) { | |
ret = xmlCatalogConvert(); | |
+ if (ret == -1) { | |
+ fprintf(stderr, "Failed to convert SGML catalog entries into XML\n"); | |
+ exit_value = 1; | |
+ } | |
+ } | |
if ((add) || (del)) { | |
for (i = 1; i < argc ; i++) { | |
diff -ru libxml2/xmllint.c libxml2-apple/libxml2/xmllint.c | |
--- libxml2/xmllint.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xmllint.c 2025-06-26 01:54:56 | |
@@ -52,6 +52,20 @@ | |
#endif | |
#endif | |
+// For use of uint64_t in HAVE_MMAP. | |
+#ifdef HAVE_STDINT_H | |
+#include <stdint.h> | |
+#endif | |
+ | |
+#ifndef MAP_RESILIENT_MEDIA | |
+/* | |
+ * Apple extension to allow reading past the end of an mmap-ped file without crashing. | |
+ * This allows for a NUL terminator on files with a length that is an even multiple of | |
+ * the page size. | |
+ */ | |
+#define MAP_RESILIENT_MEDIA 0 | |
+#endif | |
+ | |
#include <libxml/xmlmemory.h> | |
#include <libxml/parser.h> | |
#include <libxml/parserInternals.h> | |
@@ -153,6 +167,7 @@ | |
#ifdef LIBXML_PUSH_ENABLED | |
static int push = 0; | |
static int pushsize = 4096; | |
+static int push_structured_error_fatal_stop = 0; | |
#endif /* LIBXML_PUSH_ENABLED */ | |
#ifdef HAVE_MMAP | |
static int memory = 0; | |
@@ -197,6 +212,7 @@ | |
#endif | |
static int options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES; | |
static int sax = 0; | |
+static int sax_fatal_stop = 0; | |
static int oldxml10 = 0; | |
/************************************************************************ | |
@@ -358,17 +374,14 @@ | |
static void * | |
myReallocFunc(void *mem, size_t size) | |
{ | |
- void *ret; | |
+ size_t oldsize = xmlMemSize(mem); | |
- ret = xmlMemRealloc(mem, size); | |
- if (ret != NULL) { | |
- if (xmlMemUsed() > maxmem) { | |
- OOM(); | |
- xmlMemFree(ret); | |
- return (NULL); | |
- } | |
+ if (xmlMemUsed() + size - oldsize > (size_t) maxmem) { | |
+ OOM(); | |
+ return (NULL); | |
} | |
- return (ret); | |
+ | |
+ return (xmlMemRealloc(mem, size)); | |
} | |
static char * | |
myStrdupFunc(const char *str) | |
@@ -602,7 +615,7 @@ | |
len = strlen(buffer); | |
snprintf(&buffer[len], sizeof(buffer) - len, "\n"); | |
cur = input->cur; | |
- while ((*cur == '\n') || (*cur == '\r')) | |
+ while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) | |
cur--; | |
n = 0; | |
while ((cur != base) && (n++ < 80)) { | |
@@ -1427,7 +1440,7 @@ | |
* extra parameters. | |
*/ | |
static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) | |
-errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) | |
+errorDebug(void *ctx, const char *msg, ...) | |
{ | |
va_list args; | |
@@ -1438,6 +1451,13 @@ | |
fprintf(stdout, "SAX.error: "); | |
vfprintf(stdout, msg, args); | |
va_end(args); | |
+ | |
+ if (sax_fatal_stop) { | |
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; | |
+ xmlErrorPtr error = xmlCtxtGetLastError(ctxt); | |
+ if (error != NULL && error->level == XML_ERR_FATAL) | |
+ xmlStopParser(ctxt); | |
+ } | |
} | |
/** | |
@@ -1463,6 +1483,25 @@ | |
va_end(args); | |
} | |
+/** | |
+ * pushStructuredErrorFunc: | |
+ * @ctx: An XML parser context | |
+ * @error: Error data | |
+ * | |
+ * Call xmlStopParser() on fatal structured errors. | |
+ */ | |
+#ifdef LIBXML_PUSH_ENABLED | |
+static void pushStructuredErrorFunc(void *ctx, xmlErrorPtr error) | |
+{ | |
+ if (push_structured_error_fatal_stop) { | |
+ if (error != NULL && error->level == XML_ERR_FATAL) { | |
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr)ctx; | |
+ xmlStopParser(ctxt); | |
+ } | |
+ } | |
+} | |
+#endif /* LIBXML_PUSH_ENABLED */ | |
+ | |
static xmlSAXHandler debugSAXHandlerStruct = { | |
internalSubsetDebug, | |
isStandaloneDebug, | |
@@ -1627,7 +1666,6 @@ | |
static void | |
testSAX(const char *filename) { | |
xmlSAXHandlerPtr handler; | |
- const char *user_data = "user_data"; /* mostly for debugging */ | |
xmlParserInputBufferPtr buf = NULL; | |
xmlParserInputPtr inputStream; | |
xmlParserCtxtPtr ctxt = NULL; | |
@@ -1656,6 +1694,7 @@ | |
#ifdef LIBXML_SCHEMAS_ENABLED | |
if (wxschemas != NULL) { | |
int ret; | |
+ const char *user_data = "user_data"; /* mostly for debugging */ | |
xmlSchemaValidCtxtPtr vctxt; | |
vctxt = xmlSchemaNewValidCtxt(wxschemas); | |
@@ -1696,9 +1735,10 @@ | |
xmlFreeParserInputBuffer(buf); | |
goto error; | |
} | |
+ xmlCtxtUseOptions(ctxt, options); | |
old_sax = ctxt->sax; | |
ctxt->sax = handler; | |
- ctxt->userData = (void *) user_data; | |
+ ctxt->userData = (void *)ctxt; | |
inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE); | |
if (inputStream == NULL) { | |
xmlFreeParserInputBuffer(buf); | |
@@ -1834,7 +1874,14 @@ | |
return; | |
if ((fd = open(filename, O_RDONLY)) < 0) | |
return; | |
- base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ; | |
+ size_t max_size_t = (size_t)-1; | |
+ if ((uint64_t)info.st_size >= max_size_t) { | |
+ close(fd); | |
+ fprintf(stderr, "file too large to mmap %s\n", filename); | |
+ progresult = XMLLINT_ERR_RDFILE; | |
+ return; | |
+ } | |
+ base = mmap(NULL, info.st_size + 1, PROT_READ, MAP_SHARED | MAP_RESILIENT_MEDIA, fd, 0); /* +1 for NUL terminator. */ | |
if (base == (void *) MAP_FAILED) { | |
close(fd); | |
fprintf(stderr, "mmap failure for file %s\n", filename); | |
@@ -2226,10 +2273,14 @@ | |
return; | |
} | |
htmlCtxtUseOptions(ctxt, options); | |
+ if (push_structured_error_fatal_stop) | |
+ xmlSetStructuredErrorFunc(ctxt, pushStructuredErrorFunc); | |
while ((res = fread(chars, 1, pushsize, f)) > 0) { | |
htmlParseChunk(ctxt, chars, res, 0); | |
} | |
htmlParseChunk(ctxt, chars, 0, 1); | |
+ if (push_structured_error_fatal_stop) | |
+ xmlSetStructuredErrorFunc(NULL, NULL); | |
doc = ctxt->myDoc; | |
htmlFreeParserCtxt(ctxt); | |
} | |
@@ -2247,7 +2298,14 @@ | |
return; | |
if ((fd = open(filename, O_RDONLY)) < 0) | |
return; | |
- base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ; | |
+ size_t max_size_t = (size_t)-1; | |
+ if ((uint64_t)info.st_size >= max_size_t) { | |
+ close(fd); | |
+ fprintf(stderr, "file too large to mmap %s\n", filename); | |
+ progresult = XMLLINT_ERR_RDFILE; | |
+ return; | |
+ } | |
+ base = mmap(NULL, info.st_size + 1, PROT_READ, MAP_SHARED | MAP_RESILIENT_MEDIA, fd, 0); /* +1 for NUL terminator. */ | |
if (base == (void *) MAP_FAILED) { | |
close(fd); | |
fprintf(stderr, "mmap failure for file %s\n", filename); | |
@@ -2288,8 +2346,8 @@ | |
} | |
if (f != NULL) { | |
int ret; | |
- int res, size = 1024; | |
- char chars[1024]; | |
+ int res; | |
+ char chars[4096]; | |
xmlParserCtxtPtr ctxt; | |
/* if (repeat) size = 1024; */ | |
@@ -2304,10 +2362,14 @@ | |
return; | |
} | |
xmlCtxtUseOptions(ctxt, options); | |
- while ((res = fread(chars, 1, size, f)) > 0) { | |
+ if (push_structured_error_fatal_stop) | |
+ xmlSetStructuredErrorFunc(ctxt, pushStructuredErrorFunc); | |
+ while ((res = fread(chars, 1, pushsize, f)) > 0) { | |
xmlParseChunk(ctxt, chars, res, 0); | |
} | |
xmlParseChunk(ctxt, chars, 0, 1); | |
+ if (push_structured_error_fatal_stop) | |
+ xmlSetStructuredErrorFunc(NULL, NULL); | |
doc = ctxt->myDoc; | |
ret = ctxt->wellFormed; | |
xmlFreeParserCtxt(ctxt); | |
@@ -2375,7 +2437,14 @@ | |
return; | |
if ((fd = open(filename, O_RDONLY)) < 0) | |
return; | |
- base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ; | |
+ size_t max_size_t = (size_t)-1; | |
+ if ((uint64_t)info.st_size >= max_size_t) { | |
+ close(fd); | |
+ fprintf(stderr, "file too large to mmap %s\n", filename); | |
+ progresult = XMLLINT_ERR_RDFILE; | |
+ return; | |
+ } | |
+ base = mmap(NULL, info.st_size + 1, PROT_READ, MAP_SHARED | MAP_RESILIENT_MEDIA, fd, 0); /* +1 for NUL terminator. */ | |
if (base == (void *) MAP_FAILED) { | |
close(fd); | |
fprintf(stderr, "mmap failure for file %s\n", filename); | |
@@ -2798,7 +2867,6 @@ | |
xmlFreeDtd(dtd); | |
return; | |
} | |
- cvp->userData = NULL; | |
cvp->error = xmlGenericError; | |
cvp->warning = xmlGenericError; | |
@@ -2836,7 +2904,6 @@ | |
if ((timing) && (!repeat)) { | |
startTimer(); | |
} | |
- cvp->userData = NULL; | |
cvp->error = xmlGenericError; | |
cvp->warning = xmlGenericError; | |
if (!xmlValidateDocument(cvp, doc)) { | |
@@ -3082,6 +3149,7 @@ | |
#ifdef LIBXML_PUSH_ENABLED | |
fprintf(f, "\t--push : use the push mode of the parser\n"); | |
fprintf(f, "\t--pushsmall : use the push mode of the parser using tiny increments\n"); | |
+ fprintf(f, "\t--push-structured-error-fatal-stop : call xmlStopParser() on fatal structured errors\n"); | |
#endif /* LIBXML_PUSH_ENABLED */ | |
#ifdef HAVE_MMAP | |
fprintf(f, "\t--memory : parse from memory\n"); | |
@@ -3139,6 +3207,7 @@ | |
fprintf(f, "\t--sax1: use the old SAX1 interfaces for processing\n"); | |
#endif | |
fprintf(f, "\t--sax: do not build a tree but work just at the SAX level\n"); | |
+ fprintf(f, "\t--sax-fatal-stop: call xmlStopParser() on fatal errors during SAX parsing\n"); | |
fprintf(f, "\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n"); | |
#ifdef LIBXML_XPATH_ENABLED | |
fprintf(f, "\t--xpath expr: evaluate the XPath expression, imply --noout\n"); | |
@@ -3339,6 +3408,9 @@ | |
push++; | |
pushsize = 10; | |
} | |
+ else if ((!strcmp(argv[i], "-push-structured-error-fatal-stop")) || | |
+ (!strcmp(argv[i], "--push-structured-error-fatal-stop"))) | |
+ push_structured_error_fatal_stop++; | |
#endif /* LIBXML_PUSH_ENABLED */ | |
#ifdef HAVE_MMAP | |
else if ((!strcmp(argv[i], "-memory")) || | |
@@ -3485,6 +3557,10 @@ | |
options |= XML_PARSE_SAX1; | |
} | |
#endif /* LIBXML_SAX1_ENABLED */ | |
+ else if ((!strcmp(argv[i], "-sax-fatal-stop")) || | |
+ (!strcmp(argv[i], "--sax-fatal-stop"))) { | |
+ sax_fatal_stop++; | |
+ } | |
else if ((!strcmp(argv[i], "-sax")) || | |
(!strcmp(argv[i], "--sax"))) { | |
sax++; | |
diff -ru libxml2/xmlmemory.c libxml2-apple/libxml2/xmlmemory.c | |
--- libxml2/xmlmemory.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xmlmemory.c 2025-06-26 01:54:56 | |
@@ -543,7 +543,8 @@ | |
if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint(); | |
- strcpy(s,str); | |
+ strncpy(s, str, size); | |
+ s[size - 1] = '\0'; | |
TEST_POINT | |
@@ -574,6 +575,27 @@ | |
} | |
/** | |
+ * xmlMemSize: | |
+ * @ptr: pointer to the memory allocation | |
+ * | |
+ * Returns the size of a memory allocation. | |
+ */ | |
+ | |
+size_t | |
+xmlMemSize(void *ptr) { | |
+ MEMHDR *p; | |
+ | |
+ if (ptr == NULL) | |
+ return(0); | |
+ | |
+ p = CLIENT_2_HDR(ptr); | |
+ if (p->mh_tag != MEMTAG) | |
+ return(0); | |
+ | |
+ return(p->mh_size); | |
+} | |
+ | |
+/** | |
* xmlMemUsed: | |
* | |
* Provides the amount of memory currently allocated | |
@@ -609,69 +631,7 @@ | |
return(res); | |
} | |
-#ifdef MEM_LIST | |
/** | |
- * xmlMemContentShow: | |
- * @fp: a FILE descriptor used as the output file | |
- * @p: a memory block header | |
- * | |
- * tries to show some content from the memory block | |
- */ | |
- | |
-static void | |
-xmlMemContentShow(FILE *fp, MEMHDR *p) | |
-{ | |
- int i,j,k,len; | |
- const char *buf; | |
- | |
- if (p == NULL) { | |
- fprintf(fp, " NULL"); | |
- return; | |
- } | |
- len = p->mh_size; | |
- buf = (const char *) HDR_2_CLIENT(p); | |
- | |
- for (i = 0;i < len;i++) { | |
- if (buf[i] == 0) break; | |
- if (!isprint((unsigned char) buf[i])) break; | |
- } | |
- if ((i < 4) && ((buf[i] != 0) || (i == 0))) { | |
- if (len >= 4) { | |
- MEMHDR *q; | |
- void *cur; | |
- | |
- for (j = 0;(j < len -3) && (j < 40);j += 4) { | |
- cur = *((void **) &buf[j]); | |
- q = CLIENT_2_HDR(cur); | |
- p = memlist; | |
- k = 0; | |
- while (p != NULL) { | |
- if (p == q) break; | |
- p = p->mh_next; | |
- if (k++ > 100) break; | |
- } | |
- if ((p != NULL) && (p == q)) { | |
- fprintf(fp, " pointer to #%lu at index %d", | |
- p->mh_number, j); | |
- return; | |
- } | |
- } | |
- } | |
- } else if ((i == 0) && (buf[i] == 0)) { | |
- fprintf(fp," null"); | |
- } else { | |
- if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf); | |
- else { | |
- fprintf(fp," ["); | |
- for (j = 0;j < i;j++) | |
- fprintf(fp,"%c", buf[j]); | |
- fprintf(fp,"]"); | |
- } | |
- } | |
-} | |
-#endif | |
- | |
-/** | |
* xmlMemDisplayLast: | |
* @fp: a FILE descriptor used as the output file, if NULL, the result is | |
* written to the file .memorylist | |
@@ -727,10 +687,6 @@ | |
if (p->mh_tag != MEMTAG) | |
fprintf(fp," INVALID"); | |
nb++; | |
- if (nb < 100) | |
- xmlMemContentShow(fp, p); | |
- else | |
- fprintf(fp," skip"); | |
fprintf(fp,"\n"); | |
nbBytes -= (unsigned long)p->mh_size; | |
@@ -808,10 +764,6 @@ | |
if (p->mh_tag != MEMTAG) | |
fprintf(fp," INVALID"); | |
nb++; | |
- if (nb < 100) | |
- xmlMemContentShow(fp, p); | |
- else | |
- fprintf(fp," skip"); | |
fprintf(fp,"\n"); | |
p = p->mh_next; | |
@@ -911,7 +863,6 @@ | |
fprintf(fp,"%s(%u)", p->mh_file, p->mh_line); | |
if (p->mh_tag != MEMTAG) | |
fprintf(fp," INVALID"); | |
- xmlMemContentShow(fp, p); | |
fprintf(fp,"\n"); | |
nr--; | |
p = p->mh_next; | |
diff -ru libxml2/xmlreader.c libxml2-apple/libxml2/xmlreader.c | |
--- libxml2/xmlreader.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xmlreader.c 2025-06-26 01:54:56 | |
@@ -935,9 +935,7 @@ | |
} else if (val < 0) { | |
reader->mode = XML_TEXTREADER_MODE_EOF; | |
reader->state = oldstate; | |
- if ((oldstate != XML_TEXTREADER_START) || | |
- (reader->ctxt->myDoc != NULL)) | |
- return(val); | |
+ return(val); | |
} else if (val == 0) { | |
/* mark the end of the stream and process the remains */ | |
reader->mode = XML_TEXTREADER_MODE_EOF; | |
@@ -1586,6 +1584,7 @@ | |
* Handle XInclude if asked for | |
*/ | |
if ((reader->xinclude) && (reader->in_xinclude == 0) && | |
+ (reader->state != XML_TEXTREADER_BACKTRACK) && | |
(reader->node != NULL) && | |
(reader->node->type == XML_ELEMENT_NODE) && | |
(reader->node->ns != NULL) && | |
@@ -2319,36 +2318,16 @@ | |
xmlFree(reader->patternTab); | |
} | |
#endif | |
- if (reader->faketext != NULL) { | |
- xmlFreeNode(reader->faketext); | |
- } | |
+ if (reader->mode != XML_TEXTREADER_MODE_CLOSED) | |
+ xmlTextReaderClose(reader); | |
if (reader->ctxt != NULL) { | |
if (reader->dict == reader->ctxt->dict) | |
reader->dict = NULL; | |
-#ifdef LIBXML_VALID_ENABLED | |
- if ((reader->ctxt->vctxt.vstateTab != NULL) && | |
- (reader->ctxt->vctxt.vstateMax > 0)){ | |
-#ifdef LIBXML_REGEXP_ENABLED | |
- while (reader->ctxt->vctxt.vstateNr > 0) | |
- xmlValidatePopElement(&reader->ctxt->vctxt, NULL, NULL, NULL); | |
-#endif /* LIBXML_REGEXP_ENABLED */ | |
- xmlFree(reader->ctxt->vctxt.vstateTab); | |
- reader->ctxt->vctxt.vstateTab = NULL; | |
- reader->ctxt->vctxt.vstateMax = 0; | |
- } | |
-#endif /* LIBXML_VALID_ENABLED */ | |
- if (reader->ctxt->myDoc != NULL) { | |
- if (reader->preserve == 0) | |
- xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc); | |
- reader->ctxt->myDoc = NULL; | |
- } | |
if (reader->allocs & XML_TEXTREADER_CTXT) | |
xmlFreeParserCtxt(reader->ctxt); | |
} | |
if (reader->sax != NULL) | |
xmlFree(reader->sax); | |
- if ((reader->input != NULL) && (reader->allocs & XML_TEXTREADER_INPUT)) | |
- xmlFreeParserInputBuffer(reader->input); | |
if (reader->buffer != NULL) | |
xmlBufFree(reader->buffer); | |
if (reader->entTab != NULL) | |
@@ -2379,7 +2358,23 @@ | |
reader->node = NULL; | |
reader->curnode = NULL; | |
reader->mode = XML_TEXTREADER_MODE_CLOSED; | |
+ if (reader->faketext != NULL) { | |
+ xmlFreeNode(reader->faketext); | |
+ reader->faketext = NULL; | |
+ } | |
if (reader->ctxt != NULL) { | |
+#ifdef LIBXML_VALID_ENABLED | |
+ if ((reader->ctxt->vctxt.vstateTab != NULL) && | |
+ (reader->ctxt->vctxt.vstateMax > 0)){ | |
+#ifdef LIBXML_REGEXP_ENABLED | |
+ while (reader->ctxt->vctxt.vstateNr > 0) | |
+ xmlValidatePopElement(&reader->ctxt->vctxt, NULL, NULL, NULL); | |
+#endif /* LIBXML_REGEXP_ENABLED */ | |
+ xmlFree(reader->ctxt->vctxt.vstateTab); | |
+ reader->ctxt->vctxt.vstateTab = NULL; | |
+ reader->ctxt->vctxt.vstateMax = 0; | |
+ } | |
+#endif /* LIBXML_VALID_ENABLED */ | |
xmlStopParser(reader->ctxt); | |
if (reader->ctxt->myDoc != NULL) { | |
if (reader->preserve == 0) | |
diff -ru libxml2/xmlregexp.c libxml2-apple/libxml2/xmlregexp.c | |
--- libxml2/xmlregexp.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xmlregexp.c 2025-06-26 01:54:56 | |
@@ -1673,6 +1673,8 @@ | |
return(-1); | |
inter = ctxt->state; | |
counter = xmlRegGetCounter(ctxt); | |
+ if (counter < 0) | |
+ return(-1); | |
ctxt->counters[counter].min = atom->min - 1; | |
ctxt->counters[counter].max = atom->max - 1; | |
/* count the number of times we see it again */ | |
@@ -1691,6 +1693,8 @@ | |
* epsilon transition. | |
*/ | |
counter = xmlRegGetCounter(ctxt); | |
+ if (counter < 0) | |
+ return(-1); | |
ctxt->counters[counter].min = atom->min - 1; | |
ctxt->counters[counter].max = atom->max - 1; | |
/* count the number of times we see it again */ | |
@@ -6015,6 +6019,10 @@ | |
* associate a counter to the transition. | |
*/ | |
counter = xmlRegGetCounter(am); | |
+ if (counter < 0) { | |
+ xmlRegFreeAtom(atom); | |
+ return(NULL); | |
+ } | |
am->counters[counter].min = min; | |
am->counters[counter].max = max; | |
@@ -6081,6 +6089,10 @@ | |
* associate a counter to the transition. | |
*/ | |
counter = xmlRegGetCounter(am); | |
+ if (counter < 0) { | |
+ xmlRegFreeAtom(atom); | |
+ return(NULL); | |
+ } | |
am->counters[counter].min = min; | |
am->counters[counter].max = max; | |
@@ -6167,6 +6179,10 @@ | |
* associate a counter to the transition. | |
*/ | |
counter = xmlRegGetCounter(am); | |
+ if (counter < 0) { | |
+ xmlRegFreeAtom(atom); | |
+ return(NULL); | |
+ } | |
am->counters[counter].min = 1; | |
am->counters[counter].max = 1; | |
@@ -6226,6 +6242,10 @@ | |
* associate a counter to the transition. | |
*/ | |
counter = xmlRegGetCounter(am); | |
+ if (counter < 0) { | |
+ xmlRegFreeAtom(atom); | |
+ return(NULL); | |
+ } | |
am->counters[counter].min = 1; | |
am->counters[counter].max = 1; | |
diff -ru libxml2/xmlsave.c libxml2-apple/libxml2/xmlsave.c | |
--- libxml2/xmlsave.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xmlsave.c 2025-06-26 01:54:56 | |
@@ -139,7 +139,10 @@ | |
default: | |
msg = "unexpected error number\n"; | |
} | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlSimpleError(XML_FROM_OUTPUT, code, node, msg, extra); | |
+#pragma clang diagnostic pop | |
} | |
/************************************************************************ | |
diff -ru libxml2/xmlschemas.c libxml2-apple/libxml2/xmlschemas.c | |
--- libxml2/xmlschemas.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xmlschemas.c 2025-06-26 01:54:56 | |
@@ -1964,10 +1964,13 @@ | |
data = ctxt->errCtxt; | |
schannel = ctxt->serror; | |
} | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, | |
error, XML_ERR_ERROR, NULL, 0, | |
(const char *) str1, (const char *) str2, NULL, 0, 0, | |
msg, str1, str2); | |
+#pragma clang diagnostic pop | |
} | |
/** | |
@@ -2030,11 +2033,14 @@ | |
data = ctxt->errCtxt; | |
schannel = ctxt->serror; | |
} | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP, | |
error, XML_ERR_ERROR, NULL, 0, | |
(const char *) strData1, (const char *) strData2, | |
(const char *) strData3, 0, 0, msg, str1, str2, | |
str3, str4, str5); | |
+#pragma clang diagnostic pop | |
} | |
/************************************************************************ | |
@@ -2162,12 +2168,14 @@ | |
if ((file == NULL) && (vctxt->filename != NULL)) | |
file = vctxt->filename; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, channel, data, ctxt, | |
node, XML_FROM_SCHEMASV, | |
error, errorLevel, file, line, | |
(const char *) str1, (const char *) str2, | |
(const char *) str3, 0, col, msg, str1, str2, str3, str4); | |
- | |
+#pragma clang diagnostic pop | |
} else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) { | |
xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt; | |
if (errorLevel != XML_ERR_WARNING) { | |
@@ -2179,11 +2187,14 @@ | |
} | |
schannel = pctxt->serror; | |
data = pctxt->errCtxt; | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(schannel, channel, data, ctxt, | |
node, XML_FROM_SCHEMASP, error, | |
errorLevel, NULL, 0, | |
(const char *) str1, (const char *) str2, | |
(const char *) str3, 0, 0, msg, str1, str2, str3, str4); | |
+#pragma clang diagnostic pop | |
} else { | |
TODO | |
} | |
@@ -2348,11 +2359,17 @@ | |
msg = xmlStrcat(msg, BAD_CAST ".\n"); | |
if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL, | |
(const char *) msg, (const xmlChar *) funcName, str1, str2); | |
+#pragma clang diagnostic pop | |
else if (actxt->type == XML_SCHEMA_CTXT_PARSER) | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL, | |
(const char *) msg, (const xmlChar *) funcName, str1, str2); | |
+#pragma clang diagnostic pop | |
FREE_AND_NULL(msg) | |
} | |
@@ -2398,8 +2415,11 @@ | |
xmlSchemaFormatNodeForError(&msg, actxt, node); | |
msg = xmlStrcat(msg, (const xmlChar *) message); | |
msg = xmlStrcat(msg, BAD_CAST ".\n"); | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
xmlSchemaErr4(actxt, error, node, | |
(const char *) msg, str1, str2, str3, str4); | |
+#pragma clang diagnostic pop | |
FREE_AND_NULL(msg) | |
} | |
@@ -2435,8 +2455,11 @@ | |
msg = xmlStrcat(msg, BAD_CAST ".\n"); | |
/* URGENT TODO: Set the error code to something sane. */ | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0, | |
(const char *) msg, str1, str2, str3, NULL); | |
+#pragma clang diagnostic pop | |
FREE_AND_NULL(msg) | |
} | |
@@ -2457,12 +2480,15 @@ | |
msg = xmlStrdup(BAD_CAST "Element '%s': "); | |
msg = xmlStrcat(msg, (const xmlChar *) message); | |
msg = xmlStrcat(msg, BAD_CAST ".\n"); | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR, | |
error, NULL, idcNode->nodeLine, (const char *) msg, | |
xmlSchemaFormatQName(&qname, | |
vctxt->nodeQNames->items[idcNode->nodeQNameID +1], | |
vctxt->nodeQNames->items[idcNode->nodeQNameID]), | |
str1, str2, NULL); | |
+#pragma clang diagnostic pop | |
FREE_AND_NULL(qname); | |
FREE_AND_NULL(msg); | |
} | |
@@ -2556,9 +2582,12 @@ | |
msg = xmlStrcat(msg, BAD_CAST ".\n"); | |
if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) == | |
XML_ATTRIBUTE_NODE)) | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL); | |
else | |
xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); | |
+#pragma clang diagnostic pop | |
FREE_AND_NULL(msg) | |
} | |
@@ -2587,9 +2616,12 @@ | |
xmlSchemaFormatNodeForError(&msg, actxt, node); | |
msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n"); | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
xmlSchemaErr(actxt, error, node, (const char *) msg, | |
xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node), | |
NULL); | |
+#pragma clang diagnostic pop | |
FREE_AND_NULL(str) | |
FREE_AND_NULL(msg) | |
} | |
@@ -2690,7 +2722,10 @@ | |
FREE_AND_NULL(str) | |
} else | |
msg = xmlStrcat(msg, BAD_CAST "\n"); | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL); | |
+#pragma clang diagnostic pop | |
xmlFree(msg); | |
} | |
@@ -2754,6 +2789,8 @@ | |
msg = xmlStrcat(msg, | |
BAD_CAST "this underruns the allowed minimum length of '%s'.\n"); | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
if (nodeType == XML_ATTRIBUTE_NODE) | |
xmlSchemaErr3(actxt, error, node, (const char *) msg, | |
value, (const xmlChar *) actLen, (const xmlChar *) len); | |
@@ -2813,6 +2850,7 @@ | |
msg = xmlStrcat(msg, BAD_CAST ".\n"); | |
xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2); | |
} | |
+#pragma clang diagnostic pop | |
FREE_AND_NULL(str) | |
xmlFree(msg); | |
} | |
@@ -2999,8 +3037,11 @@ | |
msg = xmlStrcat(msg, BAD_CAST ".\n"); | |
if ((itemElem == NULL) && (item != NULL)) | |
itemElem = WXS_ITEM_NODE(item); | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL, | |
(const char *) msg, BAD_CAST des, str1, str2, str3, NULL); | |
+#pragma clang diagnostic pop | |
FREE_AND_NULL(des); | |
FREE_AND_NULL(msg); | |
} | |
@@ -3063,8 +3104,11 @@ | |
msg = xmlStrcat(msg, BAD_CAST ": "); | |
msg = xmlStrcat(msg, (const xmlChar *) message); | |
msg = xmlStrcat(msg, BAD_CAST ".\n"); | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
xmlSchemaErr4(ACTXT_CAST ctxt, error, node, | |
(const char *) msg, str1, str2, str3, str4); | |
+#pragma clang diagnostic pop | |
xmlFree(msg); | |
} | |
@@ -3231,14 +3275,20 @@ | |
} else | |
msg = xmlStrcat(msg, BAD_CAST "\n"); | |
if (node->type == XML_ATTRIBUTE_NODE) | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL); | |
else | |
xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL); | |
+#pragma clang diagnostic pop | |
} else { | |
msg = xmlStrcat(msg, BAD_CAST message); | |
msg = xmlStrcat(msg, BAD_CAST ".\n"); | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL, | |
(const char*) msg, str1, str2, NULL, NULL, NULL); | |
+#pragma clang diagnostic pop | |
} | |
/* Cleanup. */ | |
FREE_AND_NULL(msg) | |
@@ -13345,8 +13395,19 @@ | |
* declaration `resolved` to by the `actual value` | |
* of the substitutionGroup [attribute], if present" | |
*/ | |
- if (elemDecl->subtypes == NULL) | |
- elemDecl->subtypes = substHead->subtypes; | |
+ if (elemDecl->subtypes == NULL) { | |
+ if (substHead->subtypes == NULL) { | |
+ /* | |
+ * This can happen with self-referencing substitution | |
+ * groups. The cycle will be detected later, but we have | |
+ * to set subtypes to avoid null-pointer dereferences. | |
+ */ | |
+ elemDecl->subtypes = xmlSchemaGetBuiltInType( | |
+ XML_SCHEMAS_ANYTYPE); | |
+ } else { | |
+ elemDecl->subtypes = substHead->subtypes; | |
+ } | |
+ } | |
} | |
} | |
/* | |
@@ -14536,6 +14597,7 @@ | |
{ | |
PERROR_INT("xmlSchemaFixupTypeAttributeUses", | |
"failed to expand attributes"); | |
+ return(-1); | |
} | |
if (pctxt->attrProhibs->nbItems != 0) | |
prohibs = pctxt->attrProhibs; | |
@@ -14546,6 +14608,7 @@ | |
{ | |
PERROR_INT("xmlSchemaFixupTypeAttributeUses", | |
"failed to expand attributes"); | |
+ return(-1); | |
} | |
} | |
} | |
@@ -14762,7 +14825,7 @@ | |
min = cur; | |
part = (xmlSchemaParticlePtr) part->next; | |
} | |
- return (particle->minOccurs * min); | |
+ return (particle->minOccurs != 0 && min > INT_MAX / particle->minOccurs) ? INT_MAX : (particle->minOccurs * min); | |
} else { | |
/* <all> and <sequence> */ | |
int sum = 0; | |
@@ -14772,14 +14835,20 @@ | |
if (part == NULL) | |
return (0); | |
do { | |
+ int minOccurs; | |
if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) || | |
(part->children->type == XML_SCHEMA_TYPE_ANY)) | |
- sum += part->minOccurs; | |
+ minOccurs = part->minOccurs; | |
else | |
- sum += xmlSchemaGetParticleTotalRangeMin(part); | |
+ minOccurs = xmlSchemaGetParticleTotalRangeMin(part); | |
+ if (sum > INT_MAX - minOccurs) { | |
+ sum = INT_MAX; | |
+ } else { | |
+ sum += minOccurs; | |
+ } | |
part = (xmlSchemaParticlePtr) part->next; | |
} while (part != NULL); | |
- return (particle->minOccurs * sum); | |
+ return (particle->minOccurs != 0 && sum > INT_MAX / particle->minOccurs) ? INT_MAX : (particle->minOccurs * sum); | |
} | |
} | |
@@ -17331,10 +17400,13 @@ | |
else | |
msg = xmlStrcat(msg, BAD_CAST "'"); | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
xmlSchemaPCustomErr(pctxt, | |
XML_SCHEMAP_INVALID_FACET_VALUE, | |
WXS_BASIC_CAST facet1, NULL, | |
(const char *) msg, NULL); | |
+#pragma clang diagnostic pop | |
if (msg != NULL) | |
xmlFree(msg); | |
@@ -18608,7 +18680,7 @@ | |
"allowed to appear inside other model groups", | |
NULL, NULL); | |
- } else if (! dummySequence) { | |
+ } else if ((!dummySequence) && (baseType->subtypes != NULL)) { | |
xmlSchemaTreeItemPtr effectiveContent = | |
(xmlSchemaTreeItemPtr) type->subtypes; | |
/* | |
@@ -22986,7 +23058,7 @@ | |
} else if (pos >= matcher->sizeKeySeqs) { | |
int i = matcher->sizeKeySeqs; | |
- matcher->sizeKeySeqs *= 2; | |
+ matcher->sizeKeySeqs = pos * 2; | |
matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **) | |
xmlRealloc(matcher->keySeqs, | |
matcher->sizeKeySeqs * | |
@@ -24393,7 +24465,7 @@ | |
unsigned long length, | |
int fireErrors) | |
{ | |
- int ret, error = 0, found; | |
+ int ret = 0, error = 0, found; | |
xmlSchemaTypePtr tmpType; | |
xmlSchemaFacetLinkPtr facetLink; | |
diff -ru libxml2/xmlstring.c libxml2-apple/libxml2/xmlstring.c | |
--- libxml2/xmlstring.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xmlstring.c 2025-06-26 01:54:56 | |
@@ -45,7 +45,6 @@ | |
if ((cur == NULL) || (len < 0)) return(NULL); | |
ret = (xmlChar *) xmlMallocAtomic(((size_t) len + 1) * sizeof(xmlChar)); | |
if (ret == NULL) { | |
- xmlErrMemory(NULL, NULL); | |
return(NULL); | |
} | |
memcpy(ret, cur, len * sizeof(xmlChar)); | |
@@ -90,7 +89,6 @@ | |
if ((cur == NULL) || (len < 0)) return(NULL); | |
ret = (xmlChar *) xmlMallocAtomic(((size_t) len + 1) * sizeof(xmlChar)); | |
if (ret == NULL) { | |
- xmlErrMemory(NULL, NULL); | |
return(NULL); | |
} | |
for (i = 0;i < len;i++) { | |
@@ -465,7 +463,6 @@ | |
return(NULL); | |
ret = (xmlChar *) xmlRealloc(cur, ((size_t) size + len + 1) * sizeof(xmlChar)); | |
if (ret == NULL) { | |
- xmlErrMemory(NULL, NULL); | |
return(cur); | |
} | |
memcpy(&ret[size], add, len * sizeof(xmlChar)); | |
@@ -505,7 +502,6 @@ | |
return(NULL); | |
ret = (xmlChar *) xmlMalloc(((size_t) size + len + 1) * sizeof(xmlChar)); | |
if (ret == NULL) { | |
- xmlErrMemory(NULL, NULL); | |
return(xmlStrndup(str1, size)); | |
} | |
memcpy(ret, str1, size * sizeof(xmlChar)); | |
@@ -718,47 +714,47 @@ | |
goto error; | |
if (len == NULL) | |
goto error; | |
- if (*len < 1) | |
- goto error; | |
c = utf[0]; | |
- if (c & 0x80) { | |
- if (*len < 2) | |
+ if (c < 0x80) { | |
+ if (*len < 1) | |
goto error; | |
- if ((utf[1] & 0xc0) != 0x80) | |
+ /* 1-byte code */ | |
+ *len = 1; | |
+ } else { | |
+ if ((*len < 2) || ((utf[1] & 0xc0) != 0x80)) | |
goto error; | |
- if ((c & 0xe0) == 0xe0) { | |
- if (*len < 3) | |
+ if (c < 0xe0) { | |
+ if (c < 0xc2) | |
goto error; | |
- if ((utf[2] & 0xc0) != 0x80) | |
+ /* 2-byte code */ | |
+ *len = 2; | |
+ c = (c & 0x1f) << 6; | |
+ c |= utf[1] & 0x3f; | |
+ } else { | |
+ if ((*len < 3) || ((utf[2] & 0xc0) != 0x80)) | |
goto error; | |
- if ((c & 0xf0) == 0xf0) { | |
- if (*len < 4) | |
+ if (c < 0xf0) { | |
+ /* 3-byte code */ | |
+ *len = 3; | |
+ c = (c & 0xf) << 12; | |
+ c |= (utf[1] & 0x3f) << 6; | |
+ c |= utf[2] & 0x3f; | |
+ if ((c < 0x800) || ((c >= 0xd800) && (c < 0xe000))) | |
goto error; | |
- if ((c & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80) | |
+ } else { | |
+ if ((*len < 4) || ((utf[3] & 0xc0) != 0x80)) | |
goto error; | |
*len = 4; | |
/* 4-byte code */ | |
- c = (utf[0] & 0x7) << 18; | |
+ c = (c & 0x7) << 18; | |
c |= (utf[1] & 0x3f) << 12; | |
c |= (utf[2] & 0x3f) << 6; | |
c |= utf[3] & 0x3f; | |
- } else { | |
- /* 3-byte code */ | |
- *len = 3; | |
- c = (utf[0] & 0xf) << 12; | |
- c |= (utf[1] & 0x3f) << 6; | |
- c |= utf[2] & 0x3f; | |
+ if ((c < 0x10000) || (c >= 0x110000)) | |
+ goto error; | |
} | |
- } else { | |
- /* 2-byte code */ | |
- *len = 2; | |
- c = (utf[0] & 0x1f) << 6; | |
- c |= utf[1] & 0x3f; | |
} | |
- } else { | |
- /* 1-byte code */ | |
- *len = 1; | |
} | |
return(c); | |
@@ -1034,7 +1030,6 @@ | |
out-of-memory situations. */ | |
xmlFree(*msg); | |
*msg = NULL; | |
- xmlErrMemory(NULL, NULL); | |
return(NULL); | |
} | |
diff -ru libxml2/xmlunicode.c libxml2-apple/libxml2/xmlunicode.c | |
--- libxml2/xmlunicode.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xmlunicode.c 2025-06-26 01:54:56 | |
@@ -34,7 +34,7 @@ | |
} xmlUnicodeNameTable; | |
-static xmlIntFunc *xmlUnicodeLookup(xmlUnicodeNameTable *tptr, const char *tname); | |
+static xmlIntFunc *xmlUnicodeLookup(const xmlUnicodeNameTable *tptr, const char *tname); | |
static const xmlUnicodeRange xmlUnicodeBlocks[] = { | |
{"AegeanNumbers", xmlUCSIsAegeanNumbers}, | |
@@ -166,7 +166,7 @@ | |
{"YiSyllables", xmlUCSIsYiSyllables}, | |
{"YijingHexagramSymbols", xmlUCSIsYijingHexagramSymbols}}; | |
-static xmlUnicodeRange xmlUnicodeCats[] = { | |
+static const xmlUnicodeRange xmlUnicodeCats[] = { | |
{"C", xmlUCSIsCatC}, | |
{"Cc", xmlUCSIsCatCc}, | |
{"Cf", xmlUCSIsCatCf}, | |
@@ -212,7 +212,7 @@ | |
static const xmlChLRange xmlCL[] = {{0x1d173, 0x1d17a}, {0xe0001, 0xe0001}, | |
{0xe0020, 0xe007f}, {0xf0000, 0xf0000}, {0xffffd, 0xffffd}, | |
{0x100000, 0x100000}, {0x10fffd, 0x10fffd} }; | |
-static xmlChRangeGroup xmlCG = {18,7,xmlCS,xmlCL}; | |
+static const xmlChRangeGroup xmlCG = {18,7,xmlCS,xmlCL}; | |
static const xmlChSRange xmlCfS[] = {{0xad, 0xad}, {0x600, 0x603}, | |
{0x6dd, 0x6dd}, {0x70f, 0x70f}, {0x17b4, 0x17b5}, {0x200b, 0x200f}, | |
@@ -220,7 +220,7 @@ | |
{0xfff9, 0xfffb} }; | |
static const xmlChLRange xmlCfL[] = {{0x1d173, 0x1d17a}, {0xe0001, 0xe0001}, | |
{0xe0020, 0xe007f} }; | |
-static xmlChRangeGroup xmlCfG = {11,3,xmlCfS,xmlCfL}; | |
+static const xmlChRangeGroup xmlCfG = {11,3,xmlCfS,xmlCfL}; | |
static const xmlChSRange xmlLS[] = {{0x41, 0x5a}, {0x61, 0x7a}, | |
{0xaa, 0xaa}, {0xb5, 0xb5}, {0xba, 0xba}, {0xc0, 0xd6}, {0xd8, 0xf6}, | |
@@ -309,7 +309,7 @@ | |
{0x1d736, 0x1d74e}, {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, | |
{0x1d78a, 0x1d7a8}, {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9}, | |
{0x20000, 0x20000}, {0x2a6d6, 0x2a6d6}, {0x2f800, 0x2fa1d} }; | |
-static xmlChRangeGroup xmlLG = {279,50,xmlLS,xmlLL}; | |
+static const xmlChRangeGroup xmlLG = {279,50,xmlLS,xmlLL}; | |
static const xmlChSRange xmlLlS[] = {{0x61, 0x7a}, {0xaa, 0xaa}, | |
{0xb5, 0xb5}, {0xba, 0xba}, {0xdf, 0xf6}, {0xf8, 0xff}, {0x101, 0x101}, | |
@@ -421,7 +421,7 @@ | |
{0x1d6fc, 0x1d714}, {0x1d716, 0x1d71b}, {0x1d736, 0x1d74e}, | |
{0x1d750, 0x1d755}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d78f}, | |
{0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9} }; | |
-static xmlChRangeGroup xmlLlG = {396,28,xmlLlS,xmlLlL}; | |
+static const xmlChRangeGroup xmlLlG = {396,28,xmlLlS,xmlLlL}; | |
static const xmlChSRange xmlLmS[] = {{0x2b0, 0x2c1}, {0x2c6, 0x2d1}, | |
{0x2e0, 0x2e4}, {0x2ee, 0x2ee}, {0x37a, 0x37a}, {0x559, 0x559}, | |
@@ -429,7 +429,7 @@ | |
{0x17d7, 0x17d7}, {0x1843, 0x1843}, {0x1d2c, 0x1d61}, {0x3005, 0x3005}, | |
{0x3031, 0x3035}, {0x303b, 0x303b}, {0x309d, 0x309e}, {0x30fc, 0x30fe}, | |
{0xff70, 0xff70}, {0xff9e, 0xff9f} }; | |
-static xmlChRangeGroup xmlLmG = {20,0,xmlLmS,NULL}; | |
+static const xmlChRangeGroup xmlLmG = {20,0,xmlLmS,NULL}; | |
static const xmlChSRange xmlLoS[] = {{0x1bb, 0x1bb}, {0x1c0, 0x1c3}, | |
{0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x621, 0x63a}, {0x641, 0x64a}, | |
@@ -492,12 +492,12 @@ | |
{0x10800, 0x10805}, {0x10808, 0x10808}, {0x1080a, 0x10835}, | |
{0x10837, 0x10838}, {0x1083c, 0x1083c}, {0x1083f, 0x1083f}, | |
{0x20000, 0x20000}, {0x2a6d6, 0x2a6d6}, {0x2f800, 0x2fa1d} }; | |
-static xmlChRangeGroup xmlLoG = {211,20,xmlLoS,xmlLoL}; | |
+static const xmlChRangeGroup xmlLoG = {211,20,xmlLoS,xmlLoL}; | |
static const xmlChSRange xmlLtS[] = {{0x1c5, 0x1c5}, {0x1c8, 0x1c8}, | |
{0x1cb, 0x1cb}, {0x1f2, 0x1f2}, {0x1f88, 0x1f8f}, {0x1f98, 0x1f9f}, | |
{0x1fa8, 0x1faf}, {0x1fbc, 0x1fbc}, {0x1fcc, 0x1fcc}, {0x1ffc, 0x1ffc} }; | |
-static xmlChRangeGroup xmlLtG = {10,0,xmlLtS,NULL}; | |
+static const xmlChRangeGroup xmlLtG = {10,0,xmlLtS,NULL}; | |
static const xmlChSRange xmlLuS[] = {{0x41, 0x5a}, {0xc0, 0xd6}, | |
{0xd8, 0xde}, {0x100, 0x100}, {0x102, 0x102}, {0x104, 0x104}, | |
@@ -608,7 +608,7 @@ | |
{0x1d608, 0x1d621}, {0x1d63c, 0x1d655}, {0x1d670, 0x1d689}, | |
{0x1d6a8, 0x1d6c0}, {0x1d6e2, 0x1d6fa}, {0x1d71c, 0x1d734}, | |
{0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8} }; | |
-static xmlChRangeGroup xmlLuG = {390,31,xmlLuS,xmlLuL}; | |
+static const xmlChRangeGroup xmlLuG = {390,31,xmlLuS,xmlLuL}; | |
static const xmlChSRange xmlMS[] = {{0x300, 0x357}, {0x35d, 0x36f}, | |
{0x483, 0x486}, {0x488, 0x489}, {0x591, 0x5a1}, {0x5a3, 0x5b9}, | |
@@ -642,7 +642,7 @@ | |
static const xmlChLRange xmlML[] = {{0x1d165, 0x1d169}, {0x1d16d, 0x1d172}, | |
{0x1d17b, 0x1d182}, {0x1d185, 0x1d18b}, {0x1d1aa, 0x1d1ad}, | |
{0xe0100, 0xe01ef} }; | |
-static xmlChRangeGroup xmlMG = {113,6,xmlMS,xmlML}; | |
+static const xmlChRangeGroup xmlMG = {113,6,xmlMS,xmlML}; | |
static const xmlChSRange xmlMcS[] = {{0x903, 0x903}, {0x93e, 0x940}, | |
{0x949, 0x94c}, {0x982, 0x983}, {0x9be, 0x9c0}, {0x9c7, 0x9c8}, | |
@@ -660,7 +660,7 @@ | |
{0x17c7, 0x17c8}, {0x1923, 0x1926}, {0x1929, 0x192b}, {0x1930, 0x1931}, | |
{0x1933, 0x1938} }; | |
static const xmlChLRange xmlMcL[] = {{0x1d165, 0x1d166}, {0x1d16d, 0x1d172} }; | |
-static xmlChRangeGroup xmlMcG = {55,2,xmlMcS,xmlMcL}; | |
+static const xmlChRangeGroup xmlMcG = {55,2,xmlMcS,xmlMcL}; | |
static const xmlChSRange xmlMnS[] = {{0x300, 0x357}, {0x35d, 0x36f}, | |
{0x483, 0x486}, {0x591, 0x5a1}, {0x5a3, 0x5b9}, {0x5bb, 0x5bd}, | |
@@ -692,7 +692,7 @@ | |
{0xfe00, 0xfe0f}, {0xfe20, 0xfe23} }; | |
static const xmlChLRange xmlMnL[] = {{0x1d167, 0x1d169}, {0x1d17b, 0x1d182}, | |
{0x1d185, 0x1d18b}, {0x1d1aa, 0x1d1ad}, {0xe0100, 0xe01ef} }; | |
-static xmlChRangeGroup xmlMnG = {108,5,xmlMnS,xmlMnL}; | |
+static const xmlChRangeGroup xmlMnG = {108,5,xmlMnS,xmlMnL}; | |
static const xmlChSRange xmlNS[] = {{0x30, 0x39}, {0xb2, 0xb3}, | |
{0xb9, 0xb9}, {0xbc, 0xbe}, {0x660, 0x669}, {0x6f0, 0x6f9}, | |
@@ -707,7 +707,7 @@ | |
{0x3251, 0x325f}, {0x3280, 0x3289}, {0x32b1, 0x32bf}, {0xff10, 0xff19} }; | |
static const xmlChLRange xmlNL[] = {{0x10107, 0x10133}, {0x10320, 0x10323}, | |
{0x1034a, 0x1034a}, {0x104a0, 0x104a9}, {0x1d7ce, 0x1d7ff} }; | |
-static xmlChRangeGroup xmlNG = {42,5,xmlNS,xmlNL}; | |
+static const xmlChRangeGroup xmlNG = {42,5,xmlNS,xmlNL}; | |
static const xmlChSRange xmlNdS[] = {{0x30, 0x39}, {0x660, 0x669}, | |
{0x6f0, 0x6f9}, {0x966, 0x96f}, {0x9e6, 0x9ef}, {0xa66, 0xa6f}, | |
@@ -716,7 +716,7 @@ | |
{0xf20, 0xf29}, {0x1040, 0x1049}, {0x1369, 0x1371}, {0x17e0, 0x17e9}, | |
{0x1810, 0x1819}, {0x1946, 0x194f}, {0xff10, 0xff19} }; | |
static const xmlChLRange xmlNdL[] = {{0x104a0, 0x104a9}, {0x1d7ce, 0x1d7ff} }; | |
-static xmlChRangeGroup xmlNdG = {21,2,xmlNdS,xmlNdL}; | |
+static const xmlChRangeGroup xmlNdG = {21,2,xmlNdS,xmlNdL}; | |
static const xmlChSRange xmlNoS[] = {{0xb2, 0xb3}, {0xb9, 0xb9}, | |
{0xbc, 0xbe}, {0x9f4, 0x9f9}, {0xbf0, 0xbf2}, {0xf2a, 0xf33}, | |
@@ -725,7 +725,7 @@ | |
{0x2776, 0x2793}, {0x3192, 0x3195}, {0x3220, 0x3229}, {0x3251, 0x325f}, | |
{0x3280, 0x3289}, {0x32b1, 0x32bf} }; | |
static const xmlChLRange xmlNoL[] = {{0x10107, 0x10133}, {0x10320, 0x10323} }; | |
-static xmlChRangeGroup xmlNoG = {20,2,xmlNoS,xmlNoL}; | |
+static const xmlChRangeGroup xmlNoG = {20,2,xmlNoS,xmlNoL}; | |
static const xmlChSRange xmlPS[] = {{0x21, 0x23}, {0x25, 0x2a}, | |
{0x2c, 0x2f}, {0x3a, 0x3b}, {0x3f, 0x40}, {0x5b, 0x5d}, {0x5f, 0x5f}, | |
@@ -749,13 +749,13 @@ | |
{0xff0c, 0xff0f}, {0xff1a, 0xff1b}, {0xff1f, 0xff20}, {0xff3b, 0xff3d}, | |
{0xff3f, 0xff3f}, {0xff5b, 0xff5b}, {0xff5d, 0xff5d}, {0xff5f, 0xff65} }; | |
static const xmlChLRange xmlPL[] = {{0x10100, 0x10101}, {0x1039f, 0x1039f} }; | |
-static xmlChRangeGroup xmlPG = {84,2,xmlPS,xmlPL}; | |
+static const xmlChRangeGroup xmlPG = {84,2,xmlPS,xmlPL}; | |
static const xmlChSRange xmlPdS[] = {{0x2d, 0x2d}, {0x58a, 0x58a}, | |
{0x1806, 0x1806}, {0x2010, 0x2015}, {0x301c, 0x301c}, {0x3030, 0x3030}, | |
{0x30a0, 0x30a0}, {0xfe31, 0xfe32}, {0xfe58, 0xfe58}, {0xfe63, 0xfe63}, | |
{0xff0d, 0xff0d} }; | |
-static xmlChRangeGroup xmlPdG = {11,0,xmlPdS,NULL}; | |
+static const xmlChRangeGroup xmlPdG = {11,0,xmlPdS,NULL}; | |
static const xmlChSRange xmlPeS[] = {{0x29, 0x29}, {0x5d, 0x5d}, | |
{0x7d, 0x7d}, {0xf3b, 0xf3b}, {0xf3d, 0xf3d}, {0x169c, 0x169c}, | |
@@ -774,7 +774,7 @@ | |
{0xfe48, 0xfe48}, {0xfe5a, 0xfe5a}, {0xfe5c, 0xfe5c}, {0xfe5e, 0xfe5e}, | |
{0xff09, 0xff09}, {0xff3d, 0xff3d}, {0xff5d, 0xff5d}, {0xff60, 0xff60}, | |
{0xff63, 0xff63} }; | |
-static xmlChRangeGroup xmlPeG = {63,0,xmlPeS,NULL}; | |
+static const xmlChRangeGroup xmlPeG = {63,0,xmlPeS,NULL}; | |
static const xmlChSRange xmlPoS[] = {{0x21, 0x23}, {0x25, 0x27}, | |
{0x2a, 0x2a}, {0x2c, 0x2c}, {0x2e, 0x2f}, {0x3a, 0x3b}, {0x3f, 0x40}, | |
@@ -795,7 +795,7 @@ | |
{0xff0a, 0xff0a}, {0xff0c, 0xff0c}, {0xff0e, 0xff0f}, {0xff1a, 0xff1b}, | |
{0xff1f, 0xff20}, {0xff3c, 0xff3c}, {0xff61, 0xff61}, {0xff64, 0xff64} }; | |
static const xmlChLRange xmlPoL[] = {{0x10100, 0x10101}, {0x1039f, 0x1039f} }; | |
-static xmlChRangeGroup xmlPoG = {72,2,xmlPoS,xmlPoL}; | |
+static const xmlChRangeGroup xmlPoG = {72,2,xmlPoS,xmlPoL}; | |
static const xmlChSRange xmlPsS[] = {{0x28, 0x28}, {0x5b, 0x5b}, | |
{0x7b, 0x7b}, {0xf3a, 0xf3a}, {0xf3c, 0xf3c}, {0x169b, 0x169b}, | |
@@ -814,7 +814,7 @@ | |
{0xfe41, 0xfe41}, {0xfe43, 0xfe43}, {0xfe47, 0xfe47}, {0xfe59, 0xfe59}, | |
{0xfe5b, 0xfe5b}, {0xfe5d, 0xfe5d}, {0xff08, 0xff08}, {0xff3b, 0xff3b}, | |
{0xff5b, 0xff5b}, {0xff5f, 0xff5f}, {0xff62, 0xff62} }; | |
-static xmlChRangeGroup xmlPsG = {65,0,xmlPsS,NULL}; | |
+static const xmlChRangeGroup xmlPsG = {65,0,xmlPsS,NULL}; | |
static const xmlChSRange xmlSS[] = {{0x24, 0x24}, {0x2b, 0x2b}, | |
{0x3c, 0x3e}, {0x5e, 0x5e}, {0x60, 0x60}, {0x7c, 0x7c}, {0x7e, 0x7e}, | |
@@ -857,13 +857,13 @@ | |
{0x1d6db, 0x1d6db}, {0x1d6fb, 0x1d6fb}, {0x1d715, 0x1d715}, | |
{0x1d735, 0x1d735}, {0x1d74f, 0x1d74f}, {0x1d76f, 0x1d76f}, | |
{0x1d789, 0x1d789}, {0x1d7a9, 0x1d7a9}, {0x1d7c3, 0x1d7c3} }; | |
-static xmlChRangeGroup xmlSG = {133,20,xmlSS,xmlSL}; | |
+static const xmlChRangeGroup xmlSG = {133,20,xmlSS,xmlSL}; | |
static const xmlChSRange xmlScS[] = {{0x24, 0x24}, {0xa2, 0xa5}, | |
{0x9f2, 0x9f3}, {0xaf1, 0xaf1}, {0xbf9, 0xbf9}, {0xe3f, 0xe3f}, | |
{0x17db, 0x17db}, {0x20a0, 0x20b1}, {0xfdfc, 0xfdfc}, {0xfe69, 0xfe69}, | |
{0xff04, 0xff04}, {0xffe0, 0xffe1}, {0xffe5, 0xffe6} }; | |
-static xmlChRangeGroup xmlScG = {13,0,xmlScS,NULL}; | |
+static const xmlChRangeGroup xmlScG = {13,0,xmlScS,NULL}; | |
static const xmlChSRange xmlSkS[] = {{0x5e, 0x5e}, {0x60, 0x60}, | |
{0xa8, 0xa8}, {0xaf, 0xaf}, {0xb4, 0xb4}, {0xb8, 0xb8}, {0x2c2, 0x2c5}, | |
@@ -871,7 +871,7 @@ | |
{0x384, 0x385}, {0x1fbd, 0x1fbd}, {0x1fbf, 0x1fc1}, {0x1fcd, 0x1fcf}, | |
{0x1fdd, 0x1fdf}, {0x1fed, 0x1fef}, {0x1ffd, 0x1ffe}, {0x309b, 0x309c}, | |
{0xff3e, 0xff3e}, {0xff40, 0xff40}, {0xffe3, 0xffe3} }; | |
-static xmlChRangeGroup xmlSkG = {22,0,xmlSkS,NULL}; | |
+static const xmlChRangeGroup xmlSkG = {22,0,xmlSkS,NULL}; | |
static const xmlChSRange xmlSmS[] = {{0x2b, 0x2b}, {0x3c, 0x3e}, | |
{0x7c, 0x7c}, {0x7e, 0x7e}, {0xac, 0xac}, {0xb1, 0xb1}, {0xd7, 0xd7}, | |
@@ -890,7 +890,7 @@ | |
{0x1d6fb, 0x1d6fb}, {0x1d715, 0x1d715}, {0x1d735, 0x1d735}, | |
{0x1d74f, 0x1d74f}, {0x1d76f, 0x1d76f}, {0x1d789, 0x1d789}, | |
{0x1d7a9, 0x1d7a9}, {0x1d7c3, 0x1d7c3} }; | |
-static xmlChRangeGroup xmlSmG = {48,10,xmlSmS,xmlSmL}; | |
+static const xmlChRangeGroup xmlSmG = {48,10,xmlSmS,xmlSmL}; | |
static const xmlChSRange xmlSoS[] = {{0xa6, 0xa7}, {0xa9, 0xa9}, | |
{0xae, 0xae}, {0xb0, 0xb0}, {0xb6, 0xb6}, {0x482, 0x482}, | |
@@ -923,15 +923,15 @@ | |
{0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, {0x1d12a, 0x1d164}, | |
{0x1d16a, 0x1d16c}, {0x1d183, 0x1d184}, {0x1d18c, 0x1d1a9}, | |
{0x1d1ae, 0x1d1dd}, {0x1d300, 0x1d356} }; | |
-static xmlChRangeGroup xmlSoG = {103,10,xmlSoS,xmlSoL}; | |
+static const xmlChRangeGroup xmlSoG = {103,10,xmlSoS,xmlSoL}; | |
static const xmlChSRange xmlZS[] = {{0x20, 0x20}, {0xa0, 0xa0}, | |
{0x1680, 0x1680}, {0x180e, 0x180e}, {0x2000, 0x200a}, {0x2028, 0x2029}, | |
{0x202f, 0x202f}, {0x205f, 0x205f}, {0x3000, 0x3000} }; | |
-static xmlChRangeGroup xmlZG = {9,0,xmlZS,NULL}; | |
+static const xmlChRangeGroup xmlZG = {9,0,xmlZS,NULL}; | |
-static xmlUnicodeNameTable xmlUnicodeBlockTbl = {xmlUnicodeBlocks, 128}; | |
-static xmlUnicodeNameTable xmlUnicodeCatTbl = {xmlUnicodeCats, 36}; | |
+static const xmlUnicodeNameTable xmlUnicodeBlockTbl = {xmlUnicodeBlocks, 128}; | |
+static const xmlUnicodeNameTable xmlUnicodeCatTbl = {xmlUnicodeCats, 36}; | |
/** | |
* xmlUnicodeLookup: | |
@@ -943,7 +943,7 @@ | |
* Returns pointer to range function if found, otherwise NULL | |
*/ | |
static xmlIntFunc | |
-*xmlUnicodeLookup(xmlUnicodeNameTable *tptr, const char *tname) { | |
+*xmlUnicodeLookup(const xmlUnicodeNameTable *tptr, const char *tname) { | |
int low, high, mid, cmp; | |
const xmlUnicodeRange *sptr; | |
Only in libxml2-apple/libxml2: xmlversion.c | |
Only in libxml2-apple/libxml2: xmlversionInternal.h | |
diff -ru libxml2/xmlwriter.c libxml2-apple/libxml2/xmlwriter.c | |
--- libxml2/xmlwriter.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xmlwriter.c 2025-06-26 01:54:56 | |
@@ -158,12 +158,18 @@ | |
const char *msg, int val) | |
{ | |
if (ctxt != NULL) { | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, ctxt->ctxt, | |
NULL, XML_FROM_WRITER, error, XML_ERR_FATAL, | |
NULL, 0, NULL, NULL, NULL, val, 0, msg, val); | |
+#pragma clang diagnostic pop | |
} else { | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_WRITER, error, | |
XML_ERR_FATAL, NULL, 0, NULL, NULL, NULL, val, 0, msg, val); | |
+#pragma clang diagnostic pop | |
} | |
} | |
@@ -1541,7 +1547,7 @@ | |
xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len, | |
const unsigned char *data) | |
{ | |
- static unsigned char dtable[64] = | |
+ static unsigned char const dtable[64] = | |
{'A','B','C','D','E','F','G','H','I','J','K','L','M', | |
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z', | |
'a','b','c','d','e','f','g','h','i','j','k','l','m', | |
@@ -1674,7 +1680,7 @@ | |
{ | |
int count; | |
int sum; | |
- static char hex[16] = | |
+ static char const hex[16] = | |
{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; | |
int i; | |
diff -ru libxml2/xpath.c libxml2-apple/libxml2/xpath.c | |
--- libxml2/xpath.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xpath.c 2025-06-26 01:54:56 | |
@@ -49,7 +49,7 @@ | |
#include <libxml/xpathInternals.h> | |
#include <libxml/parserInternals.h> | |
#include <libxml/hash.h> | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
#include <libxml/xpointer.h> | |
#endif | |
#ifdef LIBXML_DEBUG_ENABLED | |
@@ -63,11 +63,16 @@ | |
#endif | |
#include "buf.h" | |
+#include "private/xpath.h" | |
#ifdef LIBXML_PATTERN_ENABLED | |
#define XPATH_STREAMING | |
#endif | |
+#ifdef __APPLE__ | |
+#include "xmlversionInternal.h" | |
+#endif | |
+ | |
#define TODO \ | |
xmlGenericError(xmlGenericErrorContext, \ | |
"Unimplemented block at %s:%d\n", \ | |
@@ -590,7 +595,7 @@ | |
/* | |
* The array xmlXPathErrorMessages corresponds to the enum xmlXPathError | |
*/ | |
-static const char *xmlXPathErrorMessages[] = { | |
+static const char * const xmlXPathErrorMessages[] = { | |
"Ok\n", | |
"Number encoding\n", | |
"Unfinished literal\n", | |
@@ -627,9 +632,9 @@ | |
* @ctxt: an XPath context | |
* @extra: extra information | |
* | |
- * Handle a redefinition of attribute error | |
+ * Handle a memory allocation failure. | |
*/ | |
-static void | |
+void | |
xmlXPathErrMemory(xmlXPathContextPtr ctxt, const char *extra) | |
{ | |
if (ctxt != NULL) { | |
@@ -670,9 +675,9 @@ | |
* @ctxt: an XPath parser context | |
* @extra: extra information | |
* | |
- * Handle a redefinition of attribute error | |
+ * Handle a memory allocation failure. | |
*/ | |
-static void | |
+void | |
xmlXPathPErrMemory(xmlXPathParserContextPtr ctxt, const char *extra) | |
{ | |
if (ctxt == NULL) | |
@@ -764,20 +769,24 @@ | |
* Adds opCount to the running total of operations and returns -1 if the | |
* operation limit is exceeded. Returns 0 otherwise. | |
*/ | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
static int | |
xmlXPathCheckOpLimit(xmlXPathParserContextPtr ctxt, unsigned long opCount) { | |
- xmlXPathContextPtr xpctxt = ctxt->context; | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ xmlXPathContextPtr xpctxt = ctxt->context; | |
- if ((opCount > xpctxt->opLimit) || | |
- (xpctxt->opCount > xpctxt->opLimit - opCount)) { | |
- xpctxt->opCount = xpctxt->opLimit; | |
- xmlXPathErr(ctxt, XPATH_OP_LIMIT_EXCEEDED); | |
- return(-1); | |
- } | |
+ if ((opCount > xpctxt->opLimit) || | |
+ (xpctxt->opCount > xpctxt->opLimit - opCount)) { | |
+ xpctxt->opCount = xpctxt->opLimit; | |
+ xmlXPathErr(ctxt, XPATH_OP_LIMIT_EXCEEDED); | |
+ return(-1); | |
+ } | |
- xpctxt->opCount += opCount; | |
+ xpctxt->opCount += opCount; | |
+ } | |
return(0); | |
} | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
#define OP_LIMIT_EXCEEDED(ctxt, n) \ | |
((ctxt->context->opLimit != 0) && (xmlXPathCheckOpLimit(ctxt, n) < 0)) | |
@@ -911,7 +920,7 @@ | |
XPATH_OP_PREDICATE, | |
XPATH_OP_FILTER, /* 16 */ | |
XPATH_OP_SORT /* 17 */ | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
,XPATH_OP_RANGETO | |
#endif | |
} xmlXPathOp; | |
@@ -984,9 +993,8 @@ | |
* Forward declarations * | |
* * | |
************************************************************************/ | |
+ | |
static void | |
-xmlXPathFreeValueTree(xmlNodeSetPtr obj); | |
-static void | |
xmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr obj); | |
static int | |
xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt, | |
@@ -1362,7 +1370,7 @@ | |
fprintf(output, "%d", i + 1); | |
xmlXPathDebugDumpNodeList(output, cur->nodeTab[0]->children, depth + 1); | |
} | |
-#if defined(LIBXML_XPTR_ENABLED) | |
+#if defined(LIBXML_XPTR_LOCS_ENABLED) | |
static void | |
xmlXPathDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur, int depth) { | |
int i; | |
@@ -1385,7 +1393,7 @@ | |
xmlXPathDebugDumpObject(output, cur->locTab[i], depth + 1); | |
} | |
} | |
-#endif /* LIBXML_XPTR_ENABLED */ | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
/** | |
* xmlXPathDebugDumpObject: | |
@@ -1454,6 +1462,7 @@ | |
xmlDebugDumpString(output, cur->stringval); | |
fprintf(output, "\n"); | |
break; | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
fprintf(output, "Object is a point : index %d in node", cur->index); | |
xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1); | |
@@ -1489,12 +1498,11 @@ | |
} | |
break; | |
case XPATH_LOCATIONSET: | |
-#if defined(LIBXML_XPTR_ENABLED) | |
fprintf(output, "Object is a Location Set:\n"); | |
xmlXPathDebugDumpLocationSet(output, | |
(xmlLocationSetPtr) cur->user, depth); | |
-#endif | |
break; | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
case XPATH_USERS: | |
fprintf(output, "Object is user defined\n"); | |
break; | |
@@ -1662,7 +1670,7 @@ | |
case XPATH_OP_ARG: fprintf(output, "ARG"); break; | |
case XPATH_OP_PREDICATE: fprintf(output, "PREDICATE"); break; | |
case XPATH_OP_FILTER: fprintf(output, "FILTER"); break; | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_OP_RANGETO: fprintf(output, "RANGETO"); break; | |
#endif | |
default: | |
@@ -1854,6 +1862,7 @@ | |
case XPATH_STRING: | |
cache->dbgReusedString++; | |
break; | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
cache->dbgReusedPoint++; | |
break; | |
@@ -1863,6 +1872,7 @@ | |
case XPATH_LOCATIONSET: | |
cache->dbgReusedLocset++; | |
break; | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
case XPATH_USERS: | |
cache->dbgReusedUsers++; | |
break; | |
@@ -1921,6 +1931,7 @@ | |
xmlXPathDebugObjMaxString = | |
xmlXPathDebugObjCounterString; | |
break; | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
if (! isCached) | |
xmlXPathDebugObjTotalPoint++; | |
@@ -1948,6 +1959,7 @@ | |
xmlXPathDebugObjMaxLocset = | |
xmlXPathDebugObjCounterLocset; | |
break; | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
case XPATH_USERS: | |
if (! isCached) | |
xmlXPathDebugObjTotalUsers++; | |
@@ -2008,6 +2020,7 @@ | |
case XPATH_STRING: | |
cache->dbgCachedString++; | |
break; | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
cache->dbgCachedPoint++; | |
break; | |
@@ -2017,6 +2030,7 @@ | |
case XPATH_LOCATIONSET: | |
cache->dbgCachedLocset++; | |
break; | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
case XPATH_USERS: | |
cache->dbgCachedUsers++; | |
break; | |
@@ -2045,6 +2059,7 @@ | |
case XPATH_STRING: | |
xmlXPathDebugObjCounterString--; | |
break; | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
xmlXPathDebugObjCounterPoint--; | |
break; | |
@@ -2054,6 +2069,7 @@ | |
case XPATH_LOCATIONSET: | |
xmlXPathDebugObjCounterLocset--; | |
break; | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
case XPATH_USERS: | |
xmlXPathDebugObjCounterUsers--; | |
break; | |
@@ -2706,9 +2722,11 @@ | |
res = xmlXPathCastNumberToString(val->floatval); | |
break; | |
case XPATH_USERS: | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
case XPATH_RANGE: | |
case XPATH_LOCATIONSET: | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
TODO; | |
break; | |
} | |
@@ -2807,42 +2825,6 @@ | |
************************************************************************/ | |
/** | |
- * xmlXPathSetFrame: | |
- * @ctxt: an XPath parser context | |
- * | |
- * Set the callee evaluation frame | |
- * | |
- * Returns the previous frame value to be restored once done | |
- */ | |
-static int | |
-xmlXPathSetFrame(xmlXPathParserContextPtr ctxt) { | |
- int ret; | |
- | |
- if (ctxt == NULL) | |
- return(0); | |
- ret = ctxt->valueFrame; | |
- ctxt->valueFrame = ctxt->valueNr; | |
- return(ret); | |
-} | |
- | |
-/** | |
- * xmlXPathPopFrame: | |
- * @ctxt: an XPath parser context | |
- * @frame: the previous frame value | |
- * | |
- * Remove the callee evaluation frame | |
- */ | |
-static void | |
-xmlXPathPopFrame(xmlXPathParserContextPtr ctxt, int frame) { | |
- if (ctxt == NULL) | |
- return; | |
- if (ctxt->valueNr < ctxt->valueFrame) { | |
- xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR); | |
- } | |
- ctxt->valueFrame = frame; | |
-} | |
- | |
-/** | |
* valuePop: | |
* @ctxt: an XPath evaluation context | |
* | |
@@ -2858,11 +2840,6 @@ | |
if ((ctxt == NULL) || (ctxt->valueNr <= 0)) | |
return (NULL); | |
- if (ctxt->valueNr <= ctxt->valueFrame) { | |
- xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR); | |
- return (NULL); | |
- } | |
- | |
ctxt->valueNr--; | |
if (ctxt->valueNr > 0) | |
ctxt->value = ctxt->valueTab[ctxt->valueNr - 1]; | |
@@ -4218,34 +4195,6 @@ | |
set->nodeNr = 1; | |
} | |
-/** | |
- * xmlXPathFreeValueTree: | |
- * @obj: the xmlNodeSetPtr to free | |
- * | |
- * Free the NodeSet compound and the actual tree, this is different | |
- * from xmlXPathFreeNodeSet() | |
- */ | |
-static void | |
-xmlXPathFreeValueTree(xmlNodeSetPtr obj) { | |
- int i; | |
- | |
- if (obj == NULL) return; | |
- | |
- if (obj->nodeTab != NULL) { | |
- for (i = 0;i < obj->nodeNr;i++) { | |
- if (obj->nodeTab[i] != NULL) { | |
- if (obj->nodeTab[i]->type == XML_NAMESPACE_DECL) { | |
- xmlXPathNodeSetFreeNs((xmlNsPtr) obj->nodeTab[i]); | |
- } else { | |
- xmlFreeNodeList(obj->nodeTab[i]); | |
- } | |
- } | |
- } | |
- xmlFree(obj->nodeTab); | |
- } | |
- xmlFree(obj); | |
-} | |
- | |
#if defined(DEBUG) || defined(DEBUG_STEP) | |
/** | |
* xmlGenericErrorContextNodeSet: | |
@@ -4330,19 +4279,13 @@ | |
xmlXPathNewValueTree(xmlNodePtr val) { | |
xmlXPathObjectPtr ret; | |
- ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); | |
+ ret = xmlXPathNewNodeSet(val); | |
if (ret == NULL) { | |
xmlXPathErrMemory(NULL, "creating result value tree\n"); | |
return(NULL); | |
} | |
- memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); | |
ret->type = XPATH_XSLT_TREE; | |
- ret->boolval = 1; | |
- ret->user = (void *) val; | |
- ret->nodesetval = xmlXPathNodeSetCreate(val); | |
-#ifdef XP_DEBUG_OBJ_USAGE | |
- xmlXPathDebugObjUsageRequested(NULL, XPATH_XSLT_TREE); | |
-#endif | |
+ | |
return(ret); | |
} | |
@@ -5112,6 +5055,8 @@ | |
int | |
xmlXPathRegisterNs(xmlXPathContextPtr ctxt, const xmlChar *prefix, | |
const xmlChar *ns_uri) { | |
+ xmlChar *copy; | |
+ | |
if (ctxt == NULL) | |
return(-1); | |
if (prefix == NULL) | |
@@ -5126,8 +5071,17 @@ | |
if (ns_uri == NULL) | |
return(xmlHashRemoveEntry(ctxt->nsHash, prefix, | |
xmlHashDefaultDeallocator)); | |
- return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) xmlStrdup(ns_uri), | |
- xmlHashDefaultDeallocator)); | |
+ | |
+ copy = xmlStrdup(ns_uri); | |
+ if (copy == NULL) | |
+ return(-1); | |
+ if (xmlHashUpdateEntry(ctxt->nsHash, prefix, copy, | |
+ xmlHashDefaultDeallocator) < 0) { | |
+ xmlFree(copy); | |
+ return(-1); | |
+ } | |
+ | |
+ return(0); | |
} | |
/** | |
@@ -5387,8 +5341,10 @@ | |
switch (val->type) { | |
case XPATH_BOOLEAN: | |
case XPATH_NUMBER: | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
case XPATH_RANGE: | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
break; | |
case XPATH_STRING: | |
ret->stringval = xmlStrdup(val->stringval); | |
@@ -5432,8 +5388,8 @@ | |
/* Do not deallocate the copied tree value */ | |
ret->boolval = 0; | |
break; | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_LOCATIONSET: | |
-#ifdef LIBXML_XPTR_ENABLED | |
{ | |
xmlLocationSetPtr loc = val->user; | |
ret->user = (void *) xmlXPtrLocationSetMerge(NULL, loc); | |
@@ -5462,21 +5418,9 @@ | |
xmlXPathFreeObject(xmlXPathObjectPtr obj) { | |
if (obj == NULL) return; | |
if ((obj->type == XPATH_NODESET) || (obj->type == XPATH_XSLT_TREE)) { | |
- if (obj->boolval) { | |
-#if 0 | |
- if (obj->user != NULL) { | |
- xmlXPathFreeNodeSet(obj->nodesetval); | |
- xmlFreeNodeList((xmlNodePtr) obj->user); | |
- } else | |
-#endif | |
- obj->type = XPATH_XSLT_TREE; /* TODO: Just for debugging. */ | |
- if (obj->nodesetval != NULL) | |
- xmlXPathFreeValueTree(obj->nodesetval); | |
- } else { | |
- if (obj->nodesetval != NULL) | |
- xmlXPathFreeNodeSet(obj->nodesetval); | |
- } | |
-#ifdef LIBXML_XPTR_ENABLED | |
+ if (obj->nodesetval != NULL) | |
+ xmlXPathFreeNodeSet(obj->nodesetval); | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
} else if (obj->type == XPATH_LOCATIONSET) { | |
if (obj->user != NULL) | |
xmlXPtrFreeLocationSet(obj->user); | |
@@ -5524,16 +5468,7 @@ | |
case XPATH_NODESET: | |
case XPATH_XSLT_TREE: | |
if (obj->nodesetval != NULL) { | |
- if (obj->boolval) { | |
- /* | |
- * It looks like the @boolval is used for | |
- * evaluation if this an XSLT Result Tree Fragment. | |
- * TODO: Check if this assumption is correct. | |
- */ | |
- obj->type = XPATH_XSLT_TREE; /* just for debugging */ | |
- xmlXPathFreeValueTree(obj->nodesetval); | |
- obj->nodesetval = NULL; | |
- } else if ((obj->nodesetval->nodeMax <= 40) && | |
+ if ((obj->nodesetval->nodeMax <= 40) && | |
(XP_CACHE_WANTS(cache->nodesetObjs, | |
cache->maxNodeset))) | |
{ | |
@@ -5566,7 +5501,7 @@ | |
goto obj_cached; | |
} | |
break; | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_LOCATIONSET: | |
if (obj->user != NULL) { | |
xmlXPtrFreeLocationSet(obj->user); | |
@@ -5769,9 +5704,11 @@ | |
break; | |
} | |
case XPATH_USERS: | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
case XPATH_RANGE: | |
case XPATH_LOCATIONSET: | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
TODO | |
ret = xmlStrdup((const xmlChar *) ""); | |
break; | |
@@ -5814,9 +5751,11 @@ | |
res = xmlXPathCastNumberToString(val->floatval); | |
break; | |
case XPATH_USERS: | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
case XPATH_RANGE: | |
case XPATH_LOCATIONSET: | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
TODO; | |
break; | |
} | |
@@ -5934,9 +5873,11 @@ | |
ret = xmlXPathCastBooleanToNumber(val->boolval); | |
break; | |
case XPATH_USERS: | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
case XPATH_RANGE: | |
case XPATH_LOCATIONSET: | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
TODO; | |
ret = xmlXPathNAN; | |
break; | |
@@ -6046,9 +5987,11 @@ | |
ret = val->boolval; | |
break; | |
case XPATH_USERS: | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
case XPATH_RANGE: | |
case XPATH_LOCATIONSET: | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
TODO; | |
ret = 0; | |
break; | |
@@ -6259,7 +6202,6 @@ | |
ret->valueNr = 0; | |
ret->valueMax = 10; | |
ret->value = NULL; | |
- ret->valueFrame = 0; | |
ret->context = ctxt; | |
ret->comp = comp; | |
@@ -6388,11 +6330,12 @@ | |
/* | |
* Skip to next node | |
*/ | |
- if ((tmp->children != NULL) && (tmp->type != XML_DTD_NODE)) { | |
- if (tmp->children->type != XML_ENTITY_DECL) { | |
- tmp = tmp->children; | |
- continue; | |
- } | |
+ if ((tmp->children != NULL) && | |
+ (tmp->type != XML_DTD_NODE) && | |
+ (tmp->type != XML_ENTITY_REF_NODE) && | |
+ (tmp->children->type != XML_ENTITY_DECL)) { | |
+ tmp = tmp->children; | |
+ continue; | |
} | |
if (tmp == node) | |
break; | |
@@ -6985,9 +6928,11 @@ | |
ret = (arg1->boolval == ret); | |
break; | |
case XPATH_USERS: | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
case XPATH_RANGE: | |
case XPATH_LOCATIONSET: | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
TODO | |
break; | |
case XPATH_NODESET: | |
@@ -7042,9 +6987,11 @@ | |
} | |
break; | |
case XPATH_USERS: | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
case XPATH_RANGE: | |
case XPATH_LOCATIONSET: | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
TODO | |
break; | |
case XPATH_NODESET: | |
@@ -7103,9 +7050,11 @@ | |
} | |
break; | |
case XPATH_USERS: | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
case XPATH_RANGE: | |
case XPATH_LOCATIONSET: | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
TODO | |
break; | |
case XPATH_NODESET: | |
@@ -7114,9 +7063,11 @@ | |
} | |
break; | |
case XPATH_USERS: | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
case XPATH_RANGE: | |
case XPATH_LOCATIONSET: | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
TODO | |
break; | |
case XPATH_NODESET: | |
@@ -7199,9 +7150,11 @@ | |
ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval, 0); | |
break; | |
case XPATH_USERS: | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
case XPATH_RANGE: | |
case XPATH_LOCATIONSET: | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
TODO | |
break; | |
} | |
@@ -7284,9 +7237,11 @@ | |
ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval,1); | |
break; | |
case XPATH_USERS: | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_POINT: | |
case XPATH_RANGE: | |
case XPATH_LOCATIONSET: | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
TODO | |
break; | |
} | |
@@ -9336,7 +9291,7 @@ | |
xmlXPathObjectPtr to; | |
xmlBufPtr target; | |
int offset, max; | |
- xmlChar ch; | |
+ int ch; | |
const xmlChar *point; | |
xmlChar *cptr; | |
@@ -10257,7 +10212,10 @@ | |
} else { | |
XP_ERROR(XPATH_START_LITERAL_ERROR); | |
} | |
- if (ret == NULL) return; | |
+ if (ret == NULL) { | |
+ xmlXPathPErrMemory(ctxt, NULL); | |
+ return; | |
+ } | |
lit = xmlXPathCacheNewString(ctxt->context, ret); | |
if (lit == NULL) { | |
ctxt->error = XPATH_MEMORY_ERROR; | |
@@ -10625,7 +10583,7 @@ | |
"PathExpr: Type search\n"); | |
#endif | |
lc = 1; | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
} else if (ctxt->xptr && | |
xmlStrEqual(name, BAD_CAST "range-to")) { | |
lc = 1; | |
@@ -10948,17 +10906,21 @@ | |
*/ | |
static void | |
xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) { | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
xmlXPathContextPtr xpctxt = ctxt->context; | |
- if (xpctxt != NULL) { | |
- if (xpctxt->depth >= XPATH_MAX_RECURSION_DEPTH) | |
- XP_ERROR(XPATH_RECURSION_LIMIT_EXCEEDED); | |
- /* | |
- * Parsing a single '(' pushes about 10 functions on the call stack | |
- * before recursing! | |
- */ | |
- xpctxt->depth += 10; | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if (xpctxt != NULL) { | |
+ if (xpctxt->depth >= XPATH_MAX_RECURSION_DEPTH) | |
+ XP_ERROR(XPATH_RECURSION_LIMIT_EXCEEDED); | |
+ /* | |
+ * Parsing a single '(' pushes about 10 functions on the call stack | |
+ * before recursing! | |
+ */ | |
+ xpctxt->depth += 10; | |
+ } | |
} | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
xmlXPathCompAndExpr(ctxt); | |
CHECK_ERROR; | |
@@ -10982,8 +10944,12 @@ | |
PUSH_UNARY_EXPR(XPATH_OP_SORT, ctxt->comp->last , 0, 0); | |
} | |
- if (xpctxt != NULL) | |
- xpctxt->depth -= 10; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if (xpctxt != NULL) | |
+ xpctxt->depth -= 10; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
} | |
/** | |
@@ -11276,7 +11242,7 @@ | |
*/ | |
static void | |
xmlXPathCompStep(xmlXPathParserContextPtr ctxt) { | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
int rangeto = 0; | |
int op2 = -1; | |
#endif | |
@@ -11301,7 +11267,7 @@ | |
/* | |
* The modification needed for XPointer change to the production | |
*/ | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
if (ctxt->xptr) { | |
name = xmlXPathParseNCName(ctxt); | |
if ((name != NULL) && (xmlStrEqual(name, BAD_CAST "range-to"))) { | |
@@ -11386,7 +11352,7 @@ | |
xmlGenericErrorContextNodeSet(stdout, ctxt->value->nodesetval); | |
#endif | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
eval_predicates: | |
#endif | |
op1 = ctxt->comp->last; | |
@@ -11397,7 +11363,7 @@ | |
xmlXPathCompPredicate(ctxt, 0); | |
} | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
if (rangeto) { | |
PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, op1, 0, 0); | |
} else | |
@@ -11740,7 +11706,7 @@ | |
xpctxt->proximityPosition = oldpp; | |
} | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
/** | |
* xmlXPathLocationSetFilter: | |
* @ctxt: the XPath Parser context | |
@@ -11857,7 +11823,7 @@ | |
xpctxt->contextSize = oldcs; | |
xpctxt->proximityPosition = oldpp; | |
} | |
-#endif /* LIBXML_XPTR_ENABLED */ | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
/** | |
* xmlXPathCompOpEvalPredicate: | |
@@ -11889,12 +11855,20 @@ | |
"xmlXPathCompOpEvalPredicate: Expected a predicate\n"); | |
XP_ERROR(XPATH_INVALID_OPERAND); | |
} | |
- if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) | |
- XP_ERROR(XPATH_RECURSION_LIMIT_EXCEEDED); | |
- ctxt->context->depth += 1; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) | |
+ XP_ERROR(XPATH_RECURSION_LIMIT_EXCEEDED); | |
+ ctxt->context->depth += 1; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
xmlXPathCompOpEvalPredicate(ctxt, &comp->steps[op->ch1], set, | |
1, set->nodeNr, hasNsNodes); | |
- ctxt->context->depth -= 1; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ ctxt->context->depth -= 1; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
CHECK_ERROR; | |
} | |
@@ -12222,8 +12196,12 @@ | |
cur = NULL; | |
hasNsNodes = 0; | |
do { | |
- if (OP_LIMIT_EXCEEDED(ctxt, 1)) | |
- goto error; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if (OP_LIMIT_EXCEEDED(ctxt, 1)) | |
+ goto error; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
cur = next(ctxt, cur); | |
if (cur == NULL) | |
@@ -12603,11 +12581,15 @@ | |
xmlXPathObjectPtr arg1, arg2; | |
CHECK_ERROR0; | |
- if (OP_LIMIT_EXCEEDED(ctxt, 1)) | |
- return(0); | |
- if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) | |
- XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED); | |
- ctxt->context->depth += 1; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if (OP_LIMIT_EXCEEDED(ctxt, 1)) | |
+ return(0); | |
+ if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) | |
+ XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED); | |
+ ctxt->context->depth += 1; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
comp = ctxt->comp; | |
switch (op->op) { | |
case XPATH_OP_END: | |
@@ -12648,17 +12630,21 @@ | |
xmlXPathReleaseObject(ctxt->context, arg2); | |
XP_ERROR0(XPATH_INVALID_TYPE); | |
} | |
- if ((ctxt->context->opLimit != 0) && | |
- (((arg1->nodesetval != NULL) && | |
- (xmlXPathCheckOpLimit(ctxt, | |
- arg1->nodesetval->nodeNr) < 0)) || | |
- ((arg2->nodesetval != NULL) && | |
- (xmlXPathCheckOpLimit(ctxt, | |
- arg2->nodesetval->nodeNr) < 0)))) { | |
- xmlXPathReleaseObject(ctxt->context, arg1); | |
- xmlXPathReleaseObject(ctxt->context, arg2); | |
- break; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if ((ctxt->context->opLimit != 0) && | |
+ (((arg1->nodesetval != NULL) && | |
+ (xmlXPathCheckOpLimit(ctxt, | |
+ arg1->nodesetval->nodeNr) < 0)) || | |
+ ((arg2->nodesetval != NULL) && | |
+ (xmlXPathCheckOpLimit(ctxt, | |
+ arg2->nodesetval->nodeNr) < 0)))) { | |
+ xmlXPathReleaseObject(ctxt->context, arg1); | |
+ xmlXPathReleaseObject(ctxt->context, arg2); | |
+ break; | |
+ } | |
} | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
/* TODO: Check memory error. */ | |
arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, | |
@@ -12720,7 +12706,11 @@ | |
break; | |
} | |
- ctxt->context->depth -= 1; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ ctxt->context->depth -= 1; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
return(total); | |
} | |
@@ -12744,11 +12734,15 @@ | |
xmlXPathObjectPtr arg1, arg2; | |
CHECK_ERROR0; | |
- if (OP_LIMIT_EXCEEDED(ctxt, 1)) | |
- return(0); | |
- if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) | |
- XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED); | |
- ctxt->context->depth += 1; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if (OP_LIMIT_EXCEEDED(ctxt, 1)) | |
+ return(0); | |
+ if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) | |
+ XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED); | |
+ ctxt->context->depth += 1; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
comp = ctxt->comp; | |
switch (op->op) { | |
case XPATH_OP_END: | |
@@ -12788,17 +12782,21 @@ | |
xmlXPathReleaseObject(ctxt->context, arg2); | |
XP_ERROR0(XPATH_INVALID_TYPE); | |
} | |
- if ((ctxt->context->opLimit != 0) && | |
- (((arg1->nodesetval != NULL) && | |
- (xmlXPathCheckOpLimit(ctxt, | |
- arg1->nodesetval->nodeNr) < 0)) || | |
- ((arg2->nodesetval != NULL) && | |
- (xmlXPathCheckOpLimit(ctxt, | |
- arg2->nodesetval->nodeNr) < 0)))) { | |
- xmlXPathReleaseObject(ctxt->context, arg1); | |
- xmlXPathReleaseObject(ctxt->context, arg2); | |
- break; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if ((ctxt->context->opLimit != 0) && | |
+ (((arg1->nodesetval != NULL) && | |
+ (xmlXPathCheckOpLimit(ctxt, | |
+ arg1->nodesetval->nodeNr) < 0)) || | |
+ ((arg2->nodesetval != NULL) && | |
+ (xmlXPathCheckOpLimit(ctxt, | |
+ arg2->nodesetval->nodeNr) < 0)))) { | |
+ xmlXPathReleaseObject(ctxt->context, arg1); | |
+ xmlXPathReleaseObject(ctxt->context, arg2); | |
+ break; | |
+ } | |
} | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
/* TODO: Check memory error. */ | |
arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, | |
@@ -12855,7 +12853,11 @@ | |
break; | |
} | |
- ctxt->context->depth -= 1; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ ctxt->context->depth -= 1; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
return (total); | |
} | |
@@ -12866,6 +12868,7 @@ | |
{ | |
int total = 0; | |
xmlXPathCompExprPtr comp; | |
+ xmlXPathObjectPtr obj; | |
xmlNodeSetPtr set; | |
CHECK_ERROR0; | |
@@ -12916,7 +12919,7 @@ | |
if (ctxt->value == NULL) | |
return (total); | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
/* | |
* Hum are we filtering the result of an XPointer expression | |
*/ | |
@@ -12931,15 +12934,22 @@ | |
return (total); | |
} | |
-#endif /* LIBXML_XPTR_ENABLED */ | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
+ /* | |
+ * In case of errors, xmlXPathNodeSetFilter can pop additional nodes from | |
+ * the stack. We have to temporarily remove the nodeset object from the | |
+ * stack to avoid freeing it prematurely. | |
+ */ | |
CHECK_TYPE0(XPATH_NODESET); | |
- set = ctxt->value->nodesetval; | |
+ obj = valuePop(ctxt); | |
+ set = obj->nodesetval; | |
if (set != NULL) { | |
xmlXPathNodeSetFilter(ctxt, set, op->ch2, 1, 1, 1); | |
if (set->nodeNr > 0) | |
*first = set->nodeTab[0]; | |
} | |
+ valuePush(ctxt, obj); | |
return (total); | |
} | |
@@ -12962,11 +12972,15 @@ | |
xmlXPathObjectPtr arg1, arg2; | |
CHECK_ERROR0; | |
- if (OP_LIMIT_EXCEEDED(ctxt, 1)) | |
- return(0); | |
- if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) | |
- XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED); | |
- ctxt->context->depth += 1; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if (OP_LIMIT_EXCEEDED(ctxt, 1)) | |
+ return(0); | |
+ if (ctxt->context->depth >= XPATH_MAX_RECURSION_DEPTH) | |
+ XP_ERROR0(XPATH_RECURSION_LIMIT_EXCEEDED); | |
+ ctxt->context->depth += 1; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
comp = ctxt->comp; | |
switch (op->op) { | |
case XPATH_OP_END: | |
@@ -13068,17 +13082,21 @@ | |
xmlXPathReleaseObject(ctxt->context, arg2); | |
XP_ERROR0(XPATH_INVALID_TYPE); | |
} | |
- if ((ctxt->context->opLimit != 0) && | |
- (((arg1->nodesetval != NULL) && | |
- (xmlXPathCheckOpLimit(ctxt, | |
- arg1->nodesetval->nodeNr) < 0)) || | |
- ((arg2->nodesetval != NULL) && | |
- (xmlXPathCheckOpLimit(ctxt, | |
- arg2->nodesetval->nodeNr) < 0)))) { | |
- xmlXPathReleaseObject(ctxt->context, arg1); | |
- xmlXPathReleaseObject(ctxt->context, arg2); | |
- break; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if ((ctxt->context->opLimit != 0) && | |
+ (((arg1->nodesetval != NULL) && | |
+ (xmlXPathCheckOpLimit(ctxt, | |
+ arg1->nodesetval->nodeNr) < 0)) || | |
+ ((arg2->nodesetval != NULL) && | |
+ (xmlXPathCheckOpLimit(ctxt, | |
+ arg2->nodesetval->nodeNr) < 0)))) { | |
+ xmlXPathReleaseObject(ctxt->context, arg1); | |
+ xmlXPathReleaseObject(ctxt->context, arg2); | |
+ break; | |
+ } | |
} | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
if ((arg1->nodesetval == NULL) || | |
((arg2->nodesetval != NULL) && | |
@@ -13156,20 +13174,17 @@ | |
int i; | |
int frame; | |
- frame = xmlXPathSetFrame(ctxt); | |
+ frame = ctxt->valueNr; | |
if (op->ch1 != -1) { | |
total += | |
xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); | |
- if (ctxt->error != XPATH_EXPRESSION_OK) { | |
- xmlXPathPopFrame(ctxt, frame); | |
+ if (ctxt->error != XPATH_EXPRESSION_OK) | |
break; | |
- } | |
} | |
- if (ctxt->valueNr < ctxt->valueFrame + op->value) { | |
+ if (ctxt->valueNr < frame + op->value) { | |
xmlGenericError(xmlGenericErrorContext, | |
"xmlXPathCompOpEval: parameter error\n"); | |
ctxt->error = XPATH_INVALID_OPERAND; | |
- xmlXPathPopFrame(ctxt, frame); | |
break; | |
} | |
for (i = 0; i < op->value; i++) { | |
@@ -13177,7 +13192,6 @@ | |
xmlGenericError(xmlGenericErrorContext, | |
"xmlXPathCompOpEval: parameter error\n"); | |
ctxt->error = XPATH_INVALID_OPERAND; | |
- xmlXPathPopFrame(ctxt, frame); | |
break; | |
} | |
} | |
@@ -13196,7 +13210,6 @@ | |
xmlGenericError(xmlGenericErrorContext, | |
"xmlXPathCompOpEval: function %s bound to undefined prefix %s\n", | |
(char *)op->value4, (char *)op->value5); | |
- xmlXPathPopFrame(ctxt, frame); | |
ctxt->error = XPATH_UNDEF_PREFIX_ERROR; | |
break; | |
} | |
@@ -13220,9 +13233,8 @@ | |
ctxt->context->function = oldFunc; | |
ctxt->context->functionURI = oldFuncURI; | |
if ((ctxt->error == XPATH_EXPRESSION_OK) && | |
- (ctxt->valueNr != ctxt->valueFrame + 1)) | |
+ (ctxt->valueNr != frame + 1)) | |
XP_ERROR0(XPATH_STACK_ERROR); | |
- xmlXPathPopFrame(ctxt, frame); | |
break; | |
} | |
case XPATH_OP_ARG: | |
@@ -13237,6 +13249,7 @@ | |
break; | |
case XPATH_OP_PREDICATE: | |
case XPATH_OP_FILTER:{ | |
+ xmlXPathObjectPtr obj; | |
xmlNodeSetPtr set; | |
/* | |
@@ -13339,7 +13352,7 @@ | |
if (ctxt->value == NULL) | |
break; | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
/* | |
* Hum are we filtering the result of an XPointer expression | |
*/ | |
@@ -13349,13 +13362,21 @@ | |
1, locset->locNr); | |
break; | |
} | |
-#endif /* LIBXML_XPTR_ENABLED */ | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
+ /* | |
+ * In case of errors, xmlXPathNodeSetFilter can pop additional | |
+ * nodes from the stack. We have to temporarily remove the | |
+ * nodeset object from the stack to avoid freeing it | |
+ * prematurely. | |
+ */ | |
CHECK_TYPE0(XPATH_NODESET); | |
- set = ctxt->value->nodesetval; | |
+ obj = valuePop(ctxt); | |
+ set = obj->nodesetval; | |
if (set != NULL) | |
xmlXPathNodeSetFilter(ctxt, set, op->ch2, | |
1, set->nodeNr, 1); | |
+ valuePush(ctxt, obj); | |
break; | |
} | |
case XPATH_OP_SORT: | |
@@ -13370,7 +13391,7 @@ | |
xmlXPathNodeSetSort(ctxt->value->nodesetval); | |
} | |
break; | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_OP_RANGETO:{ | |
xmlXPathObjectPtr range; | |
xmlXPathObjectPtr res, obj; | |
@@ -13528,7 +13549,7 @@ | |
ctxt->context->proximityPosition = oldpp; | |
break; | |
} | |
-#endif /* LIBXML_XPTR_ENABLED */ | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
default: | |
xmlGenericError(xmlGenericErrorContext, | |
"XPath: unknown precompiled operation %d\n", op->op); | |
@@ -13536,7 +13557,11 @@ | |
break; | |
} | |
- ctxt->context->depth -= 1; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ ctxt->context->depth -= 1; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
return (total); | |
} | |
@@ -13556,8 +13581,12 @@ | |
xmlXPathObjectPtr resObj = NULL; | |
start: | |
- if (OP_LIMIT_EXCEEDED(ctxt, 1)) | |
- return(0); | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if (OP_LIMIT_EXCEEDED(ctxt, 1)) | |
+ return(0); | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
/* comp = ctxt->comp; */ | |
switch (op->op) { | |
case XPATH_OP_END: | |
@@ -13760,15 +13789,19 @@ | |
goto scan_children; | |
next_node: | |
do { | |
- if (ctxt->opLimit != 0) { | |
- if (ctxt->opCount >= ctxt->opLimit) { | |
- xmlGenericError(xmlGenericErrorContext, | |
- "XPath operation limit exceeded\n"); | |
- xmlFreeStreamCtxt(patstream); | |
- return(-1); | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if (ctxt->opLimit != 0) { | |
+ if (ctxt->opCount >= ctxt->opLimit) { | |
+ xmlGenericError(xmlGenericErrorContext, | |
+ "XPath operation limit exceeded\n"); | |
+ xmlFreeStreamCtxt(patstream); | |
+ return(-1); | |
+ } | |
+ ctxt->opCount++; | |
} | |
- ctxt->opCount++; | |
} | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
nb_nodes++; | |
@@ -13894,7 +13927,11 @@ | |
if ((ctxt == NULL) || (ctxt->comp == NULL)) | |
return(-1); | |
- ctxt->context->depth = 0; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ ctxt->context->depth = 0; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
if (ctxt->valueTab == NULL) { | |
/* Allocate the value stack */ | |
@@ -13902,12 +13939,11 @@ | |
xmlMalloc(10 * sizeof(xmlXPathObjectPtr)); | |
if (ctxt->valueTab == NULL) { | |
xmlXPathPErrMemory(ctxt, "creating evaluation context\n"); | |
- xmlFree(ctxt); | |
+ return(-1); | |
} | |
ctxt->valueNr = 0; | |
ctxt->valueMax = 10; | |
ctxt->value = NULL; | |
- ctxt->valueFrame = 0; | |
} | |
#ifdef XPATH_STREAMING | |
if (ctxt->comp->stream) { | |
@@ -14039,7 +14075,7 @@ | |
return(res->nodesetval->nodeNr != 0); | |
case XPATH_STRING: | |
return((res->stringval != NULL) && (res->stringval[0] != 0)); | |
-#ifdef LIBXML_XPTR_ENABLED | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_LOCATIONSET:{ | |
xmlLocationSetPtr ptr = res->user; | |
if (ptr == NULL) | |
@@ -14139,7 +14175,9 @@ | |
xmlXPathStepOpPtr op) | |
{ | |
xmlXPathCompExprPtr comp = pctxt->comp; | |
- xmlXPathContextPtr ctxt; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ xmlXPathContextPtr ctxt = NULL; | |
+#endif | |
/* | |
* Try to rewrite "descendant-or-self::node()/foo" to an optimized | |
@@ -14196,18 +14234,26 @@ | |
return; | |
/* Recurse */ | |
- ctxt = pctxt->context; | |
- if (ctxt != NULL) { | |
- if (ctxt->depth >= XPATH_MAX_RECURSION_DEPTH) | |
- return; | |
- ctxt->depth += 1; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ ctxt = pctxt->context; | |
+ if (ctxt != NULL) { | |
+ if (ctxt->depth >= XPATH_MAX_RECURSION_DEPTH) | |
+ return; | |
+ ctxt->depth += 1; | |
+ } | |
} | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
if (op->ch1 != -1) | |
xmlXPathOptimizeExpression(pctxt, &comp->steps[op->ch1]); | |
if (op->ch2 != -1) | |
xmlXPathOptimizeExpression(pctxt, &comp->steps[op->ch2]); | |
- if (ctxt != NULL) | |
- ctxt->depth -= 1; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if (ctxt != NULL) | |
+ ctxt->depth -= 1; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
} | |
/** | |
@@ -14236,8 +14282,12 @@ | |
pctxt = xmlXPathNewParserContext(str, ctxt); | |
if (pctxt == NULL) | |
return NULL; | |
- if (ctxt != NULL) | |
- ctxt->depth = 0; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if (ctxt != NULL) | |
+ ctxt->depth = 0; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
xmlXPathCompileExpr(pctxt, 1); | |
if( pctxt->error != XPATH_EXPRESSION_OK ) | |
@@ -14258,8 +14308,12 @@ | |
} else { | |
comp = pctxt->comp; | |
if ((comp->nbStep > 1) && (comp->last >= 0)) { | |
- if (ctxt != NULL) | |
- ctxt->depth = 0; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if (ctxt != NULL) | |
+ ctxt->depth = 0; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
xmlXPathOptimizeExpression(pctxt, &comp->steps[comp->last]); | |
} | |
pctxt->comp = NULL; | |
@@ -14428,8 +14482,12 @@ | |
} else | |
#endif | |
{ | |
- if (ctxt->context != NULL) | |
- ctxt->context->depth = 0; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if (ctxt->context != NULL) | |
+ ctxt->context->depth = 0; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
xmlXPathCompileExpr(ctxt, 1); | |
CHECK_ERROR; | |
@@ -14438,8 +14496,12 @@ | |
XP_ERROR(XPATH_EXPR_ERROR); | |
if ((ctxt->comp->nbStep > 1) && (ctxt->comp->last >= 0)) { | |
- if (ctxt->context != NULL) | |
- ctxt->context->depth = 0; | |
+#ifdef LIBXML_HAS_XPATH_RESOURCE_LIMITS | |
+ if (linkedOnOrAfterFall2022OSVersions()) { | |
+ if (ctxt->context != NULL) | |
+ ctxt->context->depth = 0; | |
+ } | |
+#endif /* LIBXML_HAS_XPATH_RESOURCE_LIMITS */ | |
xmlXPathOptimizeExpression(ctxt, | |
&ctxt->comp->steps[ctxt->comp->last]); | |
} | |
diff -ru libxml2/xpointer.c libxml2-apple/libxml2/xpointer.c | |
--- libxml2/xpointer.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xpointer.c 2025-06-26 01:54:56 | |
@@ -40,11 +40,17 @@ | |
#include <libxml/xmlerror.h> | |
#include <libxml/globals.h> | |
+#ifdef __APPLE__ | |
+#include "xmlversionInternal.h" | |
+#endif | |
+ | |
#ifdef LIBXML_XPTR_ENABLED | |
/* Add support of the xmlns() xpointer scheme to initialize the namespaces */ | |
#define XPTR_XMLNS_SCHEME | |
+#include "private/xpath.h" | |
+ | |
/* #define DEBUG_RANGES */ | |
#ifdef DEBUG_RANGES | |
#ifdef LIBXML_DEBUG_ENABLED | |
@@ -97,11 +103,14 @@ | |
if (ctxt != NULL) | |
ctxt->error = error; | |
if ((ctxt == NULL) || (ctxt->context == NULL)) { | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, | |
NULL, NULL, XML_FROM_XPOINTER, error, | |
XML_ERR_ERROR, NULL, 0, | |
(const char *) extra, NULL, NULL, 0, 0, | |
msg, extra); | |
+#pragma clang diagnostic pop | |
return; | |
} | |
@@ -118,12 +127,15 @@ | |
ctxt->context->error(ctxt->context->userData, | |
&ctxt->context->lastError); | |
} else { | |
+#pragma clang diagnostic push | |
+#pragma clang diagnostic ignored "-Wformat-nonliteral" | |
__xmlRaiseError(NULL, NULL, NULL, | |
NULL, ctxt->context->debugNode, XML_FROM_XPOINTER, | |
error, XML_ERR_ERROR, NULL, 0, | |
(const char *) extra, (const char *) ctxt->base, NULL, | |
ctxt->cur - ctxt->base, 0, | |
msg, extra); | |
+#pragma clang diagnostic pop | |
} | |
} | |
@@ -132,6 +144,7 @@ | |
* A few helper functions for child sequences * | |
* * | |
************************************************************************/ | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
/* xmlXPtrAdvanceNode is a private function, but used by xinclude.c */ | |
xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur, int *level); | |
/** | |
@@ -177,6 +190,7 @@ | |
} | |
return(i); | |
} | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
/** | |
* xmlXPtrGetNthChild: | |
@@ -205,6 +219,7 @@ | |
return(cur); | |
} | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
/************************************************************************ | |
* * | |
* Handling of XPointer specific types * | |
@@ -383,6 +398,11 @@ | |
xmlNodePtr end, int endindex) { | |
xmlXPathObjectPtr ret; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return(NULL); | |
+#endif | |
+ | |
if (start == NULL) | |
return(NULL); | |
if (end == NULL) | |
@@ -410,6 +430,11 @@ | |
xmlXPtrNewRangePoints(xmlXPathObjectPtr start, xmlXPathObjectPtr end) { | |
xmlXPathObjectPtr ret; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return(NULL); | |
+#endif | |
+ | |
if (start == NULL) | |
return(NULL); | |
if (end == NULL) | |
@@ -438,6 +463,11 @@ | |
xmlXPtrNewRangePointNode(xmlXPathObjectPtr start, xmlNodePtr end) { | |
xmlXPathObjectPtr ret; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return(NULL); | |
+#endif | |
+ | |
if (start == NULL) | |
return(NULL); | |
if (end == NULL) | |
@@ -463,6 +493,11 @@ | |
xmlXPtrNewRangeNodePoint(xmlNodePtr start, xmlXPathObjectPtr end) { | |
xmlXPathObjectPtr ret; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return(NULL); | |
+#endif | |
+ | |
if (start == NULL) | |
return(NULL); | |
if (end == NULL) | |
@@ -488,6 +523,11 @@ | |
xmlXPtrNewRangeNodes(xmlNodePtr start, xmlNodePtr end) { | |
xmlXPathObjectPtr ret; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return(NULL); | |
+#endif | |
+ | |
if (start == NULL) | |
return(NULL); | |
if (end == NULL) | |
@@ -510,6 +550,11 @@ | |
xmlXPtrNewCollapsedRange(xmlNodePtr start) { | |
xmlXPathObjectPtr ret; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return(NULL); | |
+#endif | |
+ | |
if (start == NULL) | |
return(NULL); | |
@@ -532,6 +577,11 @@ | |
int endIndex; | |
xmlXPathObjectPtr ret; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return(NULL); | |
+#endif | |
+ | |
if (start == NULL) | |
return(NULL); | |
if (end == NULL) | |
@@ -578,6 +628,11 @@ | |
xmlXPtrLocationSetCreate(xmlXPathObjectPtr val) { | |
xmlLocationSetPtr ret; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return(NULL); | |
+#endif | |
+ | |
ret = (xmlLocationSetPtr) xmlMalloc(sizeof(xmlLocationSet)); | |
if (ret == NULL) { | |
xmlXPtrErrMemory("allocating locationset"); | |
@@ -612,6 +667,11 @@ | |
xmlXPtrLocationSetAdd(xmlLocationSetPtr cur, xmlXPathObjectPtr val) { | |
int i; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return; | |
+#endif | |
+ | |
if ((cur == NULL) || (val == NULL)) return; | |
/* | |
@@ -665,6 +725,11 @@ | |
xmlXPtrLocationSetMerge(xmlLocationSetPtr val1, xmlLocationSetPtr val2) { | |
int i; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return(NULL); | |
+#endif | |
+ | |
if (val1 == NULL) return(NULL); | |
if (val2 == NULL) return(val1); | |
@@ -690,6 +755,11 @@ | |
xmlXPtrLocationSetDel(xmlLocationSetPtr cur, xmlXPathObjectPtr val) { | |
int i; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return; | |
+#endif | |
+ | |
if (cur == NULL) return; | |
if (val == NULL) return; | |
@@ -721,6 +791,11 @@ | |
*/ | |
void | |
xmlXPtrLocationSetRemove(xmlLocationSetPtr cur, int val) { | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return; | |
+#endif | |
+ | |
if (cur == NULL) return; | |
if (val >= cur->locNr) return; | |
cur->locNr--; | |
@@ -739,6 +814,11 @@ | |
xmlXPtrFreeLocationSet(xmlLocationSetPtr obj) { | |
int i; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return; | |
+#endif | |
+ | |
if (obj == NULL) return; | |
if (obj->locTab != NULL) { | |
for (i = 0;i < obj->locNr; i++) { | |
@@ -763,6 +843,11 @@ | |
xmlXPtrNewLocationSetNodes(xmlNodePtr start, xmlNodePtr end) { | |
xmlXPathObjectPtr ret; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return(NULL); | |
+#endif | |
+ | |
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); | |
if (ret == NULL) { | |
xmlXPtrErrMemory("allocating locationset"); | |
@@ -790,6 +875,11 @@ | |
xmlXPtrNewLocationSetNodeSet(xmlNodeSetPtr set) { | |
xmlXPathObjectPtr ret; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return(NULL); | |
+#endif | |
+ | |
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); | |
if (ret == NULL) { | |
xmlXPtrErrMemory("allocating locationset"); | |
@@ -826,6 +916,11 @@ | |
xmlXPtrWrapLocationSet(xmlLocationSetPtr val) { | |
xmlXPathObjectPtr ret; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return(NULL); | |
+#endif | |
+ | |
ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); | |
if (ret == NULL) { | |
xmlXPtrErrMemory("allocating locationset"); | |
@@ -836,6 +931,7 @@ | |
ret->user = (void *) val; | |
return(ret); | |
} | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
/************************************************************************ | |
* * | |
@@ -1062,7 +1158,8 @@ | |
NEXT; | |
SKIP_BLANKS; | |
- xmlXPathRegisterNs(ctxt->context, prefix, ctxt->cur); | |
+ if (xmlXPathRegisterNs(ctxt->context, prefix, ctxt->cur) < 0) | |
+ xmlXPathPErrMemory(ctxt, NULL); | |
ctxt->base = oldBase; | |
ctxt->cur = oldCur; | |
xmlFree(prefix); | |
@@ -1125,12 +1222,14 @@ | |
xmlXPathObjectPtr obj = ctxt->value; | |
switch (obj->type) { | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
case XPATH_LOCATIONSET: { | |
xmlLocationSetPtr loc = ctxt->value->user; | |
if ((loc != NULL) && (loc->locNr > 0)) | |
return; | |
break; | |
} | |
+#endif | |
case XPATH_NODESET: { | |
xmlNodeSetPtr loc = ctxt->value->nodesetval; | |
if ((loc != NULL) && (loc->nodeNr > 0)) | |
@@ -1236,7 +1335,6 @@ | |
ctxt->valueNr = 0; | |
ctxt->valueMax = 10; | |
ctxt->value = NULL; | |
- ctxt->valueFrame = 0; | |
} | |
SKIP_BLANKS; | |
if (CUR == '/') { | |
@@ -1269,6 +1367,7 @@ | |
* * | |
************************************************************************/ | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
static | |
void xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs); | |
static | |
@@ -1283,6 +1382,7 @@ | |
void xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs); | |
static | |
void xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs); | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
/** | |
* xmlXPtrNewContext: | |
@@ -1298,10 +1398,13 @@ | |
xmlXPathContextPtr | |
xmlXPtrNewContext(xmlDocPtr doc, xmlNodePtr here, xmlNodePtr origin) { | |
xmlXPathContextPtr ret; | |
+ (void) here; | |
+ (void) origin; | |
ret = xmlXPathNewContext(doc); | |
if (ret == NULL) | |
return(ret); | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
ret->xptr = 1; | |
ret->here = here; | |
ret->origin = origin; | |
@@ -1320,6 +1423,7 @@ | |
xmlXPtrHereFunction); | |
xmlXPathRegisterFunc(ret, (xmlChar *)" origin", | |
xmlXPtrOriginFunction); | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
return(ret); | |
} | |
@@ -1353,8 +1457,10 @@ | |
xmlXPtrEvalXPointer(ctxt); | |
if ((ctxt->value != NULL) && | |
- (ctxt->value->type != XPATH_NODESET) && | |
- (ctxt->value->type != XPATH_LOCATIONSET)) { | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
+ (ctxt->value->type != XPATH_LOCATIONSET) && | |
+#endif | |
+ (ctxt->value->type != XPATH_NODESET)) { | |
xmlXPtrErr(ctxt, XML_XPTR_EVAL_FAILED, | |
"xmlXPtrEval: evaluation failed to return a node set\n", | |
NULL); | |
@@ -1395,6 +1501,7 @@ | |
return(res); | |
} | |
+#ifdef LIBXML_XPTR_LOCS_ENABLED | |
/** | |
* xmlXPtrBuildRangeNodeList: | |
* @range: a range object | |
@@ -1581,6 +1688,11 @@ | |
xmlNodePtr list = NULL, last = NULL; | |
int i; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return(NULL); | |
+#endif | |
+ | |
if (obj == NULL) | |
return(NULL); | |
switch (obj->type) { | |
@@ -2225,6 +2337,10 @@ | |
void | |
xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, | |
int nargs ATTRIBUTE_UNUSED) { | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return; | |
+#endif | |
XP_ERROR(XPATH_EXPR_ERROR); | |
} | |
@@ -2756,6 +2872,7 @@ | |
*/ | |
tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval); | |
xmlXPathFreeObject(set); | |
+ set = NULL; | |
if (tmp == NULL) { | |
xmlXPathErr(ctxt, XPATH_MEMORY_ERROR); | |
goto error; | |
@@ -2859,6 +2976,11 @@ | |
xmlLocationSetPtr oldset; | |
int i; | |
+#ifdef LIBXML_HAS_XPOINTER_LOCATIONS_DISABLED_AT_RUNTIME | |
+ if (linkedOnOrAfterFall2022OSVersions()) | |
+ return; | |
+#endif | |
+ | |
if (ctxt == NULL) return; | |
SKIP_BLANKS; | |
@@ -2950,6 +3072,7 @@ | |
NEXT; | |
SKIP_BLANKS; | |
} | |
+#endif /* LIBXML_XPTR_LOCS_ENABLED */ | |
#define bottom_xpointer | |
#include "elfgcchack.h" | |
diff -ru libxml2/xzlib.c libxml2-apple/libxml2/xzlib.c | |
--- libxml2/xzlib.c 2025-06-26 02:38:44 | |
+++ libxml2-apple/libxml2/xzlib.c 2025-06-26 01:54:56 | |
@@ -107,15 +107,15 @@ | |
} | |
/* construct error message with path */ | |
- if ((state->msg = | |
- xmlMalloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { | |
- state->err = LZMA_MEM_ERROR; | |
- state->msg = (char *) "out of memory"; | |
- return; | |
+ { | |
+ const size_t msgLength = strlen(state->path) + 2 + strlen(msg) + 1; | |
+ if ((state->msg = xmlMalloc(msgLength)) == NULL) { | |
+ state->err = LZMA_MEM_ERROR; | |
+ state->msg = (char *) "out of memory"; | |
+ return; | |
+ } | |
+ snprintf(state->msg, msgLength, "%s: %s", state->path, msg); | |
} | |
- strcpy(state->msg, state->path); | |
- strcat(state->msg, ": "); | |
- strcat(state->msg, msg); | |
return; | |
} | |
@@ -138,6 +138,7 @@ | |
static xzFile | |
xz_open(const char *path, int fd, const char *mode ATTRIBUTE_UNUSED) | |
{ | |
+ const size_t pathLength = strlen(path) + 1; | |
xz_statep state; | |
/* allocate xzFile structure to return */ | |
@@ -150,12 +151,13 @@ | |
state->init = 0; /* initialization of zlib data */ | |
/* save the path name for error messages */ | |
- state->path = xmlMalloc(strlen(path) + 1); | |
+ state->path = xmlMalloc(pathLength); | |
if (state->path == NULL) { | |
xmlFree(state); | |
return NULL; | |
} | |
- strcpy(state->path, path); | |
+ strncpy(state->path, path, pathLength); | |
+ state->path[pathLength - 1] = '\0'; | |
/* open the file with the appropriate mode (or just use fd) */ | |
state->fd = fd != -1 ? fd : open(path, | |
@@ -220,10 +222,11 @@ | |
{ | |
char *path; /* identifier for error messages */ | |
xzFile xz; | |
+ size_t pathLength = 7 + (3 * sizeof(int)) + 1; | |
- if (fd == -1 || (path = xmlMalloc(7 + 3 * sizeof(int))) == NULL) | |
+ if (fd == -1 || (path = xmlMalloc(pathLength)) == NULL) | |
return NULL; | |
- sprintf(path, "<fd:%d>", fd); /* for debugging */ | |
+ snprintf(path, pathLength, "<fd:%d>", fd); /* for debugging */ | |
xz = xz_open(path, fd, mode); | |
xmlFree(path); | |
return xz; | |
@@ -322,8 +325,12 @@ | |
* If someone complains, this will be reconsidered. | |
*/ | |
if (dict_size != UINT32_MAX) { | |
- uint32_t d = dict_size - 1; | |
+ uint32_t d; | |
+ if (dict_size == 0) | |
+ return 0; | |
+ | |
+ d = dict_size - 1; | |
d |= d >> 2; | |
d |= d >> 3; | |
d |= d >> 4; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment