diff --git a/HTMLparser.c b/HTMLparser.c index 9c3359f..097ed23 100644 --- a/HTMLparser.c +++ b/HTMLparser.c @@ -6841,7 +6841,8 @@ htmlCtxtReadMemory(htmlParserCtxtPtr ctxt, const char *buffer, int size, htmlCtxtReset(ctxt); - input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE); + input = xmlParserInputBufferCreateStatic(buffer, size, + XML_CHAR_ENCODING_NONE); if (input == NULL) { return(NULL); } diff --git a/NEWS b/NEWS index 48e6f78..53d3c74 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,16 @@ NEWS file for libxml2 +v2.12.4: Jan 15 2024 + +### Regressions + +- parser: Fix regression parsing standalone declarations +- autotools: Readd --with-xptr-locs configuration option +- parser: Fix build --without-output +- parser: Don't grow or shrink pull parser memory buffers +- io: Fix memory lifetime issue with input buffers + + v2.12.3: Dec 12 2023 ### Regressions diff --git a/README.md b/README.md index da64486..aa13dc4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ libxml2 Windows build with Visual Studio. -This version is libxml2-2.12.3. +This version is libxml2-2.12.4. Note that LZMA support is only available for VS2013 or later. diff --git a/THIS_VERSION_IS_2.12.3 b/THIS_VERSION_IS_2.12.4 similarity index 100% rename from THIS_VERSION_IS_2.12.3 rename to THIS_VERSION_IS_2.12.4 diff --git a/distfiles/download.url b/distfiles/download.url index 901e945..5a67ae3 100644 --- a/distfiles/download.url +++ b/distfiles/download.url @@ -1 +1 @@ -https://download.gnome.org/sources/libxml2/2.12/libxml2-2.12.3.tar.xz +https://download.gnome.org/sources/libxml2/2.12/libxml2-2.12.4.tar.xz diff --git a/distfiles/libxml2-2.12.3.tar.xz b/distfiles/libxml2-2.12.3.tar.xz deleted file mode 100644 index abca296..0000000 Binary files a/distfiles/libxml2-2.12.3.tar.xz and /dev/null differ diff --git a/distfiles/libxml2-2.12.3-import.lst b/distfiles/libxml2-2.12.4-import.lst similarity index 100% rename from distfiles/libxml2-2.12.3-import.lst rename to distfiles/libxml2-2.12.4-import.lst diff --git a/distfiles/libxml2-2.12.3-import.md5 b/distfiles/libxml2-2.12.4-import.md5 similarity index 93% rename from distfiles/libxml2-2.12.3-import.md5 rename to distfiles/libxml2-2.12.4-import.md5 index 5970c4a..200ee38 100644 --- a/distfiles/libxml2-2.12.3-import.md5 +++ b/distfiles/libxml2-2.12.4-import.md5 @@ -1,8 +1,8 @@ fec7ecfe714722b2bb0aaff7d200c701 Copyright -8274a9d01a67fd01a069f62805127a25 HTMLparser.c +721403e0fda4eada7d113aed94fae756 HTMLparser.c ac5d42c343d2093d2a031f59036c5f99 HTMLtree.c dd63184811cb2ff705c3e466364d3773 INSTALL -da5e67a440cb3ee4e3946ba845eead02 NEWS +30169376fe62b0f94a94e29017dd4ecc NEWS d52aad5f8ace0ed3e5f9b126d72473e1 README.libxml2.md 7283878f36a935a3c00df077cf45af54 SAX.c 15289caf4cf19277a510d22c24238a73 SAX2.c @@ -33,7 +33,7 @@ bc51344e21f8d3b7f0fc93cc9d554243 include/libxml/globals.h 6c03428a747fbfab599d4e86dd17d6b1 include/libxml/list.h d5c907a6d7d205e286168e007f32504c include/libxml/nanoftp.h 3f166ef07a961ee21d3561682d859edc include/libxml/nanohttp.h -ca827023c1dee058837ce0360e88fa3e include/libxml/parser.h +715cf856fa05e7633b1254edfa0a45f4 include/libxml/parser.h 36c2360e8bdaac08bfccba24e461d07f include/libxml/parserInternals.h f1afd2d52bf66fbf45f02dc35c72c3eb include/libxml/pattern.h d752e41ee40c2b028d0adb34ffc38810 include/libxml/relaxng.h @@ -45,7 +45,7 @@ d752e41ee40c2b028d0adb34ffc38810 include/libxml/relaxng.h f26be264a608ed72fb7c74de76e3be72 include/libxml/valid.h d02d257861d28021ad33dad20e2683c3 include/libxml/xinclude.h 4c7ff0fcbc3595d38f47e41f703dbc61 include/libxml/xlink.h -b0ebaf812c8258f5e631287de979d537 include/libxml/xmlIO.h +ef62ebccc685b9bb49f75feab0b2ddd0 include/libxml/xmlIO.h 78602d66c5db00b0deece2c56ab86d43 include/libxml/xmlautomata.h e3fe66a1c3ca6359481c0a4fa25491c6 include/libxml/xmlerror.h dc29dad477ae3b1779f8b15fbae14a0d include/libxml/xmlexports.h @@ -86,8 +86,8 @@ c2b5c54ee40fd7bfba8eb6b9e90d6dbd libxml.h 67985a9e0fc42eebc29d12b884baa00a list.c a9e486124ef2c3a00ecb44001d774484 nanoftp.c a2c34ca6d295906ebc9b56d8e056bf7a nanohttp.c -55cd384ef09aedba5a740cf9cf0f3d2c parser.c -1064b876a87533052e48e7e570c4e670 parserInternals.c +60bd4103a522e93fd7251f692e95a797 parser.c +6aceabaf83db5fda83b670ebfd9785dd parserInternals.c 8809dafc22e8463d81a392ac8a853a59 pattern.c 15a40570e75a1cf9f9da7350f9557b86 relaxng.c b66e180243852be9fa9f97b0722679ba runsuite.c @@ -97,11 +97,11 @@ fc8947f2849d2f27a30318dc3ca831f5 schematron.c c48cacc169fbe69e961ceafbfb92ee71 testModule.c 673cbe4047f34b7d954fd597d46b8716 testThreads.c e85d38ab99ab20ed6649989919e52fbd testapi.c -1b039d4e46c69d01fdfdb0977c18ab4c testchar.c +d665963cfccaa91533d3dfb9f69da42a testchar.c 2792f948169570feeb744ddf0cce5025 testdict.c 6a3e7cbf9864c04639a1a8ac0c388ea2 testdso.c e84fe8d1a9d8ea089bf9ea8544a6ea1b testlimits.c -f4891e39cf0cba64b9b66382d8d2b9fb testparser.c +500ff54f8cee345eb1f3005561ed6dc9 testparser.c f9dd10b6caf75faf002e92b703b36897 testrecurse.c bef5d0bbecbb90f5a441e52bd2f926a2 threads.c 1bcb15667ab695cdd2cc8d5b1bc05169 timsort.h @@ -120,7 +120,7 @@ fd3d55b1d9817a9ef205f35b1d60f527 valid.c 9ca0965eeabe09b4f8d9a1c6c5d8c3b0 win32/libxml2.rc 27b6a7946ac148c1f96755bf442ef0f4 xinclude.c 0a034450d155e35ec8ba99ee2005b695 xlink.c -2bc8d483b5b1a31e73b2f9d3956a973f xmlIO.c +ec9a5e17f4cb2e520e10f5a2d6fc71fc xmlIO.c 28bb81f9966d3ec48c510dd56fa10b94 xmlcatalog.c 77a1978e92525ab506d4f65b895d00cc xmllint.c 47188d0524f25fdb396703aa6d5e1fd6 xmlmemory.c diff --git a/distfiles/libxml2-2.12.4.tar.xz b/distfiles/libxml2-2.12.4.tar.xz new file mode 100644 index 0000000..70ec283 Binary files /dev/null and b/distfiles/libxml2-2.12.4.tar.xz differ diff --git a/include/libxml/parser.h b/include/libxml/parser.h index be8de30..87aacef 100644 --- a/include/libxml/parser.h +++ b/include/libxml/parser.h @@ -859,10 +859,16 @@ XMLPUBFUN const char *const *__xmlParserVersion(void); XML_OP(xmlLoadExtDtdDefaultValue, int, XML_DEPRECATED) \ XML_OP(xmlParserDebugEntities, int, XML_DEPRECATED) \ XML_OP(xmlPedanticParserDefaultValue, int, XML_DEPRECATED) \ - XML_OP(xmlSubstituteEntitiesDefaultValue, int, XML_DEPRECATED) \ - XML_OP(xmlIndentTreeOutput, int, XML_NO_ATTR) \ - XML_OP(xmlTreeIndentString, const char *, XML_NO_ATTR) \ - XML_OP(xmlSaveNoEmptyTags, int, XML_NO_ATTR) + XML_OP(xmlSubstituteEntitiesDefaultValue, int, XML_DEPRECATED) + +#ifdef LIBXML_OUTPUT_ENABLED + #define XML_GLOBALS_PARSER_OUTPUT \ + XML_OP(xmlIndentTreeOutput, int, XML_NO_ATTR) \ + XML_OP(xmlTreeIndentString, const char *, XML_NO_ATTR) \ + XML_OP(xmlSaveNoEmptyTags, int, XML_NO_ATTR) +#else + #define XML_GLOBALS_PARSER_OUTPUT +#endif #ifdef LIBXML_SAX1_ENABLED #define XML_GLOBALS_PARSER_SAX1 \ @@ -873,6 +879,7 @@ XMLPUBFUN const char *const *__xmlParserVersion(void); #define XML_GLOBALS_PARSER \ XML_GLOBALS_PARSER_CORE \ + XML_GLOBALS_PARSER_OUTPUT \ XML_GLOBALS_PARSER_SAX1 #define XML_OP XML_DECLARE_GLOBAL @@ -896,9 +903,11 @@ XML_GLOBALS_PARSER XML_GLOBAL_MACRO(xmlPedanticParserDefaultValue) #define xmlSubstituteEntitiesDefaultValue \ XML_GLOBAL_MACRO(xmlSubstituteEntitiesDefaultValue) - #define xmlIndentTreeOutput XML_GLOBAL_MACRO(xmlIndentTreeOutput) - #define xmlTreeIndentString XML_GLOBAL_MACRO(xmlTreeIndentString) - #define xmlSaveNoEmptyTags XML_GLOBAL_MACRO(xmlSaveNoEmptyTags) + #ifdef LIBXML_OUTPUT_ENABLED + #define xmlIndentTreeOutput XML_GLOBAL_MACRO(xmlIndentTreeOutput) + #define xmlTreeIndentString XML_GLOBAL_MACRO(xmlTreeIndentString) + #define xmlSaveNoEmptyTags XML_GLOBAL_MACRO(xmlSaveNoEmptyTags) + #endif #endif /** DOC_ENABLE */ diff --git a/include/libxml/xmlIO.h b/include/libxml/xmlIO.h index eaea076..2487be3 100644 --- a/include/libxml/xmlIO.h +++ b/include/libxml/xmlIO.h @@ -218,7 +218,6 @@ XMLPUBFUN xmlParserInputBufferPtr XMLPUBFUN xmlParserInputBufferPtr xmlParserInputBufferCreateMem (const char *mem, int size, xmlCharEncoding enc); -XML_DEPRECATED XMLPUBFUN xmlParserInputBufferPtr xmlParserInputBufferCreateStatic (const char *mem, int size, xmlCharEncoding enc); diff --git a/include/libxml/xmlversion.h b/include/libxml/xmlversion.h index 258c3ca..1a9eaa6 100644 --- a/include/libxml/xmlversion.h +++ b/include/libxml/xmlversion.h @@ -29,21 +29,21 @@ XMLPUBFUN void xmlCheckVersion(int version); * * the version string like "1.2.3" */ -#define LIBXML_DOTTED_VERSION "2.12.3" +#define LIBXML_DOTTED_VERSION "2.12.4" /** * LIBXML_VERSION: * * the version number: 1.2.3 value is 10203 */ -#define LIBXML_VERSION 21203 +#define LIBXML_VERSION 21204 /** * LIBXML_VERSION_STRING: * * the version number string, 1.2.3 value is "10203" */ -#define LIBXML_VERSION_STRING "21203" +#define LIBXML_VERSION_STRING "21204" /** * LIBXML_VERSION_EXTRA: @@ -58,7 +58,7 @@ XMLPUBFUN void xmlCheckVersion(int version); * Macro to check that the libxml version in use is compatible with * the version the software has been compiled against */ -#define LIBXML_TEST_VERSION xmlCheckVersion(21203); +#define LIBXML_TEST_VERSION xmlCheckVersion(21204); #ifndef VMS #if 0 diff --git a/parser.c b/parser.c index e3587dc..0897af8 100644 --- a/parser.c +++ b/parser.c @@ -208,8 +208,7 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt, const xmlChar *ID, xmlNodePtr *list); static int -xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, - const char *encoding); +xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options); #ifdef LIBXML_LEGACY_ENABLED static void xmlAddEntityReference(xmlEntityPtr ent, xmlNodePtr firstNode, @@ -13238,7 +13237,7 @@ xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen, } } - xmlCtxtUseOptionsInternal(ctxt, options, NULL); + xmlCtxtUseOptionsInternal(ctxt, options); xmlDetectSAX2(ctxt); ctxt->myDoc = doc; /* parsing in context, i.e. as within existing content */ @@ -13415,7 +13414,7 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax, newDoc->dict = ctxt->dict; xmlDictReference(newDoc->dict); } else { - xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT, NULL); + xmlCtxtUseOptionsInternal(ctxt, XML_PARSE_NODICT); } /* doc == NULL is only supported for historic reasons */ if (doc != NULL) { @@ -13700,7 +13699,7 @@ xmlCreateURLParserCtxt(const char *filename, int options) } if (options) - xmlCtxtUseOptionsInternal(ctxt, options, NULL); + xmlCtxtUseOptionsInternal(ctxt, options); ctxt->linenumbers = 1; inputStream = xmlLoadExternalEntity(filename, NULL, ctxt); @@ -14557,15 +14556,10 @@ xmlCtxtResetPush(xmlParserCtxtPtr ctxt, const char *chunk, * in case of error. */ static int -xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encoding) +xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options) { if (ctxt == NULL) return(-1); - if (encoding != NULL) { - if (ctxt->encoding != NULL) - xmlFree((xmlChar *) ctxt->encoding); - ctxt->encoding = xmlStrdup((const xmlChar *) encoding); - } if (options & XML_PARSE_RECOVER) { ctxt->recovery = 1; options -= XML_PARSE_RECOVER; @@ -14698,7 +14692,7 @@ xmlCtxtUseOptionsInternal(xmlParserCtxtPtr ctxt, int options, const char *encodi int xmlCtxtUseOptions(xmlParserCtxtPtr ctxt, int options) { - return(xmlCtxtUseOptionsInternal(ctxt, options, NULL)); + return(xmlCtxtUseOptionsInternal(ctxt, options)); } /** @@ -14738,7 +14732,7 @@ xmlDoRead(xmlParserCtxtPtr ctxt, const char *URL, const char *encoding, { xmlDocPtr ret; - xmlCtxtUseOptionsInternal(ctxt, options, encoding); + xmlCtxtUseOptionsInternal(ctxt, options); if (encoding != NULL) { xmlCharEncodingHandlerPtr hdlr; @@ -15040,7 +15034,8 @@ xmlCtxtReadMemory(xmlParserCtxtPtr ctxt, const char *buffer, int size, xmlCtxtReset(ctxt); - input = xmlParserInputBufferCreateMem(buffer, size, XML_CHAR_ENCODING_NONE); + input = xmlParserInputBufferCreateStatic(buffer, size, + XML_CHAR_ENCODING_NONE); if (input == NULL) { return(NULL); } diff --git a/parserInternals.c b/parserInternals.c index 5be1d06..e6b4cb1 100644 --- a/parserInternals.c +++ b/parserInternals.c @@ -520,6 +520,9 @@ xmlParserGrow(xmlParserCtxtPtr ctxt) { /* Don't grow push parser buffer. */ if ((ctxt->progressive) && (ctxt->inputNr <= 1)) return(0); + /* Don't grow memory buffers. */ + if ((buf->encoder == NULL) && (buf->readcallback == NULL)) + return(0); if (buf->error != 0) return(-1); @@ -571,6 +574,10 @@ xmlParserInputGrow(xmlParserInputPtr in, int len) { if (in->cur == NULL) return(-1); if (in->buf->buffer == NULL) return(-1); + /* Don't grow memory buffers. */ + if ((in->buf->encoder == NULL) && (in->buf->readcallback == NULL)) + return(0); + indx = in->cur - in->base; if (xmlBufUse(in->buf->buffer) > (unsigned int) indx + INPUT_CHUNK) { return(0); @@ -604,6 +611,11 @@ xmlParserShrink(xmlParserCtxtPtr ctxt) { if (buf == NULL) return; + /* Don't shrink pull parser memory buffers. */ + if (((ctxt->progressive == 0) || (ctxt->inputNr > 1)) && + (buf->encoder == NULL) && + (buf->readcallback == NULL)) + return; used = in->cur - in->base; /* diff --git a/testchar.c b/testchar.c index 8895d8d..f4b2f4f 100644 --- a/testchar.c +++ b/testchar.c @@ -648,8 +648,8 @@ static int testCharRanges(void) { fprintf(stderr, "Failed to allocate parser context\n"); return(1); } - buf = xmlParserInputBufferCreateMem(data, sizeof(data), - XML_CHAR_ENCODING_NONE); + buf = xmlParserInputBufferCreateStatic(data, sizeof(data), + XML_CHAR_ENCODING_NONE); if (buf == NULL) { fprintf(stderr, "Failed to allocate input buffer\n"); test_ret = 1; diff --git a/testparser.c b/testparser.c index 625ba10..e67cea5 100644 --- a/testparser.c +++ b/testparser.c @@ -6,6 +6,26 @@ #include +static int +testStandaloneWithEncoding(void) { + xmlDocPtr doc; + const char *str = + "\n" + "\n"; + int err = 0; + + xmlResetLastError(); + + doc = xmlReadDoc(BAD_CAST str, NULL, "UTF-8", 0); + if (doc == NULL) { + fprintf(stderr, "xmlReadDoc failed\n"); + err = 1; + } + xmlFreeDoc(doc); + + return err; +} + #ifdef LIBXML_PUSH_ENABLED static int testHugePush(void) { @@ -70,6 +90,7 @@ int main(void) { int err = 0; + err |= testStandaloneWithEncoding(); #ifdef LIBXML_PUSH_ENABLED err |= testHugePush(); err |= testHugeEncodedChunk(); diff --git a/win32/rcVersion.h b/win32/rcVersion.h index 64d27d1..c582668 100644 --- a/win32/rcVersion.h +++ b/win32/rcVersion.h @@ -1,4 +1,4 @@ #define LIBXML_MAJOR_VERSION 2 #define LIBXML_MINOR_VERSION 12 -#define LIBXML_MICRO_VERSION 3 -#define LIBXML_DOTTED_VERSION "2.12.3" +#define LIBXML_MICRO_VERSION 4 +#define LIBXML_DOTTED_VERSION "2.12.4" diff --git a/xmlIO.c b/xmlIO.c index b1ff0df..22acb59 100644 --- a/xmlIO.c +++ b/xmlIO.c @@ -2849,7 +2849,8 @@ xmlParserInputBufferCreateFd(int fd, xmlCharEncoding enc) { } typedef struct { - const char *mem; + char *mem; + const char *cur; size_t size; } xmlMemIOCtxt; @@ -2860,8 +2861,8 @@ xmlMemRead(void *vctxt, char *buf, int size) { if ((size_t) size > ctxt->size) size = ctxt->size; - memcpy(buf, ctxt->mem, size); - ctxt->mem += size; + memcpy(buf, ctxt->cur, size); + ctxt->cur += size; ctxt->size -= size; return size; @@ -2869,7 +2870,11 @@ xmlMemRead(void *vctxt, char *buf, int size) { static int xmlMemClose(void *vctxt) { - xmlFree(vctxt); + xmlMemIOCtxt *ctxt = vctxt; + + if (ctxt->mem != 0) + xmlFree(ctxt->mem); + xmlFree(ctxt); return(0); } @@ -2879,36 +2884,42 @@ xmlMemClose(void *vctxt) { * @size: the length of the memory block * @enc: the charset encoding if known * - * Create a buffered parser input for the progressive parsing for the input - * from a memory area. + * Create a parser input buffer for parsing from a memory area. * - * Returns the new parser input or NULL + * This function makes a copy of the whole input buffer. If you are sure + * that the contents of the buffer will remain valid until the document + * was parsed, you can avoid the copy by using + * xmlParserInputBufferCreateStatic. + * + * The encoding argument is deprecated and should be set to + * XML_CHAR_ENCODING_NONE. The encoding can be changed with + * xmlSwitchEncoding or xmlSwitchEncodingName later on. + * + * Returns the new parser input or NULL in case of error. */ xmlParserInputBufferPtr xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) { - xmlParserInputBufferPtr ret; + xmlParserInputBufferPtr buf; xmlMemIOCtxt *ctxt; + char *copy; - if (size < 0) return(NULL); - if (mem == NULL) return(NULL); + if ((size < 0) || (mem == NULL)) + return(NULL); - ret = xmlAllocParserInputBuffer(enc); - if (ret == NULL) + copy = (char *) xmlStrndup((const xmlChar *) mem, size); + if (copy == NULL) return(NULL); - ctxt = xmlMalloc(sizeof(*ctxt)); - if (ctxt == NULL) { - xmlFreeParserInputBuffer(ret); + buf = xmlParserInputBufferCreateStatic(copy, size, enc); + if (buf == NULL) { + xmlFree(copy); return(NULL); } - ctxt->mem = mem; - ctxt->size = size; - ret->context = ctxt; - ret->readcallback = xmlMemRead; - ret->closecallback = xmlMemClose; + ctxt = buf->context; + ctxt->mem = copy; - return(ret); + return(buf); } /** @@ -2917,14 +2928,45 @@ xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) { * @size: the length of the memory block * @enc: the charset encoding if known * - * DEPRECATED: Use xmlParserInputBufferCreateMem. + * Create a parser input buffer for parsing from a memory area. * - * Returns the new parser input or NULL + * This functions assumes that the contents of the input buffer remain + * valid until the document was parsed. Use xmlParserInputBufferCreateMem + * otherwise. + * + * The encoding argument is deprecated and should be set to + * XML_CHAR_ENCODING_NONE. The encoding can be changed with + * xmlSwitchEncoding or xmlSwitchEncodingName later on. + * + * Returns the new parser input or NULL in case of error. */ xmlParserInputBufferPtr xmlParserInputBufferCreateStatic(const char *mem, int size, xmlCharEncoding enc) { - return(xmlParserInputBufferCreateMem(mem, size, enc)); + xmlParserInputBufferPtr ret; + xmlMemIOCtxt *ctxt; + + if ((size < 0) || (mem == NULL)) + return(NULL); + + ret = xmlAllocParserInputBuffer(enc); + if (ret == NULL) + return(NULL); + + ctxt = xmlMalloc(sizeof(*ctxt)); + if (ctxt == NULL) { + xmlFreeParserInputBuffer(ret); + return(NULL); + } + ctxt->mem = NULL; + ctxt->cur = mem; + ctxt->size = size; + + ret->context = ctxt; + ret->readcallback = xmlMemRead; + ret->closecallback = xmlMemClose; + + return(ret); } typedef struct {