From: Bruno Haible Date: Sun, 28 Apr 2019 11:13:46 +0000 (+0200) Subject: libxml: Update included libxml2 to version 2.9.9. X-Git-Tag: v0.20~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e4c914eeb97f42aaa8bbe4d4245b6e6d7357e3c6;p=thirdparty%2Fgettext.git libxml: Update included libxml2 to version 2.9.9. * gnulib-local/lib/libxml/*: Update from libxml2 2.9.9. * gnulib-local/m4/libxml.m4 (gl_LIBXML): Don't test for _stat. --- diff --git a/gnulib-local/lib/libxml/HTMLparser.c b/gnulib-local/lib/libxml/HTMLparser.c index b7291972e..9e60e27ec 100644 --- a/gnulib-local/lib/libxml/HTMLparser.c +++ b/gnulib-local/lib/libxml/HTMLparser.c @@ -26,7 +26,7 @@ #ifdef HAVE_UNISTD_H #include #endif -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED #include #endif @@ -105,7 +105,7 @@ htmlErrMemory(xmlParserCtxtPtr ctxt, const char *extra) * * Handle a fatal parser error, i.e. violating Well-Formedness constraints */ -static void +static void LIBXML_ATTR_FORMAT(3,0) htmlParseErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar *str1, const xmlChar *str2) { @@ -132,7 +132,7 @@ htmlParseErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, * * Handle a fatal parser error, i.e. violating Well-Formedness constraints */ -static void +static void LIBXML_ATTR_FORMAT(3,0) htmlParseErrInt(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, int val) { @@ -303,6 +303,7 @@ htmlNodeInfoPop(htmlParserCtxtPtr ctxt) #define UPP(val) (toupper(ctxt->input->cur[(val)])) #define CUR_PTR ctxt->input->cur +#define BASE_PTR ctxt->input->base #define SHRINK if ((ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \ (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \ @@ -1083,7 +1084,7 @@ static const char * const htmlStartClose[] = { "menu", "p", "head", "ul", NULL, "p", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6", FONTSTYLE, NULL, "div", "p", "head", NULL, -"noscript", "p", NULL, +"noscript", "script", NULL, "center", "font", "b", "i", "p", "head", NULL, "a", "a", "head", NULL, "caption", "p", NULL, @@ -2471,6 +2472,10 @@ htmlParseName(htmlParserCtxtPtr ctxt) { (*in == '_') || (*in == '-') || (*in == ':') || (*in == '.')) in++; + + if (in == ctxt->input->end) + return(NULL); + if ((*in > 0) && (*in < 0x80)) { count = in - ctxt->input->cur; ret = xmlDictLookup(ctxt->dict, ctxt->input->cur, count); @@ -2488,6 +2493,7 @@ htmlParseNameComplex(xmlParserCtxtPtr ctxt) { int len = 0, l; int c; int count = 0; + const xmlChar *base = ctxt->input->base; /* * Handler for more complex cases @@ -2513,7 +2519,22 @@ htmlParseNameComplex(xmlParserCtxtPtr ctxt) { len += l; NEXTL(l); c = CUR_CHAR(l); + if (ctxt->input->base != base) { + /* + * We changed encoding from an unknown encoding + * Input buffer changed location, so we better start again + */ + return(htmlParseNameComplex(ctxt)); + } } + + if (ctxt->input->cur - ctxt->input->base < len) { + /* Sanity check */ + htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR, + "unexpected change of input buffer", NULL, NULL); + return (NULL); + } + return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len)); } @@ -2765,31 +2786,43 @@ htmlParseAttValue(htmlParserCtxtPtr ctxt) { static xmlChar * htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) { - const xmlChar *q; + size_t len = 0, startPosition = 0; xmlChar *ret = NULL; if (CUR == '"') { NEXT; - q = CUR_PTR; - while ((IS_CHAR_CH(CUR)) && (CUR != '"')) + + if (CUR_PTR < BASE_PTR) + return(ret); + startPosition = CUR_PTR - BASE_PTR; + + while ((IS_CHAR_CH(CUR)) && (CUR != '"')) { NEXT; + len++; + } if (!IS_CHAR_CH(CUR)) { htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, "Unfinished SystemLiteral\n", NULL, NULL); } else { - ret = xmlStrndup(q, CUR_PTR - q); + ret = xmlStrndup((BASE_PTR+startPosition), len); NEXT; } } else if (CUR == '\'') { NEXT; - q = CUR_PTR; - while ((IS_CHAR_CH(CUR)) && (CUR != '\'')) + + if (CUR_PTR < BASE_PTR) + return(ret); + startPosition = CUR_PTR - BASE_PTR; + + while ((IS_CHAR_CH(CUR)) && (CUR != '\'')) { NEXT; + len++; + } if (!IS_CHAR_CH(CUR)) { htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, "Unfinished SystemLiteral\n", NULL, NULL); } else { - ret = xmlStrndup(q, CUR_PTR - q); + ret = xmlStrndup((BASE_PTR+startPosition), len); NEXT; } } else { @@ -2813,32 +2846,47 @@ htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) { static xmlChar * htmlParsePubidLiteral(htmlParserCtxtPtr ctxt) { - const xmlChar *q; + size_t len = 0, startPosition = 0; xmlChar *ret = NULL; /* * Name ::= (Letter | '_') (NameChar)* */ if (CUR == '"') { NEXT; - q = CUR_PTR; - while (IS_PUBIDCHAR_CH(CUR)) NEXT; + + if (CUR_PTR < BASE_PTR) + return(ret); + startPosition = CUR_PTR - BASE_PTR; + + while (IS_PUBIDCHAR_CH(CUR)) { + len++; + NEXT; + } + if (CUR != '"') { htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, "Unfinished PubidLiteral\n", NULL, NULL); } else { - ret = xmlStrndup(q, CUR_PTR - q); + ret = xmlStrndup((BASE_PTR + startPosition), len); NEXT; } } else if (CUR == '\'') { NEXT; - q = CUR_PTR; - while ((IS_PUBIDCHAR_CH(CUR)) && (CUR != '\'')) - NEXT; + + if (CUR_PTR < BASE_PTR) + return(ret); + startPosition = CUR_PTR - BASE_PTR; + + while ((IS_PUBIDCHAR_CH(CUR)) && (CUR != '\'')){ + len++; + NEXT; + } + if (CUR != '\'') { htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, "Unfinished PubidLiteral\n", NULL, NULL); } else { - ret = xmlStrndup(q, CUR_PTR - q); + ret = xmlStrndup((BASE_PTR + startPosition), len); NEXT; } } else { @@ -3588,12 +3636,12 @@ htmlCheckEncodingDirect(htmlParserCtxtPtr ctxt, const xmlChar *encoding) { processed = ctxt->input->cur - ctxt->input->base; xmlBufShrink(ctxt->input->buf->buffer, processed); nbchars = xmlCharEncInput(ctxt->input->buf, 1); + xmlBufResetInput(ctxt->input->buf->buffer, ctxt->input); if (nbchars < 0) { htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING, "htmlCheckEncoding: encoder error\n", NULL, NULL); } - xmlBufResetInput(ctxt->input->buf->buffer, ctxt->input); } } } @@ -4400,7 +4448,7 @@ static void htmlParseElementInternal(htmlParserCtxtPtr ctxt) { const xmlChar *name; const htmlElemDesc * info; - htmlParserNodeInfo node_info = { 0, }; + htmlParserNodeInfo node_info = { NULL, 0, 0, 0, 0 }; int failed; if ((ctxt == NULL) || (ctxt->input == NULL)) { @@ -4897,6 +4945,7 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt) ctxt->wellFormed = 1; ctxt->replaceEntities = 0; ctxt->linenumbers = xmlLineNumbersDefaultValue; + ctxt->keepBlanks = xmlKeepBlanksDefaultValue; ctxt->html = 1; ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_0; ctxt->vctxt.userData = ctxt; @@ -6229,7 +6278,8 @@ htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data, */ htmlDocPtr -htmlSAXParseDoc(xmlChar *cur, const char *encoding, htmlSAXHandlerPtr sax, void *userData) { +htmlSAXParseDoc(const xmlChar *cur, const char *encoding, + htmlSAXHandlerPtr sax, void *userData) { htmlDocPtr ret; htmlParserCtxtPtr ctxt; @@ -6268,7 +6318,7 @@ htmlSAXParseDoc(xmlChar *cur, const char *encoding, htmlSAXHandlerPtr sax, void */ htmlDocPtr -htmlParseDoc(xmlChar *cur, const char *encoding) { +htmlParseDoc(const xmlChar *cur, const char *encoding) { return(htmlSAXParseDoc(cur, encoding, NULL, NULL)); } @@ -6537,7 +6587,7 @@ htmlNodeStatus(const htmlNodePtr node, int legacy) { * DICT_FREE: * @str: a string * - * Free a string if it is not owned by the "dict" dictionnary in the + * Free a string if it is not owned by the "dict" dictionary in the * current scope */ #define DICT_FREE(str) \ @@ -6624,7 +6674,7 @@ htmlCtxtReset(htmlParserCtxtPtr ctxt) xmlInitNodeInfoSeq(&ctxt->node_seq); if (ctxt->attsDefault != NULL) { - xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree); + xmlHashFree(ctxt->attsDefault, xmlHashDefaultDeallocator); ctxt->attsDefault = NULL; } if (ctxt->attsSpecial != NULL) { diff --git a/gnulib-local/lib/libxml/HTMLparser.in.h b/gnulib-local/lib/libxml/HTMLparser.in.h index 551186cb0..1d4fec2f7 100644 --- a/gnulib-local/lib/libxml/HTMLparser.in.h +++ b/gnulib-local/lib/libxml/HTMLparser.in.h @@ -115,12 +115,12 @@ XMLPUBFUN htmlParserCtxtPtr XMLCALL XMLPUBFUN int XMLCALL htmlParseDocument(htmlParserCtxtPtr ctxt); XMLPUBFUN htmlDocPtr XMLCALL - htmlSAXParseDoc (xmlChar *cur, + htmlSAXParseDoc (const xmlChar *cur, const char *encoding, htmlSAXHandlerPtr sax, void *userData); XMLPUBFUN htmlDocPtr XMLCALL - htmlParseDoc (xmlChar *cur, + htmlParseDoc (const xmlChar *cur, const char *encoding); XMLPUBFUN htmlDocPtr XMLCALL htmlSAXParseFile(const char *filename, diff --git a/gnulib-local/lib/libxml/HTMLtree.c b/gnulib-local/lib/libxml/HTMLtree.c index 2fd0c9c56..21cfcfe59 100644 --- a/gnulib-local/lib/libxml/HTMLtree.c +++ b/gnulib-local/lib/libxml/HTMLtree.c @@ -502,16 +502,16 @@ htmlNodeDumpFileFormat(FILE *out, xmlDocPtr doc, if (handler == NULL) htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding); } + } else { + /* + * Fallback to HTML or ASCII when the encoding is unspecified + */ + if (handler == NULL) + handler = xmlFindCharEncodingHandler("HTML"); + if (handler == NULL) + handler = xmlFindCharEncodingHandler("ascii"); } - /* - * Fallback to HTML or ASCII when the encoding is unspecified - */ - if (handler == NULL) - handler = xmlFindCharEncodingHandler("HTML"); - if (handler == NULL) - handler = xmlFindCharEncodingHandler("ascii"); - /* * save the content to a temp buffer. */ @@ -570,33 +570,22 @@ htmlDocDumpMemoryFormat(xmlDocPtr cur, xmlChar**mem, int *size, int format) { xmlCharEncoding enc; enc = xmlParseCharEncoding(encoding); - if (enc != cur->charset) { - if (cur->charset != XML_CHAR_ENCODING_UTF8) { - /* - * Not supported yet - */ - *mem = NULL; - *size = 0; - return; - } - + if (enc != XML_CHAR_ENCODING_UTF8) { handler = xmlFindCharEncodingHandler(encoding); if (handler == NULL) htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding); - } else { - handler = xmlFindCharEncodingHandler(encoding); } + } else { + /* + * Fallback to HTML or ASCII when the encoding is unspecified + */ + if (handler == NULL) + handler = xmlFindCharEncodingHandler("HTML"); + if (handler == NULL) + handler = xmlFindCharEncodingHandler("ascii"); } - /* - * Fallback to HTML or ASCII when the encoding is unspecified - */ - if (handler == NULL) - handler = xmlFindCharEncodingHandler("HTML"); - if (handler == NULL) - handler = xmlFindCharEncodingHandler("ascii"); - buf = xmlAllocOutputBufferInternal(handler); if (buf == NULL) { *mem = NULL; @@ -1101,30 +1090,21 @@ htmlDocDump(FILE *f, xmlDocPtr cur) { xmlCharEncoding enc; enc = xmlParseCharEncoding(encoding); - if (enc != cur->charset) { - if (cur->charset != XML_CHAR_ENCODING_UTF8) { - /* - * Not supported yet - */ - return(-1); - } - + if (enc != XML_CHAR_ENCODING_UTF8) { handler = xmlFindCharEncodingHandler(encoding); if (handler == NULL) htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding); - } else { - handler = xmlFindCharEncodingHandler(encoding); } + } else { + /* + * Fallback to HTML or ASCII when the encoding is unspecified + */ + if (handler == NULL) + handler = xmlFindCharEncodingHandler("HTML"); + if (handler == NULL) + handler = xmlFindCharEncodingHandler("ascii"); } - /* - * Fallback to HTML or ASCII when the encoding is unspecified - */ - if (handler == NULL) - handler = xmlFindCharEncodingHandler("HTML"); - if (handler == NULL) - handler = xmlFindCharEncodingHandler("ascii"); - buf = xmlOutputBufferCreateFile(f, handler); if (buf == NULL) return(-1); htmlDocContentDumpOutput(buf, cur, NULL); @@ -1160,28 +1140,21 @@ htmlSaveFile(const char *filename, xmlDocPtr cur) { xmlCharEncoding enc; enc = xmlParseCharEncoding(encoding); - if (enc != cur->charset) { - if (cur->charset != XML_CHAR_ENCODING_UTF8) { - /* - * Not supported yet - */ - return(-1); - } - + if (enc != XML_CHAR_ENCODING_UTF8) { handler = xmlFindCharEncodingHandler(encoding); if (handler == NULL) htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding); } + } else { + /* + * Fallback to HTML or ASCII when the encoding is unspecified + */ + if (handler == NULL) + handler = xmlFindCharEncodingHandler("HTML"); + if (handler == NULL) + handler = xmlFindCharEncodingHandler("ascii"); } - /* - * Fallback to HTML or ASCII when the encoding is unspecified - */ - if (handler == NULL) - handler = xmlFindCharEncodingHandler("HTML"); - if (handler == NULL) - handler = xmlFindCharEncodingHandler("ascii"); - /* * save the content to a temp buffer. */ @@ -1221,14 +1194,7 @@ htmlSaveFileFormat(const char *filename, xmlDocPtr cur, xmlCharEncoding enc; enc = xmlParseCharEncoding(encoding); - if (enc != cur->charset) { - if (cur->charset != XML_CHAR_ENCODING_UTF8) { - /* - * Not supported yet - */ - return(-1); - } - + if (enc != XML_CHAR_ENCODING_UTF8) { handler = xmlFindCharEncodingHandler(encoding); if (handler == NULL) htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding); @@ -1236,15 +1202,15 @@ htmlSaveFileFormat(const char *filename, xmlDocPtr cur, htmlSetMetaEncoding(cur, (const xmlChar *) encoding); } else { htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8"); - } - /* - * Fallback to HTML or ASCII when the encoding is unspecified - */ - if (handler == NULL) - handler = xmlFindCharEncodingHandler("HTML"); - if (handler == NULL) - handler = xmlFindCharEncodingHandler("ascii"); + /* + * Fallback to HTML or ASCII when the encoding is unspecified + */ + if (handler == NULL) + handler = xmlFindCharEncodingHandler("HTML"); + if (handler == NULL) + handler = xmlFindCharEncodingHandler("ascii"); + } /* * save the content to a temp buffer. diff --git a/gnulib-local/lib/libxml/SAX2.c b/gnulib-local/lib/libxml/SAX2.c index ffef3e146..7642501a1 100644 --- a/gnulib-local/lib/libxml/SAX2.c +++ b/gnulib-local/lib/libxml/SAX2.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -55,7 +56,7 @@ * @ctxt: an XML validation parser context * @msg: a string to accompany the error message */ -static void +static void LIBXML_ATTR_FORMAT(2,0) xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) { xmlStructuredErrorFunc schannel = NULL; const char *str1 = "out of memory\n"; @@ -93,7 +94,7 @@ xmlSAX2ErrMemory(xmlParserCtxtPtr ctxt, const char *msg) { * * Handle a validation error */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const char *str1, const char *str2) { @@ -133,7 +134,7 @@ xmlErrValid(xmlParserCtxtPtr ctxt, xmlParserErrors error, * * Handle a fatal parser error, i.e. violating Well-Formedness constraints */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar *str1, const xmlChar *str2) { @@ -164,7 +165,7 @@ xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, * * Handle a parser warning */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar *str1) { @@ -189,7 +190,7 @@ xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, * * Handle a namespace error */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar *str1, const xmlChar *str2) { @@ -213,7 +214,7 @@ xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, * * Handle a namespace warning */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlNsWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar *str1, const xmlChar *str2) { @@ -1181,6 +1182,8 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname, xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement"); if (name != NULL) xmlFree(name); + if (nval != NULL) + xmlFree(nval); return; } } else { @@ -1242,6 +1245,8 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname, xmlFree(ns); if (name != NULL) xmlFree(name); + if (nval != NULL) + xmlFree(nval); return; } } else { @@ -1311,6 +1316,8 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname, name, namespace->href); ctxt->wellFormed = 0; if (ctxt->recovery == 0) ctxt->disableSAX = 1; + if (name != NULL) + xmlFree(name); goto error; } } @@ -1658,7 +1665,11 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts) #ifdef DEBUG_SAX_TREE xmlGenericError(xmlGenericErrorContext, "pushing(%s)\n", name); #endif - nodePush(ctxt, ret); + if (nodePush(ctxt, ret) < 0) { + xmlUnlinkNode(ret); + xmlFreeNode(ret); + return; + } /* * Link the child element @@ -1908,7 +1919,7 @@ skip: else { ret->line = 65535; if (ctxt->options & XML_PARSE_BIG_LINES) - ret->psvi = (void *) (long) ctxt->input->line; + ret->psvi = (void *) (ptrdiff_t) ctxt->input->line; } } } @@ -2250,6 +2261,7 @@ xmlSAX2StartElementNs(void *ctx, ctxt->freeElems = ret->next; ctxt->freeElemsNr--; memset(ret, 0, sizeof(xmlNode)); + ret->doc = ctxt->myDoc; ret->type = XML_ELEMENT_NODE; if (ctxt->dictNames) @@ -2311,7 +2323,7 @@ xmlSAX2StartElementNs(void *ctx, } else { /* * any out of memory error would already have been raised - * but we can't be garanteed it's the actual error due to the + * but we can't be guaranteed it's the actual error due to the * API, best is to skip in this case */ continue; @@ -2329,7 +2341,11 @@ xmlSAX2StartElementNs(void *ctx, /* * We are parsing a new node. */ - nodePush(ctxt, ret); + if (nodePush(ctxt, ret) < 0) { + xmlUnlinkNode(ret); + xmlFreeNode(ret); + return; + } /* * Link the child element @@ -2805,7 +2821,8 @@ xmlSAX2CDataBlock(void *ctx, const xmlChar *value, int len) xmlTextConcat(lastChild, value, len); } else { ret = xmlNewCDataBlock(ctxt->myDoc, value, len); - xmlAddChild(ctxt->node, ret); + if (xmlAddChild(ctxt->node, ret) == NULL) + xmlFreeNode(ret); } } diff --git a/gnulib-local/lib/libxml/buf.c b/gnulib-local/lib/libxml/buf.c index 07922ff69..21cb9d804 100644 --- a/gnulib-local/lib/libxml/buf.c +++ b/gnulib-local/lib/libxml/buf.c @@ -49,7 +49,7 @@ struct _xmlBuf { size_t use; /* The buffer size used */ size_t size; /* The buffer size */ xmlBufferPtr buffer; /* wrapper for an old buffer */ - int error; /* an error code if a failure occured */ + int error; /* an error code if a failure occurred */ }; #ifdef WITH_BUFFER_COMPAT @@ -231,7 +231,7 @@ xmlBufPtr xmlBufCreateStatic(void *mem, size_t size) { xmlBufPtr ret; - if ((mem == NULL) || (size == 0)) + if (mem == NULL) return(NULL); ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf)); @@ -701,7 +701,7 @@ xmlBufUse(const xmlBufPtr buf) * used in the buffer. It does not account for the terminating zero * usually needed * - * Returns the amount or 0 if none or an error occured + * Returns the amount or 0 if none or an error occurred */ size_t diff --git a/gnulib-local/lib/libxml/c14n.c b/gnulib-local/lib/libxml/c14n.c index ca77f922a..d80ae8b7a 100644 --- a/gnulib-local/lib/libxml/c14n.c +++ b/gnulib-local/lib/libxml/c14n.c @@ -89,7 +89,7 @@ static int xmlExcC14NVisibleNsStackFind (xmlC14NVisibleNsStackPtr cur, xmlNsPtr ns, xmlC14NCtxPtr ctx); -static int xmlC14NIsNodeInNodeset (xmlNodeSetPtr nodes, +static int xmlC14NIsNodeInNodeset (void *user_data, xmlNodePtr node, xmlNodePtr parent); @@ -252,7 +252,8 @@ xmlC14NErr(xmlC14NCtxPtr ctxt, xmlNodePtr node, int error, #define XML_NAMESPACES_DEFAULT 16 static int -xmlC14NIsNodeInNodeset(xmlNodeSetPtr nodes, xmlNodePtr node, xmlNodePtr parent) { +xmlC14NIsNodeInNodeset(void *user_data, xmlNodePtr node, xmlNodePtr parent) { + xmlNodeSetPtr nodes = (xmlNodeSetPtr) user_data; if((nodes != NULL) && (node != NULL)) { if(node->type != XML_NAMESPACE_DECL) { return(xmlXPathNodeSetContains(nodes, node)); @@ -513,8 +514,10 @@ xmlC14NIsXmlNs(xmlNsPtr ns) * Returns -1 if ns1 < ns2, 0 if ns1 == ns2 or 1 if ns1 > ns2. */ static int -xmlC14NNsCompare(xmlNsPtr ns1, xmlNsPtr ns2) +xmlC14NNsCompare(const void *data1, const void *data2) { + const xmlNsPtr ns1 = (const xmlNsPtr) data1; + const xmlNsPtr ns2 = (const xmlNsPtr) data2; if (ns1 == ns2) return (0); if (ns1 == NULL) @@ -559,6 +562,11 @@ xmlC14NPrintNamespaces(const xmlNsPtr ns, xmlC14NCtxPtr ctx) return (1); } +static int +xmlC14NPrintNamespacesWalker(const void *ns, void *ctx) { + return xmlC14NPrintNamespaces((const xmlNsPtr) ns, (xmlC14NCtxPtr) ctx); +} + /** * xmlC14NProcessNamespacesAxis: * @ctx: the C14N context @@ -615,7 +623,7 @@ xmlC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible) /* * Create a sorted list to store element namespaces */ - list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNsCompare); + list = xmlListCreate(NULL, xmlC14NNsCompare); if (list == NULL) { xmlC14NErrInternal("creating namespaces list (c14n)"); return (-1); @@ -663,7 +671,7 @@ xmlC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible) /* * print out all elements from list */ - xmlListWalk(list, (xmlListWalker) xmlC14NPrintNamespaces, (const void *) ctx); + xmlListWalk(list, xmlC14NPrintNamespacesWalker, (void *) ctx); /* * Cleanup @@ -728,7 +736,7 @@ xmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible) /* * Create a sorted list to store element namespaces */ - list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NNsCompare); + list = xmlListCreate(NULL, xmlC14NNsCompare); if (list == NULL) { xmlC14NErrInternal("creating namespaces list (exc c14n)"); return (-1); @@ -840,7 +848,7 @@ xmlExcC14NProcessNamespacesAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int visible) /* * print out all elements from list */ - xmlListWalk(list, (xmlListWalker) xmlC14NPrintNamespaces, (const void *) ctx); + xmlListWalk(list, xmlC14NPrintNamespacesWalker, (void *) ctx); /* * Cleanup @@ -879,8 +887,10 @@ xmlC14NIsXmlAttr(xmlAttrPtr attr) * Returns -1 if attr1 < attr2, 0 if attr1 == attr2 or 1 if attr1 > attr2. */ static int -xmlC14NAttrsCompare(xmlAttrPtr attr1, xmlAttrPtr attr2) +xmlC14NAttrsCompare(const void *data1, const void *data2) { + const xmlAttrPtr attr1 = (const xmlAttrPtr) data1; + const xmlAttrPtr attr2 = (const xmlAttrPtr) data2; int ret = 0; /* @@ -931,8 +941,10 @@ xmlC14NAttrsCompare(xmlAttrPtr attr1, xmlAttrPtr attr2) * Returns 1 on success or 0 on fail. */ static int -xmlC14NPrintAttrs(const xmlAttrPtr attr, xmlC14NCtxPtr ctx) +xmlC14NPrintAttrs(const void *data, void *user) { + const xmlAttrPtr attr = (const xmlAttrPtr) data; + xmlC14NCtxPtr ctx = (xmlC14NCtxPtr) user; xmlChar *value; xmlChar *buffer; @@ -1142,7 +1154,7 @@ xmlC14NProcessAttrsAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int parent_visible) /* * Create a sorted list to store element attributes */ - list = xmlListCreate(NULL, (xmlListDataCompare) xmlC14NAttrsCompare); + list = xmlListCreate(NULL, xmlC14NAttrsCompare); if (list == NULL) { xmlC14NErrInternal("creating attributes list"); return (-1); @@ -1331,7 +1343,7 @@ xmlC14NProcessAttrsAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int parent_visible) /* * print out all elements from list */ - xmlListWalk(list, (xmlListWalker) xmlC14NPrintAttrs, (const void *) ctx); + xmlListWalk(list, xmlC14NPrintAttrs, (void *) ctx); /* * Cleanup @@ -1375,13 +1387,6 @@ xmlC14NCheckForRelativeNamespaces(xmlC14NCtxPtr ctx, xmlNodePtr cur) xmlFreeURI(uri); return (-1); } - if ((xmlStrcasecmp((const xmlChar *) uri->scheme, BAD_CAST "urn") != 0) - && (xmlStrcasecmp((const xmlChar *) uri->scheme, BAD_CAST "dav") !=0) - && (xmlStrlen((const xmlChar *) uri->server) == 0)) { - xmlC14NErrRelativeNamespace(uri->scheme); - xmlFreeURI(uri); - return (-1); - } xmlFreeURI(uri); } ns = ns->next; @@ -1792,15 +1797,6 @@ xmlC14NNewCtx(xmlDocPtr doc, return (NULL); } - /* - * Validate the XML document encoding value, if provided. - */ - if (doc->charset != XML_CHAR_ENCODING_UTF8) { - xmlC14NErr(ctx, (xmlNodePtr) doc, XML_C14N_REQUIRES_UTF8, - "xmlC14NNewCtx: source document not in UTF8\n"); - return (NULL); - } - /* * Allocate a new xmlC14NCtxPtr and fill the fields. */ @@ -1971,7 +1967,7 @@ xmlC14NDocSaveTo(xmlDocPtr doc, xmlNodeSetPtr nodes, int mode, xmlChar ** inclusive_ns_prefixes, int with_comments, xmlOutputBufferPtr buf) { return(xmlC14NExecute(doc, - (xmlC14NIsVisibleCallback)xmlC14NIsNodeInNodeset, + xmlC14NIsNodeInNodeset, nodes, mode, inclusive_ns_prefixes, @@ -2084,7 +2080,7 @@ xmlC14NDocSave(xmlDocPtr doc, xmlNodeSetPtr nodes, xmlC14NErrParam("saving doc"); return (-1); } -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED if (compression < 0) compression = xmlGetCompressMode(); #endif diff --git a/gnulib-local/lib/libxml/catalog.c b/gnulib-local/lib/libxml/catalog.c index 5773db3de..f814121ce 100644 --- a/gnulib-local/lib/libxml/catalog.c +++ b/gnulib-local/lib/libxml/catalog.c @@ -47,9 +47,9 @@ #define MAX_CATAL_DEPTH 50 #ifdef _WIN32 -# define PATH_SEAPARATOR ';' +# define PATH_SEPARATOR ';' #else -# define PATH_SEAPARATOR ':' +# define PATH_SEPARATOR ':' #endif /** @@ -238,7 +238,7 @@ xmlCatalogErrMemory(const char *extra) * * Handle a catalog error */ -static void +static void LIBXML_ATTR_FORMAT(4,0) xmlCatalogErr(xmlCatalogEntryPtr catal, xmlNodePtr node, int error, const char *msg, const xmlChar *str1, const xmlChar *str2, const xmlChar *str3) @@ -319,12 +319,13 @@ xmlFreeCatalogEntryList(xmlCatalogEntryPtr ret); /** * xmlFreeCatalogEntry: - * @ret: a Catalog entry + * @payload: a Catalog entry * * Free the memory allocated to a Catalog entry */ static void -xmlFreeCatalogEntry(xmlCatalogEntryPtr ret) { +xmlFreeCatalogEntry(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) { + xmlCatalogEntryPtr ret = (xmlCatalogEntryPtr) payload; if (ret == NULL) return; /* @@ -367,20 +368,22 @@ xmlFreeCatalogEntryList(xmlCatalogEntryPtr ret) { while (ret != NULL) { next = ret->next; - xmlFreeCatalogEntry(ret); + xmlFreeCatalogEntry(ret, NULL); ret = next; } } /** * xmlFreeCatalogHashEntryList: - * @ret: a Catalog entry list + * @payload: a Catalog entry list * * Free the memory allocated to list of Catalog entries from the * catalog file hash. */ static void -xmlFreeCatalogHashEntryList(xmlCatalogEntryPtr catal) { +xmlFreeCatalogHashEntryList(void *payload, + const xmlChar *name ATTRIBUTE_UNUSED) { + xmlCatalogEntryPtr catal = (xmlCatalogEntryPtr) payload; xmlCatalogEntryPtr children, next; if (catal == NULL) @@ -391,11 +394,11 @@ xmlFreeCatalogHashEntryList(xmlCatalogEntryPtr catal) { next = children->next; children->dealloc = 0; children->children = NULL; - xmlFreeCatalogEntry(children); + xmlFreeCatalogEntry(children, NULL); children = next; } catal->dealloc = 0; - xmlFreeCatalogEntry(catal); + xmlFreeCatalogEntry(catal, NULL); } /** @@ -440,8 +443,7 @@ xmlFreeCatalog(xmlCatalogPtr catal) { if (catal->xml != NULL) xmlFreeCatalogEntryList(catal->xml); if (catal->sgml != NULL) - xmlHashFree(catal->sgml, - (xmlHashDeallocator) xmlFreeCatalogEntry); + xmlHashFree(catal->sgml, xmlFreeCatalogEntry); xmlFree(catal); } @@ -460,7 +462,10 @@ xmlFreeCatalog(xmlCatalogPtr catal) { * Serialize an SGML Catalog entry */ static void -xmlCatalogDumpEntry(xmlCatalogEntryPtr entry, FILE *out) { +xmlCatalogDumpEntry(void *payload, void *data, + const xmlChar *name ATTRIBUTE_UNUSED) { + xmlCatalogEntryPtr entry = (xmlCatalogEntryPtr) payload; + FILE *out = (FILE *) data; if ((entry == NULL) || (out == NULL)) return; switch (entry->type) { @@ -723,7 +728,10 @@ BAD_CAST "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"); * Convert one entry from the catalog */ static void -xmlCatalogConvertEntry(xmlCatalogEntryPtr entry, xmlCatalogPtr catal) { +xmlCatalogConvertEntry(void *payload, void *data, + const xmlChar *name ATTRIBUTE_UNUSED) { + xmlCatalogEntryPtr entry = (xmlCatalogEntryPtr) payload; + xmlCatalogPtr catal = (xmlCatalogPtr) data; if ((entry == NULL) || (catal == NULL) || (catal->sgml == NULL) || (catal->xml == NULL)) return; @@ -756,8 +764,7 @@ xmlCatalogConvertEntry(xmlCatalogEntryPtr entry, xmlCatalogPtr catal) { entry->type = XML_CATA_CATALOG; break; default: - xmlHashRemoveEntry(catal->sgml, entry->name, - (xmlHashDeallocator) xmlFreeCatalogEntry); + xmlHashRemoveEntry(catal->sgml, entry->name, xmlFreeCatalogEntry); return; } /* @@ -797,9 +804,7 @@ xmlConvertSGMLCatalog(xmlCatalogPtr catal) { xmlGenericError(xmlGenericErrorContext, "Converting SGML catalog to XML\n"); } - xmlHashScan(catal->sgml, - (xmlHashScanner) xmlCatalogConvertEntry, - &catal); + xmlHashScan(catal->sgml, xmlCatalogConvertEntry, &catal); return(0); } @@ -2396,6 +2401,7 @@ xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value, case SGML_CATA_ENTITY: if (*cur == '%') type = SGML_CATA_PENTITY; + /* Falls through. */ case SGML_CATA_PENTITY: case SGML_CATA_DOCTYPE: case SGML_CATA_LINKTYPE: @@ -2485,7 +2491,7 @@ xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value, NULL, XML_CATA_PREFER_NONE, NULL); res = xmlHashAddEntry(catal->sgml, name, entry); if (res < 0) { - xmlFreeCatalogEntry(entry); + xmlFreeCatalogEntry(entry, NULL); } xmlFree(filename); } @@ -2498,7 +2504,7 @@ xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value, XML_CATA_PREFER_NONE, NULL); res = xmlHashAddEntry(catal->sgml, sysid, entry); if (res < 0) { - xmlFreeCatalogEntry(entry); + xmlFreeCatalogEntry(entry, NULL); } } else { xmlChar *filename; @@ -2936,8 +2942,7 @@ xmlACatalogDump(xmlCatalogPtr catal, FILE *out) { if (catal->type == XML_XML_CATALOG_TYPE) { xmlDumpXMLCatalog(out, catal->xml); } else { - xmlHashScan(catal->sgml, - (xmlHashScanner) xmlCatalogDumpEntry, out); + xmlHashScan(catal->sgml, xmlCatalogDumpEntry, out); } } #endif /* LIBXML_OUTPUT_ENABLED */ @@ -3001,8 +3006,7 @@ xmlACatalogRemove(xmlCatalogPtr catal, const xmlChar *value) { if (catal->type == XML_XML_CATALOG_TYPE) { res = xmlDelXMLCatalog(catal->xml, value); } else { - res = xmlHashRemoveEntry(catal->sgml, value, - (xmlHashDeallocator) xmlFreeCatalogEntry); + res = xmlHashRemoveEntry(catal->sgml, value, xmlFreeCatalogEntry); if (res == 0) res = 1; } @@ -3247,7 +3251,7 @@ xmlLoadCatalogs(const char *pathss) { while (xmlIsBlank_ch(*cur)) cur++; if (*cur != 0) { paths = cur; - while ((*cur != 0) && (*cur != PATH_SEAPARATOR) && (!xmlIsBlank_ch(*cur))) + while ((*cur != 0) && (*cur != PATH_SEPARATOR) && (!xmlIsBlank_ch(*cur))) cur++; path = xmlStrndup((const xmlChar *)paths, cur - paths); #ifdef _WIN32 @@ -3263,7 +3267,7 @@ xmlLoadCatalogs(const char *pathss) { xmlFree(path); } } - while (*cur == PATH_SEAPARATOR) + while (*cur == PATH_SEPARATOR) cur++; } } @@ -3283,8 +3287,7 @@ xmlCatalogCleanup(void) { xmlGenericError(xmlGenericErrorContext, "Catalogs cleanup\n"); if (xmlCatalogXMLFiles != NULL) - xmlHashFree(xmlCatalogXMLFiles, - (xmlHashDeallocator)xmlFreeCatalogHashEntryList); + xmlHashFree(xmlCatalogXMLFiles, xmlFreeCatalogHashEntryList); xmlCatalogXMLFiles = NULL; if (xmlDefaultCatalog != NULL) xmlFreeCatalog(xmlDefaultCatalog); diff --git a/gnulib-local/lib/libxml/debugXML.c b/gnulib-local/lib/libxml/debugXML.c index b05fdff52..c98db0bcc 100644 --- a/gnulib-local/lib/libxml/debugXML.c +++ b/gnulib-local/lib/libxml/debugXML.c @@ -44,10 +44,10 @@ struct _xmlDebugCtxt { int depth; /* current depth */ xmlDocPtr doc; /* current document */ xmlNodePtr node; /* current node */ - xmlDictPtr dict; /* the doc dictionnary */ + xmlDictPtr dict; /* the doc dictionary */ int check; /* do just checkings */ int errors; /* number of errors found */ - int nodict; /* if the document has no dictionnary */ + int nodict; /* if the document has no dictionary */ int options; /* options */ }; @@ -164,7 +164,7 @@ xmlDebugErr(xmlDebugCtxtPtr ctxt, int error, const char *msg) NULL, NULL, NULL, 0, 0, "%s", msg); } -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlDebugErr2(xmlDebugCtxtPtr ctxt, int error, const char *msg, int extra) { ctxt->errors++; @@ -174,7 +174,7 @@ xmlDebugErr2(xmlDebugCtxtPtr ctxt, int error, const char *msg, int extra) NULL, NULL, NULL, 0, 0, msg, extra); } -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlDebugErr3(xmlDebugCtxtPtr ctxt, int error, const char *msg, const char *extra) { ctxt->errors++; @@ -243,7 +243,7 @@ xmlCtxtCheckString(xmlDebugCtxtPtr ctxt, const xmlChar * str) * @ctxt: the debug context * @name: the name * - * Do debugging on the name, for example the dictionnary status and + * Do debugging on the name, for example the dictionary status and * conformance to the Name production. */ static void @@ -265,7 +265,7 @@ xmlCtxtCheckName(xmlDebugCtxtPtr ctxt, const xmlChar * name) ((ctxt->doc == NULL) || ((ctxt->doc->parseFlags & (XML_PARSE_SAX1 | XML_PARSE_NODICT)) == 0))) { xmlDebugErr3(ctxt, XML_CHECK_OUTSIDE_DICT, - "Name is not from the document dictionnary '%s'", + "Name is not from the document dictionary '%s'", (const char *) name); } } @@ -292,7 +292,7 @@ xmlCtxtGenericNodeCheck(xmlDebugCtxtPtr ctxt, xmlNodePtr node) { /* desactivated right now as it raises too many errors */ if (doc->type == XML_DOCUMENT_NODE) xmlDebugErr(ctxt, XML_CHECK_NO_DICT, - "Document has no dictionnary\n"); + "Document has no dictionary\n"); #endif ctxt->nodict = 1; } @@ -1229,8 +1229,11 @@ xmlCtxtDumpDocument(xmlDebugCtxtPtr ctxt, xmlDocPtr doc) } static void -xmlCtxtDumpEntityCallback(xmlEntityPtr cur, xmlDebugCtxtPtr ctxt) +xmlCtxtDumpEntityCallback(void *payload, void *data, + const xmlChar *name ATTRIBUTE_UNUSED) { + xmlEntityPtr cur = (xmlEntityPtr) payload; + xmlDebugCtxtPtr ctxt = (xmlDebugCtxtPtr) data; if (cur == NULL) { if (!ctxt->check) fprintf(ctxt->output, "Entity is NULL"); @@ -1289,8 +1292,7 @@ xmlCtxtDumpEntities(xmlDebugCtxtPtr ctxt, xmlDocPtr doc) if (!ctxt->check) fprintf(ctxt->output, "Entities in internal subset\n"); - xmlHashScan(table, (xmlHashScanner) xmlCtxtDumpEntityCallback, - ctxt); + xmlHashScan(table, xmlCtxtDumpEntityCallback, ctxt); } else fprintf(ctxt->output, "No entities in internal subset\n"); if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) { @@ -1299,8 +1301,7 @@ xmlCtxtDumpEntities(xmlDebugCtxtPtr ctxt, xmlDocPtr doc) if (!ctxt->check) fprintf(ctxt->output, "Entities in external subset\n"); - xmlHashScan(table, (xmlHashScanner) xmlCtxtDumpEntityCallback, - ctxt); + xmlHashScan(table, xmlCtxtDumpEntityCallback, ctxt); } else if (!ctxt->check) fprintf(ctxt->output, "No entities in external subset\n"); } @@ -2931,7 +2932,7 @@ xmlShell(xmlDocPtr doc, char *filename, xmlShellReadlineFunc input, fprintf(ctxt->output, "\tvalidate check the document for errors\n"); #endif /* LIBXML_VALID_ENABLED */ #ifdef LIBXML_SCHEMAS_ENABLED - fprintf(ctxt->output, "\trelaxng rng validate the document agaisnt the Relax-NG schemas\n"); + fprintf(ctxt->output, "\trelaxng rng validate the document against the Relax-NG schemas\n"); #endif fprintf(ctxt->output, "\tgrep string search for a string in the subtree\n"); #ifdef LIBXML_VALID_ENABLED diff --git a/gnulib-local/lib/libxml/dict.c b/gnulib-local/lib/libxml/dict.c index 8c8f93148..0ef3718da 100644 --- a/gnulib-local/lib/libxml/dict.c +++ b/gnulib-local/lib/libxml/dict.c @@ -48,7 +48,7 @@ #else #ifdef HAVE_INTTYPES_H #include -#elif defined(WIN32) +#elif defined(_WIN32) typedef unsigned __int32 uint32_t; #endif #endif @@ -87,7 +87,7 @@ typedef unsigned __int32 uint32_t; #endif /* WITH_BIG_KEY */ /* - * An entry in the dictionnary + * An entry in the dictionary */ typedef struct _xmlDictEntry xmlDictEntry; typedef xmlDictEntry *xmlDictEntryPtr; @@ -110,7 +110,7 @@ struct _xmlDictStrings { xmlChar array[1]; }; /* - * The entire dictionnary + * The entire dictionary */ struct _xmlDict { int ref_counter; @@ -229,7 +229,7 @@ xmlDictCleanup(void) { /* * xmlDictAddString: - * @dict: the dictionnary + * @dict: the dictionary * @name: the name of the userdata * @len: the length of the name * @@ -249,7 +249,7 @@ xmlDictAddString(xmlDictPtr dict, const xmlChar *name, unsigned int namelen) { #endif pool = dict->strings; while (pool != NULL) { - if (pool->end - pool->free > namelen) + if ((size_t)(pool->end - pool->free) > namelen) goto found_pool; if (pool->size > size) size = pool->size; limit += pool->size; @@ -291,7 +291,7 @@ found_pool: /* * xmlDictAddQString: - * @dict: the dictionnary + * @dict: the dictionary * @prefix: the prefix of the userdata * @plen: the prefix length * @name: the name of the userdata @@ -317,7 +317,7 @@ xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, unsigned int plen, #endif pool = dict->strings; while (pool != NULL) { - if (pool->end - pool->free > namelen + plen + 1) + if ((size_t)(pool->end - pool->free) > namelen + plen + 1) goto found_pool; if (pool->size > size) size = pool->size; limit += pool->size; @@ -453,14 +453,23 @@ xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) { } switch (namelen) { case 10: value += name[9]; + /* Falls through. */ case 9: value += name[8]; + /* Falls through. */ case 8: value += name[7]; + /* Falls through. */ case 7: value += name[6]; + /* Falls through. */ case 6: value += name[5]; + /* Falls through. */ case 5: value += name[4]; + /* Falls through. */ case 4: value += name[3]; + /* Falls through. */ case 3: value += name[2]; + /* Falls through. */ case 2: value += name[1]; + /* Falls through. */ default: break; } return(value); @@ -496,15 +505,25 @@ xmlDictComputeFastQKey(const xmlChar *prefix, int plen, } switch (plen) { case 10: value += prefix[9]; + /* Falls through. */ case 9: value += prefix[8]; + /* Falls through. */ case 8: value += prefix[7]; + /* Falls through. */ case 7: value += prefix[6]; + /* Falls through. */ case 6: value += prefix[5]; + /* Falls through. */ case 5: value += prefix[4]; + /* Falls through. */ case 4: value += prefix[3]; + /* Falls through. */ case 3: value += prefix[2]; + /* Falls through. */ case 2: value += prefix[1]; + /* Falls through. */ case 1: value += prefix[0]; + /* Falls through. */ default: break; } len -= plen; @@ -514,15 +533,25 @@ xmlDictComputeFastQKey(const xmlChar *prefix, int plen, } switch (len) { case 10: value += name[9]; + /* Falls through. */ case 9: value += name[8]; + /* Falls through. */ case 8: value += name[7]; + /* Falls through. */ case 7: value += name[6]; + /* Falls through. */ case 6: value += name[5]; + /* Falls through. */ case 5: value += name[4]; + /* Falls through. */ case 4: value += name[3]; + /* Falls through. */ case 3: value += name[2]; + /* Falls through. */ case 2: value += name[1]; + /* Falls through. */ case 1: value += name[0]; + /* Falls through. */ default: break; } return(value); @@ -533,7 +562,7 @@ xmlDictComputeFastQKey(const xmlChar *prefix, int plen, * * Create a new dictionary * - * Returns the newly created dictionnary, or NULL if an error occured. + * Returns the newly created dictionary, or NULL if an error occurred. */ xmlDictPtr xmlDictCreate(void) { @@ -573,14 +602,14 @@ xmlDictCreate(void) { /** * xmlDictCreateSub: - * @sub: an existing dictionnary + * @sub: an existing dictionary * * Create a new dictionary, inheriting strings from the read-only - * dictionnary @sub. On lookup, strings are first searched in the - * new dictionnary, then in @sub, and if not found are created in the - * new dictionnary. + * dictionary @sub. On lookup, strings are first searched in the + * new dictionary, then in @sub, and if not found are created in the + * new dictionary. * - * Returns the newly created dictionnary, or NULL if an error occured. + * Returns the newly created dictionary, or NULL if an error occurred. */ xmlDictPtr xmlDictCreateSub(xmlDictPtr sub) { @@ -599,7 +628,7 @@ xmlDictCreateSub(xmlDictPtr sub) { /** * xmlDictReference: - * @dict: the dictionnary + * @dict: the dictionary * * Increment the reference counter of a dictionary * @@ -620,10 +649,10 @@ xmlDictReference(xmlDictPtr dict) { /** * xmlDictGrow: - * @dict: the dictionnary - * @size: the new size of the dictionnary + * @dict: the dictionary + * @size: the new size of the dictionary * - * resize the dictionnary + * resize the dictionary * * Returns 0 in case of success, -1 in case of failure */ @@ -699,7 +728,7 @@ xmlDictGrow(xmlDictPtr dict, size_t size) { } else { /* * we don't have much ways to alert from herei - * result is loosing an entry and unicity garantee + * result is losing an entry and unicity guarantee */ ret = -1; } @@ -755,7 +784,7 @@ xmlDictGrow(xmlDictPtr dict, size_t size) { /** * xmlDictFree: - * @dict: the dictionnary + * @dict: the dictionary * * Free the hash @dict and its contents. The userdata is * deallocated with @f if provided. @@ -817,11 +846,11 @@ xmlDictFree(xmlDictPtr dict) { /** * xmlDictLookup: - * @dict: the dictionnary + * @dict: the dictionary * @name: the name of the userdata * @len: the length of the name, if -1 it is recomputed * - * Add the @name to the dictionnary @dict if not present. + * Add the @name to the dictionary @dict if not present. * * Returns the internal copy of the name or NULL in case of internal error */ @@ -957,11 +986,11 @@ xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) { /** * xmlDictExists: - * @dict: the dictionnary + * @dict: the dictionary * @name: the name of the userdata * @len: the length of the name, if -1 it is recomputed * - * Check if the @name exists in the dictionnary @dict. + * Check if the @name exists in the dictionary @dict. * * Returns the internal copy of the name or NULL if not found. */ @@ -1065,7 +1094,7 @@ xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) { /** * xmlDictQLookup: - * @dict: the dictionnary + * @dict: the dictionary * @prefix: the prefix * @name: the name * @@ -1170,7 +1199,7 @@ xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name) { /** * xmlDictOwns: - * @dict: the dictionnary + * @dict: the dictionary * @str: the string * * check if a string is owned by the disctionary @@ -1197,11 +1226,11 @@ xmlDictOwns(xmlDictPtr dict, const xmlChar *str) { /** * xmlDictSize: - * @dict: the dictionnary + * @dict: the dictionary * * Query the number of elements installed in the hash @dict. * - * Returns the number of elements in the dictionnary or + * Returns the number of elements in the dictionary or * -1 in case of error */ int @@ -1215,7 +1244,7 @@ xmlDictSize(xmlDictPtr dict) { /** * xmlDictSetLimit: - * @dict: the dictionnary + * @dict: the dictionary * @limit: the limit in bytes * * Set a size limit for the dictionary @@ -1236,7 +1265,7 @@ xmlDictSetLimit(xmlDictPtr dict, size_t limit) { /** * xmlDictGetUsage: - * @dict: the dictionnary + * @dict: the dictionary * * Get how much memory is used by a dictionary for strings * Added in 2.9.0 diff --git a/gnulib-local/lib/libxml/dict.in.h b/gnulib-local/lib/libxml/dict.in.h index 7022ec8be..b83db59a1 100644 --- a/gnulib-local/lib/libxml/dict.in.h +++ b/gnulib-local/lib/libxml/dict.in.h @@ -1,5 +1,5 @@ /* - * Summary: string dictionnary + * Summary: string dictionary * Description: dictionary of reusable strings, just used to avoid allocation * and freeing operations. * @@ -11,6 +11,18 @@ #ifndef __XML_DICT_H__ #define __XML_DICT_H__ +#ifdef __cplusplus +#define __XML_EXTERNC extern "C" +#else +#define __XML_EXTERNC +#endif + +/* + * The dictionary. + */ +__XML_EXTERNC typedef struct _xmlDict xmlDict; +__XML_EXTERNC typedef xmlDict *xmlDictPtr; + #include #include #include @@ -19,12 +31,6 @@ extern "C" { #endif -/* - * The dictionnary. - */ -typedef struct _xmlDict xmlDict; -typedef xmlDict *xmlDictPtr; - /* * Initializer */ @@ -48,7 +54,7 @@ XMLPUBFUN void XMLCALL xmlDictFree (xmlDictPtr dict); /* - * Lookup of entry in the dictionnary. + * Lookup of entry in the dictionary. */ XMLPUBFUN const xmlChar * XMLCALL xmlDictLookup (xmlDictPtr dict, diff --git a/gnulib-local/lib/libxml/elfgcchack.h b/gnulib-local/lib/libxml/elfgcchack.h index 2a3398846..da2ad7317 100644 --- a/gnulib-local/lib/libxml/elfgcchack.h +++ b/gnulib-local/lib/libxml/elfgcchack.h @@ -11,7 +11,7 @@ #if defined IN_LIBXML && !defined IN_LIBTEXTSTYLE #ifdef __GNUC__ #ifdef PIC -#ifdef linux +#ifdef __linux__ #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ > 3) #include "libxml/c14n.h" diff --git a/gnulib-local/lib/libxml/encoding.c b/gnulib-local/lib/libxml/encoding.c index 574e1aede..a3aaf10ec 100644 --- a/gnulib-local/lib/libxml/encoding.c +++ b/gnulib-local/lib/libxml/encoding.c @@ -93,7 +93,7 @@ xmlEncodingErrMemory(const char *extra) * * n encoding error */ -static void +static void LIBXML_ATTR_FORMAT(2,0) xmlEncodingErr(xmlParserErrors error, const char *msg, const char *val) { __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, @@ -110,6 +110,9 @@ openIcuConverter(const char* name, int toUnicode) if (conv == NULL) return NULL; + conv->pivot_source = conv->pivot_buf; + conv->pivot_target = conv->pivot_buf; + conv->uconv = ucnv_open(name, &status); if (U_FAILURE(status)) goto error; @@ -354,8 +357,14 @@ UTF8ToUTF8(unsigned char* out, int *outlen, { int len; - if ((out == NULL) || (inb == NULL) || (outlen == NULL) || (inlenb == NULL)) + if ((out == NULL) || (outlen == NULL) || (inlenb == NULL)) return(-1); + if (inb == NULL) { + /* inb == NULL means output is initialized. */ + *outlen = 0; + *inlenb = 0; + return(0); + } if (*outlen > *inlenb) { len = *inlenb; } else { @@ -1844,6 +1853,7 @@ xmlIconvWrapper(iconv_t cd, unsigned char *out, int *outlen, * @outlen: the length of @out * @in: a pointer to an array of ISO Latin 1 chars * @inlen: the length of @in + * @flush: if true, indicates end of input * * Returns 0 if success, or * -1 by lack of space, or @@ -1857,7 +1867,7 @@ xmlIconvWrapper(iconv_t cd, unsigned char *out, int *outlen, */ static int xmlUconvWrapper(uconv_t *cd, int toUnicode, unsigned char *out, int *outlen, - const unsigned char *in, int *inlen) { + const unsigned char *in, int *inlen, int flush) { const char *ucv_in = (const char *) in; char *ucv_out = (char *) out; UErrorCode err = U_ZERO_ERROR; @@ -1867,33 +1877,31 @@ xmlUconvWrapper(uconv_t *cd, int toUnicode, unsigned char *out, int *outlen, return(-1); } - /* - * TODO(jungshik) - * 1. is ucnv_convert(To|From)Algorithmic better? - * 2. had we better use an explicit pivot buffer? - * 3. error returned comes from 'fromUnicode' only even - * when toUnicode is true ! - */ if (toUnicode) { /* encoding => UTF-16 => UTF-8 */ ucnv_convertEx(cd->utf8, cd->uconv, &ucv_out, ucv_out + *outlen, - &ucv_in, ucv_in + *inlen, NULL, NULL, NULL, NULL, - 0, TRUE, &err); + &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 { /* UTF-8 => UTF-16 => encoding */ ucnv_convertEx(cd->uconv, cd->utf8, &ucv_out, ucv_out + *outlen, - &ucv_in, ucv_in + *inlen, NULL, NULL, NULL, NULL, - 0, TRUE, &err); + &ucv_in, ucv_in + *inlen, cd->pivot_buf, + &cd->pivot_source, &cd->pivot_target, + cd->pivot_buf + ICU_PIVOT_BUF_SIZE, 0, flush, &err); } *inlen = ucv_in - (const char*) in; *outlen = ucv_out - (char *) out; - if (U_SUCCESS(err)) + 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; return 0; + } if (err == U_BUFFER_OVERFLOW_ERROR) return -1; if (err == U_INVALID_CHAR_FOUND || err == U_ILLEGAL_CHAR_FOUND) return -2; - /* if (err == U_TRUNCATED_CHAR_FOUND) */ return -3; } #endif /* LIBXML_ICU_ENABLED */ @@ -1904,6 +1912,64 @@ xmlUconvWrapper(uconv_t *cd, int toUnicode, unsigned char *out, int *outlen, * * ************************************************************************/ +static int +xmlEncInputChunk(xmlCharEncodingHandler *handler, unsigned char *out, + int *outlen, const unsigned char *in, int *inlen, int flush) { + int ret; + (void)flush; + + if (handler->input != NULL) { + ret = handler->input(out, outlen, in, inlen); + } +#ifdef LIBXML_ICONV_ENABLED + else if (handler->iconv_in != NULL) { + ret = xmlIconvWrapper(handler->iconv_in, out, outlen, in, inlen); + } +#endif /* LIBXML_ICONV_ENABLED */ +#ifdef LIBXML_ICU_ENABLED + else if (handler->uconv_in != NULL) { + ret = xmlUconvWrapper(handler->uconv_in, 1, out, outlen, in, inlen, + flush); + } +#endif /* LIBXML_ICU_ENABLED */ + else { + *outlen = 0; + *inlen = 0; + ret = -2; + } + + return(ret); +} + +/* Returns -4 if no output function was found. */ +static int +xmlEncOutputChunk(xmlCharEncodingHandler *handler, unsigned char *out, + int *outlen, const unsigned char *in, int *inlen) { + int ret; + + if (handler->output != NULL) { + ret = handler->output(out, outlen, in, inlen); + } +#ifdef LIBXML_ICONV_ENABLED + else if (handler->iconv_out != NULL) { + ret = xmlIconvWrapper(handler->iconv_out, out, outlen, in, inlen); + } +#endif /* LIBXML_ICONV_ENABLED */ +#ifdef LIBXML_ICU_ENABLED + else if (handler->uconv_out != NULL) { + ret = xmlUconvWrapper(handler->uconv_out, 0, out, outlen, in, inlen, + TRUE); + } +#endif /* LIBXML_ICU_ENABLED */ + else { + *outlen = 0; + *inlen = 0; + ret = -4; + } + + return(ret); +} + /** * xmlCharEncFirstLineInt: * @handler: char enconding transformation data structure @@ -1922,7 +1988,7 @@ xmlUconvWrapper(uconv_t *cd, int toUnicode, unsigned char *out, int *outlen, int xmlCharEncFirstLineInt(xmlCharEncodingHandler *handler, xmlBufferPtr out, xmlBufferPtr in, int len) { - int ret = -2; + int ret; int written; int toconv; @@ -1953,33 +2019,13 @@ xmlCharEncFirstLineInt(xmlCharEncodingHandler *handler, xmlBufferPtr out, written = out->size - out->use - 1; } - if (handler->input != NULL) { - ret = handler->input(&out->content[out->use], &written, - in->content, &toconv); - xmlBufferShrink(in, toconv); - out->use += written; - out->content[out->use] = 0; - } -#ifdef LIBXML_ICONV_ENABLED - else if (handler->iconv_in != NULL) { - ret = xmlIconvWrapper(handler->iconv_in, &out->content[out->use], - &written, in->content, &toconv); - xmlBufferShrink(in, toconv); - out->use += written; - out->content[out->use] = 0; - if (ret == -1) ret = -3; - } -#endif /* LIBXML_ICONV_ENABLED */ -#ifdef LIBXML_ICU_ENABLED - else if (handler->uconv_in != NULL) { - ret = xmlUconvWrapper(handler->uconv_in, 1, &out->content[out->use], - &written, in->content, &toconv); - xmlBufferShrink(in, toconv); - out->use += written; - out->content[out->use] = 0; - if (ret == -1) ret = -3; - } -#endif /* LIBXML_ICU_ENABLED */ + ret = xmlEncInputChunk(handler, &out->content[out->use], &written, + in->content, &toconv, 0); + xmlBufferShrink(in, toconv); + out->use += written; + out->content[out->use] = 0; + if (ret == -1) ret = -3; + #ifdef DEBUG_ENCODING switch (ret) { case 0: @@ -2049,7 +2095,7 @@ xmlCharEncFirstLine(xmlCharEncodingHandler *handler, xmlBufferPtr out, int xmlCharEncFirstLineInput(xmlParserInputBufferPtr input, int len) { - int ret = -2; + int ret; size_t written; size_t toconv; int c_in; @@ -2091,32 +2137,13 @@ xmlCharEncFirstLineInput(xmlParserInputBufferPtr input, int len) c_in = toconv; c_out = written; - if (input->encoder->input != NULL) { - ret = input->encoder->input(xmlBufEnd(out), &c_out, - xmlBufContent(in), &c_in); - xmlBufShrink(in, c_in); - xmlBufAddLen(out, c_out); - } -#ifdef LIBXML_ICONV_ENABLED - else if (input->encoder->iconv_in != NULL) { - ret = xmlIconvWrapper(input->encoder->iconv_in, xmlBufEnd(out), - &c_out, xmlBufContent(in), &c_in); - xmlBufShrink(in, c_in); - xmlBufAddLen(out, c_out); - if (ret == -1) - ret = -3; - } -#endif /* LIBXML_ICONV_ENABLED */ -#ifdef LIBXML_ICU_ENABLED - else if (input->encoder->uconv_in != NULL) { - ret = xmlUconvWrapper(input->encoder->uconv_in, 1, xmlBufEnd(out), - &c_out, xmlBufContent(in), &c_in); - xmlBufShrink(in, c_in); - xmlBufAddLen(out, c_out); - if (ret == -1) - ret = -3; - } -#endif /* LIBXML_ICU_ENABLED */ + ret = xmlEncInputChunk(input->encoder, xmlBufEnd(out), &c_out, + xmlBufContent(in), &c_in, 0); + xmlBufShrink(in, c_in); + xmlBufAddLen(out, c_out); + if (ret == -1) + ret = -3; + switch (ret) { case 0: #ifdef DEBUG_ENCODING @@ -2175,7 +2202,7 @@ xmlCharEncFirstLineInput(xmlParserInputBufferPtr input, int len) int xmlCharEncInput(xmlParserInputBufferPtr input, int flush) { - int ret = -2; + int ret; size_t written; size_t toconv; int c_in; @@ -2208,32 +2235,13 @@ xmlCharEncInput(xmlParserInputBufferPtr input, int flush) c_in = toconv; c_out = written; - if (input->encoder->input != NULL) { - ret = input->encoder->input(xmlBufEnd(out), &c_out, - xmlBufContent(in), &c_in); - xmlBufShrink(in, c_in); - xmlBufAddLen(out, c_out); - } -#ifdef LIBXML_ICONV_ENABLED - else if (input->encoder->iconv_in != NULL) { - ret = xmlIconvWrapper(input->encoder->iconv_in, xmlBufEnd(out), - &c_out, xmlBufContent(in), &c_in); - xmlBufShrink(in, c_in); - xmlBufAddLen(out, c_out); - if (ret == -1) - ret = -3; - } -#endif /* LIBXML_ICONV_ENABLED */ -#ifdef LIBXML_ICU_ENABLED - else if (input->encoder->uconv_in != NULL) { - ret = xmlUconvWrapper(input->encoder->uconv_in, 1, xmlBufEnd(out), - &c_out, xmlBufContent(in), &c_in); - xmlBufShrink(in, c_in); - xmlBufAddLen(out, c_out); - if (ret == -1) - ret = -3; - } -#endif /* LIBXML_ICU_ENABLED */ + ret = xmlEncInputChunk(input->encoder, xmlBufEnd(out), &c_out, + xmlBufContent(in), &c_in, flush); + xmlBufShrink(in, c_in); + xmlBufAddLen(out, c_out); + if (ret == -1) + ret = -3; + switch (ret) { case 0: #ifdef DEBUG_ENCODING @@ -2294,7 +2302,7 @@ int xmlCharEncInFunc(xmlCharEncodingHandler * handler, xmlBufferPtr out, xmlBufferPtr in) { - int ret = -2; + int ret; int written; int toconv; @@ -2313,35 +2321,14 @@ xmlCharEncInFunc(xmlCharEncodingHandler * handler, xmlBufferPtr out, xmlBufferGrow(out, out->size + toconv * 2); written = out->size - out->use - 1; } - if (handler->input != NULL) { - ret = handler->input(&out->content[out->use], &written, - in->content, &toconv); - xmlBufferShrink(in, toconv); - out->use += written; - out->content[out->use] = 0; - } -#ifdef LIBXML_ICONV_ENABLED - else if (handler->iconv_in != NULL) { - ret = xmlIconvWrapper(handler->iconv_in, &out->content[out->use], - &written, in->content, &toconv); - xmlBufferShrink(in, toconv); - out->use += written; - out->content[out->use] = 0; - if (ret == -1) - ret = -3; - } -#endif /* LIBXML_ICONV_ENABLED */ -#ifdef LIBXML_ICU_ENABLED - else if (handler->uconv_in != NULL) { - ret = xmlUconvWrapper(handler->uconv_in, 1, &out->content[out->use], - &written, in->content, &toconv); - xmlBufferShrink(in, toconv); - out->use += written; - out->content[out->use] = 0; - if (ret == -1) - ret = -3; - } -#endif /* LIBXML_ICU_ENABLED */ + ret = xmlEncInputChunk(handler, &out->content[out->use], &written, + in->content, &toconv, 1); + xmlBufferShrink(in, toconv); + out->use += written; + out->content[out->use] = 0; + if (ret == -1) + ret = -3; + switch (ret) { case 0: #ifdef DEBUG_ENCODING @@ -2405,7 +2392,7 @@ xmlCharEncInFunc(xmlCharEncodingHandler * handler, xmlBufferPtr out, int xmlCharEncOutput(xmlOutputBufferPtr output, int init) { - int ret = -2; + int ret; size_t written; size_t writtentot = 0; size_t toconv; @@ -2413,7 +2400,6 @@ xmlCharEncOutput(xmlOutputBufferPtr output, int init) int c_out; xmlBufPtr in; xmlBufPtr out; - int charref_len = 0; if ((output == NULL) || (output->encoder == NULL) || (output->buffer == NULL) || (output->conv == NULL)) @@ -2433,26 +2419,10 @@ retry: if (init) { c_in = 0; c_out = written; - if (output->encoder->output != NULL) { - ret = output->encoder->output(xmlBufEnd(out), &c_out, - NULL, &c_in); - if (ret > 0) /* Gennady: check return value */ - xmlBufAddLen(out, c_out); - } -#ifdef LIBXML_ICONV_ENABLED - else if (output->encoder->iconv_out != NULL) { - ret = xmlIconvWrapper(output->encoder->iconv_out, xmlBufEnd(out), - &c_out, NULL, &c_in); - xmlBufAddLen(out, c_out); - } -#endif /* LIBXML_ICONV_ENABLED */ -#ifdef LIBXML_ICU_ENABLED - else if (output->encoder->uconv_out != NULL) { - ret = xmlUconvWrapper(output->encoder->uconv_out, 0, xmlBufEnd(out), - &c_out, NULL, &c_in); - xmlBufAddLen(out, c_out); - } -#endif /* LIBXML_ICU_ENABLED */ + /* TODO: Check return value. */ + xmlEncOutputChunk(output->encoder, xmlBufEnd(out), &c_out, + NULL, &c_in); + xmlBufAddLen(out, c_out); #ifdef DEBUG_ENCODING xmlGenericError(xmlGenericErrorContext, "initialized encoder\n"); @@ -2477,60 +2447,18 @@ retry: c_in = toconv; c_out = written; - if (output->encoder->output != NULL) { - ret = output->encoder->output(xmlBufEnd(out), &c_out, - xmlBufContent(in), &c_in); + ret = xmlEncOutputChunk(output->encoder, xmlBufEnd(out), &c_out, + xmlBufContent(in), &c_in); + xmlBufShrink(in, c_in); + xmlBufAddLen(out, c_out); + writtentot += c_out; + if (ret == -1) { if (c_out > 0) { - xmlBufShrink(in, c_in); - xmlBufAddLen(out, c_out); - writtentot += c_out; - } - } -#ifdef LIBXML_ICONV_ENABLED - else if (output->encoder->iconv_out != NULL) { - ret = xmlIconvWrapper(output->encoder->iconv_out, xmlBufEnd(out), - &c_out, xmlBufContent(in), &c_in); - xmlBufShrink(in, c_in); - xmlBufAddLen(out, c_out); - writtentot += c_out; - if (ret == -1) { - if (c_out > 0) { - /* - * Can be a limitation of iconv - */ - charref_len = 0; - goto retry; - } - ret = -3; - } - } -#endif /* LIBXML_ICONV_ENABLED */ -#ifdef LIBXML_ICU_ENABLED - else if (output->encoder->uconv_out != NULL) { - ret = xmlUconvWrapper(output->encoder->uconv_out, 0, xmlBufEnd(out), - &c_out, xmlBufContent(in), &c_in); - xmlBufShrink(in, c_in); - xmlBufAddLen(out, c_out); - writtentot += c_out; - if (ret == -1) { - if (c_out > 0) { - /* - * Can be a limitation of uconv - */ - charref_len = 0; - goto retry; - } - ret = -3; + /* Can be a limitation of iconv or uconv */ + goto retry; } + ret = -3; } -#endif /* LIBXML_ICU_ENABLED */ - else { - xmlEncodingErr(XML_I18N_NO_OUTPUT, - "xmlCharEncOutFunc: no output function !\n", NULL); - return(-1); - } - - if (ret >= 0) output += ret; /* * Attempt to handle error cases @@ -2555,47 +2483,44 @@ retry: c_in, c_out, (int) xmlBufUse(in)); #endif break; + case -4: + xmlEncodingErr(XML_I18N_NO_OUTPUT, + "xmlCharEncOutFunc: no output function !\n", NULL); + ret = -1; + break; case -2: { + xmlChar charref[20]; int len = (int) xmlBufUse(in); xmlChar *content = xmlBufContent(in); - int cur; + int cur, charrefLen; cur = xmlGetUTF8Char(content, &len); - if ((charref_len != 0) && (c_out < charref_len)) { - /* - * We attempted to insert a character reference and failed. - * Undo what was written and skip the remaining charref. - */ - xmlBufErase(out, c_out); - writtentot -= c_out; - xmlBufShrink(in, charref_len - c_out); - charref_len = 0; - - ret = -1; + if (cur <= 0) break; - } else if (cur > 0) { - xmlChar charref[20]; #ifdef DEBUG_ENCODING - xmlGenericError(xmlGenericErrorContext, - "handling output conversion error\n"); - xmlGenericError(xmlGenericErrorContext, - "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n", - content[0], content[1], - content[2], content[3]); + xmlGenericError(xmlGenericErrorContext, + "handling output conversion error\n"); + xmlGenericError(xmlGenericErrorContext, + "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n", + content[0], content[1], + content[2], content[3]); #endif - /* - * Removes the UTF8 sequence, and replace it by a charref - * and continue the transcoding phase, hoping the error - * did not mangle the encoder state. - */ - charref_len = snprintf((char *) &charref[0], sizeof(charref), - "&#%d;", cur); - xmlBufShrink(in, len); - xmlBufAddHead(in, charref, -1); - - goto retry; - } else { + /* + * Removes the UTF8 sequence, and replace it by a charref + * and continue the transcoding phase, hoping the error + * did not mangle the encoder state. + */ + charrefLen = snprintf((char *) &charref[0], sizeof(charref), + "&#%d;", cur); + xmlBufShrink(in, len); + xmlBufGrow(out, charrefLen * 4); + c_out = xmlBufAvail(out) - 1; + c_in = charrefLen; + ret = xmlEncOutputChunk(output->encoder, xmlBufEnd(out), &c_out, + charref, &c_in); + + if ((ret < 0) || (c_in != charrefLen)) { char buf[50]; snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X", @@ -2607,8 +2532,12 @@ retry: buf); if (xmlBufGetAllocationScheme(in) != XML_BUFFER_ALLOC_IMMUTABLE) content[0] = ' '; + break; } - break; + + xmlBufAddLen(out, c_out); + writtentot += c_out; + goto retry; } } return(ret); @@ -2636,12 +2565,11 @@ retry: int xmlCharEncOutFunc(xmlCharEncodingHandler *handler, xmlBufferPtr out, xmlBufferPtr in) { - int ret = -2; + int ret; int written; int writtentot = 0; int toconv; int output = 0; - int charref_len = 0; if (handler == NULL) return(-1); if (out == NULL) return(-1); @@ -2658,31 +2586,11 @@ retry: */ if (in == NULL) { toconv = 0; - if (handler->output != NULL) { - ret = handler->output(&out->content[out->use], &written, - NULL, &toconv); - if (ret >= 0) { /* Gennady: check return value */ - out->use += written; - out->content[out->use] = 0; - } - } -#ifdef LIBXML_ICONV_ENABLED - else if (handler->iconv_out != NULL) { - ret = xmlIconvWrapper(handler->iconv_out, &out->content[out->use], - &written, NULL, &toconv); - out->use += written; - out->content[out->use] = 0; - } -#endif /* LIBXML_ICONV_ENABLED */ -#ifdef LIBXML_ICU_ENABLED - else if (handler->uconv_out != NULL) { - ret = xmlUconvWrapper(handler->uconv_out, 0, - &out->content[out->use], - &written, NULL, &toconv); - out->use += written; - out->content[out->use] = 0; - } -#endif /* LIBXML_ICU_ENABLED */ + /* TODO: Check return value. */ + xmlEncOutputChunk(handler, &out->content[out->use], &written, + NULL, &toconv); + out->use += written; + out->content[out->use] = 0; #ifdef DEBUG_ENCODING xmlGenericError(xmlGenericErrorContext, "initialized encoder\n"); @@ -2700,61 +2608,18 @@ retry: xmlBufferGrow(out, toconv * 4); written = out->size - out->use - 1; } - if (handler->output != NULL) { - ret = handler->output(&out->content[out->use], &written, - in->content, &toconv); - if (written > 0) { - xmlBufferShrink(in, toconv); - out->use += written; - writtentot += written; - } - out->content[out->use] = 0; - } -#ifdef LIBXML_ICONV_ENABLED - else if (handler->iconv_out != NULL) { - ret = xmlIconvWrapper(handler->iconv_out, &out->content[out->use], - &written, in->content, &toconv); - xmlBufferShrink(in, toconv); - out->use += written; - writtentot += written; - out->content[out->use] = 0; - if (ret == -1) { - if (written > 0) { - /* - * Can be a limitation of iconv - */ - charref_len = 0; - goto retry; - } - ret = -3; - } - } -#endif /* LIBXML_ICONV_ENABLED */ -#ifdef LIBXML_ICU_ENABLED - else if (handler->uconv_out != NULL) { - ret = xmlUconvWrapper(handler->uconv_out, 0, - &out->content[out->use], - &written, in->content, &toconv); - xmlBufferShrink(in, toconv); - out->use += written; - writtentot += written; - out->content[out->use] = 0; - if (ret == -1) { - if (written > 0) { - /* - * Can be a limitation of iconv - */ - charref_len = 0; - goto retry; - } - ret = -3; - } - } -#endif /* LIBXML_ICU_ENABLED */ - else { - xmlEncodingErr(XML_I18N_NO_OUTPUT, - "xmlCharEncOutFunc: no output function !\n", NULL); - return(-1); + ret = xmlEncOutputChunk(handler, &out->content[out->use], &written, + in->content, &toconv); + xmlBufferShrink(in, toconv); + out->use += written; + writtentot += written; + out->content[out->use] = 0; + if (ret == -1) { + if (written > 0) { + /* Can be a limitation of iconv or uconv */ + goto retry; + } + ret = -3; } if (ret >= 0) output += ret; @@ -2782,47 +2647,44 @@ retry: toconv, written, in->use); #endif break; + case -4: + xmlEncodingErr(XML_I18N_NO_OUTPUT, + "xmlCharEncOutFunc: no output function !\n", NULL); + ret = -1; + break; case -2: { + xmlChar charref[20]; int len = in->use; const xmlChar *utf = (const xmlChar *) in->content; - int cur; + int cur, charrefLen; cur = xmlGetUTF8Char(utf, &len); - if ((charref_len != 0) && (written < charref_len)) { - /* - * We attempted to insert a character reference and failed. - * Undo what was written and skip the remaining charref. - */ - out->use -= written; - writtentot -= written; - xmlBufferShrink(in, charref_len - written); - charref_len = 0; - - ret = -1; + if (cur <= 0) break; - } else if (cur > 0) { - xmlChar charref[20]; #ifdef DEBUG_ENCODING - xmlGenericError(xmlGenericErrorContext, - "handling output conversion error\n"); - xmlGenericError(xmlGenericErrorContext, - "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n", - in->content[0], in->content[1], - in->content[2], in->content[3]); + xmlGenericError(xmlGenericErrorContext, + "handling output conversion error\n"); + xmlGenericError(xmlGenericErrorContext, + "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n", + in->content[0], in->content[1], + in->content[2], in->content[3]); #endif - /* - * Removes the UTF8 sequence, and replace it by a charref - * and continue the transcoding phase, hoping the error - * did not mangle the encoder state. - */ - charref_len = snprintf((char *) &charref[0], sizeof(charref), - "&#%d;", cur); - xmlBufferShrink(in, len); - xmlBufferAddHead(in, charref, -1); - - goto retry; - } else { + /* + * Removes the UTF8 sequence, and replace it by a charref + * and continue the transcoding phase, hoping the error + * did not mangle the encoder state. + */ + charrefLen = snprintf((char *) &charref[0], sizeof(charref), + "&#%d;", cur); + xmlBufferShrink(in, len); + xmlBufferGrow(out, charrefLen * 4); + written = out->size - out->use - 1; + toconv = charrefLen; + ret = xmlEncOutputChunk(handler, &out->content[out->use], &written, + charref, &toconv); + + if ((ret < 0) || (toconv != charrefLen)) { char buf[50]; snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X", @@ -2834,8 +2696,13 @@ retry: buf); if (in->alloc != XML_BUFFER_ALLOC_IMMUTABLE) in->content[0] = ' '; + break; } - break; + + out->use += written; + writtentot += written; + out->content[out->use] = 0; + goto retry; } } return(ret); @@ -2954,54 +2821,20 @@ xmlByteConsumed(xmlParserCtxtPtr ctxt) { int ret; - if (handler->output != NULL) { - do { - toconv = in->end - cur; - written = 32000; - ret = handler->output(&convbuf[0], &written, - cur, &toconv); - if (ret == -1) return(-1); - unused += written; - cur += toconv; - } while (ret == -2); -#ifdef LIBXML_ICONV_ENABLED - } else if (handler->iconv_out != NULL) { - do { - toconv = in->end - cur; - written = 32000; - ret = xmlIconvWrapper(handler->iconv_out, &convbuf[0], - &written, cur, &toconv); - if (ret < 0) { - if (written > 0) - ret = -2; - else - return(-1); - } - unused += written; - cur += toconv; - } while (ret == -2); -#endif -#ifdef LIBXML_ICU_ENABLED - } else if (handler->uconv_out != NULL) { - do { - toconv = in->end - cur; - written = 32000; - ret = xmlUconvWrapper(handler->uconv_out, 0, &convbuf[0], - &written, cur, &toconv); - if (ret < 0) { - if (written > 0) - ret = -2; - else - return(-1); - } - unused += written; - cur += toconv; - } while (ret == -2); -#endif - } else { - /* could not find a converter */ - return(-1); - } + do { + toconv = in->end - cur; + written = 32000; + ret = xmlEncOutputChunk(handler, &convbuf[0], &written, + cur, &toconv); + if (ret < 0) { + if (written > 0) + ret = -2; + else + return(-1); + } + unused += written; + cur += toconv; + } while (ret == -2); } if (in->buf->rawconsumed < unused) return(-1); diff --git a/gnulib-local/lib/libxml/encoding.in.h b/gnulib-local/lib/libxml/encoding.in.h index 7967cc66a..c875af6fb 100644 --- a/gnulib-local/lib/libxml/encoding.in.h +++ b/gnulib-local/lib/libxml/encoding.in.h @@ -129,9 +129,14 @@ typedef int (* xmlCharEncodingOutputFunc)(unsigned char *out, int *outlen, * If iconv is supported, there are two extra fields. */ #ifdef LIBXML_ICU_ENABLED +/* Size of pivot buffer, same as icu/source/common/ucnv.cpp CHUNK_SIZE */ +#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; }; typedef struct _uconv_t uconv_t; #endif diff --git a/gnulib-local/lib/libxml/entities.c b/gnulib-local/lib/libxml/entities.c index a72afb345..43549bc5d 100644 --- a/gnulib-local/lib/libxml/entities.c +++ b/gnulib-local/lib/libxml/entities.c @@ -6,6 +6,11 @@ * daniel@veillard.com */ +/* To avoid EBCDIC trouble when parsing on zOS */ +#if defined(__MVS__) +#pragma convert("ISO8859-1") +#endif + #define IN_LIBXML #include "libxml.h" @@ -83,7 +88,7 @@ xmlEntitiesErrMemory(const char *extra) * * Handle an out of memory condition */ -static void +static void LIBXML_ATTR_FORMAT(2,0) xmlEntitiesErr(xmlParserErrors code, const char *msg) { __xmlSimpleError(XML_FROM_TREE, code, NULL, msg, NULL); @@ -880,10 +885,9 @@ xmlCreateEntitiesTable(void) { * Deallocate the memory used by an entities in the hash table. */ static void -xmlFreeEntityWrapper(xmlEntityPtr entity, - const xmlChar *name ATTRIBUTE_UNUSED) { +xmlFreeEntityWrapper(void *entity, const xmlChar *name ATTRIBUTE_UNUSED) { if (entity != NULL) - xmlFreeEntity(entity); + xmlFreeEntity((xmlEntityPtr) entity); } /** @@ -894,7 +898,7 @@ xmlFreeEntityWrapper(xmlEntityPtr entity, */ void xmlFreeEntitiesTable(xmlEntitiesTablePtr table) { - xmlHashFree(table, (xmlHashDeallocator) xmlFreeEntityWrapper); + xmlHashFree(table, xmlFreeEntityWrapper); } #ifdef LIBXML_TREE_ENABLED @@ -906,8 +910,9 @@ xmlFreeEntitiesTable(xmlEntitiesTablePtr table) { * * Returns the new xmlEntitiesPtr or NULL in case of error. */ -static xmlEntityPtr -xmlCopyEntity(xmlEntityPtr ent) { +static void * +xmlCopyEntity(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) { + xmlEntityPtr ent = (xmlEntityPtr) payload; xmlEntityPtr cur; cur = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity)); @@ -944,7 +949,7 @@ xmlCopyEntity(xmlEntityPtr ent) { */ xmlEntitiesTablePtr xmlCopyEntitiesTable(xmlEntitiesTablePtr table) { - return(xmlHashCopy(table, (xmlHashCopier) xmlCopyEntity)); + return(xmlHashCopy(table, xmlCopyEntity)); } #endif /* LIBXML_TREE_ENABLED */ @@ -1085,8 +1090,9 @@ xmlDumpEntityDecl(xmlBufferPtr buf, xmlEntityPtr ent) { * When using the hash table scan function, arguments need to be reversed */ static void -xmlDumpEntityDeclScan(xmlEntityPtr ent, xmlBufferPtr buf) { - xmlDumpEntityDecl(buf, ent); +xmlDumpEntityDeclScan(void *ent, void *buf, + const xmlChar *name ATTRIBUTE_UNUSED) { + xmlDumpEntityDecl((xmlBufferPtr) buf, (xmlEntityPtr) ent); } /** @@ -1098,7 +1104,7 @@ xmlDumpEntityDeclScan(xmlEntityPtr ent, xmlBufferPtr buf) { */ void xmlDumpEntitiesTable(xmlBufferPtr buf, xmlEntitiesTablePtr table) { - xmlHashScan(table, (xmlHashScanner)xmlDumpEntityDeclScan, buf); + xmlHashScan(table, xmlDumpEntityDeclScan, buf); } #endif /* LIBXML_OUTPUT_ENABLED */ #define bottom_entities diff --git a/gnulib-local/lib/libxml/error.c b/gnulib-local/lib/libxml/error.c index 9c4504055..50e9e6f86 100644 --- a/gnulib-local/lib/libxml/error.c +++ b/gnulib-local/lib/libxml/error.c @@ -18,7 +18,7 @@ void XMLCDECL xmlGenericErrorDefaultFunc (void *ctx ATTRIBUTE_UNUSED, const char *msg, - ...); + ...) LIBXML_ATTR_FORMAT(2,3); #define XML_GET_VAR_STR(msg, str) { \ int size, prev_size = -1; \ @@ -177,8 +177,8 @@ xmlParserPrintFileContextInternal(xmlParserInputPtr input , xmlChar content[81]; /* space for 80 chars + line terminator */ xmlChar *ctnt; - if ((input == NULL) || (input->cur == NULL) || - (*input->cur == 0)) return; + if ((input == NULL) || (input->cur == NULL)) + return; cur = input->cur; base = input->base; @@ -853,7 +853,7 @@ xmlParserValidityWarning(void *ctx, const char *msg, ...) * Get the last global error registered. This is per thread if compiled * with thread support. * - * Returns NULL if no error occured or a pointer to the error + * Returns NULL if no error occurred or a pointer to the error */ xmlErrorPtr xmlGetLastError(void) @@ -910,7 +910,7 @@ xmlResetLastError(void) * * Get the last parsing error registered. * - * Returns NULL if no error occured or a pointer to the error + * Returns NULL if no error occurred or a pointer to the error */ xmlErrorPtr xmlCtxtGetLastError(void *ctx) diff --git a/gnulib-local/lib/libxml/globals.c b/gnulib-local/lib/libxml/globals.c index 0f8bf05a2..5655afe61 100644 --- a/gnulib-local/lib/libxml/globals.c +++ b/gnulib-local/lib/libxml/globals.c @@ -96,7 +96,7 @@ xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup; * * The variable holding the libxml free() implementation */ -xmlFreeFunc xmlFree = (xmlFreeFunc) free; +xmlFreeFunc xmlFree = free; /** * xmlMalloc: * @size: the size requested in bytes @@ -105,7 +105,7 @@ xmlFreeFunc xmlFree = (xmlFreeFunc) free; * * Returns a pointer to the newly allocated block or NULL in case of error */ -xmlMallocFunc xmlMalloc = (xmlMallocFunc) malloc; +xmlMallocFunc xmlMalloc = malloc; /** * xmlMallocAtomic: * @size: the size requested in bytes @@ -116,7 +116,7 @@ xmlMallocFunc xmlMalloc = (xmlMallocFunc) malloc; * * Returns a pointer to the newly allocated block or NULL in case of error */ -xmlMallocFunc xmlMallocAtomic = (xmlMallocFunc) malloc; +xmlMallocFunc xmlMallocAtomic = malloc; /** * xmlRealloc: * @mem: an already allocated block of memory @@ -126,7 +126,19 @@ xmlMallocFunc xmlMallocAtomic = (xmlMallocFunc) malloc; * * Returns a pointer to the newly reallocated block or NULL in case of error */ -xmlReallocFunc xmlRealloc = (xmlReallocFunc) realloc; +xmlReallocFunc xmlRealloc = realloc; +/** + * xmlPosixStrdup + * @cur: the input char * + * + * a strdup implementation with a type signature matching POSIX + * + * Returns a new xmlChar * or NULL + */ +static char * +xmlPosixStrdup(const char *cur) { + return((char*) xmlCharStrdup(cur)); +} /** * xmlMemStrdup: * @str: a zero terminated string @@ -135,7 +147,7 @@ xmlReallocFunc xmlRealloc = (xmlReallocFunc) realloc; * * Returns the copy of the string or NULL in case of error */ -xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlStrdup; +xmlStrdupFunc xmlMemStrdup = xmlPosixStrdup; #endif /* DEBUG_MEMORY_LOCATION || DEBUG_MEMORY */ #include diff --git a/gnulib-local/lib/libxml/globals.in.h b/gnulib-local/lib/libxml/globals.in.h index 1f6ad1793..6774afd30 100644 --- a/gnulib-local/lib/libxml/globals.in.h +++ b/gnulib-local/lib/libxml/globals.in.h @@ -17,7 +17,6 @@ #include #include #include -#include #include #include diff --git a/gnulib-local/lib/libxml/hash.c b/gnulib-local/lib/libxml/hash.c index f9a201722..b0b4abc92 100644 --- a/gnulib-local/lib/libxml/hash.c +++ b/gnulib-local/lib/libxml/hash.c @@ -168,7 +168,7 @@ xmlHashComputeQKey(xmlHashTablePtr table, * * Create a new xmlHashTablePtr. * - * Returns the newly created object, or NULL if an error occured. + * Returns the newly created object, or NULL if an error occurred. */ xmlHashTablePtr xmlHashCreate(int size) { @@ -202,7 +202,7 @@ xmlHashCreate(int size) { * * Create a new xmlHashTablePtr which will use @dict as the internal dictionary * - * Returns the newly created object, or NULL if an error occured. + * Returns the newly created object, or NULL if an error occurred. */ xmlHashTablePtr xmlHashCreateDict(int size, xmlDictPtr dict) { @@ -360,6 +360,18 @@ xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) { xmlFree(table); } +/** + * xmlHashDefaultDeallocator: + * @entry: the hash table entry + * @name: the entry's name + * + * Free a hash table entry with xmlFree. + */ +void +xmlHashDefaultDeallocator(void *entry, const xmlChar *name ATTRIBUTE_UNUSED) { + xmlFree(entry); +} + /** * xmlHashAddEntry: * @table: the hash table @@ -912,8 +924,11 @@ void xmlHashScan3(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2, const xmlChar *name3, xmlHashScanner f, void *data) { - xmlHashScanFull3 (table, name, name2, name3, - (xmlHashScannerFull) f, data); + stubData stubdata; + stubdata.data = data; + stubdata.hashscanner = f; + xmlHashScanFull3(table, name, name2, name3, stubHashScannerFull, + &stubdata); } /** diff --git a/gnulib-local/lib/libxml/hash.in.h b/gnulib-local/lib/libxml/hash.in.h index dc8ab7ec5..6352874ef 100644 --- a/gnulib-local/lib/libxml/hash.in.h +++ b/gnulib-local/lib/libxml/hash.in.h @@ -66,7 +66,7 @@ extern "C" { * * Callback to free data from a hash. */ -typedef void (*xmlHashDeallocator)(void *payload, xmlChar *name); +typedef void (*xmlHashDeallocator)(void *payload, const xmlChar *name); /** * xmlHashCopier: * @payload: the data in the hash @@ -76,7 +76,7 @@ typedef void (*xmlHashDeallocator)(void *payload, xmlChar *name); * * Returns a copy of the data or NULL in case of error. */ -typedef void *(*xmlHashCopier)(void *payload, xmlChar *name); +typedef void *(*xmlHashCopier)(void *payload, const xmlChar *name); /** * xmlHashScanner: * @payload: the data in the hash @@ -85,7 +85,7 @@ typedef void *(*xmlHashCopier)(void *payload, xmlChar *name); * * Callback when scanning data in a hash with the simple scanner. */ -typedef void (*xmlHashScanner)(void *payload, void *data, xmlChar *name); +typedef void (*xmlHashScanner)(void *payload, void *data, const xmlChar *name); /** * xmlHashScannerFull: * @payload: the data in the hash @@ -111,6 +111,9 @@ XMLPUBFUN xmlHashTablePtr XMLCALL XMLPUBFUN void XMLCALL xmlHashFree (xmlHashTablePtr table, xmlHashDeallocator f); +XMLPUBFUN void XMLCALL + xmlHashDefaultDeallocator(void *entry, + const xmlChar *name); /* * Add a new entry to the hash table. diff --git a/gnulib-local/lib/libxml/libxml.h b/gnulib-local/lib/libxml/libxml.h index 24b2b57a4..031ddd4e1 100644 --- a/gnulib-local/lib/libxml/libxml.h +++ b/gnulib-local/lib/libxml/libxml.h @@ -9,6 +9,8 @@ #ifndef __XML_LIBXML_H__ #define __XML_LIBXML_H__ +#include + #ifndef NO_LARGEFILE_SOURCE #ifndef _LARGEFILE_SOURCE #define _LARGEFILE_SOURCE @@ -58,6 +60,18 @@ int vfprintf(FILE *, const char *, va_list); #include "trio.h" #endif +#if defined(__clang__) || \ + (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) +#define XML_IGNORE_PEDANTIC_WARNINGS \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wpedantic\"") +#define XML_POP_WARNINGS \ + _Pragma("GCC diagnostic pop") +#else +#define XML_IGNORE_PEDANTIC_WARNINGS +#define XML_POP_WARNINGS +#endif + /* * Internal variable indicating if a callback has been registered for * node creation/destruction. It avoids spending a lot of time in locking @@ -68,7 +82,7 @@ extern int __xmlRegisterCallbacks; * internal error reporting routines, shared but not partof the API. */ void __xmlIOErr(int domain, int code, const char *extra); -void __xmlLoaderErr(void *ctx, const char *msg, const char *filename); +void __xmlLoaderErr(void *ctx, const char *msg, const char *filename) LIBXML_ATTR_FORMAT(2,0); #ifdef LIBXML_HTML_ENABLED /* * internal function of HTML parser needed for xmlParseInNodeContext @@ -93,12 +107,13 @@ int __xmlInitializeDict(void); int __xmlRandom(void); #endif -int xmlNop(void); +XMLPUBFUN xmlChar * XMLCALL xmlEscapeFormatString(xmlChar **msg); +int xmlInputReadCallbackNop(void *context, char *buffer, int len); #ifdef IN_LIBXML #ifdef __GNUC__ #ifdef PIC -#ifdef linux +#ifdef __linux__ #if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ > 3) #include "elfgcchack.h" #endif @@ -106,7 +121,7 @@ int xmlNop(void); #endif #endif #endif -#if !defined(PIC) && !defined(NOLIBTOOL) +#if !defined(PIC) && !defined(NOLIBTOOL) && !defined(LIBXML_STATIC) # define LIBXML_STATIC 1 #endif #endif /* ! __XML_LIBXML_H__ */ diff --git a/gnulib-local/lib/libxml/list.c b/gnulib-local/lib/libxml/list.c index d33d92818..24da6b1e9 100644 --- a/gnulib-local/lib/libxml/list.c +++ b/gnulib-local/lib/libxml/list.c @@ -347,7 +347,7 @@ void xmlListDelete(xmlListPtr l) * * Remove the first instance associated to data in the list * - * Returns 1 if a deallocation occured, or 0 if not found + * Returns 1 if a deallocation occurred, or 0 if not found */ int xmlListRemoveFirst(xmlListPtr l, void *data) @@ -372,7 +372,7 @@ xmlListRemoveFirst(xmlListPtr l, void *data) * * Remove the last instance associated to data in the list * - * Returns 1 if a deallocation occured, or 0 if not found + * Returns 1 if a deallocation occurred, or 0 if not found */ int xmlListRemoveLast(xmlListPtr l, void *data) @@ -673,7 +673,7 @@ xmlListSort(xmlListPtr l) * apply the walker function to it */ void -xmlListWalk(xmlListPtr l, xmlListWalker walker, const void *user) { +xmlListWalk(xmlListPtr l, xmlListWalker walker, void *user) { xmlLinkPtr lk; if ((l == NULL) || (walker == NULL)) @@ -694,7 +694,7 @@ xmlListWalk(xmlListPtr l, xmlListWalker walker, const void *user) { * apply the walker function to it */ void -xmlListReverseWalk(xmlListPtr l, xmlListWalker walker, const void *user) { +xmlListReverseWalk(xmlListPtr l, xmlListWalker walker, void *user) { xmlLinkPtr lk; if ((l == NULL) || (walker == NULL)) diff --git a/gnulib-local/lib/libxml/list.in.h b/gnulib-local/lib/libxml/list.in.h index 0504e0cff..3211c7552 100644 --- a/gnulib-local/lib/libxml/list.in.h +++ b/gnulib-local/lib/libxml/list.in.h @@ -49,7 +49,7 @@ typedef int (*xmlListDataCompare) (const void *data0, const void *data1); * * Returns 0 to stop walking the list, 1 otherwise. */ -typedef int (*xmlListWalker) (const void *data, const void *user); +typedef int (*xmlListWalker) (const void *data, void *user); /* Creation/Deletion */ XMLPUBFUN xmlListPtr XMLCALL @@ -110,11 +110,11 @@ XMLPUBFUN void XMLCALL XMLPUBFUN void XMLCALL xmlListWalk (xmlListPtr l, xmlListWalker walker, - const void *user); + void *user); XMLPUBFUN void XMLCALL xmlListReverseWalk (xmlListPtr l, xmlListWalker walker, - const void *user); + void *user); XMLPUBFUN void XMLCALL xmlListMerge (xmlListPtr l1, xmlListPtr l2); diff --git a/gnulib-local/lib/libxml/nanoftp.c b/gnulib-local/lib/libxml/nanoftp.c index 2135ab9b0..54fa026d1 100644 --- a/gnulib-local/lib/libxml/nanoftp.c +++ b/gnulib-local/lib/libxml/nanoftp.c @@ -12,8 +12,6 @@ #define HAVE_NETINET_IN_H #define HAVE_NETDB_H #define HAVE_SYS_TIME_H -#else /* TESTING */ -#define NEED_SOCKETS #endif /* TESTING */ #define IN_LIBXML @@ -77,14 +75,8 @@ #endif -#if defined(__MINGW32__) || defined(_WIN32_WCE) -#ifndef _WINSOCKAPI_ -#define _WINSOCKAPI_ -#endif +#if defined(_WIN32) && !defined(__CYGWIN__) #include -#include -#undef XML_SOCKLEN_T -#define XML_SOCKLEN_T unsigned int #endif /** @@ -511,6 +503,8 @@ xmlNanoFTPFreeCtxt(void * ctx) { if (ctxt->hostname != NULL) xmlFree(ctxt->hostname); if (ctxt->protocol != NULL) xmlFree(ctxt->protocol); if (ctxt->path != NULL) xmlFree(ctxt->path); + if (ctxt->user != NULL) xmlFree(ctxt->user); + if (ctxt->passwd != NULL) xmlFree(ctxt->passwd); ctxt->passive = 1; if (ctxt->controlFd != INVALID_SOCKET) closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET; @@ -907,7 +901,7 @@ xmlNanoFTPConnect(void *ctx) { __xmlIOErr(XML_FROM_FTP, 0, "getaddrinfo failed"); return (-1); } - if (tmp->ai_addrlen > sizeof(ctxt->ftpAddr)) { + if ((size_t)tmp->ai_addrlen > sizeof(ctxt->ftpAddr)) { if (result) freeaddrinfo (result); __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname address mismatch"); @@ -1042,6 +1036,7 @@ xmlNanoFTPConnect(void *ctx) { case 2: if (proxyPasswd == NULL) break; + /* Falls through. */ case 3: if (proxyPasswd != NULL) snprintf(buf, sizeof(buf), "PASS %s\r\n", proxyPasswd); @@ -1111,6 +1106,7 @@ xmlNanoFTPConnect(void *ctx) { ctxt->controlFd = INVALID_SOCKET; return(-1); } + /* Falls through. */ case 2: /* USER user@host command */ if (ctxt->user == NULL) @@ -1164,6 +1160,7 @@ xmlNanoFTPConnect(void *ctx) { ctxt->controlFd = INVALID_SOCKET; return(-1); } + /* Falls through. */ case 3: /* * If you need support for other Proxy authentication scheme @@ -1212,6 +1209,7 @@ xmlNanoFTPConnect(void *ctx) { case 3: __xmlIOErr(XML_FROM_FTP, XML_FTP_ACCNT, "FTP server asking for ACCNT on anonymous\n"); + /* Falls through. */ case 1: case 4: case 5: diff --git a/gnulib-local/lib/libxml/nanoftp.in.h b/gnulib-local/lib/libxml/nanoftp.in.h index abb4bf714..7335faf10 100644 --- a/gnulib-local/lib/libxml/nanoftp.in.h +++ b/gnulib-local/lib/libxml/nanoftp.in.h @@ -16,7 +16,7 @@ #ifdef LIBXML_FTP_ENABLED /* Needed for portability to Windows 64 bits */ -#if defined(__MINGW32__) || defined(_WIN32_WCE) +#if defined(_WIN32) && !defined(__CYGWIN__) #include #else /** diff --git a/gnulib-local/lib/libxml/nanohttp.c b/gnulib-local/lib/libxml/nanohttp.c index e109ad753..2143718a1 100644 --- a/gnulib-local/lib/libxml/nanohttp.c +++ b/gnulib-local/lib/libxml/nanohttp.c @@ -11,7 +11,6 @@ * daniel@veillard.com */ -#define NEED_SOCKETS #define IN_LIBXML #include "libxml.h" @@ -64,7 +63,7 @@ #ifdef HAVE_STRINGS_H #include #endif -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED #include #endif @@ -74,14 +73,8 @@ #define XML_SOCKLEN_T unsigned int #endif -#if defined(__MINGW32__) || defined(_WIN32_WCE) -#ifndef _WINSOCKAPI_ -#define _WINSOCKAPI_ -#endif +#if defined(_WIN32) && !defined(__CYGWIN__) #include -#include -#undef XML_SOCKLEN_T -#define XML_SOCKLEN_T unsigned int #endif #include @@ -152,7 +145,7 @@ typedef struct xmlNanoHTTPCtxt { char *authHeader; /* contents of {WWW,Proxy}-Authenticate header */ char *encoding; /* encoding extracted from the contentType */ char *mimeType; /* Mime-Type extracted from the contentType */ -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED z_stream *strm; /* Zlib stream object */ int usesGzip; /* "Content-Encoding: gzip" was detected */ #endif @@ -182,7 +175,21 @@ xmlHTTPErrMemory(const char *extra) */ static int socket_errno(void) { #ifdef _WINSOCKAPI_ - return(WSAGetLastError()); + int err = WSAGetLastError(); + switch(err) { + case WSAECONNRESET: + return(ECONNRESET); + case WSAEINPROGRESS: + return(EINPROGRESS); + case WSAEINTR: + return(EINTR); + case WSAESHUTDOWN: + return(ESHUTDOWN); + case WSAEWOULDBLOCK: + return(EWOULDBLOCK); + default: + return(err); + } #else return(errno); #endif @@ -427,7 +434,7 @@ xmlNanoHTTPFreeCtxt(xmlNanoHTTPCtxtPtr ctxt) { if (ctxt->mimeType != NULL) xmlFree(ctxt->mimeType); if (ctxt->location != NULL) xmlFree(ctxt->location); if (ctxt->authHeader != NULL) xmlFree(ctxt->authHeader); -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED if (ctxt->strm != NULL) { inflateEnd(ctxt->strm); xmlFree(ctxt->strm); @@ -629,7 +636,7 @@ xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt) if ((select(ctxt->fd + 1, &rfd, NULL, NULL, &tv) < 1) #if defined(EINTR) - && (errno != EINTR) + && (socket_errno() != EINTR) #endif ) return (0); @@ -810,7 +817,7 @@ xmlNanoHTTPScanAnswer(xmlNanoHTTPCtxtPtr ctxt, const char *line) { if (ctxt->authHeader != NULL) xmlFree(ctxt->authHeader); ctxt->authHeader = xmlMemStrdup(cur); -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED } else if ( !xmlStrncasecmp( BAD_CAST line, BAD_CAST"Content-Encoding:", 17) ) { cur += 17; while ((*cur == ' ') || (*cur == '\t')) cur++; @@ -1038,16 +1045,13 @@ xmlNanoHTTPConnectAttempt(struct sockaddr *addr) static SOCKET xmlNanoHTTPConnectHost(const char *host, int port) { - struct hostent *h; struct sockaddr *addr = NULL; - struct in_addr ia; struct sockaddr_in sockin; #ifdef SUPPORT_IP6 struct in6_addr ia6; struct sockaddr_in6 sockin6; #endif - int i; SOCKET s; memset (&sockin, 0, sizeof(sockin)); @@ -1084,7 +1088,7 @@ xmlNanoHTTPConnectHost(const char *host, int port) for (res = result; res; res = res->ai_next) { if (res->ai_family == AF_INET) { - if (res->ai_addrlen > sizeof(sockin)) { + if ((size_t)res->ai_addrlen > sizeof(sockin)) { __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n"); freeaddrinfo (result); return INVALID_SOCKET; @@ -1094,7 +1098,7 @@ xmlNanoHTTPConnectHost(const char *host, int port) addr = (struct sockaddr *)&sockin; #ifdef SUPPORT_IP6 } else if (have_ipv6 () && (res->ai_family == AF_INET6)) { - if (res->ai_addrlen > sizeof(sockin6)) { + if ((size_t)res->ai_addrlen > sizeof(sockin6)) { __xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n"); freeaddrinfo (result); return INVALID_SOCKET; @@ -1122,6 +1126,10 @@ xmlNanoHTTPConnectHost(const char *host, int port) #endif #if !defined(HAVE_GETADDRINFO) || !defined(_WIN32) { + struct hostent *h; + struct in_addr ia; + int i; + h = gethostbyname (GETHOSTBYNAME_ARG_CAST host); if (h == NULL) { @@ -1130,7 +1138,7 @@ xmlNanoHTTPConnectHost(const char *host, int port) * extraction code. it work on Linux, if it work on your platform * and one want to enable it, send me the defined(foobar) needed */ -#if defined(HAVE_NETDB_H) && defined(HOST_NOT_FOUND) && defined(linux) +#if defined(HAVE_NETDB_H) && defined(HOST_NOT_FOUND) && defined(__linux__) const char *h_err_txt = ""; switch (h_errno) { @@ -1265,7 +1273,7 @@ xmlNanoHTTPOpenRedir(const char *URL, char **contentType, char **redir) { int xmlNanoHTTPRead(void *ctx, void *dest, int len) { xmlNanoHTTPCtxtPtr ctxt = (xmlNanoHTTPCtxtPtr) ctx; -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED int bytes_read = 0; int orig_avail_in; int z_ret; @@ -1275,7 +1283,7 @@ xmlNanoHTTPRead(void *ctx, void *dest, int len) { if (dest == NULL) return(-1); if (len <= 0) return(0); -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED if (ctxt->usesGzip == 1) { if (ctxt->strm == NULL) return(0); @@ -1416,16 +1424,16 @@ retry: /* 1 for '?' */ blen += strlen(ctxt->query) + 1; blen += strlen(method) + strlen(ctxt->path) + 24; -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED /* reserve for possible 'Accept-Encoding: gzip' string */ blen += 23; #endif if (ctxt->port != 80) { /* reserve space for ':xxxxx', incl. potential proxy */ if (proxy) - blen += 12; + blen += 17; else - blen += 6; + blen += 11; } bp = (char*)xmlMallocAtomic(blen); if ( bp == NULL ) { @@ -1460,7 +1468,7 @@ retry: ctxt->hostname, ctxt->port); } -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED p += snprintf(p, blen - (p - bp), "Accept-Encoding: gzip\r\n"); #endif @@ -1534,7 +1542,8 @@ retry: xmlGenericError(xmlGenericErrorContext, "\nRedirect to: %s\n", ctxt->location); #endif - while ( xmlNanoHTTPRecv(ctxt) > 0 ) ; + while ( xmlNanoHTTPRecv(ctxt) > 0 ) + ; if (nbRedirects < XML_NANO_HTTP_MAX_REDIR) { nbRedirects++; if (redirURL != NULL) diff --git a/gnulib-local/lib/libxml/parser.c b/gnulib-local/lib/libxml/parser.c index c5741e3b8..5813a6643 100644 --- a/gnulib-local/lib/libxml/parser.c +++ b/gnulib-local/lib/libxml/parser.c @@ -30,10 +30,15 @@ * daniel@veillard.com */ +/* To avoid EBCDIC trouble when parsing on zOS */ +#if defined(__MVS__) +#pragma convert("ISO8859-1") +#endif + #define IN_LIBXML #include "libxml.h" -#if defined(WIN32) && !defined (__CYGWIN__) +#if defined(_WIN32) && !defined (__CYGWIN__) #define XML_DIR_SEP '\\' #else #define XML_DIR_SEP '/' @@ -43,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -77,12 +83,6 @@ #ifdef HAVE_UNISTD_H #include #endif -#ifdef HAVE_ZLIB_H -#include -#endif -#ifdef HAVE_LZMA_H -#include -#endif #include "buf.h" #include "enc.h" @@ -138,14 +138,20 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size, * entities problems */ if ((ent != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) && - (ent->content != NULL) && (ent->checked == 0)) { + (ent->content != NULL) && (ent->checked == 0) && + (ctxt->errNo != XML_ERR_ENTITY_LOOP)) { unsigned long oldnbent = ctxt->nbentities; xmlChar *rep; ent->checked = 1; + ++ctxt->depth; rep = xmlStringDecodeEntities(ctxt, ent->content, XML_SUBSTITUTE_REF, 0, 0, 0); + --ctxt->depth; + if ((rep == NULL) || (ctxt->errNo == XML_ERR_ENTITY_LOOP)) { + ent->content[0] = 0; + } ent->checked = (ctxt->nbentities - oldnbent + 1) * 2; if (rep != NULL) { @@ -344,7 +350,6 @@ static void xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info) { const char *errmsg; - char errstr[129] = ""; if ((ctxt != NULL) && (ctxt->disableSAX != 0) && (ctxt->instate == XML_PARSER_EOF)) @@ -531,15 +536,17 @@ xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info) default: errmsg = "Unregistered error message"; } - if (info == NULL) - snprintf(errstr, 128, "%s\n", errmsg); - else - snprintf(errstr, 128, "%s: %%s\n", errmsg); if (ctxt != NULL) ctxt->errNo = error; - __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error, - XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, &errstr[0], - info); + if (info == NULL) { + __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error, + XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s\n", + errmsg); + } else { + __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error, + XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s: %s\n", + errmsg, info); + } if (ctxt != NULL) { ctxt->wellFormed = 0; if (ctxt->recovery == 0) @@ -555,7 +562,7 @@ xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info) * * Handle a fatal parser error, i.e. violating Well-Formedness constraints */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg) { @@ -583,7 +590,7 @@ xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, * * Handle a warning. */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar *str1, const xmlChar *str2) { @@ -621,7 +628,7 @@ xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, * * Handle a validity error. */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar *str1, const xmlChar *str2) { @@ -661,7 +668,7 @@ xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error, * * Handle a fatal parser error, i.e. violating Well-Formedness constraints */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, int val) { @@ -691,7 +698,7 @@ xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error, * * Handle a fatal parser error, i.e. violating Well-Formedness constraints */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar *str1, int val, const xmlChar *str2) @@ -721,7 +728,7 @@ xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error, * * Handle a fatal parser error, i.e. violating Well-Formedness constraints */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar * val) { @@ -750,7 +757,7 @@ xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error, * * Handle a non fatal parser error */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar * val) { @@ -775,7 +782,7 @@ xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error, * * Handle a fatal parser error, i.e. violating Well-Formedness constraints */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar * info1, const xmlChar * info2, @@ -804,7 +811,7 @@ xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, * * Handle a namespace warning error */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, const xmlChar * info1, const xmlChar * info2, @@ -1080,7 +1087,12 @@ typedef xmlDefAttrs *xmlDefAttrsPtr; struct _xmlDefAttrs { int nbAttrs; /* number of defaulted attributes on that element */ int maxAttrs; /* the size of the array */ - const xmlChar *values[5]; /* array of localname/prefix/values/external */ +#if __STDC_VERSION__ >= 199901L + /* Using a C99 flexible array member avoids UBSan errors. */ + const xmlChar *values[]; /* array of localname/prefix/values/external */ +#else + const xmlChar *values[5]; +#endif }; /** @@ -1317,7 +1329,7 @@ xmlAddSpecialAttr(xmlParserCtxtPtr ctxt, return; xmlHashAddEntry2(ctxt->attsSpecial, fullname, fullattr, - (void *) (long) type); + (void *) (ptrdiff_t) type); return; mem_error: @@ -1336,7 +1348,7 @@ xmlCleanSpecialAttrCallback(void *payload, void *data, const xmlChar *unused ATTRIBUTE_UNUSED) { xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) data; - if (((long) payload) == XML_ATTRIBUTE_CDATA) { + if (((ptrdiff_t) payload) == XML_ATTRIBUTE_CDATA) { xmlHashRemoveEntry2(ctxt->attsSpecial, fullname, fullattr, NULL); } } @@ -1848,7 +1860,7 @@ nameNsPush(xmlParserCtxtPtr ctxt, const xmlChar * value, ctxt->name = value; ctxt->pushTab[ctxt->nameNr * 3] = (void *) prefix; ctxt->pushTab[ctxt->nameNr * 3 + 1] = (void *) URI; - ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (long) nsNr; + ctxt->pushTab[ctxt->nameNr * 3 + 2] = (void *) (ptrdiff_t) nsNr; return (ctxt->nameNr++); mem_error: xmlErrMemory(ctxt, NULL); @@ -2008,6 +2020,7 @@ static int spacePop(xmlParserCtxtPtr ctxt) { #define CUR (*ctxt->input->cur) #define NXT(val) ctxt->input->cur[(val)] #define CUR_PTR ctxt->input->cur +#define BASE_PTR ctxt->input->base #define CMP4( s, c1, c2, c3, c4 ) \ ( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \ @@ -2029,10 +2042,8 @@ static int spacePop(xmlParserCtxtPtr ctxt) { #define SKIP(val) do { \ ctxt->nbChars += (val),ctxt->input->cur += (val),ctxt->input->col+=(val); \ - if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \ - if ((*ctxt->input->cur == 0) && \ - (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) \ - xmlPopInput(ctxt); \ + if (*ctxt->input->cur == 0) \ + xmlParserInputGrow(ctxt->input, INPUT_CHUNK); \ } while (0) #define SKIPL(val) do { \ @@ -2044,10 +2055,8 @@ static int spacePop(xmlParserCtxtPtr ctxt) { ctxt->nbChars++; \ ctxt->input->cur++; \ } \ - if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \ - if ((*ctxt->input->cur == 0) && \ - (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) \ - xmlPopInput(ctxt); \ + if (*ctxt->input->cur == 0) \ + xmlParserInputGrow(ctxt->input, INPUT_CHUNK); \ } while (0) #define SHRINK if ((ctxt->progressive == 0) && \ @@ -2057,10 +2066,9 @@ static int spacePop(xmlParserCtxtPtr ctxt) { static void xmlSHRINK (xmlParserCtxtPtr ctxt) { xmlParserInputShrink(ctxt->input); - if ((*ctxt->input->cur == 0) && - (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) - xmlPopInput(ctxt); - } + if (*ctxt->input->cur == 0) + xmlParserInputGrow(ctxt->input, INPUT_CHUNK); +} #define GROW if ((ctxt->progressive == 0) && \ (ctxt->input->end - ctxt->input->cur < INPUT_CHUNK)) \ @@ -2072,7 +2080,8 @@ static void xmlGROW (xmlParserCtxtPtr ctxt) { if (((curEnd > (unsigned long) XML_MAX_LOOKUP_LIMIT) || (curBase > (unsigned long) XML_MAX_LOOKUP_LIMIT)) && - ((ctxt->input->buf) && (ctxt->input->buf->readcallback != (xmlInputReadCallback) xmlNop)) && + ((ctxt->input->buf) && + (ctxt->input->buf->readcallback != xmlInputReadCallbackNop)) && ((ctxt->options & XML_PARSE_HUGE) == 0)) { xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup"); xmlHaltParser(ctxt); @@ -2085,9 +2094,8 @@ static void xmlGROW (xmlParserCtxtPtr ctxt) { xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "cur index out of bound"); return; } - if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) && - (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) - xmlPopInput(ctxt); + if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0)) + xmlParserInputGrow(ctxt->input, INPUT_CHUNK); } #define SKIP_BLANKS xmlSkipBlankChars(ctxt) @@ -2107,7 +2115,6 @@ static void xmlGROW (xmlParserCtxtPtr ctxt) { ctxt->input->line++; ctxt->input->col = 1; \ } else ctxt->input->col++; \ ctxt->input->cur += l; \ - if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \ } while (0) #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l) @@ -2157,26 +2164,35 @@ xmlSkipBlankChars(xmlParserCtxtPtr ctxt) { } ctxt->input->cur = cur; } else { - int cur; - do { - cur = CUR; - while ((IS_BLANK_CH(cur) && /* CHECKED tstblanks.xml */ - (ctxt->instate != XML_PARSER_EOF))) { + int expandPE = ((ctxt->external != 0) || (ctxt->inputNr != 1)); + + while (1) { + if (IS_BLANK_CH(CUR)) { /* CHECKED tstblanks.xml */ NEXT; - cur = CUR; - res++; - } - while ((cur == 0) && (ctxt->inputNr > 1) && - (ctxt->instate != XML_PARSER_COMMENT)) { - xmlPopInput(ctxt); - cur = CUR; - } - /* - * Need to handle support of entities branching here - */ - if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); - } while ((IS_BLANK(cur)) && /* CHECKED tstblanks.xml */ - (ctxt->instate != XML_PARSER_EOF)); + } else if (CUR == '%') { + /* + * Need to handle support of entities branching here + */ + if ((expandPE == 0) || (IS_BLANK_CH(NXT(1))) || (NXT(1) == 0)) + break; + xmlParsePEReference(ctxt); + } else if (CUR == 0) { + if (ctxt->inputNr <= 1) + break; + xmlPopInput(ctxt); + } else { + break; + } + + /* + * Also increase the counter when entering or exiting a PERef. + * The spec says: "When a parameter-entity reference is recognized + * in the DTD and included, its replacement text MUST be enlarged + * by the attachment of one leading and one following space (#x20) + * character." + */ + res++; + } } return(res); } @@ -2202,10 +2218,13 @@ xmlPopInput(xmlParserCtxtPtr ctxt) { if (xmlParserDebugEntities) xmlGenericError(xmlGenericErrorContext, "Popping input %d\n", ctxt->inputNr); + if ((ctxt->inputNr > 1) && (ctxt->inSubset == 0) && + (ctxt->instate != XML_PARSER_EOF)) + xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, + "Unfinished entity outside the DTD"); xmlFreeInputStream(inputPop(ctxt)); - if ((*ctxt->input->cur == 0) && - (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) - return(xmlPopInput(ctxt)); + if (*ctxt->input->cur == 0) + xmlParserInputGrow(ctxt->input, INPUT_CHUNK); return(CUR); } @@ -2231,6 +2250,13 @@ xmlPushInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr input) { 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)) { + 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); @@ -2435,57 +2461,6 @@ xmlParseStringCharRef(xmlParserCtxtPtr ctxt, const xmlChar **str) { return(0); } -/** - * xmlNewBlanksWrapperInputStream: - * @ctxt: an XML parser context - * @entity: an Entity pointer - * - * Create a new input stream for wrapping - * blanks around a PEReference - * - * Returns the new input stream or NULL - */ - -static void deallocblankswrapper (xmlChar *str) {xmlFree(str);} - -static xmlParserInputPtr -xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) { - xmlParserInputPtr input; - xmlChar *buffer; - size_t length; - if (entity == NULL) { - xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, - "xmlNewBlanksWrapperInputStream entity\n"); - return(NULL); - } - if (xmlParserDebugEntities) - xmlGenericError(xmlGenericErrorContext, - "new blanks wrapper for entity: %s\n", entity->name); - input = xmlNewInputStream(ctxt); - if (input == NULL) { - return(NULL); - } - length = xmlStrlen(entity->name) + 5; - buffer = xmlMallocAtomic(length); - if (buffer == NULL) { - xmlErrMemory(ctxt, NULL); - xmlFree(input); - return(NULL); - } - buffer [0] = ' '; - buffer [1] = '%'; - buffer [length-3] = ';'; - buffer [length-2] = ' '; - buffer [length-1] = 0; - memcpy(buffer + 2, entity->name, length - 5); - input->free = deallocblankswrapper; - input->base = buffer; - input->cur = buffer; - input->length = length; - input->end = &buffer[length]; - return(input); -} - /** * xmlParserHandlePEReference: * @ctxt: the parser context @@ -2520,11 +2495,6 @@ xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) { */ void xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) { - const xmlChar *name; - xmlEntityPtr entity = NULL; - xmlParserInputPtr input; - - if (RAW != '%') return; switch(ctxt->instate) { case XML_PARSER_CDATA_SECTION: return; @@ -2579,128 +2549,7 @@ xmlParserHandlePEReference(xmlParserCtxtPtr ctxt) { return; } - NEXT; - name = xmlParseName(ctxt); - if (xmlParserDebugEntities) - xmlGenericError(xmlGenericErrorContext, - "PEReference: %s\n", name); - if (name == NULL) { - xmlFatalErr(ctxt, XML_ERR_PEREF_NO_NAME, NULL); - } else { - if (RAW == ';') { - NEXT; - if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL)) - entity = ctxt->sax->getParameterEntity(ctxt->userData, name); - if (ctxt->instate == XML_PARSER_EOF) - return; - if (entity == NULL) { - - /* - * [ WFC: Entity Declared ] - * In a document without any DTD, a document with only an - * internal DTD subset which contains no parameter entity - * references, or a document with "standalone='yes'", ... - * ... The declaration of a parameter entity must precede - * any reference to it... - */ - if ((ctxt->standalone == 1) || - ((ctxt->hasExternalSubset == 0) && - (ctxt->hasPErefs == 0))) { - xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY, - "PEReference: %%%s; not found\n", name); - } else { - /* - * [ VC: Entity Declared ] - * In a document with an external subset or external - * parameter entities with "standalone='no'", ... - * ... The declaration of a parameter entity must precede - * any reference to it... - */ - if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) { - xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY, - "PEReference: %%%s; not found\n", - name, NULL); - } else - xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY, - "PEReference: %%%s; not found\n", - name, NULL); - ctxt->valid = 0; - } - xmlParserEntityCheck(ctxt, 0, NULL, 0); - } else if (ctxt->input->free != deallocblankswrapper) { - input = xmlNewBlanksWrapperInputStream(ctxt, entity); - if (xmlPushInput(ctxt, input) < 0) - return; - } else { - if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) || - (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) { - xmlChar start[4]; - xmlCharEncoding enc; - - /* - * Note: external parameter entities will not be loaded, it - * is not required for a non-validating parser, unless the - * option of validating, or substituting entities were - * given. Doing so is far more secure as the parser will - * only process data coming from the document entity by - * default. - */ - if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) && - ((ctxt->options & XML_PARSE_NOENT) == 0) && - ((ctxt->options & XML_PARSE_DTDVALID) == 0) && - ((ctxt->options & XML_PARSE_DTDLOAD) == 0) && - ((ctxt->options & XML_PARSE_DTDATTR) == 0) && - (ctxt->replaceEntities == 0) && - (ctxt->validate == 0)) - return; - - /* - * handle the extra spaces added before and after - * c.f. http://www.w3.org/TR/REC-xml#as-PE - * this is done independently. - */ - input = xmlNewEntityInputStream(ctxt, entity); - if (xmlPushInput(ctxt, input) < 0) - return; - - /* - * Get the 4 first bytes and decode the charset - * if enc != XML_CHAR_ENCODING_NONE - * plug some encoding conversion routines. - * Note that, since we may have some non-UTF8 - * encoding (like UTF16, bug 135229), the 'length' - * is not known, but we can calculate based upon - * the amount of data in the buffer. - */ - GROW - if (ctxt->instate == XML_PARSER_EOF) - return; - if ((ctxt->input->end - ctxt->input->cur)>=4) { - start[0] = RAW; - start[1] = NXT(1); - start[2] = NXT(2); - start[3] = NXT(3); - enc = xmlDetectCharEncoding(start, 4); - if (enc != XML_CHAR_ENCODING_NONE) { - xmlSwitchEncoding(ctxt, enc); - } - } - - if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) && - (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l' )) && - (IS_BLANK_CH(NXT(5)))) { - xmlParseTextDecl(ctxt); - } - } else { - xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_IS_PARAMETER, - "PEReference: %s is not a parameter entity\n", - name); - } - } - } else { - xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL); - } - } + xmlParsePEReference(ctxt); } /* @@ -2782,9 +2631,9 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, if (c == 0) break; if ((c == '&') && (str[1] == '#')) { int val = xmlParseStringCharRef(ctxt, &str); - if (val != 0) { - COPY_BUF(0,buffer,nbchars,val); - } + if (val == 0) + goto int_error; + COPY_BUF(0,buffer,nbchars,val); if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) { growBuffer(buffer, XML_PARSER_BUFFER_SIZE); } @@ -2794,9 +2643,6 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, "String decoding Entity Reference: %.30s\n", str); ent = xmlParseStringEntityRef(ctxt, &str); - if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) || - (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR)) - goto int_error; xmlParserEntityCheck(ctxt, 0, ent, 0); if (ent != NULL) ctxt->nbentities += ent->checked / 2; @@ -2810,30 +2656,27 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, } else { xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR, "predefined entity has no content\n"); + goto int_error; } } else if ((ent != NULL) && (ent->content != NULL)) { ctxt->depth++; rep = xmlStringDecodeEntities(ctxt, ent->content, what, 0, 0, 0); ctxt->depth--; - - if ((ctxt->lastError.code == XML_ERR_ENTITY_LOOP) || - (ctxt->lastError.code == XML_ERR_INTERNAL_ERROR)) - goto int_error; - - if (rep != NULL) { - current = rep; - while (*current != 0) { /* non input consuming loop */ - buffer[nbchars++] = *current++; - if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) { - if (xmlParserEntityCheck(ctxt, nbchars, ent, 0)) - goto int_error; - growBuffer(buffer, XML_PARSER_BUFFER_SIZE); - } - } - xmlFree(rep); - rep = NULL; - } + if (rep == NULL) + goto int_error; + + current = rep; + while (*current != 0) { /* non input consuming loop */ + buffer[nbchars++] = *current++; + if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) { + if (xmlParserEntityCheck(ctxt, nbchars, ent, 0)) + goto int_error; + growBuffer(buffer, XML_PARSER_BUFFER_SIZE); + } + } + xmlFree(rep); + rep = NULL; } else if (ent != NULL) { int i = xmlStrlen(ent->name); const xmlChar *cur = ent->name; @@ -2851,32 +2694,44 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, xmlGenericError(xmlGenericErrorContext, "String decoding PE Reference: %.30s\n", str); ent = xmlParseStringPEReference(ctxt, &str); - if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP) - goto int_error; xmlParserEntityCheck(ctxt, 0, ent, 0); if (ent != NULL) ctxt->nbentities += ent->checked / 2; if (ent != NULL) { if (ent->content == NULL) { - xmlLoadEntityContent(ctxt, ent); + /* + * Note: external parsed entities will not be loaded, + * it is not required for a non-validating parser to + * complete external PEreferences coming from the + * internal subset + */ + if (((ctxt->options & XML_PARSE_NOENT) != 0) || + ((ctxt->options & XML_PARSE_DTDVALID) != 0) || + (ctxt->validate != 0)) { + xmlLoadEntityContent(ctxt, ent); + } else { + xmlWarningMsg(ctxt, XML_ERR_ENTITY_PROCESSING, + "not validating will not read content for PE entity %s\n", + ent->name, NULL); + } } ctxt->depth++; rep = xmlStringDecodeEntities(ctxt, ent->content, what, 0, 0, 0); ctxt->depth--; - if (rep != NULL) { - current = rep; - while (*current != 0) { /* non input consuming loop */ - buffer[nbchars++] = *current++; - if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) { - if (xmlParserEntityCheck(ctxt, nbchars, ent, 0)) - goto int_error; - growBuffer(buffer, XML_PARSER_BUFFER_SIZE); - } - } - xmlFree(rep); - rep = NULL; - } + if (rep == NULL) + goto int_error; + current = rep; + while (*current != 0) { /* non input consuming loop */ + buffer[nbchars++] = *current++; + if (nbchars + XML_PARSER_BUFFER_SIZE > buffer_size) { + if (xmlParserEntityCheck(ctxt, nbchars, ent, 0)) + goto int_error; + growBuffer(buffer, XML_PARSER_BUFFER_SIZE); + } + } + xmlFree(rep); + rep = NULL; } } else { COPY_BUF(l,buffer,nbchars,c); @@ -3384,13 +3239,6 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) { len += l; NEXTL(l); c = CUR_CHAR(l); - if (c == 0) { - count = 0; - GROW; - if (ctxt->instate == XML_PARSER_EOF) - return(NULL); - c = CUR_CHAR(l); - } } } if ((len > XML_MAX_NAME_LENGTH) && @@ -3398,6 +3246,16 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) { xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name"); return(NULL); } + if (ctxt->input->cur - ctxt->input->base < len) { + /* + * There were a couple of bugs where PERefs lead to to a change + * of the buffer. Check the buffer size to avoid passing an invalid + * pointer to xmlDictLookup. + */ + xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, + "unexpected change of input buffer"); + return (NULL); + } if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r')) return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len)); return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len)); @@ -3470,7 +3328,7 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) { int len = 0, l; int c; int count = 0; - const xmlChar *end; /* needed because CUR_CHAR() can move cur on \r\n */ + size_t startPosition = 0; #ifdef DEBUG nbParseNCNameComplex++; @@ -3480,7 +3338,7 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) { * Handler for more complex cases */ GROW; - end = ctxt->input->cur; + startPosition = CUR_PTR - BASE_PTR; c = CUR_CHAR(l); if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */ (!xmlIsNameStartChar(ctxt, c) || (c == ':'))) { @@ -3502,7 +3360,6 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) { } len += l; NEXTL(l); - end = ctxt->input->cur; c = CUR_CHAR(l); if (c == 0) { count = 0; @@ -3513,10 +3370,9 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) { */ ctxt->input->cur -= l; GROW; - ctxt->input->cur += l; if (ctxt->instate == XML_PARSER_EOF) return(NULL); - end = ctxt->input->cur; + ctxt->input->cur += l; c = CUR_CHAR(l); } } @@ -3525,7 +3381,7 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) { xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName"); return(NULL); } - return(xmlDictLookup(ctxt->dict, end - len, len)); + return(xmlDictLookup(ctxt->dict, (BASE_PTR + startPosition), len)); } /** @@ -3625,7 +3481,7 @@ xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) { } /* failure (or end of input buffer), check with full function */ ret = xmlParseName (ctxt); - /* strings coming from the dictionnary direct compare possible */ + /* strings coming from the dictionary direct compare possible */ if (ret == other) { return (const xmlChar*) 1; } @@ -3872,10 +3728,8 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) { ctxt->instate = XML_PARSER_ENTITY_VALUE; input = ctxt->input; GROW; - if (ctxt->instate == XML_PARSER_EOF) { - xmlFree(buf); - return(NULL); - } + if (ctxt->instate == XML_PARSER_EOF) + goto error; NEXT; c = CUR_CHAR(l); /* @@ -3896,18 +3750,12 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) { tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar)); if (tmp == NULL) { xmlErrMemory(ctxt, NULL); - xmlFree(buf); - return(NULL); + goto error; } buf = tmp; } COPY_BUF(l,buf,len,c); NEXTL(l); - /* - * Pop-up of finished entities. - */ - while ((RAW == 0) && (ctxt->inputNr > 1)) /* non input consuming */ - xmlPopInput(ctxt); GROW; c = CUR_CHAR(l); @@ -3917,10 +3765,13 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) { } } buf[len] = 0; - if (ctxt->instate == XML_PARSER_EOF) { - xmlFree(buf); - return(NULL); + if (ctxt->instate == XML_PARSER_EOF) + goto error; + if (c != stop) { + xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL); + goto error; } + NEXT; /* * Raise problem w.r.t. '&' and '%' being used in non-entities @@ -3932,20 +3783,25 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) { if ((*cur == '%') || ((*cur == '&') && (cur[1] != '#'))) { xmlChar *name; xmlChar tmp = *cur; + int nameOk = 0; cur++; name = xmlParseStringName(ctxt, &cur); - if ((name == NULL) || (*cur != ';')) { + if (name != NULL) { + nameOk = 1; + xmlFree(name); + } + if ((nameOk == 0) || (*cur != ';')) { xmlFatalErrMsgInt(ctxt, XML_ERR_ENTITY_CHAR_ERROR, "EntityValue: '%c' forbidden except for entities references\n", tmp); + goto error; } if ((tmp == '%') && (ctxt->inSubset == 1) && (ctxt->inputNr == 1)) { xmlFatalErr(ctxt, XML_ERR_ENTITY_PE_INTERNAL, NULL); + goto error; } - if (name != NULL) - xmlFree(name); if (*cur == 0) break; } @@ -3954,26 +3810,24 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) { /* * Then PEReference entities are substituted. + * + * NOTE: 4.4.7 Bypassed + * When a general entity reference appears in the EntityValue in + * an entity declaration, it is bypassed and left as is. + * so XML_SUBSTITUTE_REF is not set here. */ - if (c != stop) { - xmlFatalErr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, NULL); - xmlFree(buf); - } else { - NEXT; - /* - * NOTE: 4.4.7 Bypassed - * When a general entity reference appears in the EntityValue in - * an entity declaration, it is bypassed and left as is. - * so XML_SUBSTITUTE_REF is not set here. - */ - ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF, - 0, 0, 0); - if (orig != NULL) - *orig = buf; - else - xmlFree(buf); + ++ctxt->depth; + ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF, + 0, 0, 0); + --ctxt->depth; + if (orig != NULL) { + *orig = buf; + buf = NULL; } +error: + if (buf != NULL) + xmlFree(buf); return(ret); } @@ -4092,9 +3946,11 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) { } else if ((ent != NULL) && (ctxt->replaceEntities != 0)) { if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) { + ++ctxt->depth; rep = xmlStringDecodeEntities(ctxt, ent->content, XML_SUBSTITUTE_REF, 0, 0, 0); + --ctxt->depth; if (rep != NULL) { current = rep; while (*current != 0) { /* non input consuming */ @@ -4130,8 +3986,10 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) { (ent->content != NULL) && (ent->checked == 0)) { unsigned long oldnbent = ctxt->nbentities; + ++ctxt->depth; rep = xmlStringDecodeEntities(ctxt, ent->content, XML_SUBSTITUTE_REF, 0, 0, 0); + --ctxt->depth; ent->checked = (ctxt->nbentities - oldnbent + 1) * 2; if (rep != NULL) { @@ -4139,7 +3997,9 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) { ent->checked |= 1; xmlFree(rep); rep = NULL; - } + } else { + ent->content[0] = 0; + } } /* @@ -4563,7 +4423,7 @@ get_more: if (*in == ']') { if ((in[1] == ']') && (in[2] == '>')) { xmlFatalErr(ctxt, XML_ERR_MISPLACED_CDATA_END, NULL); - ctxt->input->cur = in; + ctxt->input->cur = in + 1; return; } in++; @@ -4756,22 +4616,20 @@ xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) { *publicID = NULL; if (CMP6(CUR_PTR, 'S', 'Y', 'S', 'T', 'E', 'M')) { SKIP(6); - if (!IS_BLANK_CH(CUR)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space required after 'SYSTEM'\n"); } - SKIP_BLANKS; URI = xmlParseSystemLiteral(ctxt); if (URI == NULL) { xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL); } } else if (CMP6(CUR_PTR, 'P', 'U', 'B', 'L', 'I', 'C')) { SKIP(6); - if (!IS_BLANK_CH(CUR)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space required after 'PUBLIC'\n"); } - SKIP_BLANKS; *publicID = xmlParsePubidLiteral(ctxt); if (*publicID == NULL) { xmlFatalErr(ctxt, XML_ERR_PUBID_REQUIRED, NULL); @@ -4780,26 +4638,20 @@ xmlParseExternalID(xmlParserCtxtPtr ctxt, xmlChar **publicID, int strict) { /* * We don't handle [83] so "S SystemLiteral" is required. */ - if (!IS_BLANK_CH(CUR)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space required after the Public Identifier\n"); } } else { /* * We handle [83] so we return immediately, if - * "S SystemLiteral" is not detected. From a purely parsing - * point of view that's a nice mess. + * "S SystemLiteral" is not detected. We skip blanks if no + * system literal was found, but this is harmless since we must + * be at the end of a NotationDecl. */ - const xmlChar *ptr; - GROW; - - ptr = CUR_PTR; - if (!IS_BLANK_CH(*ptr)) return(NULL); - - while (IS_BLANK_CH(*ptr)) ptr++; /* TODO: dangerous, fix ! */ - if ((*ptr != '\'') && (*ptr != '"')) return(NULL); + if (SKIP_BLANKS == 0) return(NULL); + if ((CUR != '\'') && (CUR != '"')) return(NULL); } - SKIP_BLANKS; URI = xmlParseSystemLiteral(ctxt); if (URI == NULL) { xmlFatalErr(ctxt, XML_ERR_URI_REQUIRED, NULL); @@ -4929,7 +4781,8 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf, } else { if (inputid != ctxt->input->id) { xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, - "Comment doesn't start and stop in the same entity\n"); + "Comment doesn't start and stop in the same" + " entity\n"); } NEXT; if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) && @@ -5077,7 +4930,8 @@ get_more: if (in[2] == '>') { if (ctxt->input->id != inputid) { xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, - "comment doesn't start and stop in the same entity\n"); + "comment doesn't start and stop in the" + " same entity\n"); } SKIP(3); if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) && @@ -5245,7 +5099,7 @@ xmlParsePI(xmlParserCtxtPtr ctxt) { int count = 0; if ((RAW == '<') && (NXT(1) == '?')) { - xmlParserInputPtr input = ctxt->input; + int inputid = ctxt->input->id; state = ctxt->instate; ctxt->instate = XML_PARSER_PI; /* @@ -5261,9 +5115,10 @@ xmlParsePI(xmlParserCtxtPtr ctxt) { target = xmlParsePITarget(ctxt); if (target != NULL) { if ((RAW == '?') && (NXT(1) == '>')) { - if (input != ctxt->input) { + if (inputid != ctxt->input->id) { xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, - "PI declaration doesn't start and stop in the same entity\n"); + "PI declaration doesn't start and stop in" + " the same entity\n"); } SKIP(2); @@ -5284,12 +5139,10 @@ xmlParsePI(xmlParserCtxtPtr ctxt) { ctxt->instate = state; return; } - cur = CUR; - if (!IS_BLANK(cur)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsgStr(ctxt, XML_ERR_SPACE_REQUIRED, "ParsePI: PI %s space expected\n", target); } - SKIP_BLANKS; cur = CUR_CHAR(l); while (IS_CHAR(cur) && /* checked */ ((cur != '?') || (NXT(1) != '>'))) { @@ -5345,9 +5198,10 @@ xmlParsePI(xmlParserCtxtPtr ctxt) { xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED, "ParsePI: PI %s never end ...\n", target); } else { - if (input != ctxt->input) { - xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, - "PI declaration doesn't start and stop in the same entity\n"); + if (inputid != ctxt->input->id) { + xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, + "PI declaration doesn't start and stop in" + " the same entity\n"); } SKIP(2); @@ -5403,32 +5257,30 @@ xmlParseNotationDecl(xmlParserCtxtPtr ctxt) { xmlChar *Systemid; if (CMP10(CUR_PTR, '<', '!', 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) { - xmlParserInputPtr input = ctxt->input; + int inputid = ctxt->input->id; SHRINK; SKIP(10); - if (!IS_BLANK_CH(CUR)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space required after '') { - if (input != ctxt->input) { - xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, - "Notation declaration doesn't start and stop in the same entity\n"); + if (inputid != ctxt->input->id) { + xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, + "Notation declaration doesn't start and stop" + " in the same entity\n"); } NEXT; if ((ctxt->sax != NULL) && (!ctxt->disableSAX) && @@ -5483,25 +5336,22 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) { const xmlChar *ndata = NULL; int isParameter = 0; xmlChar *orig = NULL; - int skipped; /* GROW; done in the caller */ if (CMP8(CUR_PTR, '<', '!', 'E', 'N', 'T', 'I', 'T', 'Y')) { - xmlParserInputPtr input = ctxt->input; + int inputid = ctxt->input->id; SHRINK; SKIP(8); - skipped = SKIP_BLANKS; - if (skipped == 0) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space required after '') && (!IS_BLANK_CH(CUR))) { + if ((RAW != '>') && (SKIP_BLANKS == 0)) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space required before 'NDATA'\n"); } - SKIP_BLANKS; if (CMP5(CUR_PTR, 'N', 'D', 'A', 'T', 'A')) { SKIP(5); - if (!IS_BLANK_CH(CUR)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space required after 'NDATA'\n"); } - SKIP_BLANKS; ndata = xmlParseName(ctxt); if ((ctxt->sax != NULL) && (!ctxt->disableSAX) && (ctxt->sax->unparsedEntityDecl != NULL)) @@ -5679,16 +5526,17 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) { } } if (ctxt->instate == XML_PARSER_EOF) - return; + goto done; SKIP_BLANKS; if (RAW != '>') { xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED, "xmlParseEntityDecl: entity %s not terminated\n", name); xmlHaltParser(ctxt); } else { - if (input != ctxt->input) { + if (inputid != ctxt->input->id) { xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, - "Entity declaration doesn't start and stop in the same entity\n"); + "Entity declaration doesn't start and stop in" + " the same entity\n"); } NEXT; } @@ -5710,17 +5558,17 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) { cur = xmlSAX2GetEntity(ctxt, name); } } - if (cur != NULL) { - if (cur->orig != NULL) - xmlFree(orig); - else - cur->orig = orig; - } else - xmlFree(orig); + if ((cur != NULL) && (cur->orig == NULL)) { + cur->orig = orig; + orig = NULL; + } } + +done: if (value != NULL) xmlFree(value); if (URI != NULL) xmlFree(URI); if (literal != NULL) xmlFree(literal); + if (orig != NULL) xmlFree(orig); } } @@ -5771,11 +5619,10 @@ xmlParseDefaultDecl(xmlParserCtxtPtr ctxt, xmlChar **value) { if (CMP6(CUR_PTR, '#', 'F', 'I', 'X', 'E', 'D')) { SKIP(6); val = XML_ATTRIBUTE_FIXED; - if (!IS_BLANK_CH(CUR)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space required after '#FIXED'\n"); } - SKIP_BLANKS; } ret = xmlParseAttValue(ctxt); ctxt->instate = XML_PARSER_DTD; @@ -5947,12 +5794,11 @@ int xmlParseEnumeratedType(xmlParserCtxtPtr ctxt, xmlEnumerationPtr *tree) { if (CMP8(CUR_PTR, 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N')) { SKIP(8); - if (!IS_BLANK_CH(CUR)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space required after 'NOTATION'\n"); return(0); } - SKIP_BLANKS; *tree = xmlParseNotationType(ctxt); if (*tree == NULL) return(0); return(XML_ATTRIBUTE_NOTATION); @@ -6056,14 +5902,13 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) { xmlEnumerationPtr tree; if (CMP9(CUR_PTR, '<', '!', 'A', 'T', 'T', 'L', 'I', 'S', 'T')) { - xmlParserInputPtr input = ctxt->input; + int inputid = ctxt->input->id; SKIP(9); - if (!IS_BLANK_CH(CUR)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space required after '') && (ctxt->instate != XML_PARSER_EOF)) { - const xmlChar *check = CUR_PTR; int type; int def; xmlChar *defaultValue = NULL; @@ -6087,12 +5931,11 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) { break; } GROW; - if (!IS_BLANK_CH(CUR)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space required after the attribute name\n"); break; } - SKIP_BLANKS; type = xmlParseAttributeType(ctxt, &tree); if (type <= 0) { @@ -6100,14 +5943,13 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) { } GROW; - if (!IS_BLANK_CH(CUR)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space required after the attribute type\n"); if (tree != NULL) xmlFreeEnumeration(tree); break; } - SKIP_BLANKS; def = xmlParseDefaultDecl(ctxt, &defaultValue); if (def <= 0) { @@ -6122,7 +5964,7 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) { GROW; if (RAW != '>') { - if (!IS_BLANK_CH(CUR)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space required after the attribute default value\n"); if (defaultValue != NULL) @@ -6131,16 +5973,6 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) { xmlFreeEnumeration(tree); break; } - SKIP_BLANKS; - } - if (check == CUR_PTR) { - xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, - "in xmlParseAttributeListDecl\n"); - if (defaultValue != NULL) - xmlFree(defaultValue); - if (tree != NULL) - xmlFreeEnumeration(tree); - break; } if ((ctxt->sax != NULL) && (!ctxt->disableSAX) && (ctxt->sax->attributeDecl != NULL)) @@ -6162,10 +5994,10 @@ xmlParseAttributeListDecl(xmlParserCtxtPtr ctxt) { GROW; } if (RAW == '>') { - if (input != ctxt->input) { - xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY, - "Attribute list declaration doesn't start and stop in the same entity\n", - NULL, NULL); + if (inputid != ctxt->input->id) { + xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, + "Attribute list declaration doesn't start and" + " stop in the same entity\n"); } NEXT; } @@ -6202,10 +6034,10 @@ xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) { SKIP_BLANKS; SHRINK; if (RAW == ')') { - if ((ctxt->validate) && (ctxt->input->id != inputchk)) { - xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY, -"Element content declaration doesn't start and stop in the same entity\n", - NULL, NULL); + if (ctxt->input->id != inputchk) { + xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, + "Element content declaration doesn't start and" + " stop in the same entity\n"); } NEXT; ret = xmlNewDocElementContent(ctxt->myDoc, NULL, XML_ELEMENT_CONTENT_PCDATA); @@ -6246,7 +6078,7 @@ xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) { if (elem == NULL) { xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED, "xmlParseElementMixedContentDecl : Name expected\n"); - xmlFreeDocElementContent(ctxt->myDoc, cur); + xmlFreeDocElementContent(ctxt->myDoc, ret); return(NULL); } SKIP_BLANKS; @@ -6261,10 +6093,10 @@ xmlParseElementMixedContentDecl(xmlParserCtxtPtr ctxt, int inputchk) { } if (ret != NULL) ret->ocur = XML_ELEMENT_CONTENT_MULT; - if ((ctxt->validate) && (ctxt->input->id != inputchk)) { - xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY, -"Element content declaration doesn't start and stop in the same entity\n", - NULL, NULL); + if (ctxt->input->id != inputchk) { + xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, + "Element content declaration doesn't start and" + " stop in the same entity\n"); } SKIP(2); } else { @@ -6504,10 +6336,10 @@ xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk, if (last != NULL) last->parent = cur; } - if ((ctxt->validate) && (ctxt->input->id != inputchk)) { - xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY, -"Element content declaration doesn't start and stop in the same entity\n", - NULL, NULL); + if (ctxt->input->id != inputchk) { + xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, + "Element content declaration doesn't start and stop in" + " the same entity\n"); } NEXT; if (RAW == '?') { @@ -6680,27 +6512,24 @@ xmlParseElementDecl(xmlParserCtxtPtr ctxt) { /* GROW; done in the caller */ if (CMP9(CUR_PTR, '<', '!', 'E', 'L', 'E', 'M', 'E', 'N', 'T')) { - xmlParserInputPtr input = ctxt->input; + int inputid = ctxt->input->id; SKIP(9); - if (!IS_BLANK_CH(CUR)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space required after 'ELEMENT'\n"); + return(-1); } - SKIP_BLANKS; name = xmlParseName(ctxt); if (name == NULL) { xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED, "xmlParseElementDecl: no name for Element\n"); return(-1); } - while ((RAW == 0) && (ctxt->inputNr > 1)) - xmlPopInput(ctxt); - if (!IS_BLANK_CH(CUR)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space required after the element name\n"); } - SKIP_BLANKS; if (CMP5(CUR_PTR, 'E', 'M', 'P', 'T', 'Y')) { SKIP(5); /* @@ -6732,12 +6561,6 @@ xmlParseElementDecl(xmlParserCtxtPtr ctxt) { } SKIP_BLANKS; - /* - * Pop-up of finished entities. - */ - while ((RAW == 0) && (ctxt->inputNr > 1)) - xmlPopInput(ctxt); - SKIP_BLANKS; if (RAW != '>') { xmlFatalErr(ctxt, XML_ERR_GT_REQUIRED, NULL); @@ -6745,9 +6568,10 @@ xmlParseElementDecl(xmlParserCtxtPtr ctxt) { xmlFreeDocElementContent(ctxt->myDoc, content); } } else { - if (input != ctxt->input) { + if (inputid != ctxt->input->id) { xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, - "Element declaration doesn't start and stop in the same entity\n"); + "Element declaration doesn't start and stop in" + " the same entity\n"); } NEXT; @@ -6800,9 +6624,9 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) { return; } else { if (ctxt->input->id != id) { - xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY, - "All markup of the conditional section is not in the same entity\n", - NULL, NULL); + xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, + "All markup of the conditional section is not" + " in the same entity\n"); } NEXT; } @@ -6815,6 +6639,8 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) { "Entering INCLUDE Conditional Section\n"); } + SKIP_BLANKS; + GROW; while (((RAW != 0) && ((RAW != ']') || (NXT(1) != ']') || (NXT(2) != '>'))) && (ctxt->instate != XML_PARSER_EOF)) { const xmlChar *check = CUR_PTR; @@ -6822,21 +6648,15 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) { if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) { xmlParseConditionalSections(ctxt); - } else if (IS_BLANK_CH(CUR)) { - NEXT; - } else if (RAW == '%') { - xmlParsePEReference(ctxt); } else xmlParseMarkupDecl(ctxt); - /* - * Pop-up of finished entities. - */ - while ((RAW == 0) && (ctxt->inputNr > 1)) - xmlPopInput(ctxt); + SKIP_BLANKS; + GROW; if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) { xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL); + xmlHaltParser(ctxt); break; } } @@ -6862,9 +6682,9 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) { return; } else { if (ctxt->input->id != id) { - xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY, - "All markup of the conditional section is not in the same entity\n", - NULL, NULL); + xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, + "All markup of the conditional section is not" + " in the same entity\n"); } NEXT; } @@ -6926,9 +6746,9 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) { xmlFatalErr(ctxt, XML_ERR_CONDSEC_NOT_FINISHED, NULL); } else { if (ctxt->input->id != id) { - xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY, - "All markup of the conditional section is not in the same entity\n", - NULL, NULL); + xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, + "All markup of the conditional section is not in" + " the same entity\n"); } if ((ctxt-> instate != XML_PARSER_EOF) && ((ctxt->input->cur + 3) <= ctxt->input->end)) @@ -6995,13 +6815,6 @@ xmlParseMarkupDecl(xmlParserCtxtPtr ctxt) { if (ctxt->instate == XML_PARSER_EOF) return; - /* - * This is only for internal subset. On external entities, - * the replacement is done before parsing stage - */ - if ((ctxt->external == 0) && (ctxt->inputNr == 1)) - xmlParsePEReference(ctxt); - /* * Conditional sections are allowed from entities included * by PE References in the internal subset. @@ -7039,11 +6852,10 @@ xmlParseTextDecl(xmlParserCtxtPtr ctxt) { return; } - if (!IS_BLANK_CH(CUR)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Space needed after 'instate = XML_PARSER_DTD; ctxt->external = 1; + SKIP_BLANKS; while (((RAW == '<') && (NXT(1) == '?')) || ((RAW == '<') && (NXT(1) == '!')) || - (RAW == '%') || IS_BLANK_CH(CUR)) { + (RAW == '%')) { const xmlChar *check = CUR_PTR; unsigned int cons = ctxt->input->consumed; GROW; if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) { xmlParseConditionalSections(ctxt); - } else if (IS_BLANK_CH(CUR)) { - NEXT; - } else if (RAW == '%') { - xmlParsePEReference(ctxt); } else xmlParseMarkupDecl(ctxt); - - /* - * Pop-up of finished entities. - */ - while ((RAW == 0) && (ctxt->inputNr > 1)) - xmlPopInput(ctxt); + SKIP_BLANKS; if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) { xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL); @@ -7385,6 +7189,8 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { (ret != XML_WAR_UNDECLARED_ENTITY)) { xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY, "Entity '%s' failed to parse\n", ent->name); + if (ent->content != NULL) + ent->content[0] = 0; xmlParserEntityCheck(ctxt, 0, ent, 0); } else if (list != NULL) { xmlFreeNodeList(list); @@ -7392,6 +7198,9 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { } if (ent->checked == 0) ent->checked = 2; + + /* Prevent entity from being parsed and expanded twice (Bug 760367). */ + was_checked = 0; } else if (ent->checked != 1) { ctxt->nbentities += ent->checked / 2; } @@ -8028,12 +7837,14 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt) NEXT; name = xmlParseName(ctxt); if (name == NULL) { - xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED, - "xmlParsePEReference: no name\n"); + xmlFatalErrMsg(ctxt, XML_ERR_PEREF_NO_NAME, "PEReference: no name\n"); return; } + if (xmlParserDebugEntities) + xmlGenericError(xmlGenericErrorContext, + "PEReference: %s\n", name); if (RAW != ';') { - xmlFatalErr(ctxt, XML_ERR_ENTITYREF_SEMICOL_MISSING, NULL); + xmlFatalErr(ctxt, XML_ERR_PEREF_SEMICOL_MISSING, NULL); return; } @@ -8075,10 +7886,15 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt) * ... The declaration of a parameter entity must * precede any reference to it... */ - xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY, - "PEReference: %%%s; not found\n", - name, NULL); - ctxt->valid = 0; + if ((ctxt->validate) && (ctxt->vctxt.error != NULL)) { + xmlValidityError(ctxt, XML_WAR_UNDECLARED_ENTITY, + "PEReference: %%%s; not found\n", + name, NULL); + } else + xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY, + "PEReference: %%%s; not found\n", + name, NULL); + ctxt->valid = 0; } xmlParserEntityCheck(ctxt, 0, NULL, 0); } else { @@ -8090,33 +7906,54 @@ xmlParsePEReference(xmlParserCtxtPtr ctxt) xmlWarningMsg(ctxt, XML_WAR_UNDECLARED_ENTITY, "Internal: %%%s; is not a parameter entity\n", name, NULL); - } else if (ctxt->input->free != deallocblankswrapper) { - input = xmlNewBlanksWrapperInputStream(ctxt, entity); - if (xmlPushInput(ctxt, input) < 0) - return; } else { - /* - * TODO !!! - * handle the extra spaces added before and after - * c.f. http://www.w3.org/TR/REC-xml#as-PE - */ + xmlChar start[4]; + xmlCharEncoding enc; + + if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) && + ((ctxt->options & XML_PARSE_NOENT) == 0) && + ((ctxt->options & XML_PARSE_DTDVALID) == 0) && + ((ctxt->options & XML_PARSE_DTDLOAD) == 0) && + ((ctxt->options & XML_PARSE_DTDATTR) == 0) && + (ctxt->replaceEntities == 0) && + (ctxt->validate == 0)) + return; + input = xmlNewEntityInputStream(ctxt, entity); - if (xmlPushInput(ctxt, input) < 0) + if (xmlPushInput(ctxt, input) < 0) { + xmlFreeInputStream(input); return; - if ((entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) && - (CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && - (IS_BLANK_CH(NXT(5)))) { - xmlParseTextDecl(ctxt); - if (ctxt->errNo == - XML_ERR_UNSUPPORTED_ENCODING) { - /* - * The XML REC instructs us to stop parsing - * right here - */ - xmlHaltParser(ctxt); - return; - } - } + } + + if (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY) { + /* + * Get the 4 first bytes and decode the charset + * if enc != XML_CHAR_ENCODING_NONE + * plug some encoding conversion routines. + * Note that, since we may have some non-UTF8 + * encoding (like UTF16, bug 135229), the 'length' + * is not known, but we can calculate based upon + * the amount of data in the buffer. + */ + GROW + if (ctxt->instate == XML_PARSER_EOF) + return; + if ((ctxt->input->end - ctxt->input->cur)>=4) { + start[0] = RAW; + start[1] = NXT(1); + start[2] = NXT(2); + start[3] = NXT(3); + enc = xmlDetectCharEncoding(start, 4); + if (enc != XML_CHAR_ENCODING_NONE) { + xmlSwitchEncoding(ctxt, enc); + } + } + + if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && + (IS_BLANK_CH(NXT(5)))) { + xmlParseTextDecl(ctxt); + } + } } } ctxt->hasPErefs = 1; @@ -8292,6 +8129,7 @@ xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) { entity = ctxt->sax->getParameterEntity(ctxt->userData, name); if (ctxt->instate == XML_PARSER_EOF) { xmlFree(name); + *str = ptr; return(NULL); } if (entity == NULL) { @@ -8430,6 +8268,7 @@ xmlParseInternalSubset(xmlParserCtxtPtr ctxt) { * Is there any DTD definition ? */ if (RAW == '[') { + int baseInputNr = ctxt->inputNr; ctxt->instate = XML_PARSER_DTD; NEXT; /* @@ -8437,7 +8276,8 @@ xmlParseInternalSubset(xmlParserCtxtPtr ctxt) { * PEReferences. * Subsequence (markupdecl | PEReference | S)* */ - while ((RAW != ']') && (ctxt->instate != XML_PARSER_EOF)) { + while (((RAW != ']') || (ctxt->inputNr > baseInputNr)) && + (ctxt->instate != XML_PARSER_EOF)) { const xmlChar *check = CUR_PTR; unsigned int cons = ctxt->input->consumed; @@ -8445,16 +8285,13 @@ xmlParseInternalSubset(xmlParserCtxtPtr ctxt) { xmlParseMarkupDecl(ctxt); xmlParsePEReference(ctxt); - /* - * Pop-up of finished entities. - */ - while ((RAW == 0) && (ctxt->inputNr > 1)) - xmlPopInput(ctxt); - if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) { xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "xmlParseInternalSubset: error detected in Markup declaration\n"); - break; + if (ctxt->inputNr > baseInputNr) + xmlPopInput(ctxt); + else + break; } } if (RAW == ']') { @@ -8468,6 +8305,7 @@ xmlParseInternalSubset(xmlParserCtxtPtr ctxt) { */ if (RAW != '>') { xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL); + return; } NEXT; } @@ -8531,7 +8369,7 @@ xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlChar **value) { ctxt->instate = XML_PARSER_CONTENT; } else { xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE, - "Specification mandate value for attribute %s\n", name); + "Specification mandates value for attribute %s\n", name); return(NULL); } @@ -8688,11 +8526,10 @@ failed: GROW if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>')))) break; - if (!IS_BLANK_CH(RAW)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "attributes construct error\n"); } - SKIP_BLANKS; if ((cons == ctxt->input->consumed) && (q == CUR_PTR) && (attname == NULL) && (attvalue == NULL)) { xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR, @@ -8818,7 +8655,7 @@ xmlParseEndTag(xmlParserCtxtPtr ctxt) { * @prefix: the prefix to lookup * * Lookup the namespace name for the @prefix (which ca be NULL) - * The prefix must come from the @ctxt->dict dictionnary + * The prefix must come from the @ctxt->dict dictionary * * Returns the namespace name or NULL if not bound */ @@ -9230,8 +9067,8 @@ xmlParseAttribute2(xmlParserCtxtPtr ctxt, if (ctxt->attsSpecial != NULL) { int type; - type = (int) (long) xmlHashQLookup2(ctxt->attsSpecial, - pref, elem, *prefix, name); + type = (int) (ptrdiff_t) xmlHashQLookup2(ctxt->attsSpecial, + pref, elem, *prefix, name); if (type != 0) normalize = 1; } @@ -9264,7 +9101,7 @@ xmlParseAttribute2(xmlParserCtxtPtr ctxt, ctxt->instate = XML_PARSER_CONTENT; } else { xmlFatalErrMsgStr(ctxt, XML_ERR_ATTRIBUTE_WITHOUT_VALUE, - "Specification mandate value for attribute %s\n", + "Specification mandates value for attribute %s\n", name); return (NULL); } @@ -9347,9 +9184,8 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref, xmlChar *attvalue; const xmlChar **atts = ctxt->atts; int maxatts = ctxt->maxatts; - int nratts, nbatts, nbdef; - int i, j, nbNs, attval, oldline, oldcol, inputNr; - const xmlChar *base; + int nratts, nbatts, nbdef, inputid; + int i, j, nbNs, attval; unsigned long cur; int nsNr = ctxt->nsNr; @@ -9363,13 +9199,9 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref, * The Shrinking is only possible once the full set of attribute * callbacks have been done. */ -reparse: SHRINK; - base = ctxt->input->base; cur = ctxt->input->cur - ctxt->input->base; - inputNr = ctxt->inputNr; - oldline = ctxt->input->line; - oldcol = ctxt->input->col; + inputid = ctxt->input->id; nbatts = 0; nratts = 0; nbdef = 0; @@ -9393,8 +9225,6 @@ reparse: */ SKIP_BLANKS; GROW; - if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr)) - goto base_changed; while (((RAW != '>') && ((RAW != '/') || (NXT(1) != '>')) && @@ -9405,203 +9235,181 @@ reparse: attname = xmlParseAttribute2(ctxt, prefix, localname, &aprefix, &attvalue, &len, &alloc); - if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr)) { - if ((attvalue != NULL) && (alloc != 0)) - xmlFree(attvalue); - attvalue = NULL; - goto base_changed; - } - if ((attname != NULL) && (attvalue != NULL)) { - if (len < 0) len = xmlStrlen(attvalue); - if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) { - const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len); - xmlURIPtr uri; - - if (URL == NULL) { - xmlErrMemory(ctxt, "dictionary allocation failure"); - if ((attvalue != NULL) && (alloc != 0)) - xmlFree(attvalue); - return(NULL); - } - if (*URL != 0) { - uri = xmlParseURI((const char *) URL); - if (uri == NULL) { - xmlNsErr(ctxt, XML_WAR_NS_URI, - "xmlns: '%s' is not a valid URI\n", - URL, NULL, NULL); - } else { - if (uri->scheme == NULL) { - xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE, - "xmlns: URI %s is not absolute\n", - URL, NULL, NULL); - } - xmlFreeURI(uri); - } - if (URL == ctxt->str_xml_ns) { - if (attname != ctxt->str_xml) { - xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE, - "xml namespace URI cannot be the default namespace\n", - NULL, NULL, NULL); - } - goto skip_default_ns; - } - if ((len == 29) && - (xmlStrEqual(URL, - BAD_CAST "http://www.w3.org/2000/xmlns/"))) { - xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE, - "reuse of the xmlns namespace name is forbidden\n", - NULL, NULL, NULL); - goto skip_default_ns; - } - } - /* - * check that it's not a defined namespace - */ - for (j = 1;j <= nbNs;j++) - if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL) - break; - if (j <= nbNs) - xmlErrAttributeDup(ctxt, NULL, attname); - else - if (nsPush(ctxt, NULL, URL) > 0) nbNs++; -skip_default_ns: - if (alloc != 0) xmlFree(attvalue); - if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>')))) - break; - if (!IS_BLANK_CH(RAW)) { - xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, - "attributes construct error\n"); - break; - } - SKIP_BLANKS; - continue; - } - if (aprefix == ctxt->str_xmlns) { - const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len); - xmlURIPtr uri; - - if (attname == ctxt->str_xml) { - if (URL != ctxt->str_xml_ns) { - xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE, - "xml namespace prefix mapped to wrong URI\n", - NULL, NULL, NULL); - } - /* - * Do not keep a namespace definition node - */ - goto skip_ns; - } + if ((attname == NULL) || (attvalue == NULL)) + goto next_attr; + if (len < 0) len = xmlStrlen(attvalue); + + if ((attname == ctxt->str_xmlns) && (aprefix == NULL)) { + const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len); + xmlURIPtr uri; + + if (URL == NULL) { + xmlErrMemory(ctxt, "dictionary allocation failure"); + if ((attvalue != NULL) && (alloc != 0)) + xmlFree(attvalue); + return(NULL); + } + if (*URL != 0) { + uri = xmlParseURI((const char *) URL); + if (uri == NULL) { + xmlNsErr(ctxt, XML_WAR_NS_URI, + "xmlns: '%s' is not a valid URI\n", + URL, NULL, NULL); + } else { + if (uri->scheme == NULL) { + xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE, + "xmlns: URI %s is not absolute\n", + URL, NULL, NULL); + } + xmlFreeURI(uri); + } if (URL == ctxt->str_xml_ns) { - if (attname != ctxt->str_xml) { - xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE, - "xml namespace URI mapped to wrong prefix\n", - NULL, NULL, NULL); - } - goto skip_ns; - } - if (attname == ctxt->str_xmlns) { - xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE, - "redefinition of the xmlns prefix is forbidden\n", - NULL, NULL, NULL); - goto skip_ns; - } - if ((len == 29) && - (xmlStrEqual(URL, - BAD_CAST "http://www.w3.org/2000/xmlns/"))) { - xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE, - "reuse of the xmlns namespace name is forbidden\n", - NULL, NULL, NULL); - goto skip_ns; - } - if ((URL == NULL) || (URL[0] == 0)) { - xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE, - "xmlns:%s: Empty XML namespace is not allowed\n", - attname, NULL, NULL); - goto skip_ns; - } else { - uri = xmlParseURI((const char *) URL); - if (uri == NULL) { - xmlNsErr(ctxt, XML_WAR_NS_URI, - "xmlns:%s: '%s' is not a valid URI\n", - attname, URL, NULL); - } else { - if ((ctxt->pedantic) && (uri->scheme == NULL)) { - xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE, - "xmlns:%s: URI %s is not absolute\n", - attname, URL, NULL); - } - xmlFreeURI(uri); - } - } - - /* - * check that it's not a defined namespace - */ - for (j = 1;j <= nbNs;j++) - if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname) - break; - if (j <= nbNs) - xmlErrAttributeDup(ctxt, aprefix, attname); - else - if (nsPush(ctxt, attname, URL) > 0) nbNs++; -skip_ns: - if (alloc != 0) xmlFree(attvalue); - if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>')))) - break; - if (!IS_BLANK_CH(RAW)) { - xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, - "attributes construct error\n"); - break; - } - SKIP_BLANKS; - if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr)) - goto base_changed; - continue; - } + if (attname != ctxt->str_xml) { + xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE, + "xml namespace URI cannot be the default namespace\n", + NULL, NULL, NULL); + } + goto next_attr; + } + if ((len == 29) && + (xmlStrEqual(URL, + BAD_CAST "http://www.w3.org/2000/xmlns/"))) { + xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE, + "reuse of the xmlns namespace name is forbidden\n", + NULL, NULL, NULL); + goto next_attr; + } + } + /* + * check that it's not a defined namespace + */ + for (j = 1;j <= nbNs;j++) + if (ctxt->nsTab[ctxt->nsNr - 2 * j] == NULL) + break; + if (j <= nbNs) + xmlErrAttributeDup(ctxt, NULL, attname); + else + if (nsPush(ctxt, NULL, URL) > 0) nbNs++; + + } else if (aprefix == ctxt->str_xmlns) { + const xmlChar *URL = xmlDictLookup(ctxt->dict, attvalue, len); + xmlURIPtr uri; + + if (attname == ctxt->str_xml) { + if (URL != ctxt->str_xml_ns) { + xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE, + "xml namespace prefix mapped to wrong URI\n", + NULL, NULL, NULL); + } + /* + * Do not keep a namespace definition node + */ + goto next_attr; + } + if (URL == ctxt->str_xml_ns) { + if (attname != ctxt->str_xml) { + xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE, + "xml namespace URI mapped to wrong prefix\n", + NULL, NULL, NULL); + } + goto next_attr; + } + if (attname == ctxt->str_xmlns) { + xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE, + "redefinition of the xmlns prefix is forbidden\n", + NULL, NULL, NULL); + goto next_attr; + } + if ((len == 29) && + (xmlStrEqual(URL, + BAD_CAST "http://www.w3.org/2000/xmlns/"))) { + xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE, + "reuse of the xmlns namespace name is forbidden\n", + NULL, NULL, NULL); + goto next_attr; + } + if ((URL == NULL) || (URL[0] == 0)) { + xmlNsErr(ctxt, XML_NS_ERR_XML_NAMESPACE, + "xmlns:%s: Empty XML namespace is not allowed\n", + attname, NULL, NULL); + goto next_attr; + } else { + uri = xmlParseURI((const char *) URL); + if (uri == NULL) { + xmlNsErr(ctxt, XML_WAR_NS_URI, + "xmlns:%s: '%s' is not a valid URI\n", + attname, URL, NULL); + } else { + if ((ctxt->pedantic) && (uri->scheme == NULL)) { + xmlNsWarn(ctxt, XML_WAR_NS_URI_RELATIVE, + "xmlns:%s: URI %s is not absolute\n", + attname, URL, NULL); + } + xmlFreeURI(uri); + } + } - /* - * Add the pair to atts - */ - if ((atts == NULL) || (nbatts + 5 > maxatts)) { - if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) { - if (attvalue[len] == 0) - xmlFree(attvalue); - goto failed; - } - maxatts = ctxt->maxatts; - atts = ctxt->atts; - } - ctxt->attallocs[nratts++] = alloc; - atts[nbatts++] = attname; - atts[nbatts++] = aprefix; - atts[nbatts++] = NULL; /* the URI will be fetched later */ - atts[nbatts++] = attvalue; - attvalue += len; - atts[nbatts++] = attvalue; - /* - * tag if some deallocation is needed - */ - if (alloc != 0) attval = 1; - } else { - if ((attvalue != NULL) && (attvalue[len] == 0)) - xmlFree(attvalue); - } + /* + * check that it's not a defined namespace + */ + for (j = 1;j <= nbNs;j++) + if (ctxt->nsTab[ctxt->nsNr - 2 * j] == attname) + break; + if (j <= nbNs) + xmlErrAttributeDup(ctxt, aprefix, attname); + else + if (nsPush(ctxt, attname, URL) > 0) nbNs++; + + } else { + /* + * Add the pair to atts + */ + if ((atts == NULL) || (nbatts + 5 > maxatts)) { + if (xmlCtxtGrowAttrs(ctxt, nbatts + 5) < 0) { + goto next_attr; + } + maxatts = ctxt->maxatts; + atts = ctxt->atts; + } + ctxt->attallocs[nratts++] = alloc; + atts[nbatts++] = attname; + atts[nbatts++] = aprefix; + /* + * The namespace URI field is used temporarily to point at the + * base of the current input buffer for non-alloced attributes. + * When the input buffer is reallocated, all the pointers become + * invalid, but they can be reconstructed later. + */ + if (alloc) + atts[nbatts++] = NULL; + else + atts[nbatts++] = ctxt->input->base; + atts[nbatts++] = attvalue; + attvalue += len; + atts[nbatts++] = attvalue; + /* + * tag if some deallocation is needed + */ + if (alloc != 0) attval = 1; + attvalue = NULL; /* moved into atts */ + } -failed: +next_attr: + if ((attvalue != NULL) && (alloc != 0)) { + xmlFree(attvalue); + attvalue = NULL; + } GROW if (ctxt->instate == XML_PARSER_EOF) break; - if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr)) - goto base_changed; if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>')))) break; - if (!IS_BLANK_CH(RAW)) { + if (SKIP_BLANKS == 0) { xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "attributes construct error\n"); break; } - SKIP_BLANKS; if ((cons == ctxt->input->consumed) && (q == CUR_PTR) && (attname == NULL) && (attvalue == NULL)) { xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, @@ -9609,8 +9417,27 @@ failed: break; } GROW; - if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr)) - goto base_changed; + } + + if (ctxt->input->id != inputid) { + xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, + "Unexpected change of input\n"); + localname = NULL; + goto done; + } + + /* Reconstruct attribute value pointers. */ + for (i = 0, j = 0; j < nratts; i += 5, j++) { + if (atts[i+2] != NULL) { + /* + * Arithmetic on dangling pointers is technically undefined + * behavior, but well... + */ + ptrdiff_t offset = ctxt->input->base - atts[i+2]; + atts[i+2] = NULL; /* Reset repurposed namespace URI */ + atts[i+3] += offset; /* value */ + atts[i+4] += offset; /* valuend */ + } } /* @@ -9757,6 +9584,7 @@ failed: nsname, 0, NULL, nbatts / 5, nbdef, atts); } +done: /* * Free up attribute allocated strings if needed */ @@ -9767,34 +9595,6 @@ failed: } return(localname); - -base_changed: - /* - * the attribute strings are valid iif the base didn't changed - */ - if (attval != 0) { - for (i = 3,j = 0; j < nratts;i += 5,j++) - if ((ctxt->attallocs[j] != 0) && (atts[i] != NULL)) - xmlFree((xmlChar *) atts[i]); - } - - /* - * We can't switch from one entity to another in the middle - * of a start tag - */ - if (inputNr != ctxt->inputNr) { - xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY, - "Start tag doesn't start and stop in the same entity\n"); - return(NULL); - } - - ctxt->input->cur = ctxt->input->base + cur; - ctxt->input->line = oldline; - ctxt->input->col = oldcol; - if (ctxt->wellFormed == 1) { - goto reparse; - } - return(NULL); } /** @@ -9816,6 +9616,7 @@ static void xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix, const xmlChar *URI, int line, int nsNr, int tlen) { const xmlChar *name; + size_t curLength; GROW; if ((RAW != '<') || (NXT(1) != '/')) { @@ -9824,8 +9625,11 @@ xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix, } SKIP(2); - if ((tlen > 0) && (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) { - if (ctxt->input->cur[tlen] == '>') { + curLength = ctxt->input->end - ctxt->input->cur; + if ((tlen > 0) && (curLength >= (size_t)tlen) && + (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) { + if ((curLength >= (size_t)(tlen + 1)) && + (ctxt->input->cur[tlen] == '>')) { ctxt->input->cur += tlen + 1; ctxt->input->col += tlen + 1; goto done; @@ -10059,11 +9863,6 @@ xmlParseContent(xmlParserCtxtPtr ctxt) { } GROW; - /* - * Pop-up of finished entities. - */ - while ((RAW == 0) && (ctxt->inputNr > 1)) - xmlPopInput(ctxt); SHRINK; if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) { @@ -11209,16 +11008,17 @@ xmlParseGetLasts(xmlParserCtxtPtr ctxt, const xmlChar **lastlt, } /** * xmlCheckCdataPush: - * @cur: pointer to the bock of characters + * @cur: pointer to the block of characters * @len: length of the block in bytes + * @complete: 1 if complete CDATA block is passed in, 0 if partial block * * Check that the block of characters is okay as SCdata content [20] * * Returns the number of bytes to pass if okay, a negative index where an - * UTF-8 error occured otherwise + * UTF-8 error occurred otherwise */ static int -xmlCheckCdataPush(const xmlChar *utf, int len) { +xmlCheckCdataPush(const xmlChar *utf, int len, int complete) { int ix; unsigned char c; int codepoint; @@ -11236,7 +11036,7 @@ xmlCheckCdataPush(const xmlChar *utf, int len) { else return(-ix); } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */ - if (ix + 2 > len) return(-ix); + if (ix + 2 > len) return(complete ? -ix : ix); if ((utf[ix+1] & 0xc0 ) != 0x80) return(-ix); codepoint = (utf[ix] & 0x1f) << 6; @@ -11245,7 +11045,7 @@ xmlCheckCdataPush(const xmlChar *utf, int len) { return(-ix); ix += 2; } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */ - if (ix + 3 > len) return(-ix); + if (ix + 3 > len) return(complete ? -ix : ix); if (((utf[ix+1] & 0xc0) != 0x80) || ((utf[ix+2] & 0xc0) != 0x80)) return(-ix); @@ -11256,7 +11056,7 @@ xmlCheckCdataPush(const xmlChar *utf, int len) { return(-ix); ix += 3; } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */ - if (ix + 4 > len) return(-ix); + if (ix + 4 > len) return(complete ? -ix : ix); if (((utf[ix+1] & 0xc0) != 0x80) || ((utf[ix+2] & 0xc0) != 0x80) || ((utf[ix+3] & 0xc0) != 0x80)) @@ -11357,13 +11157,6 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) { if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1)) return(0); - - /* - * Pop-up of finished entities. - */ - while ((RAW == 0) && (ctxt->inputNr > 1)) - xmlPopInput(ctxt); - if (ctxt->input == NULL) break; if (ctxt->input->buf == NULL) avail = ctxt->input->length - @@ -11714,11 +11507,6 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) { ctxt->checkIndex = 0; xmlParseCharData(ctxt, 0); } - /* - * Pop-up of finished entities. - */ - while ((RAW == 0) && (ctxt->inputNr > 1)) - xmlPopInput(ctxt); if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) { xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "detected an error in element content\n"); @@ -11741,9 +11529,10 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) { } if (ctxt->sax2) { xmlParseEndTag2(ctxt, - (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3], - (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0, - (int) (long) ctxt->pushTab[ctxt->nameNr * 3 - 1], 0); + (void *) ctxt->pushTab[ctxt->nameNr * 3 - 3], + (void *) ctxt->pushTab[ctxt->nameNr * 3 - 2], 0, + (int) (ptrdiff_t) + ctxt->pushTab[ctxt->nameNr * 3 - 1], 0); nameNsPop(ctxt); } #ifdef LIBXML_SAX1_ENABLED @@ -11771,7 +11560,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) { int tmp; tmp = xmlCheckCdataPush(ctxt->input->cur, - XML_PARSER_BIG_BUFFER_SIZE); + XML_PARSER_BIG_BUFFER_SIZE, 0); if (tmp < 0) { tmp = -tmp; ctxt->input->cur += tmp; @@ -11794,7 +11583,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) { } else { int tmp; - tmp = xmlCheckCdataPush(ctxt->input->cur, base); + tmp = xmlCheckCdataPush(ctxt->input->cur, base, 1); if ((tmp < 0) || (tmp != base)) { tmp = -tmp; ctxt->input->cur += tmp; @@ -12429,6 +12218,7 @@ xmldecl_done: /* TODO 2.6.0 */ xmlGenericError(xmlGenericErrorContext, "xmlParseChunk: encoder error\n"); + xmlHaltParser(ctxt); return(XML_ERR_INVALID_ENCODING); } xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current); @@ -12661,6 +12451,8 @@ xmlHaltParser(xmlParserCtxtPtr ctxt) { 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 @@ -12670,8 +12462,14 @@ xmlHaltParser(xmlParserCtxtPtr ctxt) { 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; } } @@ -13440,7 +13238,7 @@ xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt, /* * And record the last error if any */ - if (ctxt->lastError.code != XML_ERR_OK) + if ((oldctxt != NULL) && (ctxt->lastError.code != XML_ERR_OK)) xmlCopyError(&ctxt->lastError, &oldctxt->lastError); if (sax != NULL) @@ -13574,6 +13372,7 @@ xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt, ctxt->userData = ctxt; if (ctxt->dict != NULL) xmlDictFree(ctxt->dict); ctxt->dict = oldctxt->dict; + ctxt->input_id = oldctxt->input_id + 1; ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3); ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5); ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36); @@ -13827,6 +13626,7 @@ xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen, xmlDetectSAX2(ctxt); ctxt->myDoc = doc; /* parsing in context, i.e. as within existing content */ + ctxt->input_id = 2; ctxt->instate = XML_PARSER_CONTENT; fake = xmlNewComment(NULL); @@ -14039,6 +13839,7 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax, newDoc->oldNs = doc->oldNs; } ctxt->instate = XML_PARSER_CONTENT; + ctxt->input_id = 2; ctxt->depth = depth; /* @@ -14199,6 +14000,11 @@ xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID, if (pctx != NULL) { ctxt->options = pctx->options; ctxt->_private = pctx->_private; + /* + * this is a subparser of pctx, so the input_id should be + * incremented to distinguish from main entity + */ + ctxt->input_id = pctx->input_id + 1; } uri = xmlBuildURI(URL, base); @@ -14989,7 +14795,7 @@ xmlCleanupParser(void) { * DICT_FREE: * @str: a string * - * Free a string if it is not owned by the "dict" dictionnary in the + * Free a string if it is not owned by the "dict" dictionary in the * current scope */ #define DICT_FREE(str) \ @@ -15080,7 +14886,7 @@ xmlCtxtReset(xmlParserCtxtPtr ctxt) xmlInitNodeInfoSeq(&ctxt->node_seq); if (ctxt->attsDefault != NULL) { - xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree); + xmlHashFree(ctxt->attsDefault, xmlHashDefaultDeallocator); ctxt->attsDefault = NULL; } if (ctxt->attsSpecial != NULL) { diff --git a/gnulib-local/lib/libxml/parser.in.h b/gnulib-local/lib/libxml/parser.in.h index 3f5730dc6..47fbec03f 100644 --- a/gnulib-local/lib/libxml/parser.in.h +++ b/gnulib-local/lib/libxml/parser.in.h @@ -260,7 +260,7 @@ struct _xmlParserCtxt { void *catalogs; /* document's own catalog */ int recovery; /* run in recovery mode */ int progressive; /* is this a progressive parsing */ - xmlDictPtr dict; /* dictionnary for the parser */ + xmlDictPtr dict; /* dictionary for the parser */ const xmlChar * *atts; /* array for the attributes callbacks */ int maxatts; /* the size of the array */ int docdict; /* use strings from dict to build tree */ @@ -1099,7 +1099,7 @@ typedef enum { XML_PARSE_SAX1 = 1<<9, /* use the SAX1 interface internally */ XML_PARSE_XINCLUDE = 1<<10,/* Implement XInclude substitition */ XML_PARSE_NONET = 1<<11,/* Forbid network access */ - XML_PARSE_NODICT = 1<<12,/* Do not reuse the context dictionnary */ + XML_PARSE_NODICT = 1<<12,/* Do not reuse the context dictionary */ XML_PARSE_NSCLEAN = 1<<13,/* remove redundant namespaces declarations */ XML_PARSE_NOCDATA = 1<<14,/* merge CDATA as text nodes */ XML_PARSE_NOXINCNODE= 1<<15,/* do not generate XINCLUDE START/END nodes */ diff --git a/gnulib-local/lib/libxml/parserInternals.c b/gnulib-local/lib/libxml/parserInternals.c index 2b8646c21..0f015dede 100644 --- a/gnulib-local/lib/libxml/parserInternals.c +++ b/gnulib-local/lib/libxml/parserInternals.c @@ -10,7 +10,7 @@ #define IN_LIBXML #include "libxml.h" -#if defined(WIN32) && !defined (__CYGWIN__) +#if defined(_WIN32) && !defined (__CYGWIN__) #define XML_DIR_SEP '\\' #else #define XML_DIR_SEP '/' @@ -32,7 +32,7 @@ #ifdef HAVE_UNISTD_H #include #endif -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED #include #endif @@ -55,6 +55,10 @@ #include #include +#define CUR(ctxt) ctxt->input->cur +#define END(ctxt) ctxt->input->end +#define VALID_CTXT(ctxt) (CUR(ctxt) <= END(ctxt)) + #include "buf.h" #include "enc.h" @@ -165,7 +169,7 @@ __xmlErrEncoding(xmlParserCtxtPtr ctxt, xmlParserErrors xmlerr, * * Handle an internal error */ -static void +static void LIBXML_ATTR_FORMAT(2,0) xmlErrInternal(xmlParserCtxtPtr ctxt, const char *msg, const xmlChar * str) { if ((ctxt != NULL) && (ctxt->disableSAX != 0) && @@ -193,7 +197,7 @@ xmlErrInternal(xmlParserCtxtPtr ctxt, const char *msg, const xmlChar * str) * * n encoding error */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlErrEncodingInt(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *msg, int val) { @@ -294,7 +298,7 @@ xmlParserInputRead(xmlParserInputPtr in ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUS */ int xmlParserInputGrow(xmlParserInputPtr in, int len) { - size_t ret; + int ret; size_t indx; const xmlChar *content; @@ -422,103 +426,101 @@ xmlNextChar(xmlParserCtxtPtr ctxt) (ctxt->input == NULL)) return; + if (!(VALID_CTXT(ctxt))) { + xmlErrInternal(ctxt, "Parser input data memory error\n", NULL); + ctxt->errNo = XML_ERR_INTERNAL_ERROR; + xmlStopParser(ctxt); + return; + } + + if ((*ctxt->input->cur == 0) && + (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) { + return; + } + if (ctxt->charset == XML_CHAR_ENCODING_UTF8) { - if ((*ctxt->input->cur == 0) && - (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0) && - (ctxt->instate != XML_PARSER_COMMENT)) { - /* - * If we are at the end of the current entity and - * the context allows it, we pop consumed entities - * automatically. - * the auto closing should be blocked in other cases - */ - xmlPopInput(ctxt); - } else { - const unsigned char *cur; - unsigned char c; + const unsigned char *cur; + unsigned char c; - /* - * 2.11 End-of-Line Handling - * the literal two-character sequence "#xD#xA" or a standalone - * literal #xD, an XML processor must pass to the application - * the single character #xA. - */ - if (*(ctxt->input->cur) == '\n') { - ctxt->input->line++; ctxt->input->col = 1; - } else - ctxt->input->col++; + /* + * 2.11 End-of-Line Handling + * the literal two-character sequence "#xD#xA" or a standalone + * literal #xD, an XML processor must pass to the application + * the single character #xA. + */ + if (*(ctxt->input->cur) == '\n') { + ctxt->input->line++; ctxt->input->col = 1; + } else + ctxt->input->col++; - /* - * We are supposed to handle UTF8, check it's valid - * From rfc2044: encoding of the Unicode values on UTF-8: - * - * UCS-4 range (hex.) UTF-8 octet sequence (binary) - * 0000 0000-0000 007F 0xxxxxxx - * 0000 0080-0000 07FF 110xxxxx 10xxxxxx - * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx - * - * Check for the 0x110000 limit too - */ - cur = ctxt->input->cur; + /* + * We are supposed to handle UTF8, check it's valid + * From rfc2044: encoding of the Unicode values on UTF-8: + * + * UCS-4 range (hex.) UTF-8 octet sequence (binary) + * 0000 0000-0000 007F 0xxxxxxx + * 0000 0080-0000 07FF 110xxxxx 10xxxxxx + * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx + * + * Check for the 0x110000 limit too + */ + cur = ctxt->input->cur; - c = *cur; - if (c & 0x80) { - if (c == 0xC0) - goto encoding_error; - if (cur[1] == 0) { + c = *cur; + if (c & 0x80) { + if (c == 0xC0) + goto encoding_error; + if (cur[1] == 0) { + xmlParserInputGrow(ctxt->input, INPUT_CHUNK); + cur = ctxt->input->cur; + } + if ((cur[1] & 0xc0) != 0x80) + goto encoding_error; + if ((c & 0xe0) == 0xe0) { + unsigned int val; + + if (cur[2] == 0) { xmlParserInputGrow(ctxt->input, INPUT_CHUNK); cur = ctxt->input->cur; } - if ((cur[1] & 0xc0) != 0x80) + if ((cur[2] & 0xc0) != 0x80) goto encoding_error; - if ((c & 0xe0) == 0xe0) { - unsigned int val; - - if (cur[2] == 0) { + if ((c & 0xf0) == 0xf0) { + if (cur[3] == 0) { xmlParserInputGrow(ctxt->input, INPUT_CHUNK); cur = ctxt->input->cur; } - if ((cur[2] & 0xc0) != 0x80) + if (((c & 0xf8) != 0xf0) || + ((cur[3] & 0xc0) != 0x80)) goto encoding_error; - if ((c & 0xf0) == 0xf0) { - if (cur[3] == 0) { - xmlParserInputGrow(ctxt->input, INPUT_CHUNK); - cur = ctxt->input->cur; - } - if (((c & 0xf8) != 0xf0) || - ((cur[3] & 0xc0) != 0x80)) - goto encoding_error; - /* 4-byte code */ - ctxt->input->cur += 4; - val = (cur[0] & 0x7) << 18; - val |= (cur[1] & 0x3f) << 12; - val |= (cur[2] & 0x3f) << 6; - val |= cur[3] & 0x3f; - } else { - /* 3-byte code */ - ctxt->input->cur += 3; - val = (cur[0] & 0xf) << 12; - val |= (cur[1] & 0x3f) << 6; - val |= cur[2] & 0x3f; - } - if (((val > 0xd7ff) && (val < 0xe000)) || - ((val > 0xfffd) && (val < 0x10000)) || - (val >= 0x110000)) { - xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR, - "Char 0x%X out of allowed range\n", - val); - } - } else - /* 2-byte code */ - ctxt->input->cur += 2; + /* 4-byte code */ + ctxt->input->cur += 4; + val = (cur[0] & 0x7) << 18; + val |= (cur[1] & 0x3f) << 12; + val |= (cur[2] & 0x3f) << 6; + val |= cur[3] & 0x3f; + } else { + /* 3-byte code */ + ctxt->input->cur += 3; + val = (cur[0] & 0xf) << 12; + val |= (cur[1] & 0x3f) << 6; + val |= cur[2] & 0x3f; + } + if (((val > 0xd7ff) && (val < 0xe000)) || + ((val > 0xfffd) && (val < 0x10000)) || + (val >= 0x110000)) { + xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR, + "Char 0x%X out of allowed range\n", + val); + } } else - /* 1-byte code */ - ctxt->input->cur++; + /* 2-byte code */ + ctxt->input->cur += 2; + } else + /* 1-byte code */ + ctxt->input->cur++; - ctxt->nbChars++; - if (*ctxt->input->cur == 0) - xmlParserInputGrow(ctxt->input, INPUT_CHUNK); - } + ctxt->nbChars++; } else { /* * Assume it's a fixed length encoding (1) with @@ -532,14 +534,9 @@ xmlNextChar(xmlParserCtxtPtr ctxt) ctxt->input->col++; ctxt->input->cur++; ctxt->nbChars++; - if (*ctxt->input->cur == 0) - xmlParserInputGrow(ctxt->input, INPUT_CHUNK); } - if ((*ctxt->input->cur == '%') && (!ctxt->html)) - xmlParserHandlePEReference(ctxt); - if ((*ctxt->input->cur == 0) && - (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) - xmlPopInput(ctxt); + if (*ctxt->input->cur == 0) + xmlParserInputGrow(ctxt->input, INPUT_CHUNK); return; encoding_error: /* @@ -1095,8 +1092,15 @@ xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc) break; } } - if (handler == NULL) + /* + * TODO: We could recover from errors in external entites if we + * didn't stop the parser. But most callers of this function don't + * check the return value. + */ + if (handler == NULL) { + xmlStopParser(ctxt); return(-1); + } ctxt->charset = XML_CHAR_ENCODING_UTF8; ret = xmlSwitchToEncodingInt(ctxt, handler, len); if ((ret < 0) || (ctxt->errNo == XML_I18N_CONV_FAILED)) { @@ -1220,6 +1224,7 @@ xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input, */ nbchars = xmlCharEncFirstLineInput(input->buf, len); } + xmlBufResetInput(input->buf->buffer, input); if (nbchars < 0) { xmlErrInternal(ctxt, "switching encoding: encoder error\n", @@ -1227,7 +1232,6 @@ xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input, return (-1); } input->buf->rawconsumed += use - xmlBufUse(input->buf->raw); - xmlBufResetInput(input->buf->buffer, input); } return (0); } else if (input->length == 0) { @@ -1236,8 +1240,18 @@ xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input, * size to be able to convert the buffer. */ xmlErrInternal(ctxt, "switching encoding : no input\n", NULL); + /* + * Callers assume that the input buffer takes ownership of the + * encoding handler. xmlCharEncCloseFunc frees unregistered + * handlers and avoids a memory leak. + */ + xmlCharEncCloseFunc(handler); return (-1); } + /* + * We should actually raise an error here, see issue #34. + */ + xmlCharEncCloseFunc(handler); return (0); } @@ -1791,7 +1805,7 @@ xmlFreeParserCtxt(xmlParserCtxtPtr ctxt) if (ctxt->pushTab != NULL) xmlFree(ctxt->pushTab); if (ctxt->attallocs != NULL) xmlFree(ctxt->attallocs); if (ctxt->attsDefault != NULL) - xmlHashFree(ctxt->attsDefault, (xmlHashDeallocator) xmlFree); + xmlHashFree(ctxt->attsDefault, xmlHashDefaultDeallocator); if (ctxt->attsSpecial != NULL) xmlHashFree(ctxt->attsSpecial, NULL); if (ctxt->freeElems != NULL) { diff --git a/gnulib-local/lib/libxml/parserInternals.in.h b/gnulib-local/lib/libxml/parserInternals.in.h index 6065320eb..f30fc6876 100644 --- a/gnulib-local/lib/libxml/parserInternals.in.h +++ b/gnulib-local/lib/libxml/parserInternals.in.h @@ -351,7 +351,7 @@ XMLPUBFUN void XMLCALL xmlParserErrors xmlerr, const char *msg, const xmlChar * str1, - const xmlChar * str2); + const xmlChar * str2) LIBXML_ATTR_FORMAT(3,0); #endif /** diff --git a/gnulib-local/lib/libxml/pattern.c b/gnulib-local/lib/libxml/pattern.c index 33dee3aac..0eb8d8124 100644 --- a/gnulib-local/lib/libxml/pattern.c +++ b/gnulib-local/lib/libxml/pattern.c @@ -969,6 +969,7 @@ xmlCompileAttributeTest(xmlPatParserContextPtr ctxt) { ERROR5(NULL, NULL, NULL, "xmlCompileAttributeTest : no namespace bound to prefix %s\n", prefix); + XML_PAT_FREE_STRING(ctxt, prefix); ctxt->error = 1; goto error; } diff --git a/gnulib-local/lib/libxml/relaxng.c b/gnulib-local/lib/libxml/relaxng.c index 5779e7fc5..914706ac1 100644 --- a/gnulib-local/lib/libxml/relaxng.c +++ b/gnulib-local/lib/libxml/relaxng.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -507,7 +508,7 @@ xmlRngVErrMemory(xmlRelaxNGValidCtxtPtr ctxt, const char *extra) * * Handle a Relax NG Parsing error */ -static void +static void LIBXML_ATTR_FORMAT(4,0) xmlRngPErr(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, int error, const char *msg, const xmlChar * str1, const xmlChar * str2) { @@ -541,7 +542,7 @@ xmlRngPErr(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, int error, * * Handle a Relax NG Validation error */ -static void +static void LIBXML_ATTR_FORMAT(4,0) xmlRngVErr(xmlRelaxNGValidCtxtPtr ctxt, xmlNodePtr node, int error, const char *msg, const xmlChar * str1, const xmlChar * str2) { @@ -1572,6 +1573,9 @@ xmlRelaxNGRemoveRedefine(xmlRelaxNGParserCtxtPtr ctxt, #endif } } + if (xmlRelaxNGRemoveRedefine(ctxt, URL, tmp->children, name) == 1) { + found = 1; + } } tmp = tmp2; } @@ -1738,7 +1742,18 @@ xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL, xmlFree(name); } } - cur = cur->next; + if (IS_RELAXNG(cur, "div") && cur->children != NULL) { + cur = cur->children; + } else { + if (cur->next != NULL) { + cur = cur->next; + } else { + while (cur->parent != node && cur->parent->next == NULL) { + cur = cur->parent; + } + cur = cur->parent != node ? cur->parent->next : NULL; + } + } } @@ -2088,6 +2103,7 @@ xmlRelaxNGGetErrorString(xmlRelaxNGValidErr err, const xmlChar * arg1, const xmlChar * arg2) { char msg[1000]; + xmlChar *result; if (arg1 == NULL) arg1 = BAD_CAST ""; @@ -2215,7 +2231,8 @@ xmlRelaxNGGetErrorString(xmlRelaxNGValidErr err, const xmlChar * arg1, snprintf(msg, 1000, "Unknown error code %d\n", err); } msg[1000 - 1] = 0; - return (xmlStrdup((xmlChar *) msg)); + result = xmlCharStrdup(msg); + return (xmlEscapeFormatString(&result)); } /** @@ -2726,9 +2743,10 @@ static xmlHashTablePtr xmlRelaxNGRegisteredTypes = NULL; * Free the structure associated to the type library */ static void -xmlRelaxNGFreeTypeLibrary(xmlRelaxNGTypeLibraryPtr lib, +xmlRelaxNGFreeTypeLibrary(void *payload, const xmlChar * namespace ATTRIBUTE_UNUSED) { + xmlRelaxNGTypeLibraryPtr lib = (xmlRelaxNGTypeLibraryPtr) payload; if (lib == NULL) return; if (lib->namespace != NULL) @@ -2839,8 +2857,7 @@ xmlRelaxNGCleanupTypes(void) xmlSchemaCleanupTypes(); if (xmlRelaxNGTypeInitialized == 0) return; - xmlHashFree(xmlRelaxNGRegisteredTypes, (xmlHashDeallocator) - xmlRelaxNGFreeTypeLibrary); + xmlHashFree(xmlRelaxNGRegisteredTypes, xmlRelaxNGFreeTypeLibrary); xmlRelaxNGTypeInitialized = 0; } @@ -3976,7 +3993,7 @@ xmlRelaxNGGenerateAttributes(xmlRelaxNGParserCtxtPtr ctxt, * xmlRelaxNGGetElements: * @ctxt: a Relax-NG parser context * @def: the definition definition - * @eora: gather elements (0) or attributes (1) + * @eora: gather elements (0), attributes (1) or elements and text (2) * * Compute the list of top elements a definition can generate * @@ -4002,7 +4019,12 @@ xmlRelaxNGGetElements(xmlRelaxNGParserCtxtPtr ctxt, while (cur != NULL) { if (((eora == 0) && ((cur->type == XML_RELAXNG_ELEMENT) || (cur->type == XML_RELAXNG_TEXT))) || - ((eora == 1) && (cur->type == XML_RELAXNG_ATTRIBUTE))) { + ((eora == 1) && (cur->type == XML_RELAXNG_ATTRIBUTE)) || + ((eora == 2) && ((cur->type == XML_RELAXNG_DATATYPE) || + (cur->type == XML_RELAXNG_ELEMENT) || + (cur->type == XML_RELAXNG_LIST) || + (cur->type == XML_RELAXNG_TEXT) || + (cur->type == XML_RELAXNG_VALUE)))) { if (ret == NULL) { max = 10; ret = (xmlRelaxNGDefinePtr *) @@ -4308,10 +4330,11 @@ xmlRelaxNGCheckGroupAttrs(xmlRelaxNGParserCtxtPtr ctxt, * algorithm */ static void -xmlRelaxNGComputeInterleaves(xmlRelaxNGDefinePtr def, - xmlRelaxNGParserCtxtPtr ctxt, - xmlChar * name ATTRIBUTE_UNUSED) +xmlRelaxNGComputeInterleaves(void *payload, void *data, + const xmlChar * name ATTRIBUTE_UNUSED) { + xmlRelaxNGDefinePtr def = (xmlRelaxNGDefinePtr) payload; + xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data; xmlRelaxNGDefinePtr cur, *tmp; xmlRelaxNGPartitionPtr partitions = NULL; @@ -4356,7 +4379,7 @@ xmlRelaxNGComputeInterleaves(xmlRelaxNGDefinePtr def, if (cur->type == XML_RELAXNG_TEXT) is_mixed++; groups[nbgroups]->rule = cur; - groups[nbgroups]->defs = xmlRelaxNGGetElements(ctxt, cur, 0); + groups[nbgroups]->defs = xmlRelaxNGGetElements(ctxt, cur, 2); groups[nbgroups]->attrs = xmlRelaxNGGetElements(ctxt, cur, 1); nbgroups++; cur = cur->next; @@ -4402,7 +4425,7 @@ xmlRelaxNGComputeInterleaves(xmlRelaxNGDefinePtr def, if ((*tmp)->type == XML_RELAXNG_TEXT) { res = xmlHashAddEntry2(partitions->triage, BAD_CAST "#text", NULL, - (void *) (long) (i + 1)); + (void *) (ptrdiff_t) (i + 1)); if (res != 0) is_determinist = -1; } else if (((*tmp)->type == XML_RELAXNG_ELEMENT) && @@ -4410,22 +4433,22 @@ xmlRelaxNGComputeInterleaves(xmlRelaxNGDefinePtr def, if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0)) res = xmlHashAddEntry2(partitions->triage, (*tmp)->name, NULL, - (void *) (long) (i + 1)); + (void *) (ptrdiff_t) (i + 1)); else res = xmlHashAddEntry2(partitions->triage, (*tmp)->name, (*tmp)->ns, - (void *) (long) (i + 1)); + (void *) (ptrdiff_t) (i + 1)); if (res != 0) is_determinist = -1; } else if ((*tmp)->type == XML_RELAXNG_ELEMENT) { if (((*tmp)->ns == NULL) || ((*tmp)->ns[0] == 0)) res = xmlHashAddEntry2(partitions->triage, BAD_CAST "#any", NULL, - (void *) (long) (i + 1)); + (void *) (ptrdiff_t) (i + 1)); else res = xmlHashAddEntry2(partitions->triage, BAD_CAST "#any", (*tmp)->ns, - (void *) (long) (i + 1)); + (void *) (ptrdiff_t) (i + 1)); if ((*tmp)->nameClass != NULL) is_determinist = 2; if (res != 0) @@ -4660,7 +4683,7 @@ xmlRelaxNGParseDefine(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) * Import import one references into the current grammar */ static void -xmlRelaxNGParseImportRef(void *payload, void *data, xmlChar *name) { +xmlRelaxNGParseImportRef(void *payload, void *data, const xmlChar *name) { xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data; xmlRelaxNGDefinePtr def = (xmlRelaxNGDefinePtr) payload; int tmp; @@ -5343,11 +5366,15 @@ xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, xmlNodePtr child; xmlRelaxNGDefinePtr last = NULL; - ret = xmlRelaxNGNewDefine(ctxt, node); - if (ret == NULL) - return (NULL); - ret->parent = def; - ret->type = XML_RELAXNG_CHOICE; + if (def->type == XML_RELAXNG_CHOICE) { + ret = def; + } else { + ret = xmlRelaxNGNewDefine(ctxt, node); + if (ret == NULL) + return (NULL); + ret->parent = def; + ret->type = XML_RELAXNG_CHOICE; + } if (node->children == NULL) { xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_EMPTY, @@ -5359,7 +5386,7 @@ xmlRelaxNGParseNameClass(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node, tmp = xmlRelaxNGParseNameClass(ctxt, child, ret); if (tmp != NULL) { if (last == NULL) { - last = ret->nameClass = tmp; + last = tmp; } else { last->next = tmp; last = tmp; @@ -5667,10 +5694,10 @@ xmlRelaxNGParseGrammarContent(xmlRelaxNGParserCtxtPtr ctxt, * element of a given grammar using the same name. */ static void -xmlRelaxNGCheckReference(xmlRelaxNGDefinePtr ref, - xmlRelaxNGParserCtxtPtr ctxt, - const xmlChar * name) +xmlRelaxNGCheckReference(void *payload, void *data, const xmlChar * name) { + xmlRelaxNGDefinePtr ref = (xmlRelaxNGDefinePtr) payload; + xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data; xmlRelaxNGGrammarPtr grammar; xmlRelaxNGDefinePtr def, cur; @@ -5723,9 +5750,10 @@ xmlRelaxNGCheckReference(xmlRelaxNGDefinePtr ref, * element of a given grammar using the same name. */ static void -xmlRelaxNGCheckCombine(xmlRelaxNGDefinePtr define, - xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * name) +xmlRelaxNGCheckCombine(void *payload, void *data, const xmlChar * name) { + xmlRelaxNGDefinePtr define = (xmlRelaxNGDefinePtr) payload; + xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data; xmlChar *combine; int choiceOrInterleave = -1; int missing = 0; @@ -6608,16 +6636,14 @@ xmlRelaxNGParseGrammar(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr nodes) */ xmlRelaxNGCombineStart(ctxt, ret); if (ret->defs != NULL) { - xmlHashScan(ret->defs, (xmlHashScanner) xmlRelaxNGCheckCombine, - ctxt); + xmlHashScan(ret->defs, xmlRelaxNGCheckCombine, ctxt); } /* * link together defines and refs in this grammar */ if (ret->refs != NULL) { - xmlHashScan(ret->refs, (xmlHashScanner) xmlRelaxNGCheckReference, - ctxt); + xmlHashScan(ret->refs, xmlRelaxNGCheckReference, ctxt); } @@ -7548,8 +7574,7 @@ xmlRelaxNGParse(xmlRelaxNGParserCtxtPtr ctxt) * try to preprocess interleaves */ if (ctxt->interleaves != NULL) { - xmlHashScan(ctxt->interleaves, - (xmlHashScanner) xmlRelaxNGComputeInterleaves, ctxt); + xmlHashScan(ctxt->interleaves, xmlRelaxNGComputeInterleaves, ctxt); } /* @@ -8888,7 +8913,7 @@ xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt, if (ret != 0) { break; } - /* no break on purpose */ + /* Falls through. */ case XML_RELAXNG_ZEROORMORE:{ xmlChar *cur, *temp; @@ -9260,7 +9285,10 @@ xmlRelaxNGNodeMatchesList(xmlNodePtr node, xmlRelaxNGDefinePtr * list) return (1); } else if (((node->type == XML_TEXT_NODE) || (node->type == XML_CDATA_SECTION_NODE)) && - (cur->type == XML_RELAXNG_TEXT)) { + ((cur->type == XML_RELAXNG_DATATYPE) || + (cur->type == XML_RELAXNG_LIST) || + (cur->type == XML_RELAXNG_TEXT) || + (cur->type == XML_RELAXNG_VALUE))) { return (1); } cur = list[i++]; @@ -9385,7 +9413,7 @@ xmlRelaxNGValidateInterleave(xmlRelaxNGValidCtxtPtr ctxt, if (tmp == NULL) { i = nbgroups; } else { - i = ((long) tmp) - 1; + i = ((ptrdiff_t) tmp) - 1; if (partitions->flags & IS_NEEDCHECK) { group = partitions->groups[i]; if (!xmlRelaxNGNodeMatchesList(cur, group->defs)) @@ -10165,7 +10193,7 @@ xmlRelaxNGValidateState(xmlRelaxNGValidCtxtPtr ctxt, } if (ctxt->errNr > errNr) xmlRelaxNGPopErrors(ctxt, errNr); - /* no break on purpose */ + /* Falls through. */ case XML_RELAXNG_ZEROORMORE:{ int progress; xmlRelaxNGStatesPtr states = NULL, res = NULL; diff --git a/gnulib-local/lib/libxml/schemasInternals.in.h b/gnulib-local/lib/libxml/schemasInternals.in.h index 4f0ca9a1f..6fb71139c 100644 --- a/gnulib-local/lib/libxml/schemasInternals.in.h +++ b/gnulib-local/lib/libxml/schemasInternals.in.h @@ -3,7 +3,7 @@ * Description: internal interfaces for the XML Schemas handling * and schema validity checking * The Schemas development is a Work In Progress. - * Some of those interfaces are not garanteed to be API or ABI stable ! + * Some of those interfaces are not guaranteed to be API or ABI stable ! * * Copy: See Copyright for the status of this software. * @@ -28,52 +28,52 @@ extern "C" { typedef enum { XML_SCHEMAS_UNKNOWN = 0, - XML_SCHEMAS_STRING, - XML_SCHEMAS_NORMSTRING, - XML_SCHEMAS_DECIMAL, - XML_SCHEMAS_TIME, - XML_SCHEMAS_GDAY, - XML_SCHEMAS_GMONTH, - XML_SCHEMAS_GMONTHDAY, - XML_SCHEMAS_GYEAR, - XML_SCHEMAS_GYEARMONTH, - XML_SCHEMAS_DATE, - XML_SCHEMAS_DATETIME, - XML_SCHEMAS_DURATION, - XML_SCHEMAS_FLOAT, - XML_SCHEMAS_DOUBLE, - XML_SCHEMAS_BOOLEAN, - XML_SCHEMAS_TOKEN, - XML_SCHEMAS_LANGUAGE, - XML_SCHEMAS_NMTOKEN, - XML_SCHEMAS_NMTOKENS, - XML_SCHEMAS_NAME, - XML_SCHEMAS_QNAME, - XML_SCHEMAS_NCNAME, - XML_SCHEMAS_ID, - XML_SCHEMAS_IDREF, - XML_SCHEMAS_IDREFS, - XML_SCHEMAS_ENTITY, - XML_SCHEMAS_ENTITIES, - XML_SCHEMAS_NOTATION, - XML_SCHEMAS_ANYURI, - XML_SCHEMAS_INTEGER, - XML_SCHEMAS_NPINTEGER, - XML_SCHEMAS_NINTEGER, - XML_SCHEMAS_NNINTEGER, - XML_SCHEMAS_PINTEGER, - XML_SCHEMAS_INT, - XML_SCHEMAS_UINT, - XML_SCHEMAS_LONG, - XML_SCHEMAS_ULONG, - XML_SCHEMAS_SHORT, - XML_SCHEMAS_USHORT, - XML_SCHEMAS_BYTE, - XML_SCHEMAS_UBYTE, - XML_SCHEMAS_HEXBINARY, - XML_SCHEMAS_BASE64BINARY, - XML_SCHEMAS_ANYTYPE, - XML_SCHEMAS_ANYSIMPLETYPE + XML_SCHEMAS_STRING = 1, + XML_SCHEMAS_NORMSTRING = 2, + XML_SCHEMAS_DECIMAL = 3, + XML_SCHEMAS_TIME = 4, + XML_SCHEMAS_GDAY = 5, + XML_SCHEMAS_GMONTH = 6, + XML_SCHEMAS_GMONTHDAY = 7, + XML_SCHEMAS_GYEAR = 8, + XML_SCHEMAS_GYEARMONTH = 9, + XML_SCHEMAS_DATE = 10, + XML_SCHEMAS_DATETIME = 11, + XML_SCHEMAS_DURATION = 12, + XML_SCHEMAS_FLOAT = 13, + XML_SCHEMAS_DOUBLE = 14, + XML_SCHEMAS_BOOLEAN = 15, + XML_SCHEMAS_TOKEN = 16, + XML_SCHEMAS_LANGUAGE = 17, + XML_SCHEMAS_NMTOKEN = 18, + XML_SCHEMAS_NMTOKENS = 19, + XML_SCHEMAS_NAME = 20, + XML_SCHEMAS_QNAME = 21, + XML_SCHEMAS_NCNAME = 22, + XML_SCHEMAS_ID = 23, + XML_SCHEMAS_IDREF = 24, + XML_SCHEMAS_IDREFS = 25, + XML_SCHEMAS_ENTITY = 26, + XML_SCHEMAS_ENTITIES = 27, + XML_SCHEMAS_NOTATION = 28, + XML_SCHEMAS_ANYURI = 29, + XML_SCHEMAS_INTEGER = 30, + XML_SCHEMAS_NPINTEGER = 31, + XML_SCHEMAS_NINTEGER = 32, + XML_SCHEMAS_NNINTEGER = 33, + XML_SCHEMAS_PINTEGER = 34, + XML_SCHEMAS_INT = 35, + XML_SCHEMAS_UINT = 36, + XML_SCHEMAS_LONG = 37, + XML_SCHEMAS_ULONG = 38, + XML_SCHEMAS_SHORT = 39, + XML_SCHEMAS_USHORT = 40, + XML_SCHEMAS_BYTE = 41, + XML_SCHEMAS_UBYTE = 42, + XML_SCHEMAS_HEXBINARY = 43, + XML_SCHEMAS_BASE64BINARY = 44, + XML_SCHEMAS_ANYTYPE = 45, + XML_SCHEMAS_ANYSIMPLETYPE = 46 } xmlSchemaValType; /* diff --git a/gnulib-local/lib/libxml/schematron.c b/gnulib-local/lib/libxml/schematron.c index eb4befebf..6200f2d41 100644 --- a/gnulib-local/lib/libxml/schematron.c +++ b/gnulib-local/lib/libxml/schematron.c @@ -133,7 +133,7 @@ struct _xmlSchematron { int flags; /* specific to this schematron */ void *_private; /* unused by the library */ - xmlDictPtr dict; /* the dictionnary used internally */ + xmlDictPtr dict; /* the dictionary used internally */ const xmlChar *title; /* the title if any */ @@ -186,7 +186,7 @@ struct _xmlSchematronParserCtxt { const char *buffer; int size; - xmlDictPtr dict; /* dictionnary for interned string names */ + xmlDictPtr dict; /* dictionary for interned string names */ int nberrors; int err; @@ -245,7 +245,7 @@ xmlSchematronPErrMemory(xmlSchematronParserCtxtPtr ctxt, * * Handle a parser error */ -static void +static void LIBXML_ATTR_FORMAT(4,0) xmlSchematronPErr(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr node, int error, const char *msg, const xmlChar * str1, const xmlChar * str2) { diff --git a/gnulib-local/lib/libxml/threads.c b/gnulib-local/lib/libxml/threads.c index b9d6cae35..0433ac0f5 100644 --- a/gnulib-local/lib/libxml/threads.c +++ b/gnulib-local/lib/libxml/threads.c @@ -27,6 +27,7 @@ #ifdef HAVE_PTHREAD_H #include #elif defined HAVE_WIN32_THREADS +#define WIN32_LEAN_AND_MEAN #include #ifndef HAVE_COMPILER_TLS #include @@ -46,50 +47,37 @@ #ifdef HAVE_PTHREAD_H +#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 303) && \ + defined(__GLIBC__) && defined(__linux__) + static int libxml_is_threaded = -1; -#if defined(__GNUC__) && defined(__GLIBC__) -#ifdef linux -#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ > 3) -extern int pthread_once (pthread_once_t *__once_control, - void (*__init_routine) (void)) - __attribute((weak)); -extern void *pthread_getspecific (pthread_key_t __key) - __attribute((weak)); -extern int pthread_setspecific (pthread_key_t __key, - __const void *__pointer) - __attribute((weak)); -extern int pthread_key_create (pthread_key_t *__key, - void (*__destr_function) (void *)) - __attribute((weak)); -extern int pthread_key_delete (pthread_key_t __key) - __attribute((weak)); -extern int pthread_mutex_init () - __attribute((weak)); -extern int pthread_mutex_destroy () - __attribute((weak)); -extern int pthread_mutex_lock () - __attribute((weak)); -extern int pthread_mutex_unlock () - __attribute((weak)); -extern int pthread_cond_init () - __attribute((weak)); -extern int pthread_cond_destroy () - __attribute((weak)); -extern int pthread_cond_wait () - __attribute((weak)); -extern int pthread_equal () - __attribute((weak)); -extern pthread_t pthread_self () - __attribute((weak)); -extern int pthread_key_create () - __attribute((weak)); -extern int pthread_key_delete () - __attribute((weak)); -extern int pthread_cond_signal () - __attribute((weak)); -#endif -#endif /* linux */ -#endif /* defined(__GNUC__) && defined(__GLIBC__) */ + +#define XML_PTHREAD_WEAK + +#pragma weak pthread_once +#pragma weak pthread_getspecific +#pragma weak pthread_setspecific +#pragma weak pthread_key_create +#pragma weak pthread_key_delete +#pragma weak pthread_mutex_init +#pragma weak pthread_mutex_destroy +#pragma weak pthread_mutex_lock +#pragma weak pthread_mutex_unlock +#pragma weak pthread_cond_init +#pragma weak pthread_cond_destroy +#pragma weak pthread_cond_wait +#pragma weak pthread_equal +#pragma weak pthread_self +#pragma weak pthread_key_create +#pragma weak pthread_key_delete +#pragma weak pthread_cond_signal + +#else /* __GNUC__, __GLIBC__, __linux__ */ + +static int libxml_is_threaded = 1; + +#endif /* __GNUC__, __GLIBC__, __linux__ */ + #endif /* HAVE_PTHREAD_H */ /* @@ -158,7 +146,7 @@ static DWORD globalkey = TLS_OUT_OF_INDEXES; static DWORD mainthread; static struct { DWORD done; - DWORD control; + LONG control; } run_once = { 0, 0}; static volatile LPCRITICAL_SECTION global_init_lock = NULL; @@ -441,8 +429,11 @@ __xmlGlobalInitMutexLock(void) /* Make sure the global init lock is initialized and then lock it. */ #ifdef HAVE_PTHREAD_H /* The mutex is statically initialized, so we just lock it. */ - if (pthread_mutex_lock != NULL) - pthread_mutex_lock(&global_init_lock); +#ifdef XML_PTHREAD_WEAK + if (pthread_mutex_lock == NULL) + return; +#endif /* XML_PTHREAD_WEAK */ + pthread_mutex_lock(&global_init_lock); #elif defined HAVE_WIN32_THREADS LPCRITICAL_SECTION cs; @@ -458,7 +449,8 @@ __xmlGlobalInitMutexLock(void) /* Swap it into the global_init_lock */ #ifdef InterlockedCompareExchangePointer - InterlockedCompareExchangePointer(&global_init_lock, cs, NULL); + InterlockedCompareExchangePointer((void **) &global_init_lock, + cs, NULL); #else /* Use older void* version */ InterlockedCompareExchange((void **) &global_init_lock, (void *) cs, NULL); @@ -510,8 +502,11 @@ void __xmlGlobalInitMutexUnlock(void) { #ifdef HAVE_PTHREAD_H - if (pthread_mutex_unlock != NULL) - pthread_mutex_unlock(&global_init_lock); +#ifdef XML_PTHREAD_WEAK + if (pthread_mutex_unlock == NULL) + return; +#endif /* XML_PTHREAD_WEAK */ + pthread_mutex_unlock(&global_init_lock); #elif defined HAVE_WIN32_THREADS if (global_init_lock != NULL) { LeaveCriticalSection(global_init_lock); @@ -863,6 +858,7 @@ void xmlInitThreads(void) { #ifdef HAVE_PTHREAD_H +#ifdef XML_PTHREAD_WEAK if (libxml_is_threaded == -1) { if ((pthread_once != NULL) && (pthread_getspecific != NULL) && @@ -888,6 +884,7 @@ xmlInitThreads(void) libxml_is_threaded = 0; } } +#endif /* XML_PTHREAD_WEAK */ #elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) InitializeCriticalSection(&cleanup_helpers_cs); #endif @@ -914,7 +911,7 @@ xmlCleanupThreads(void) xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n"); #endif #ifdef HAVE_PTHREAD_H - if ((libxml_is_threaded) && (pthread_key_delete != NULL)) + if (libxml_is_threaded != 0) pthread_key_delete(globalkey); once_control = once_control_init; #elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) @@ -999,11 +996,23 @@ xmlOnceInit(void) #ifdef HAVE_PTHREAD_H #elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) #if defined(LIBXML_STATIC_FOR_DLL) -BOOL XMLCALL -xmlDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +int XMLCALL +xmlDllMain(ATTRIBUTE_UNUSED void *hinstDLL, unsigned long fdwReason, + ATTRIBUTE_UNUSED void *lpvReserved) #else +/* declare to avoid "no previous prototype for 'DllMain'" warning */ +/* Note that we do NOT want to include this function declaration in + a public header because it's meant to be called by Windows itself, + not a program that uses this library. This also has to be exported. */ + +XMLPUBFUN BOOL WINAPI +DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved); + BOOL WINAPI -DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +DllMain(ATTRIBUTE_UNUSED HINSTANCE hinstDLL, DWORD fdwReason, + ATTRIBUTE_UNUSED LPVOID lpvReserved) #endif { switch (fdwReason) { diff --git a/gnulib-local/lib/libxml/threads.in.h b/gnulib-local/lib/libxml/threads.in.h index d31f16acb..9969ae7cf 100644 --- a/gnulib-local/lib/libxml/threads.in.h +++ b/gnulib-local/lib/libxml/threads.in.h @@ -72,8 +72,13 @@ XMLPUBFUN void XMLCALL XMLPUBFUN xmlGlobalStatePtr XMLCALL xmlGetGlobalState(void); -#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && defined(LIBXML_STATIC_FOR_DLL) -int XMLCALL xmlDllMain(void *hinstDLL, unsigned long fdwReason, void *lpvReserved); +#ifdef HAVE_PTHREAD_H +#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) +#if defined(LIBXML_STATIC_FOR_DLL) +int XMLCALL +xmlDllMain(void *hinstDLL, unsigned long fdwReason, + void *lpvReserved); +#endif #endif #ifdef __cplusplus diff --git a/gnulib-local/lib/libxml/timsort.h b/gnulib-local/lib/libxml/timsort.h index 9369e7c6c..0c6346b8a 100644 --- a/gnulib-local/lib/libxml/timsort.h +++ b/gnulib-local/lib/libxml/timsort.h @@ -1,312 +1,350 @@ /* - * taken from https://github.com/swenson/sort - * Kept as is for the moment to be able to apply upstream patches for that - * code, currently used only to speed up XPath node sorting, see xpath.c + * Taken from https://github.com/swenson/sort + * Revision: 05fd77bfec049ce8b7c408c4d3dd2d51ee061a15 + * Removed all code unrelated to Timsort and made minor adjustments for + * cross-platform compatibility. */ /* - * All code in this header, unless otherwise specified, is hereby licensed under the MIT Public License: - -Copyright (c) 2010 Christopher Swenson - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ + * The MIT License (MIT) + * + * Copyright (c) 2010-2017 Christopher Swenson. + * Copyright (c) 2012 Vojtech Fried. + * Copyright (c) 2012 Google Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ #include #include #include #ifdef HAVE_STDINT_H #include -#else -#ifdef HAVE_INTTYPES_H -#include -#elif defined(WIN32) -typedef __int64 int64_t; +#elif defined(_WIN32) typedef unsigned __int64 uint64_t; #endif + +#ifndef SORT_NAME +#error "Must declare SORT_NAME" #endif -#ifndef MK_UINT64 -#if defined(WIN32) && defined(_MSC_VER) && _MSC_VER < 1300 -#define MK_UINT64(x) ((uint64_t)(x)) -#else -#define MK_UINT64(x) x##ULL +#ifndef SORT_TYPE +#error "Must declare SORT_TYPE" #endif + +#ifndef SORT_CMP +#define SORT_CMP(x, y) ((x) < (y) ? -1 : ((x) == (y) ? 0 : 1)) #endif +#ifndef TIM_SORT_STACK_SIZE +#define TIM_SORT_STACK_SIZE 128 +#endif + +#define SORT_SWAP(x,y) {SORT_TYPE __SORT_SWAP_t = (x); (x) = (y); (y) = __SORT_SWAP_t;} + + +/* Common, type-agnosting functions and constants that we don't want to declare twice. */ +#ifndef SORT_COMMON_H +#define SORT_COMMON_H + #ifndef MAX #define MAX(x,y) (((x) > (y) ? (x) : (y))) #endif + #ifndef MIN #define MIN(x,y) (((x) < (y) ? (x) : (y))) #endif -int compute_minrun(uint64_t); +static int compute_minrun(const uint64_t); #ifndef CLZ -#if defined(__GNUC__) && ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ > 3)) +#ifdef __GNUC__ #define CLZ __builtin_clzll #else -int clzll(uint64_t); +static int clzll(uint64_t); /* adapted from Hacker's Delight */ -int clzll(uint64_t x) /* {{{ */ -{ +static int clzll(uint64_t x) { int n; - if (x == 0) return(64); + if (x == 0) { + return 64; + } + n = 0; - if (x <= MK_UINT64(0x00000000FFFFFFFF)) {n = n + 32; x = x << 32;} - if (x <= MK_UINT64(0x0000FFFFFFFFFFFF)) {n = n + 16; x = x << 16;} - if (x <= MK_UINT64(0x00FFFFFFFFFFFFFF)) {n = n + 8; x = x << 8;} - if (x <= MK_UINT64(0x0FFFFFFFFFFFFFFF)) {n = n + 4; x = x << 4;} - if (x <= MK_UINT64(0x3FFFFFFFFFFFFFFF)) {n = n + 2; x = x << 2;} - if (x <= MK_UINT64(0x7FFFFFFFFFFFFFFF)) {n = n + 1;} + + if (x <= 0x00000000FFFFFFFFL) { + n = n + 32; + x = x << 32; + } + + if (x <= 0x0000FFFFFFFFFFFFL) { + n = n + 16; + x = x << 16; + } + + if (x <= 0x00FFFFFFFFFFFFFFL) { + n = n + 8; + x = x << 8; + } + + if (x <= 0x0FFFFFFFFFFFFFFFL) { + n = n + 4; + x = x << 4; + } + + if (x <= 0x3FFFFFFFFFFFFFFFL) { + n = n + 2; + x = x << 2; + } + + if (x <= 0x7FFFFFFFFFFFFFFFL) { + n = n + 1; + } + return n; } -/* }}} */ #define CLZ clzll #endif #endif -int compute_minrun(uint64_t size) /* {{{ */ -{ +static __inline int compute_minrun(const uint64_t size) { const int top_bit = 64 - CLZ(size); const int shift = MAX(top_bit, 6) - 6; const int minrun = size >> shift; - const uint64_t mask = (MK_UINT64(1) << shift) - 1; - if (mask & size) return minrun + 1; - return minrun; -} -/* }}} */ - -#ifndef SORT_NAME -#error "Must declare SORT_NAME" -#endif + const uint64_t mask = (1ULL << shift) - 1; -#ifndef SORT_TYPE -#error "Must declare SORT_TYPE" -#endif - -#ifndef SORT_CMP -#define SORT_CMP(x, y) ((x) < (y) ? -1 : ((x) == (y) ? 0 : 1)) -#endif + if (mask & size) { + return minrun + 1; + } + return minrun; +} -#define SORT_SWAP(x,y) {SORT_TYPE __SORT_SWAP_t = (x); (x) = (y); (y) = __SORT_SWAP_t;} +#endif /* SORT_COMMON_H */ #define SORT_CONCAT(x, y) x ## _ ## y #define SORT_MAKE_STR1(x, y) SORT_CONCAT(x,y) #define SORT_MAKE_STR(x) SORT_MAKE_STR1(SORT_NAME,x) -#define BINARY_INSERTION_FIND SORT_MAKE_STR(binary_insertion_find) -#define BINARY_INSERTION_SORT_START SORT_MAKE_STR(binary_insertion_sort_start) -#define BINARY_INSERTION_SORT SORT_MAKE_STR(binary_insertion_sort) -#define REVERSE_ELEMENTS SORT_MAKE_STR(reverse_elements) -#define COUNT_RUN SORT_MAKE_STR(count_run) -#define CHECK_INVARIANT SORT_MAKE_STR(check_invariant) -#define TIM_SORT SORT_MAKE_STR(tim_sort) -#define TIM_SORT_RESIZE SORT_MAKE_STR(tim_sort_resize) -#define TIM_SORT_MERGE SORT_MAKE_STR(tim_sort_merge) -#define TIM_SORT_COLLAPSE SORT_MAKE_STR(tim_sort_collapse) +#define BINARY_INSERTION_FIND SORT_MAKE_STR(binary_insertion_find) +#define BINARY_INSERTION_SORT_START SORT_MAKE_STR(binary_insertion_sort_start) +#define BINARY_INSERTION_SORT SORT_MAKE_STR(binary_insertion_sort) +#define REVERSE_ELEMENTS SORT_MAKE_STR(reverse_elements) +#define COUNT_RUN SORT_MAKE_STR(count_run) +#define CHECK_INVARIANT SORT_MAKE_STR(check_invariant) +#define TIM_SORT SORT_MAKE_STR(tim_sort) +#define TIM_SORT_RESIZE SORT_MAKE_STR(tim_sort_resize) +#define TIM_SORT_MERGE SORT_MAKE_STR(tim_sort_merge) +#define TIM_SORT_COLLAPSE SORT_MAKE_STR(tim_sort_collapse) -#define TIM_SORT_RUN_T SORT_MAKE_STR(tim_sort_run_t) -#define TEMP_STORAGE_T SORT_MAKE_STR(temp_storage_t) +#ifndef MAX +#define MAX(x,y) (((x) > (y) ? (x) : (y))) +#endif +#ifndef MIN +#define MIN(x,y) (((x) < (y) ? (x) : (y))) +#endif typedef struct { - int64_t start; - int64_t length; + size_t start; + size_t length; } TIM_SORT_RUN_T; + void BINARY_INSERTION_SORT(SORT_TYPE *dst, const size_t size); void TIM_SORT(SORT_TYPE *dst, const size_t size); + /* Function used to do a binary search for binary insertion sort */ -static int64_t BINARY_INSERTION_FIND(SORT_TYPE *dst, const SORT_TYPE x, const size_t size) -{ - int64_t l, c, r; - SORT_TYPE lx; +static __inline size_t BINARY_INSERTION_FIND(SORT_TYPE *dst, const SORT_TYPE x, + const size_t size) { + size_t l, c, r; SORT_TYPE cx; l = 0; r = size - 1; c = r >> 1; - lx = dst[l]; - /* check for beginning conditions */ - if (SORT_CMP(x, lx) < 0) + /* check for out of bounds at the beginning. */ + if (SORT_CMP(x, dst[0]) < 0) { return 0; - else if (SORT_CMP(x, lx) == 0) - { - int64_t i = 1; - while (SORT_CMP(x, dst[i]) == 0) i++; - return i; + } else if (SORT_CMP(x, dst[r]) > 0) { + return r; } cx = dst[c]; - while (1) - { + + while (1) { const int val = SORT_CMP(x, cx); - if (val < 0) - { - if (c - l <= 1) return c; + + if (val < 0) { + if (c - l <= 1) { + return c; + } + r = c; - } - else if (val > 0) - { - if (r - c <= 1) return c + 1; + } else { /* allow = for stability. The binary search favors the right. */ + if (r - c <= 1) { + return c + 1; + } + l = c; - lx = cx; - } - else - { - do - { - cx = dst[++c]; - } while (SORT_CMP(x, cx) == 0); - return c; } + c = l + ((r - l) >> 1); cx = dst[c]; } } /* Binary insertion sort, but knowing that the first "start" entries are sorted. Used in timsort. */ -static void BINARY_INSERTION_SORT_START(SORT_TYPE *dst, const size_t start, const size_t size) -{ - int64_t i; - for (i = start; i < (int64_t) size; i++) - { - int64_t j; +static void BINARY_INSERTION_SORT_START(SORT_TYPE *dst, const size_t start, const size_t size) { + size_t i; + + for (i = start; i < size; i++) { + size_t j; SORT_TYPE x; - int64_t location; + size_t location; + /* If this entry is already correct, just move along */ - if (SORT_CMP(dst[i - 1], dst[i]) <= 0) continue; + if (SORT_CMP(dst[i - 1], dst[i]) <= 0) { + continue; + } /* Else we need to find the right place, shift everything over, and squeeze in */ x = dst[i]; location = BINARY_INSERTION_FIND(dst, x, i); - for (j = i - 1; j >= location; j--) - { + + for (j = i - 1; j >= location; j--) { dst[j + 1] = dst[j]; + + if (j == 0) { /* check edge case because j is unsigned */ + break; + } } + dst[location] = x; } } /* Binary insertion sort */ -void BINARY_INSERTION_SORT(SORT_TYPE *dst, const size_t size) -{ +void BINARY_INSERTION_SORT(SORT_TYPE *dst, const size_t size) { + /* don't bother sorting an array of size <= 1 */ + if (size <= 1) { + return; + } + BINARY_INSERTION_SORT_START(dst, 1, size); } /* timsort implementation, based on timsort.txt */ -static void REVERSE_ELEMENTS(SORT_TYPE *dst, int64_t start, int64_t end) -{ - while (1) - { - if (start >= end) return; +static __inline void REVERSE_ELEMENTS(SORT_TYPE *dst, size_t start, size_t end) { + while (1) { + if (start >= end) { + return; + } + SORT_SWAP(dst[start], dst[end]); start++; end--; } } -static int64_t COUNT_RUN(SORT_TYPE *dst, const int64_t start, const size_t size) -{ - int64_t curr; - if (size - start == 1) return 1; - if (start >= (int64_t) size - 2) - { - if (SORT_CMP(dst[size - 2], dst[size - 1]) > 0) +static size_t COUNT_RUN(SORT_TYPE *dst, const size_t start, const size_t size) { + size_t curr; + + if (size - start == 1) { + return 1; + } + + if (start >= size - 2) { + if (SORT_CMP(dst[size - 2], dst[size - 1]) > 0) { SORT_SWAP(dst[size - 2], dst[size - 1]); + } + return 2; } curr = start + 2; - if (SORT_CMP(dst[start], dst[start + 1]) <= 0) - { + if (SORT_CMP(dst[start], dst[start + 1]) <= 0) { /* increasing run */ - while (1) - { - if (curr == (int64_t) size - 1) break; - if (SORT_CMP(dst[curr - 1], dst[curr]) > 0) break; + while (1) { + if (curr == size - 1) { + break; + } + + if (SORT_CMP(dst[curr - 1], dst[curr]) > 0) { + break; + } + curr++; } + return curr - start; - } - else - { + } else { /* decreasing run */ - while (1) - { - if (curr == (int64_t) size - 1) break; - if (SORT_CMP(dst[curr - 1], dst[curr]) <= 0) break; + while (1) { + if (curr == size - 1) { + break; + } + + if (SORT_CMP(dst[curr - 1], dst[curr]) <= 0) { + break; + } + curr++; } + /* reverse in-place */ REVERSE_ELEMENTS(dst, start, curr - 1); return curr - start; } } -#define PUSH_NEXT() do {\ -len = COUNT_RUN(dst, curr, size);\ -run = minrun;\ -if (run < minrun) run = minrun;\ -if (run > (int64_t) size - curr) run = size - curr;\ -if (run > len)\ -{\ - BINARY_INSERTION_SORT_START(&dst[curr], len, run);\ - len = run;\ -}\ -{\ -run_stack[stack_curr].start = curr;\ -run_stack[stack_curr].length = len;\ -stack_curr++;\ -}\ -curr += len;\ -if (curr == (int64_t) size)\ -{\ - /* finish up */ \ - while (stack_curr > 1) \ - { \ - TIM_SORT_MERGE(dst, run_stack, stack_curr, store); \ - run_stack[stack_curr - 2].length += run_stack[stack_curr - 1].length; \ - stack_curr--; \ - } \ - if (store->storage != NULL)\ - {\ - free(store->storage);\ - store->storage = NULL;\ - }\ - return;\ -}\ -}\ -while (0) - -static int CHECK_INVARIANT(TIM_SORT_RUN_T *stack, const int stack_curr) -{ - int64_t A, B, C; - if (stack_curr < 2) return 1; - if (stack_curr == 2) - { - const int64_t A1 = stack[stack_curr - 2].length; - const int64_t B1 = stack[stack_curr - 1].length; - if (A1 <= B1) return 0; +static int CHECK_INVARIANT(TIM_SORT_RUN_T *stack, const int stack_curr) { + size_t A, B, C; + + if (stack_curr < 2) { return 1; } + + if (stack_curr == 2) { + const size_t A1 = stack[stack_curr - 2].length; + const size_t B1 = stack[stack_curr - 1].length; + + if (A1 <= B1) { + return 0; + } + + return 1; + } + A = stack[stack_curr - 3].length; B = stack[stack_curr - 2].length; C = stack[stack_curr - 1].length; - if ((A <= B + C) || (B <= C)) return 0; + + if ((A <= B + C) || (B <= C)) { + return 0; + } + return 1; } @@ -315,86 +353,78 @@ typedef struct { SORT_TYPE *storage; } TEMP_STORAGE_T; - -static void TIM_SORT_RESIZE(TEMP_STORAGE_T *store, const size_t new_size) -{ - if (store->alloc < new_size) - { +static void TIM_SORT_RESIZE(TEMP_STORAGE_T *store, const size_t new_size) { + if (store->alloc < new_size) { SORT_TYPE *tempstore = (SORT_TYPE *)realloc(store->storage, new_size * sizeof(SORT_TYPE)); - if (tempstore == NULL) - { - fprintf(stderr, "Error allocating temporary storage for tim sort: need %lu bytes", (unsigned long) (sizeof(SORT_TYPE) * new_size)); + + if (tempstore == NULL) { + fprintf(stderr, "Error allocating temporary storage for tim sort: need %lu bytes", + (unsigned long)(sizeof(SORT_TYPE) * new_size)); exit(1); } + store->storage = tempstore; store->alloc = new_size; } } -static void TIM_SORT_MERGE(SORT_TYPE *dst, const TIM_SORT_RUN_T *stack, const int stack_curr, TEMP_STORAGE_T *store) -{ - const int64_t A = stack[stack_curr - 2].length; - const int64_t B = stack[stack_curr - 1].length; - const int64_t curr = stack[stack_curr - 2].start; +static void TIM_SORT_MERGE(SORT_TYPE *dst, const TIM_SORT_RUN_T *stack, const int stack_curr, + TEMP_STORAGE_T *store) { + const size_t A = stack[stack_curr - 2].length; + const size_t B = stack[stack_curr - 1].length; + const size_t curr = stack[stack_curr - 2].start; SORT_TYPE *storage; - int64_t i, j, k; - + size_t i, j, k; TIM_SORT_RESIZE(store, MIN(A, B)); storage = store->storage; /* left merge */ - if (A < B) - { + if (A < B) { memcpy(storage, &dst[curr], A * sizeof(SORT_TYPE)); i = 0; j = curr + A; - for (k = curr; k < curr + A + B; k++) - { - if ((i < A) && (j < curr + A + B)) - { - if (SORT_CMP(storage[i], dst[j]) <= 0) + for (k = curr; k < curr + A + B; k++) { + if ((i < A) && (j < curr + A + B)) { + if (SORT_CMP(storage[i], dst[j]) <= 0) { dst[k] = storage[i++]; - else + } else { dst[k] = dst[j++]; - } - else if (i < A) - { + } + } else if (i < A) { dst[k] = storage[i++]; + } else { + break; } - else - dst[k] = dst[j++]; } - } - /* right merge */ - else - { + } else { + /* right merge */ memcpy(storage, &dst[curr + A], B * sizeof(SORT_TYPE)); - i = B - 1; - j = curr + A - 1; - - for (k = curr + A + B - 1; k >= curr; k--) - { - if ((i >= 0) && (j >= curr)) - { - if (SORT_CMP(dst[j], storage[i]) > 0) - dst[k] = dst[j--]; - else - dst[k] = storage[i--]; + i = B; + j = curr + A; + k = curr + A + B; + + while (k-- > curr) { + if ((i > 0) && (j > curr)) { + if (SORT_CMP(dst[j - 1], storage[i - 1]) > 0) { + dst[k] = dst[--j]; + } else { + dst[k] = storage[--i]; + } + } else if (i > 0) { + dst[k] = storage[--i]; + } else { + break; } - else if (i >= 0) - dst[k] = storage[i--]; - else - dst[k] = dst[j--]; } } } -static int TIM_SORT_COLLAPSE(SORT_TYPE *dst, TIM_SORT_RUN_T *stack, int stack_curr, TEMP_STORAGE_T *store, const size_t size) -{ +static int TIM_SORT_COLLAPSE(SORT_TYPE *dst, TIM_SORT_RUN_T *stack, int stack_curr, + TEMP_STORAGE_T *store, const size_t size) { while (1) { - int64_t A, B, C, D; - int ABC, BCD, BD, CD; + size_t A, B, C, D; + int ABC, BCD, CD; /* if the stack only has one thing on it, we are done with the collapse */ if (stack_curr <= 1) { @@ -431,7 +461,6 @@ static int TIM_SORT_COLLAPSE(SORT_TYPE *dst, TIM_SORT_RUN_T *stack, int stack_cu BCD = (B <= C + D) || ABC; CD = (C <= D); - BD = (B < D); /* Both invariants are good */ if (!BCD && !CD) { @@ -455,41 +484,94 @@ static int TIM_SORT_COLLAPSE(SORT_TYPE *dst, TIM_SORT_RUN_T *stack, int stack_cu return stack_curr; } -void TIM_SORT(SORT_TYPE *dst, const size_t size) -{ - int minrun; +static __inline int PUSH_NEXT(SORT_TYPE *dst, + const size_t size, + TEMP_STORAGE_T *store, + const size_t minrun, + TIM_SORT_RUN_T *run_stack, + size_t *stack_curr, + size_t *curr) { + size_t len = COUNT_RUN(dst, *curr, size); + size_t run = minrun; + + if (run > size - *curr) { + run = size - *curr; + } + + if (run > len) { + BINARY_INSERTION_SORT_START(&dst[*curr], len, run); + len = run; + } + + run_stack[*stack_curr].start = *curr; + run_stack[*stack_curr].length = len; + (*stack_curr)++; + *curr += len; + + if (*curr == size) { + /* finish up */ + while (*stack_curr > 1) { + TIM_SORT_MERGE(dst, run_stack, *stack_curr, store); + run_stack[*stack_curr - 2].length += run_stack[*stack_curr - 1].length; + (*stack_curr)--; + } + + if (store->storage != NULL) { + free(store->storage); + store->storage = NULL; + } + + return 0; + } + + return 1; +} + +void TIM_SORT(SORT_TYPE *dst, const size_t size) { + size_t minrun; TEMP_STORAGE_T _store, *store; - TIM_SORT_RUN_T run_stack[128]; - int stack_curr = 0; - int64_t len, run; - int64_t curr = 0; + TIM_SORT_RUN_T run_stack[TIM_SORT_STACK_SIZE]; + size_t stack_curr = 0; + size_t curr = 0; - if (size < 64) - { + /* don't bother sorting an array of size 1 */ + if (size <= 1) { + return; + } + + if (size < 64) { BINARY_INSERTION_SORT(dst, size); return; } /* compute the minimum run length */ minrun = compute_minrun(size); - /* temporary storage for merges */ store = &_store; store->alloc = 0; store->storage = NULL; - PUSH_NEXT(); - PUSH_NEXT(); - PUSH_NEXT(); + if (!PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) { + return; + } + + if (!PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) { + return; + } - while (1) - { - if (!CHECK_INVARIANT(run_stack, stack_curr)) - { + if (!PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) { + return; + } + + while (1) { + if (!CHECK_INVARIANT(run_stack, stack_curr)) { stack_curr = TIM_SORT_COLLAPSE(dst, run_stack, stack_curr, store, size); continue; } - PUSH_NEXT(); + + if (!PUSH_NEXT(dst, size, store, minrun, run_stack, &stack_curr, &curr)) { + return; + } } } diff --git a/gnulib-local/lib/libxml/tree.c b/gnulib-local/lib/libxml/tree.c index 6a158cec3..959421bd6 100644 --- a/gnulib-local/lib/libxml/tree.c +++ b/gnulib-local/lib/libxml/tree.c @@ -10,10 +10,16 @@ * */ +/* To avoid EBCDIC trouble when parsing on zOS */ +#if defined(__MVS__) +#pragma convert("ISO8859-1") +#endif + #define IN_LIBXML #include "libxml.h" #include /* for memset() only ! */ +#include #include #ifdef HAVE_CTYPE_H #include @@ -21,7 +27,7 @@ #ifdef HAVE_STDLIB_H #include #endif -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED #include #endif @@ -254,10 +260,10 @@ xmlBuildQName(const xmlChar *ncname, const xmlChar *prefix, * * [NS 7] LocalPart ::= NCName * - * Returns NULL if not a QName, otherwise the local part, and prefix - * is updated to get the Prefix if any. + * Returns NULL if the name doesn't have a prefix. Otherwise, returns the + * local part, and prefix is updated to get the Prefix. Both the return value + * and the prefix must be freed by the caller. */ - xmlChar * xmlSplitQName2(const xmlChar *name, xmlChar **prefix) { int len = 0; @@ -1044,7 +1050,7 @@ xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name, * DICT_FREE: * @str: a string * - * Free a string if it is not owned by the "dict" dictionnary in the + * Free a string if it is not owned by the "dict" dictionary in the * current scope */ #define DICT_FREE(str) \ @@ -1057,7 +1063,7 @@ xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name, * DICT_COPY: * @str: a string * - * Copy a string using a "dict" dictionnary in the current scope, + * Copy a string using a "dict" dictionary in the current scope, * if availabe. */ #define DICT_COPY(str, cpy) \ @@ -1074,7 +1080,7 @@ xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name, * DICT_CONST_COPY: * @str: a string * - * Copy a string using a "dict" dictionnary in the current scope, + * Copy a string using a "dict" dictionary in the current scope, * if availabe. */ #define DICT_CONST_COPY(str, cpy) \ @@ -1401,6 +1407,8 @@ xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) { else if ((ent != NULL) && (ent->children == NULL)) { xmlNodePtr temp; + /* Set to non-NULL value to avoid recursion. */ + ent->children = (xmlNodePtr) -1; ent->children = xmlStringGetNodeList(doc, (const xmlChar*)node->content); ent->owner = 1; @@ -1593,12 +1601,15 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { else if ((ent != NULL) && (ent->children == NULL)) { xmlNodePtr temp; + /* Set to non-NULL value to avoid recursion. */ + ent->children = (xmlNodePtr) -1; ent->children = xmlStringGetNodeList(doc, (const xmlChar*)node->content); ent->owner = 1; temp = ent->children; while (temp) { temp->parent = (xmlNodePtr)ent; + ent->last = temp; temp = temp->next; } } @@ -2270,7 +2281,7 @@ xmlNewNodeEatName(xmlNsPtr ns, xmlChar *name) { cur = (xmlNodePtr) xmlMalloc(sizeof(xmlNode)); if (cur == NULL) { xmlTreeErrMemory("building node"); - /* we can't check here that name comes from the doc dictionnary */ + /* we can't check here that name comes from the doc dictionary */ return(NULL); } memset(cur, 0, sizeof(xmlNode)); @@ -2350,7 +2361,7 @@ xmlNewDocNodeEatName(xmlDocPtr doc, xmlNsPtr ns, UPDATE_LAST_CHILD_AND_PARENT(cur) } } else { - /* if name don't come from the doc dictionnary free it here */ + /* if name don't come from the doc dictionary free it here */ if ((name != NULL) && (doc != NULL) && (!(xmlDictOwns(doc->dict, name)))) xmlFree(name); @@ -3701,7 +3712,7 @@ xmlFreeNodeList(xmlNodePtr cur) { * When a node is a text node or a comment, it uses a global static * variable for the name of the node. * Otherwise the node name might come from the document's - * dictionnary + * dictionary */ if ((cur->name != NULL) && (cur->type != XML_TEXT_NODE) && @@ -3770,7 +3781,7 @@ xmlFreeNode(xmlNodePtr cur) { /* * When a node is a text node or a comment, it uses a global static * variable for the name of the node. - * Otherwise the node name might come from the document's dictionnary + * Otherwise the node name might come from the document's dictionary */ if ((cur->name != NULL) && (cur->type != XML_TEXT_NODE) && @@ -4595,7 +4606,7 @@ xmlGetLineNoInternal(const xmlNode *node, int depth) (node->type == XML_PI_NODE)) { if (node->line == 65535) { if ((node->type == XML_TEXT_NODE) && (node->psvi != NULL)) - result = (long) node->psvi; + result = (long) (ptrdiff_t) node->psvi; else if ((node->type == XML_ELEMENT_NODE) && (node->children != NULL)) result = xmlGetLineNoInternal(node->children, depth + 1); @@ -4754,8 +4765,8 @@ xmlGetNodePath(const xmlNode *node) if (occur == 0) { tmp = cur->next; while (tmp != NULL && occur == 0) { - if (tmp->type == XML_COMMENT_NODE) - occur++; + if (tmp->type == XML_COMMENT_NODE) + occur++; tmp = tmp->next; } if (occur != 0) @@ -8248,7 +8259,7 @@ xmlDOMWrapRemoveNode(xmlDOMWrapCtxtPtr ctxt, xmlDocPtr doc, ns = ns->next; } while (ns != NULL); } - /* No break on purpose. */ + /* Falls through. */ case XML_ATTRIBUTE_NODE: if (node->ns != NULL) { /* @@ -8839,7 +8850,7 @@ next_ns_decl: } if (! adoptns) goto ns_end; - /* No break on purpose. */ + /* Falls through. */ case XML_ATTRIBUTE_NODE: /* No ns, no fun. */ if (cur->ns == NULL) @@ -9120,7 +9131,7 @@ xmlDOMWrapAdoptBranch(xmlDOMWrapCtxtPtr ctxt, goto internal_error; } } - /* No break on purpose. */ + /* Falls through. */ case XML_ATTRIBUTE_NODE: /* No namespace, no fun. */ if (cur->ns == NULL) diff --git a/gnulib-local/lib/libxml/tree.in.h b/gnulib-local/lib/libxml/tree.in.h index 4a9b3bc63..626ed6ae3 100644 --- a/gnulib-local/lib/libxml/tree.in.h +++ b/gnulib-local/lib/libxml/tree.in.h @@ -575,7 +575,7 @@ struct _xmlDoc { void *ids; /* Hash table for ID attributes if any */ void *refs; /* Hash table for IDREFs attributes if any */ const xmlChar *URL; /* The URI for that document */ - int charset; /* encoding of the in-memory content + int charset; /* Internal flag for charset handling, actually an xmlCharEncoding */ struct _xmlDict *dict; /* dict used to allocate names or NULL */ void *psvi; /* for type/PSVI informations */ diff --git a/gnulib-local/lib/libxml/uri.c b/gnulib-local/lib/libxml/uri.c index ff47abbec..2cf8d9f19 100644 --- a/gnulib-local/lib/libxml/uri.c +++ b/gnulib-local/lib/libxml/uri.c @@ -314,7 +314,7 @@ xmlParse3986Query(xmlURIPtr uri, const char **str) * @uri: pointer to an URI structure * @str: the string to analyze * - * Parse a port part and fills in the appropriate fields + * Parse a port part and fills in the appropriate fields * of the @uri structure * * port = *DIGIT @@ -325,15 +325,16 @@ static int xmlParse3986Port(xmlURIPtr uri, const char **str) { const char *cur = *str; + unsigned port = 0; /* unsigned for defined overflow behavior */ if (ISA_DIGIT(cur)) { - if (uri != NULL) - uri->port = 0; while (ISA_DIGIT(cur)) { - if (uri != NULL) - uri->port = uri->port * 10 + (*cur - '0'); + port = port * 10 + (*cur - '0'); + cur++; } + if (uri != NULL) + uri->port = port & INT_MAX; /* port value modulo INT_MAX+1 */ *str = cur; return(0); } @@ -1960,8 +1961,9 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) { res->scheme = xmlMemStrdup(bas->scheme); if (bas->authority != NULL) res->authority = xmlMemStrdup(bas->authority); - else if (bas->server != NULL) { - res->server = xmlMemStrdup(bas->server); + else if ((bas->server != NULL) || (bas->port == -1)) { + if (bas->server != NULL) + res->server = xmlMemStrdup(bas->server); if (bas->user != NULL) res->user = xmlMemStrdup(bas->user); res->port = bas->port; @@ -2023,8 +2025,9 @@ xmlBuildURI(const xmlChar *URI, const xmlChar *base) { } if (bas->authority != NULL) res->authority = xmlMemStrdup(bas->authority); - else if (bas->server != NULL) { - res->server = xmlMemStrdup(bas->server); + else if ((bas->server != NULL) || (bas->port == -1)) { + if (bas->server != NULL) + res->server = xmlMemStrdup(bas->server); if (bas->user != NULL) res->user = xmlMemStrdup(bas->user); res->port = bas->port; @@ -2162,7 +2165,6 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base) xmlChar *val = NULL; int ret; int ix; - int pos = 0; int nbslash = 0; int len; xmlURIPtr ref = NULL; @@ -2234,38 +2236,24 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base) * First we take care of the special case where either of the * two path components may be missing (bug 316224) */ - if (bas->path == NULL) { - if (ref->path != NULL) { - uptr = (xmlChar *) ref->path; - if (*uptr == '/') - uptr++; - /* exception characters from xmlSaveUri */ - val = xmlURIEscapeStr(uptr, BAD_CAST "/;&=+$,"); - } - goto done; - } bptr = (xmlChar *)bas->path; - if (ref->path == NULL) { - for (ix = 0; bptr[ix] != 0; ix++) { - if (bptr[ix] == '/') - nbslash++; - } - uptr = NULL; - len = 1; /* this is for a string terminator only */ - } else { - /* - * Next we compare the two strings and find where they first differ - */ - if ((ref->path[pos] == '.') && (ref->path[pos+1] == '/')) - pos += 2; + { + xmlChar *rptr = (xmlChar *) ref->path; + int pos = 0; + + /* + * Next we compare the two strings and find where they first differ + */ + if ((*rptr == '.') && (rptr[1] == '/')) + rptr += 2; if ((*bptr == '.') && (bptr[1] == '/')) bptr += 2; - else if ((*bptr == '/') && (ref->path[pos] != '/')) + else if ((*bptr == '/') && (*rptr != '/')) bptr++; - while ((bptr[pos] == ref->path[pos]) && (bptr[pos] != 0)) + while ((bptr[pos] == rptr[pos]) && (bptr[pos] != 0)) pos++; - if (bptr[pos] == ref->path[pos]) { + if (bptr[pos] == rptr[pos]) { val = xmlStrdup(BAD_CAST ""); goto done; /* (I can't imagine why anyone would do this) */ } @@ -2275,30 +2263,28 @@ xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base) * beginning of the "unique" suffix of URI */ ix = pos; - if ((ref->path[ix] == '/') && (ix > 0)) - ix--; - else if ((ref->path[ix] == 0) && (ix > 1) && (ref->path[ix - 1] == '/')) - ix -= 2; for (; ix > 0; ix--) { - if (ref->path[ix] == '/') + if (rptr[ix - 1] == '/') break; } - if (ix == 0) { - uptr = (xmlChar *)ref->path; - } else { - ix++; - uptr = (xmlChar *)&ref->path[ix]; - } + uptr = (xmlChar *)&rptr[ix]; /* * In base, count the number of '/' from the differing point */ - if (bptr[pos] != ref->path[pos]) {/* check for trivial URI == base */ - for (; bptr[ix] != 0; ix++) { - if (bptr[ix] == '/') - nbslash++; - } + for (; bptr[ix] != 0; ix++) { + if (bptr[ix] == '/') + nbslash++; + } + + /* + * e.g: URI="foo/" base="foo/bar" -> "./" + */ + if (nbslash == 0 && !uptr[0]) { + val = xmlStrdup(BAD_CAST "./"); + goto done; } + len = xmlStrlen (uptr) + 1; } @@ -2389,8 +2375,7 @@ xmlCanonicPath(const xmlChar *path) */ #if defined(_WIN32) && !defined(__CYGWIN__) int len = 0; - int i = 0; - xmlChar *p = NULL; + char *p = NULL; #endif xmlURIPtr uri; xmlChar *ret; @@ -2454,6 +2439,7 @@ xmlCanonicPath(const xmlChar *path) xmlFreeURI(uri); return escURI; } + xmlFree(escURI); } } @@ -2471,7 +2457,7 @@ path_processing: len = xmlStrlen(path); if ((len > 2) && IS_WINDOWS_PATH(path)) { /* make the scheme 'file' */ - uri->scheme = xmlStrdup(BAD_CAST "file"); + uri->scheme = (char *) xmlStrdup(BAD_CAST "file"); /* allocate space for leading '/' + path + string terminator */ uri->path = xmlMallocAtomic(len + 2); if (uri->path == NULL) { @@ -2481,9 +2467,9 @@ path_processing: /* Put in leading '/' plus path */ uri->path[0] = '/'; p = uri->path + 1; - strncpy(p, path, len + 1); + strncpy(p, (char *) path, len + 1); } else { - uri->path = xmlStrdup(path); + uri->path = (char *) xmlStrdup(path); if (uri->path == NULL) { xmlFreeURI(uri); return(NULL); diff --git a/gnulib-local/lib/libxml/valid.c b/gnulib-local/lib/libxml/valid.c index 45a3f703a..b1cfede2d 100644 --- a/gnulib-local/lib/libxml/valid.c +++ b/gnulib-local/lib/libxml/valid.c @@ -93,7 +93,7 @@ xmlVErrMemory(xmlValidCtxtPtr ctxt, const char *extra) * * Handle a validation error */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlErrValid(xmlValidCtxtPtr ctxt, xmlParserErrors error, const char *msg, const char *extra) { @@ -137,7 +137,7 @@ xmlErrValid(xmlValidCtxtPtr ctxt, xmlParserErrors error, * * Handle a validation error, provide contextual informations */ -static void +static void LIBXML_ATTR_FORMAT(4,0) xmlErrValidNode(xmlValidCtxtPtr ctxt, xmlNodePtr node, xmlParserErrors error, const char *msg, const xmlChar * str1, @@ -163,7 +163,7 @@ xmlErrValidNode(xmlValidCtxtPtr ctxt, __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error, XML_ERR_ERROR, NULL, 0, (const char *) str1, - (const char *) str1, + (const char *) str2, (const char *) str3, 0, 0, msg, str1, str2, str3); } #endif /* LIBXML_VALID_ENABLED or LIBXML_SCHEMAS_ENABLED */ @@ -180,7 +180,7 @@ xmlErrValidNode(xmlValidCtxtPtr ctxt, * * Handle a validation error, provide contextual informations */ -static void +static void LIBXML_ATTR_FORMAT(4,0) xmlErrValidNodeNr(xmlValidCtxtPtr ctxt, xmlNodePtr node, xmlParserErrors error, const char *msg, const xmlChar * str1, @@ -221,7 +221,7 @@ xmlErrValidNodeNr(xmlValidCtxtPtr ctxt, * * Handle a validation error, provide contextual information */ -static void +static void LIBXML_ATTR_FORMAT(4,0) xmlErrValidWarning(xmlValidCtxtPtr ctxt, xmlNodePtr node, xmlParserErrors error, const char *msg, const xmlChar * str1, @@ -247,7 +247,7 @@ xmlErrValidWarning(xmlValidCtxtPtr ctxt, __xmlRaiseError(schannel, channel, data, pctxt, node, XML_FROM_VALID, error, XML_ERR_WARNING, NULL, 0, (const char *) str1, - (const char *) str1, + (const char *) str2, (const char *) str3, 0, 0, msg, str1, str2, str3); } @@ -1172,29 +1172,33 @@ xmlDumpElementContent(xmlBufferPtr buf, xmlElementContentPtr content, int glob) xmlBufferWriteCHAR(buf, content->name); break; case XML_ELEMENT_CONTENT_SEQ: - if ((content->c1->type == XML_ELEMENT_CONTENT_OR) || - (content->c1->type == XML_ELEMENT_CONTENT_SEQ)) + if ((content->c1 != NULL) && + ((content->c1->type == XML_ELEMENT_CONTENT_OR) || + (content->c1->type == XML_ELEMENT_CONTENT_SEQ))) xmlDumpElementContent(buf, content->c1, 1); else xmlDumpElementContent(buf, content->c1, 0); xmlBufferWriteChar(buf, " , "); - if ((content->c2->type == XML_ELEMENT_CONTENT_OR) || - ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) && - (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE))) + if ((content->c2 != NULL) && + ((content->c2->type == XML_ELEMENT_CONTENT_OR) || + ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) && + (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)))) xmlDumpElementContent(buf, content->c2, 1); else xmlDumpElementContent(buf, content->c2, 0); break; case XML_ELEMENT_CONTENT_OR: - if ((content->c1->type == XML_ELEMENT_CONTENT_OR) || - (content->c1->type == XML_ELEMENT_CONTENT_SEQ)) + if ((content->c1 != NULL) && + ((content->c1->type == XML_ELEMENT_CONTENT_OR) || + (content->c1->type == XML_ELEMENT_CONTENT_SEQ))) xmlDumpElementContent(buf, content->c1, 1); else xmlDumpElementContent(buf, content->c1, 0); xmlBufferWriteChar(buf, " | "); - if ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) || - ((content->c2->type == XML_ELEMENT_CONTENT_OR) && - (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE))) + if ((content->c2 != NULL) && + ((content->c2->type == XML_ELEMENT_CONTENT_SEQ) || + ((content->c2->type == XML_ELEMENT_CONTENT_OR) && + (content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)))) xmlDumpElementContent(buf, content->c2, 1); else xmlDumpElementContent(buf, content->c2, 0); @@ -1262,22 +1266,23 @@ xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int case XML_ELEMENT_CONTENT_PCDATA: strcat(buf, "#PCDATA"); break; - case XML_ELEMENT_CONTENT_ELEMENT: + 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) { - if (size - len < xmlStrlen(content->prefix) + 10) { - strcat(buf, " ..."); - return; - } strcat(buf, (char *) content->prefix); strcat(buf, ":"); } - if (size - len < xmlStrlen(content->name) + 10) { - strcat(buf, " ..."); - return; - } if (content->name != NULL) strcat(buf, (char *) content->name); break; + } case XML_ELEMENT_CONTENT_SEQ: if ((content->c1->type == XML_ELEMENT_CONTENT_OR) || (content->c1->type == XML_ELEMENT_CONTENT_SEQ)) @@ -1319,6 +1324,7 @@ xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int xmlSnprintfElementContent(buf, size, content->c2, 0); break; } + if (size - strlen(buf) <= 2) return; if (englob) strcat(buf, ")"); switch (content->ocur) { @@ -1591,6 +1597,11 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt, return(ret); } +static void +xmlFreeElementTableEntry(void *elem, const xmlChar *name ATTRIBUTE_UNUSED) { + xmlFreeElement((xmlElementPtr) elem); +} + /** * xmlFreeElementTable: * @table: An element table @@ -1599,7 +1610,7 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt, */ void xmlFreeElementTable(xmlElementTablePtr table) { - xmlHashFree(table, (xmlHashDeallocator) xmlFreeElement); + xmlHashFree(table, xmlFreeElementTableEntry); } #ifdef LIBXML_TREE_ENABLED @@ -1611,8 +1622,9 @@ xmlFreeElementTable(xmlElementTablePtr table) { * * Returns the new xmlElementPtr or NULL in case of error. */ -static xmlElementPtr -xmlCopyElement(xmlElementPtr elem) { +static void * +xmlCopyElement(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) { + xmlElementPtr elem = (xmlElementPtr) payload; xmlElementPtr cur; cur = (xmlElementPtr) xmlMalloc(sizeof(xmlElement)); @@ -1647,8 +1659,7 @@ xmlCopyElement(xmlElementPtr elem) { */ xmlElementTablePtr xmlCopyElementTable(xmlElementTablePtr table) { - return((xmlElementTablePtr) xmlHashCopy(table, - (xmlHashCopier) xmlCopyElement)); + return((xmlElementTablePtr) xmlHashCopy(table, xmlCopyElement)); } #endif /* LIBXML_TREE_ENABLED */ @@ -1722,8 +1733,9 @@ xmlDumpElementDecl(xmlBufferPtr buf, xmlElementPtr elem) { * the arguments. */ static void -xmlDumpElementDeclScan(xmlElementPtr elem, xmlBufferPtr buf) { - xmlDumpElementDecl(buf, elem); +xmlDumpElementDeclScan(void *elem, void *buf, + const xmlChar *name ATTRIBUTE_UNUSED) { + xmlDumpElementDecl((xmlBufferPtr) buf, (xmlElementPtr) elem); } /** @@ -1737,7 +1749,7 @@ void xmlDumpElementTable(xmlBufferPtr buf, xmlElementTablePtr table) { if ((buf == NULL) || (table == NULL)) return; - xmlHashScan(table, (xmlHashScanner) xmlDumpElementDeclScan, buf); + xmlHashScan(table, xmlDumpElementDeclScan, buf); } #endif /* LIBXML_OUTPUT_ENABLED */ @@ -2137,6 +2149,11 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, return(ret); } +static void +xmlFreeAttributeTableEntry(void *attr, const xmlChar *name ATTRIBUTE_UNUSED) { + xmlFreeAttribute((xmlAttributePtr) attr); +} + /** * xmlFreeAttributeTable: * @table: An attribute table @@ -2145,7 +2162,7 @@ xmlAddAttributeDecl(xmlValidCtxtPtr ctxt, */ void xmlFreeAttributeTable(xmlAttributeTablePtr table) { - xmlHashFree(table, (xmlHashDeallocator) xmlFreeAttribute); + xmlHashFree(table, xmlFreeAttributeTableEntry); } #ifdef LIBXML_TREE_ENABLED @@ -2157,8 +2174,9 @@ xmlFreeAttributeTable(xmlAttributeTablePtr table) { * * Returns the new xmlAttributePtr or NULL in case of error. */ -static xmlAttributePtr -xmlCopyAttribute(xmlAttributePtr attr) { +static void * +xmlCopyAttribute(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) { + xmlAttributePtr attr = (xmlAttributePtr) payload; xmlAttributePtr cur; cur = (xmlAttributePtr) xmlMalloc(sizeof(xmlAttribute)); @@ -2192,8 +2210,7 @@ xmlCopyAttribute(xmlAttributePtr attr) { */ xmlAttributeTablePtr xmlCopyAttributeTable(xmlAttributeTablePtr table) { - return((xmlAttributeTablePtr) xmlHashCopy(table, - (xmlHashCopier) xmlCopyAttribute)); + return((xmlAttributeTablePtr) xmlHashCopy(table, xmlCopyAttribute)); } #endif /* LIBXML_TREE_ENABLED */ @@ -2288,8 +2305,9 @@ xmlDumpAttributeDecl(xmlBufferPtr buf, xmlAttributePtr attr) { * This is used with the hash scan function - just reverses arguments */ static void -xmlDumpAttributeDeclScan(xmlAttributePtr attr, xmlBufferPtr buf) { - xmlDumpAttributeDecl(buf, attr); +xmlDumpAttributeDeclScan(void *attr, void *buf, + const xmlChar *name ATTRIBUTE_UNUSED) { + xmlDumpAttributeDecl((xmlBufferPtr) buf, (xmlAttributePtr) attr); } /** @@ -2303,7 +2321,7 @@ void xmlDumpAttributeTable(xmlBufferPtr buf, xmlAttributeTablePtr table) { if ((buf == NULL) || (table == NULL)) return; - xmlHashScan(table, (xmlHashScanner) xmlDumpAttributeDeclScan, buf); + xmlHashScan(table, xmlDumpAttributeDeclScan, buf); } #endif /* LIBXML_OUTPUT_ENABLED */ @@ -2409,6 +2427,11 @@ xmlAddNotationDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, return(ret); } +static void +xmlFreeNotationTableEntry(void *nota, const xmlChar *name ATTRIBUTE_UNUSED) { + xmlFreeNotation((xmlNotationPtr) nota); +} + /** * xmlFreeNotationTable: * @table: An notation table @@ -2417,7 +2440,7 @@ xmlAddNotationDecl(xmlValidCtxtPtr ctxt, xmlDtdPtr dtd, */ void xmlFreeNotationTable(xmlNotationTablePtr table) { - xmlHashFree(table, (xmlHashDeallocator) xmlFreeNotation); + xmlHashFree(table, xmlFreeNotationTableEntry); } #ifdef LIBXML_TREE_ENABLED @@ -2429,8 +2452,9 @@ xmlFreeNotationTable(xmlNotationTablePtr table) { * * Returns the new xmlNotationPtr or NULL in case of error. */ -static xmlNotationPtr -xmlCopyNotation(xmlNotationPtr nota) { +static void * +xmlCopyNotation(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) { + xmlNotationPtr nota = (xmlNotationPtr) payload; xmlNotationPtr cur; cur = (xmlNotationPtr) xmlMalloc(sizeof(xmlNotation)); @@ -2463,8 +2487,7 @@ xmlCopyNotation(xmlNotationPtr nota) { */ xmlNotationTablePtr xmlCopyNotationTable(xmlNotationTablePtr table) { - return((xmlNotationTablePtr) xmlHashCopy(table, - (xmlHashCopier) xmlCopyNotation)); + return((xmlNotationTablePtr) xmlHashCopy(table, xmlCopyNotation)); } #endif /* LIBXML_TREE_ENABLED */ @@ -2504,8 +2527,9 @@ xmlDumpNotationDecl(xmlBufferPtr buf, xmlNotationPtr nota) { * This is called with the hash scan function, and just reverses args */ static void -xmlDumpNotationDeclScan(xmlNotationPtr nota, xmlBufferPtr buf) { - xmlDumpNotationDecl(buf, nota); +xmlDumpNotationDeclScan(void *nota, void *buf, + const xmlChar *name ATTRIBUTE_UNUSED) { + xmlDumpNotationDecl((xmlBufferPtr) buf, (xmlNotationPtr) nota); } /** @@ -2519,7 +2543,7 @@ void xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) { if ((buf == NULL) || (table == NULL)) return; - xmlHashScan(table, (xmlHashScanner) xmlDumpNotationDeclScan, buf); + xmlHashScan(table, xmlDumpNotationDeclScan, buf); } #endif /* LIBXML_OUTPUT_ENABLED */ @@ -2532,7 +2556,7 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) { * DICT_FREE: * @str: a string * - * Free a string if it is not owned by the "dict" dictionnary in the + * Free a string if it is not owned by the "dict" dictionary in the * current scope */ #define DICT_FREE(str) \ @@ -2647,6 +2671,11 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value, return(ret); } +static void +xmlFreeIDTableEntry(void *id, const xmlChar *name ATTRIBUTE_UNUSED) { + xmlFreeID((xmlIDPtr) id); +} + /** * xmlFreeIDTable: * @table: An id table @@ -2655,7 +2684,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value, */ void xmlFreeIDTable(xmlIDTablePtr table) { - xmlHashFree(table, (xmlHashDeallocator) xmlFreeID); + xmlHashFree(table, xmlFreeIDTableEntry); } /** @@ -2755,7 +2784,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) { return(-1); } - xmlHashRemoveEntry(table, ID, (xmlHashDeallocator) xmlFreeID); + xmlHashRemoveEntry(table, ID, xmlFreeIDTableEntry); xmlFree(ID); attr->atype = 0; return(0); @@ -2839,13 +2868,14 @@ xmlFreeRef(xmlLinkPtr lk) { } /** - * xmlFreeRefList: + * xmlFreeRefTableEntry: * @list_ref: A list of references. * * Deallocate the memory used by a list of references */ static void -xmlFreeRefList(xmlListPtr list_ref) { +xmlFreeRefTableEntry(void *payload, const xmlChar *name ATTRIBUTE_UNUSED) { + xmlListPtr list_ref = (xmlListPtr) payload; if (list_ref == NULL) return; xmlListDelete(list_ref); } @@ -2858,7 +2888,7 @@ xmlFreeRefList(xmlListPtr list_ref) { * Returns 0 to abort the walk or 1 to continue */ static int -xmlWalkRemoveRef(const void *data, const void *user) +xmlWalkRemoveRef(const void *data, void *user) { xmlAttrPtr attr0 = ((xmlRefPtr)data)->attr; xmlAttrPtr attr1 = ((xmlRemoveMemoPtr)user)->ap; @@ -2996,7 +3026,7 @@ failed: */ void xmlFreeRefTable(xmlRefTablePtr table) { - xmlHashFree(table, (xmlHashDeallocator) xmlFreeRefList); + xmlHashFree(table, xmlFreeRefTableEntry); } /** @@ -3093,8 +3123,7 @@ xmlRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) { /*If the list is empty then remove the list entry in the hash */ if (xmlListEmpty(ref_list)) - xmlHashUpdateEntry(table, ID, NULL, (xmlHashDeallocator) - xmlFreeRefList); + xmlHashUpdateEntry(table, ID, NULL, xmlFreeRefTableEntry); xmlFree(ID); return(0); } @@ -4090,8 +4119,10 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem, } static void -xmlValidateAttributeIdCallback(xmlAttributePtr attr, int *count, - const xmlChar* name ATTRIBUTE_UNUSED) { +xmlValidateAttributeIdCallback(void *payload, void *data, + const xmlChar *name ATTRIBUTE_UNUSED) { + xmlAttributePtr attr = (xmlAttributePtr) payload; + int *count = (int *) data; if (attr->atype == XML_ATTRIBUTE_ID) (*count)++; } @@ -4163,7 +4194,7 @@ xmlValidateAttributeDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc, nbId = 0; if (doc->intSubset != NULL) { table = (xmlAttributeTablePtr) doc->intSubset->attributes; - xmlHashScan3(table, NULL, NULL, attr->elem, (xmlHashScanner) + xmlHashScan3(table, NULL, NULL, attr->elem, xmlValidateAttributeIdCallback, &nbId); } } @@ -4621,6 +4652,12 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) { } } + /* + * Casting ns to xmlAttrPtr is wrong. We'd need separate functions + * xmlAddID and xmlAddRef for namespace declarations, but it makes + * no practical sense to use ID types anyway. + */ +#if 0 /* Validity Constraint: ID uniqueness */ if (attrDecl->atype == XML_ATTRIBUTE_ID) { if (xmlAddID(ctxt, doc, value, (xmlAttrPtr) ns) == NULL) @@ -4632,6 +4669,7 @@ xmlNodePtr elem, const xmlChar *prefix, xmlNsPtr ns, const xmlChar *value) { if (xmlAddRef(ctxt, doc, value, (xmlAttrPtr) ns) == NULL) ret = 0; } +#endif /* Validity Constraint: Notation Attributes */ if (attrDecl->atype == XML_ATTRIBUTE_NOTATION) { @@ -5177,6 +5215,7 @@ xmlSnprintfElements(char *buf, int size, xmlNodePtr node, int glob) { case XML_TEXT_NODE: if (xmlIsBlankNode(cur)) break; + /* Falls through. */ case XML_CDATA_SECTION_NODE: case XML_ENTITY_REF_NODE: strcat(buf, "CDATA"); @@ -5725,7 +5764,7 @@ xmlValidatePushElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlElementPtr elemDecl; /* - * Check the new element agaisnt the content model of the new elem. + * Check the new element against the content model of the new elem. */ if (state->elemDecl != NULL) { elemDecl = state->elemDecl; @@ -5817,7 +5856,7 @@ xmlValidatePushCData(xmlValidCtxtPtr ctxt, const xmlChar *data, int len) { xmlElementPtr elemDecl; /* - * Check the new element agaisnt the content model of the new elem. + * Check the new element against the content model of the new elem. */ if (state->elemDecl != NULL) { elemDecl = state->elemDecl; @@ -5891,7 +5930,7 @@ xmlValidatePopElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc ATTRIBUTE_UNUSED, xmlElementPtr elemDecl; /* - * Check the new element agaisnt the content model of the new elem. + * Check the new element against the content model of the new elem. */ if (state->elemDecl != NULL) { elemDecl = state->elemDecl; @@ -6516,7 +6555,7 @@ xmlValidateRef(xmlRefPtr ref, xmlValidCtxtPtr ctxt, * Returns 0 to abort the walk or 1 to continue */ static int -xmlWalkValidateList(const void *data, const void *user) +xmlWalkValidateList(const void *data, void *user) { xmlValidateMemoPtr memo = (xmlValidateMemoPtr)user; xmlValidateRef((xmlRefPtr)data, memo->ctxt, memo->name); @@ -6531,8 +6570,9 @@ xmlWalkValidateList(const void *data, const void *user) * */ static void -xmlValidateCheckRefCallback(xmlListPtr ref_list, xmlValidCtxtPtr ctxt, - const xmlChar *name) { +xmlValidateCheckRefCallback(void *payload, void *data, const xmlChar *name) { + xmlListPtr ref_list = (xmlListPtr) payload; + xmlValidCtxtPtr ctxt = (xmlValidCtxtPtr) data; xmlValidateMemo memo; if (ref_list == NULL) @@ -6588,7 +6628,7 @@ xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) { table = (xmlRefTablePtr) doc->refs; ctxt->doc = doc; ctxt->valid = 1; - xmlHashScan(table, (xmlHashScanner) xmlValidateCheckRefCallback, ctxt); + xmlHashScan(table, xmlValidateCheckRefCallback, ctxt); ctxt->finishDtd = save; return(ctxt->valid); @@ -6645,8 +6685,10 @@ xmlValidateDtd(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlDtdPtr dtd) { } static void -xmlValidateNotationCallback(xmlEntityPtr cur, xmlValidCtxtPtr ctxt, +xmlValidateNotationCallback(void *payload, void *data, const xmlChar *name ATTRIBUTE_UNUSED) { + xmlEntityPtr cur = (xmlEntityPtr) payload; + xmlValidCtxtPtr ctxt = (xmlValidCtxtPtr) data; if (cur == NULL) return; if (cur->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) { @@ -6664,8 +6706,10 @@ xmlValidateNotationCallback(xmlEntityPtr cur, xmlValidCtxtPtr ctxt, } static void -xmlValidateAttributeCallback(xmlAttributePtr cur, xmlValidCtxtPtr ctxt, - const xmlChar *name ATTRIBUTE_UNUSED) { +xmlValidateAttributeCallback(void *payload, void *data, + const xmlChar *name ATTRIBUTE_UNUSED) { + xmlAttributePtr cur = (xmlAttributePtr) payload; + xmlValidCtxtPtr ctxt = (xmlValidCtxtPtr) data; int ret; xmlDocPtr doc; xmlElementPtr elem = NULL; @@ -6764,22 +6808,20 @@ xmlValidateDtdFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) { dtd = doc->intSubset; if ((dtd != NULL) && (dtd->attributes != NULL)) { table = (xmlAttributeTablePtr) dtd->attributes; - xmlHashScan(table, (xmlHashScanner) xmlValidateAttributeCallback, ctxt); + xmlHashScan(table, xmlValidateAttributeCallback, ctxt); } if ((dtd != NULL) && (dtd->entities != NULL)) { entities = (xmlEntitiesTablePtr) dtd->entities; - xmlHashScan(entities, (xmlHashScanner) xmlValidateNotationCallback, - ctxt); + xmlHashScan(entities, xmlValidateNotationCallback, ctxt); } dtd = doc->extSubset; if ((dtd != NULL) && (dtd->attributes != NULL)) { table = (xmlAttributeTablePtr) dtd->attributes; - xmlHashScan(table, (xmlHashScanner) xmlValidateAttributeCallback, ctxt); + xmlHashScan(table, xmlValidateAttributeCallback, ctxt); } if ((dtd != NULL) && (dtd->entities != NULL)) { entities = (xmlEntitiesTablePtr) dtd->entities; - xmlHashScan(entities, (xmlHashScanner) xmlValidateNotationCallback, - ctxt); + xmlHashScan(entities, xmlValidateNotationCallback, ctxt); } return(ctxt->valid); } diff --git a/gnulib-local/lib/libxml/xinclude.c b/gnulib-local/lib/libxml/xinclude.c index ff3dafbb9..001e992f7 100644 --- a/gnulib-local/lib/libxml/xinclude.c +++ b/gnulib-local/lib/libxml/xinclude.c @@ -125,7 +125,7 @@ xmlXIncludeErrMemory(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, * * Handle an XInclude error */ -static void +static void LIBXML_ATTR_FORMAT(4,0) xmlXIncludeErr(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error, const char *msg, const xmlChar *extra) { @@ -147,7 +147,7 @@ xmlXIncludeErr(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error, * * Emit an XInclude warning. */ -static void +static void LIBXML_ATTR_FORMAT(4,0) xmlXIncludeWarn(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node, int error, const char *msg, const xmlChar *extra) { @@ -1261,8 +1261,10 @@ struct _xmlXIncludeMergeData { * Inplements the merge of one entity */ static void -xmlXIncludeMergeEntity(xmlEntityPtr ent, xmlXIncludeMergeDataPtr data, - xmlChar *name ATTRIBUTE_UNUSED) { +xmlXIncludeMergeEntity(void *payload, void *vdata, + const xmlChar *name ATTRIBUTE_UNUSED) { + xmlEntityPtr ent = (xmlEntityPtr) payload; + xmlXIncludeMergeDataPtr data = (xmlXIncludeMergeDataPtr) vdata; xmlEntityPtr ret, prev; xmlDocPtr doc; xmlXIncludeCtxtPtr ctxt; @@ -1367,7 +1369,7 @@ xmlXIncludeMergeEntities(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, data.doc = doc; xmlHashScan((xmlHashTablePtr) source->entities, - (xmlHashScanner) xmlXIncludeMergeEntity, &data); + xmlXIncludeMergeEntity, &data); } source = from->extSubset; if ((source != NULL) && (source->entities != NULL)) { @@ -1382,7 +1384,7 @@ xmlXIncludeMergeEntities(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, if ((!xmlStrEqual(target->ExternalID, source->ExternalID)) && (!xmlStrEqual(target->SystemID, source->SystemID))) { xmlHashScan((xmlHashTablePtr) source->entities, - (xmlHashScanner) xmlXIncludeMergeEntity, &data); + xmlXIncludeMergeEntity, &data); } } return(0); diff --git a/gnulib-local/lib/libxml/xlink.c b/gnulib-local/lib/libxml/xlink.c index c0e4ff323..ecf9f968a 100644 --- a/gnulib-local/lib/libxml/xlink.c +++ b/gnulib-local/lib/libxml/xlink.c @@ -28,7 +28,7 @@ #ifdef HAVE_UNISTD_H #include #endif -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED #include #endif diff --git a/gnulib-local/lib/libxml/xmlIO.c b/gnulib-local/lib/libxml/xmlIO.c index 8b13184aa..f61dd05a9 100644 --- a/gnulib-local/lib/libxml/xmlIO.c +++ b/gnulib-local/lib/libxml/xmlIO.c @@ -12,6 +12,7 @@ #include "libxml.h" #include +#include #ifdef HAVE_ERRNO_H #include #endif @@ -32,14 +33,15 @@ #ifdef HAVE_STDLIB_H #include #endif -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED #include #endif -#ifdef HAVE_LZMA_H +#ifdef LIBXML_LZMA_ENABLED #include #endif -#if defined(WIN32) || defined(_WIN32) +#if defined(_WIN32) && !defined(__CYGWIN__) +#define WIN32_LEAN_AND_MEAN #include #endif @@ -47,38 +49,14 @@ #include /* for CP_UTF8 */ #endif -/* Figure a portable way to know if a file is a directory. */ -#ifndef HAVE_STAT -# ifdef HAVE__STAT - /* MS C library seems to define stat and _stat. The definition - is identical. Still, mapping them to each other causes a warning. */ -# ifndef _MSC_VER -# define stat(x,y) _stat(x,y) -# endif -# define HAVE_STAT -# endif -#else -# ifdef HAVE__STAT -# if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) -# define stat _stat -# endif -# endif -#endif -#ifdef HAVE_STAT -# ifndef S_ISDIR -# ifdef _S_ISDIR -# define S_ISDIR(x) _S_ISDIR(x) -# else -# ifdef S_IFDIR -# ifndef S_IFMT -# ifdef _S_IFMT -# define S_IFMT _S_IFMT -# endif -# endif -# ifdef S_IFMT -# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -# endif -# endif +#ifndef S_ISDIR +# ifdef _S_ISDIR +# define S_ISDIR(x) _S_ISDIR(x) +# elif defined(S_IFDIR) +# ifdef S_IFMT +# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +# elif defined(_S_IFMT) +# define S_ISDIR(m) (((m) & _S_IFMT) == S_IFDIR) # endif # endif #endif @@ -619,7 +597,7 @@ xmlWrapOpenUtf8(const char *path,int mode) return fd; } -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED static gzFile xmlWrapGzOpenUtf8(const char *path, const char *mode) { @@ -656,99 +634,19 @@ xmlWrapGzOpenUtf8(const char *path, const char *mode) * */ static int -xmlWrapStatUtf8(const char *path,struct stat *info) -{ -#ifdef HAVE_STAT +xmlWrapStatUtf8(const char *path, struct _stat *info) { int retval = -1; wchar_t *wPath; wPath = __xmlIOWin32UTF8ToWChar(path); - if (wPath) - { - retval = _wstat(wPath,info); + if (wPath) { + retval = _wstat(wPath, info); xmlFree(wPath); } /* maybe path in native encoding */ if(retval < 0) - retval = stat(path,info); + retval = _stat(path, info); return retval; -#else - return -1; -#endif -} - -/** - * xmlWrapOpenNative: - * @path: the path - * @mode: type of access (0 - read, 1 - write) - * - * function opens the file specified by @path - * - */ -static FILE* -xmlWrapOpenNative(const char *path,int mode) -{ - return fopen(path,mode ? "wb" : "rb"); -} - -/** - * xmlWrapStatNative: - * @path: the path - * @info: structure that stores results - * - * function obtains information about the file or directory - * - */ -static int -xmlWrapStatNative(const char *path,struct stat *info) -{ -#ifdef HAVE_STAT - return stat(path,info); -#else - return -1; -#endif -} - -typedef int (* xmlWrapStatFunc) (const char *f, struct stat *s); -static xmlWrapStatFunc xmlWrapStat = xmlWrapStatNative; -typedef FILE* (* xmlWrapOpenFunc)(const char *f,int mode); -static xmlWrapOpenFunc xmlWrapOpen = xmlWrapOpenNative; -#ifdef HAVE_ZLIB_H -typedef gzFile (* xmlWrapGzOpenFunc) (const char *f, const char *mode); -static xmlWrapGzOpenFunc xmlWrapGzOpen = gzopen; -#endif -/** - * xmlInitPlatformSpecificIo: - * - * Initialize platform specific features. - */ -static void -xmlInitPlatformSpecificIo(void) -{ - static int xmlPlatformIoInitialized = 0; - OSVERSIONINFO osvi; - - if(xmlPlatformIoInitialized) - return; - - osvi.dwOSVersionInfoSize = sizeof(osvi); - - if(GetVersionEx(&osvi) && (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)) { - xmlWrapStat = xmlWrapStatUtf8; - xmlWrapOpen = xmlWrapOpenUtf8; -#ifdef HAVE_ZLIB_H - xmlWrapGzOpen = xmlWrapGzOpenUtf8; -#endif - } else { - xmlWrapStat = xmlWrapStatNative; - xmlWrapOpen = xmlWrapOpenNative; -#ifdef HAVE_ZLIB_H - xmlWrapGzOpen = gzopen; -#endif - } - - xmlPlatformIoInitialized = 1; - return; } #endif @@ -771,7 +669,11 @@ int xmlCheckFilename (const char *path) { #ifdef HAVE_STAT +#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) + struct _stat stat_buffer; +#else struct stat stat_buffer; +#endif #endif if (path == NULL) return(0); @@ -786,7 +688,7 @@ xmlCheckFilename (const char *path) (path[3] == '\\') ) return 1; - if (xmlWrapStat(path, &stat_buffer) == -1) + if (xmlWrapStatUtf8(path, &stat_buffer) == -1) return 0; #else if (stat(path, &stat_buffer) == -1) @@ -801,14 +703,16 @@ xmlCheckFilename (const char *path) } /** - * xmlNop: + * xmlInputReadCallbackNop: * - * No Operation function, does nothing, no input + * No Operation xmlInputReadCallback function, does nothing. * * Returns zero */ int -xmlNop(void) { +xmlInputReadCallbackNop(void *context ATTRIBUTE_UNUSED, + char *buffer ATTRIBUTE_UNUSED, + int len ATTRIBUTE_UNUSED) { return(0); } @@ -826,7 +730,7 @@ static int xmlFdRead (void * context, char * buffer, int len) { int ret; - ret = read((int) (long) context, &buffer[0], len); + ret = read((int) (ptrdiff_t) context, &buffer[0], len); if (ret < 0) xmlIOErr(0, "read()"); return(ret); } @@ -847,7 +751,7 @@ xmlFdWrite (void * context, const char * buffer, int len) { int ret = 0; if (len > 0) { - ret = write((int) (long) context, &buffer[0], len); + ret = write((int) (ptrdiff_t) context, &buffer[0], len); if (ret < 0) xmlIOErr(0, "write()"); } return(ret); @@ -865,7 +769,7 @@ xmlFdWrite (void * context, const char * buffer, int len) { static int xmlFdClose (void * context) { int ret; - ret = close((int) (long) context); + ret = close((int) (ptrdiff_t) context); if (ret < 0) xmlIOErr(0, "close()"); return(ret); } @@ -926,11 +830,14 @@ xmlFileOpen_real (const char *filename) { #endif } + /* Do not check DDNAME on zOS ! */ +#if !defined(__MVS__) if (!xmlCheckFilename(path)) return(NULL); +#endif #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) - fd = xmlWrapOpen(path, 0); + fd = xmlWrapOpenUtf8(path, 0); #else fd = fopen(path, "r"); #endif /* WIN32 */ @@ -1003,12 +910,14 @@ xmlFileOpenW (const char *filename) { return(NULL); #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) - fd = xmlWrapOpen(path, 1); + fd = xmlWrapOpenUtf8(path, 1); +#elif(__MVS__) + fd = fopen(path, "w"); #else - fd = fopen(path, "wb"); + fd = fopen(path, "wb"); #endif /* WIN32 */ - if (fd == NULL) xmlIOErr(0, path); + if (fd == NULL) xmlIOErr(0, path); return((void *) fd); } #endif /* LIBXML_OUTPUT_ENABLED */ @@ -1129,7 +1038,7 @@ xmlBufferWrite (void * context, const char * buffer, int len) { } #endif -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED /************************************************************************ * * * I/O for compressed file accesses * @@ -1193,7 +1102,7 @@ xmlGzfileOpen_real (const char *filename) { return(NULL); #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) - fd = xmlWrapGzOpen(path, "rb"); + fd = xmlWrapGzOpenUtf8(path, "rb"); #else fd = gzopen(path, "rb"); #endif @@ -1270,7 +1179,7 @@ xmlGzfileOpenW (const char *filename, int compression) { return(NULL); #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) - fd = xmlWrapGzOpen(path, mode); + fd = xmlWrapGzOpenUtf8(path, mode); #else fd = gzopen(path, mode); #endif @@ -1286,7 +1195,7 @@ xmlGzfileOpenW (const char *filename, int compression) { * * Read @len bytes to @buffer from the compressed I/O channel. * - * Returns the number of bytes written + * Returns the number of bytes read. */ static int xmlGzfileRead (void * context, char * buffer, int len) { @@ -1332,7 +1241,7 @@ xmlGzfileClose (void * context) { if (ret < 0) xmlIOErr(0, "gzclose()"); return(ret); } -#endif /* HAVE_ZLIB_H */ +#endif /* LIBXML_ZLIB_ENABLED */ #ifdef LIBXML_LZMA_ENABLED /************************************************************************ @@ -1471,7 +1380,7 @@ typedef struct xmlIOHTTPWriteCtxt_ } xmlIOHTTPWriteCtxt, *xmlIOHTTPWriteCtxtPtr; -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED #define DFLT_WBITS ( -15 ) #define DFLT_MEM_LVL ( 8 ) @@ -1604,7 +1513,7 @@ xmlCreateZMemBuff( int compression ) { xmlFreeZMemBuff( buff ); buff = NULL; xmlStrPrintf(msg, 500, - (const xmlChar *) "xmlCreateZMemBuff: %s %d\n", + "xmlCreateZMemBuff: %s %d\n", "Error initializing compression context. ZLIB error:", z_err ); xmlIOErr(XML_IO_WRITE, (const char *) msg); @@ -1672,9 +1581,9 @@ xmlZMemBuffExtend( xmlZMemBuffPtr buff, size_t ext_amt ) { else { xmlChar msg[500]; xmlStrPrintf(msg, 500, - (const xmlChar *) "xmlZMemBuffExtend: %s %lu bytes.\n", + "xmlZMemBuffExtend: %s %lu bytes.\n", "Allocation failure extending output buffer to", - new_size ); + (unsigned long) new_size ); xmlIOErr(XML_IO_WRITE, (const char *) msg); } @@ -1718,7 +1627,7 @@ xmlZMemBuffAppend( xmlZMemBuffPtr buff, const char * src, int len ) { if ( z_err != Z_OK ) { xmlChar msg[500]; xmlStrPrintf(msg, 500, - (const xmlChar *) "xmlZMemBuffAppend: %s %d %s - %d", + "xmlZMemBuffAppend: %s %d %s - %d", "Compression error while appending", len, "bytes to buffer. ZLIB error", z_err ); xmlIOErr(XML_IO_WRITE, (const char *) msg); @@ -1791,7 +1700,7 @@ xmlZMemBuffGetContent( xmlZMemBuffPtr buff, char ** data_ref ) { else { xmlChar msg[500]; xmlStrPrintf(msg, 500, - (const xmlChar *) "xmlZMemBuffGetContent: %s - %d\n", + "xmlZMemBuffGetContent: %s - %d\n", "Error flushing zlib buffers. Error code", z_err ); xmlIOErr(XML_IO_WRITE, (const char *) msg); } @@ -1799,7 +1708,7 @@ xmlZMemBuffGetContent( xmlZMemBuffPtr buff, char ** data_ref ) { return ( zlgth ); } #endif /* LIBXML_OUTPUT_ENABLED */ -#endif /* HAVE_ZLIB_H */ +#endif /* LIBXML_ZLIB_ENABLED */ #ifdef LIBXML_OUTPUT_ENABLED /** @@ -1818,7 +1727,7 @@ xmlFreeHTTPWriteCtxt( xmlIOHTTPWriteCtxtPtr ctxt ) if ( ctxt->doc_buff != NULL ) { -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED if ( ctxt->compression > 0 ) { xmlFreeZMemBuff( ctxt->doc_buff ); } @@ -1876,7 +1785,7 @@ xmlIOHTTPOpen (const char *filename) { */ void * -xmlIOHTTPOpenW(const char *post_uri, int compression) +xmlIOHTTPOpenW(const char *post_uri, int compression ATTRIBUTE_UNUSED) { xmlIOHTTPWriteCtxtPtr ctxt = NULL; @@ -1905,7 +1814,7 @@ xmlIOHTTPOpenW(const char *post_uri, int compression) * ** is being used to avoid pushing the data to disk and back. */ -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED if ((compression > 0) && (compression <= 9)) { ctxt->compression = compression; @@ -1985,7 +1894,7 @@ xmlIOHTTPWrite( void * context, const char * buffer, int len ) { /* Use gzwrite or fwrite as previously setup in the open call */ -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED if ( ctxt->compression > 0 ) len = xmlZMemBuffAppend( ctxt->doc_buff, buffer, len ); @@ -1996,7 +1905,7 @@ xmlIOHTTPWrite( void * context, const char * buffer, int len ) { if ( len < 0 ) { xmlChar msg[500]; xmlStrPrintf(msg, 500, - (const xmlChar *) "xmlIOHTTPWrite: %s\n%s '%s'.\n", + "xmlIOHTTPWrite: %s\n%s '%s'.\n", "Error appending to internal buffer.", "Error sending document to URI", ctxt->uri ); @@ -2049,7 +1958,7 @@ xmlIOHTTPCloseWrite( void * context, const char * http_mthd ) { /* Retrieve the content from the appropriate buffer */ -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED if ( ctxt->compression > 0 ) { content_lgth = xmlZMemBuffGetContent( ctxt->doc_buff, &http_content ); @@ -2068,7 +1977,7 @@ xmlIOHTTPCloseWrite( void * context, const char * http_mthd ) { if ( http_content == NULL ) { xmlChar msg[500]; xmlStrPrintf(msg, 500, - (const xmlChar *) "xmlIOHTTPCloseWrite: %s '%s' %s '%s'.\n", + "xmlIOHTTPCloseWrite: %s '%s' %s '%s'.\n", "Error retrieving content.\nUnable to", http_mthd, "data to URI", ctxt->uri ); xmlIOErr(XML_IO_WRITE, (const char *) msg); @@ -2140,7 +2049,7 @@ xmlIOHTTPCloseWrite( void * context, const char * http_mthd ) { else { xmlChar msg[500]; xmlStrPrintf(msg, 500, - (const xmlChar *) "xmlIOHTTPCloseWrite: HTTP '%s' of %d %s\n'%s' %s %d\n", + "xmlIOHTTPCloseWrite: HTTP '%s' of %d %s\n'%s' %s %d\n", http_mthd, content_lgth, "bytes to URI", ctxt->uri, "failed. HTTP return code:", http_rtn ); @@ -2318,16 +2227,12 @@ xmlRegisterDefaultInputCallbacks(void) { if (xmlInputCallbackInitialized) return; -#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) - xmlInitPlatformSpecificIo(); -#endif - xmlRegisterInputCallbacks(xmlFileMatch, xmlFileOpen, xmlFileRead, xmlFileClose); -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED xmlRegisterInputCallbacks(xmlGzfileMatch, xmlGzfileOpen, xmlGzfileRead, xmlGzfileClose); -#endif /* HAVE_ZLIB_H */ +#endif /* LIBXML_ZLIB_ENABLED */ #ifdef LIBXML_LZMA_ENABLED xmlRegisterInputCallbacks(xmlXzfileMatch, xmlXzfileOpen, xmlXzfileRead, xmlXzfileClose); @@ -2356,10 +2261,6 @@ xmlRegisterDefaultOutputCallbacks (void) { if (xmlOutputCallbackInitialized) return; -#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__) - xmlInitPlatformSpecificIo(); -#endif - xmlRegisterOutputCallbacks(xmlFileMatch, xmlFileOpenW, xmlFileWrite, xmlFileClose); @@ -2373,7 +2274,7 @@ xmlRegisterDefaultOutputCallbacks (void) { uncompressed ones except opening if existing then closing and saving with same compression ratio ... a pain. -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED xmlRegisterOutputCallbacks(xmlGzfileMatch, xmlGzfileOpen, xmlGzfileWrite, xmlGzfileClose); #endif @@ -2663,7 +2564,7 @@ __xmlParserInputBufferCreateFilename(const char *URI, xmlCharEncoding enc) { ret->context = context; ret->readcallback = xmlInputCallbackTable[i].readcallback; ret->closecallback = xmlInputCallbackTable[i].closecallback; -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED if ((xmlInputCallbackTable[i].opencallback == xmlGzfileOpen) && (strcmp(URI, "-") != 0)) { #if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1230 @@ -2727,7 +2628,7 @@ __xmlOutputBufferCreateFilename(const char *URI, int i = 0; void *context = NULL; char *unescaped = NULL; -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED int is_file_uri = 1; #endif @@ -2738,7 +2639,7 @@ __xmlOutputBufferCreateFilename(const char *URI, puri = xmlParseURI(URI); if (puri != NULL) { -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED if ((puri->scheme != NULL) && (!xmlStrEqual(BAD_CAST puri->scheme, BAD_CAST "file"))) is_file_uri = 0; @@ -2758,7 +2659,7 @@ __xmlOutputBufferCreateFilename(const char *URI, * try with an unescaped version of the URI */ if (unescaped != NULL) { -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED if ((compression > 0) && (compression <= 9) && (is_file_uri == 1)) { context = xmlGzfileOpenW(unescaped, compression); if (context != NULL) { @@ -2776,7 +2677,7 @@ __xmlOutputBufferCreateFilename(const char *URI, for (i = xmlOutputCallbackNr - 1;i >= 0;i--) { if ((xmlOutputCallbackTable[i].matchcallback != NULL) && (xmlOutputCallbackTable[i].matchcallback(unescaped) != 0)) { -#if defined(LIBXML_HTTP_ENABLED) && defined(HAVE_ZLIB_H) +#if defined(LIBXML_HTTP_ENABLED) && defined(LIBXML_ZLIB_ENABLED) /* Need to pass compression parameter into HTTP open calls */ if (xmlOutputCallbackTable[i].matchcallback == xmlIOHTTPMatch) context = xmlIOHTTPOpenW(unescaped, compression); @@ -2795,7 +2696,7 @@ __xmlOutputBufferCreateFilename(const char *URI, * filename */ if (context == NULL) { -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED if ((compression > 0) && (compression <= 9) && (is_file_uri == 1)) { context = xmlGzfileOpenW(URI, compression); if (context != NULL) { @@ -2812,7 +2713,7 @@ __xmlOutputBufferCreateFilename(const char *URI, for (i = xmlOutputCallbackNr - 1;i >= 0;i--) { if ((xmlOutputCallbackTable[i].matchcallback != NULL) && (xmlOutputCallbackTable[i].matchcallback(URI) != 0)) { -#if defined(LIBXML_HTTP_ENABLED) && defined(HAVE_ZLIB_H) +#if defined(LIBXML_HTTP_ENABLED) && defined(LIBXML_ZLIB_ENABLED) /* Need to pass compression parameter into HTTP open calls */ if (xmlOutputCallbackTable[i].matchcallback == xmlIOHTTPMatch) context = xmlIOHTTPOpenW(URI, compression); @@ -2942,10 +2843,8 @@ xmlOutputBufferCreateBuffer(xmlBufferPtr buffer, if (buffer == NULL) return(NULL); - ret = xmlOutputBufferCreateIO((xmlOutputWriteCallback) - xmlBufferWrite, - (xmlOutputCloseCallback) - NULL, (void *) buffer, encoder); + ret = xmlOutputBufferCreateIO(xmlBufferWrite, NULL, (void *) buffer, + encoder); return(ret); } @@ -3003,7 +2902,7 @@ xmlParserInputBufferCreateFd(int fd, xmlCharEncoding enc) { ret = xmlAllocParserInputBuffer(enc); if (ret != NULL) { - ret->context = (void *) (long) fd; + ret->context = (void *) (ptrdiff_t) fd; ret->readcallback = xmlFdRead; ret->closecallback = xmlFdClose; } @@ -3027,13 +2926,13 @@ xmlParserInputBufferCreateMem(const char *mem, int size, xmlCharEncoding enc) { xmlParserInputBufferPtr ret; int errcode; - if (size <= 0) return(NULL); + if (size < 0) return(NULL); if (mem == NULL) return(NULL); ret = xmlAllocParserInputBuffer(enc); if (ret != NULL) { ret->context = (void *) mem; - ret->readcallback = (xmlInputReadCallback) xmlNop; + ret->readcallback = xmlInputReadCallbackNop; ret->closecallback = NULL; errcode = xmlBufAdd(ret->buffer, (const xmlChar *) mem, size); if (errcode != 0) { @@ -3063,7 +2962,7 @@ xmlParserInputBufferCreateStatic(const char *mem, int size, xmlCharEncoding enc) { xmlParserInputBufferPtr ret; - if (size <= 0) return(NULL); + if (size < 0) return(NULL); if (mem == NULL) return(NULL); ret = (xmlParserInputBufferPtr) xmlMalloc(sizeof(xmlParserInputBuffer)); @@ -3109,7 +3008,7 @@ xmlOutputBufferCreateFd(int fd, xmlCharEncodingHandlerPtr encoder) { ret = xmlAllocOutputBufferInternal(encoder); if (ret != NULL) { - ret->context = (void *) (long) fd; + ret->context = (void *) (ptrdiff_t) fd; ret->writecallback = xmlFdWrite; ret->closecallback = NULL; } @@ -3823,7 +3722,7 @@ xmlParserGetDirectory(const char *filename) { if (filename == NULL) return(NULL); -#if defined(WIN32) && !defined(__CYGWIN__) +#if defined(_WIN32) && !defined(__CYGWIN__) # define IS_XMLPGD_SEP(ch) ((ch=='/')||(ch=='\\')) #else # define IS_XMLPGD_SEP(ch) (ch=='/') diff --git a/gnulib-local/lib/libxml/xmlerror.in.h b/gnulib-local/lib/libxml/xmlerror.in.h index 43e68ca59..037c16d57 100644 --- a/gnulib-local/lib/libxml/xmlerror.in.h +++ b/gnulib-local/lib/libxml/xmlerror.in.h @@ -937,7 +937,7 @@ XMLPUBFUN void XMLCALL int code, xmlNodePtr node, const char *msg, - const char *extra); + const char *extra) LIBXML_ATTR_FORMAT(4,0); #endif #ifdef __cplusplus } diff --git a/gnulib-local/lib/libxml/xmlmemory.c b/gnulib-local/lib/libxml/xmlmemory.c index b6e559f54..839399702 100644 --- a/gnulib-local/lib/libxml/xmlmemory.c +++ b/gnulib-local/lib/libxml/xmlmemory.c @@ -109,8 +109,9 @@ typedef struct memnod { #define RESERVE_SIZE (((HDR_SIZE + (ALIGN_SIZE-1)) \ / ALIGN_SIZE ) * ALIGN_SIZE) +#define MAX_SIZE_T ((size_t)-1) -#define CLIENT_2_HDR(a) ((MEMHDR *) (((char *) (a)) - RESERVE_SIZE)) +#define CLIENT_2_HDR(a) ((void *) (((char *) (a)) - RESERVE_SIZE)) #define HDR_2_CLIENT(a) ((void *) (((char *) (a)) + RESERVE_SIZE)) @@ -171,6 +172,13 @@ xmlMallocLoc(size_t size, const char * file, int line) TEST_POINT + if (size > (MAX_SIZE_T - RESERVE_SIZE)) { + xmlGenericError(xmlGenericErrorContext, + "xmlMallocLoc : Unsigned overflow\n"); + xmlMemoryDump(); + return(NULL); + } + p = (MEMHDR *) malloc(RESERVE_SIZE+size); if (!p) { @@ -217,7 +225,7 @@ xmlMallocLoc(size_t size, const char * file, int line) /** * xmlMallocAtomicLoc: - * @size: an int specifying the size in byte to allocate. + * @size: an unsigned int specifying the size in byte to allocate. * @file: the file name or NULL * @line: the line number * @@ -240,11 +248,18 @@ xmlMallocAtomicLoc(size_t size, const char * file, int line) TEST_POINT + if (size > (MAX_SIZE_T - RESERVE_SIZE)) { + xmlGenericError(xmlGenericErrorContext, + "xmlMallocAtomicLoc : Unsigned overflow\n"); + xmlMemoryDump(); + return(NULL); + } + p = (MEMHDR *) malloc(RESERVE_SIZE+size); if (!p) { xmlGenericError(xmlGenericErrorContext, - "xmlMallocLoc : Out of free space\n"); + "xmlMallocAtomicLoc : Out of free space\n"); xmlMemoryDump(); return(NULL); } @@ -344,6 +359,13 @@ xmlReallocLoc(void *ptr,size_t size, const char * file, int line) #endif xmlMutexUnlock(xmlMemMutex); + if (size > (MAX_SIZE_T - RESERVE_SIZE)) { + xmlGenericError(xmlGenericErrorContext, + "xmlReallocLoc : Unsigned overflow\n"); + xmlMemoryDump(); + return(NULL); + } + tmp = (MEMHDR *) realloc(p,RESERVE_SIZE+size); if (!tmp) { free(p); @@ -465,7 +487,7 @@ xmlMemFree(void *ptr) error: xmlGenericError(xmlGenericErrorContext, - "xmlMemFree(%lX) error\n", (unsigned long) ptr); + "xmlMemFree(%p) error\n", ptr); xmlMallocBreakpoint(); return; } @@ -491,6 +513,13 @@ xmlMemStrdupLoc(const char *str, const char *file, int line) if (!xmlMemInitialized) xmlInitMemory(); TEST_POINT + if (size > (MAX_SIZE_T - RESERVE_SIZE)) { + xmlGenericError(xmlGenericErrorContext, + "xmlMemStrdupLoc : Unsigned overflow\n"); + xmlMemoryDump(); + return(NULL); + } + p = (MEMHDR *) malloc(RESERVE_SIZE+size); if (!p) { goto error; diff --git a/gnulib-local/lib/libxml/xmlmodule.c b/gnulib-local/lib/libxml/xmlmodule.c index 50ed666af..a95ab66ac 100644 --- a/gnulib-local/lib/libxml/xmlmodule.c +++ b/gnulib-local/lib/libxml/xmlmodule.c @@ -8,6 +8,11 @@ * http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html */ +/* In order RTLD_GLOBAL and RTLD_NOW to be defined on zOS */ +#if defined(__MVS__) +#define _UNIX03_SOURCE +#endif + #define IN_LIBXML #include "libxml.h" @@ -296,8 +301,9 @@ xmlModulePlatformSymbol(void *handle, const char *name, void **symbol) #endif /* HAVE_SHLLOAD */ #endif /* ! HAVE_DLOPEN */ -#ifdef _WIN32 +#if defined(_WIN32) && !defined(__CYGWIN__) +#define WIN32_LEAN_AND_MEAN #include /* @@ -334,6 +340,7 @@ xmlModulePlatformClose(void *handle) static int xmlModulePlatformSymbol(void *handle, const char *name, void **symbol) { +XML_IGNORE_PEDANTIC_WARNINGS #ifdef _WIN32_WCE /* * GetProcAddressA seems only available on WinCE @@ -343,6 +350,7 @@ xmlModulePlatformSymbol(void *handle, const char *name, void **symbol) *symbol = GetProcAddress(handle, name); #endif return (NULL == *symbol) ? -1 : 0; +XML_POP_WARNINGS } #endif /* _WIN32 */ diff --git a/gnulib-local/lib/libxml/xmlreader.c b/gnulib-local/lib/libxml/xmlreader.c index 8caac6926..a1f7473df 100644 --- a/gnulib-local/lib/libxml/xmlreader.c +++ b/gnulib-local/lib/libxml/xmlreader.c @@ -142,7 +142,7 @@ struct _xmlTextReader { xmlNodePtr faketext;/* fake xmlNs chld */ int preserve;/* preserve the resulting document */ xmlBufPtr buffer; /* used to return const xmlChar * */ - xmlDictPtr dict; /* the context dictionnary */ + xmlDictPtr dict; /* the context dictionary */ /* entity stack when traversing entities content */ xmlNodePtr ent; /* Current Entity Ref Node */ @@ -210,7 +210,7 @@ static int xmlTextReaderNextTree(xmlTextReaderPtr reader); * DICT_FREE: * @str: a string * - * Free a string if it is not owned by the "dict" dictionnary in the + * Free a string if it is not owned by the "dict" dictionary in the * current scope */ #define DICT_FREE(str) \ @@ -491,6 +491,11 @@ xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur) { } } +static void +xmlTextReaderFreeIDTableEntry(void *id, const xmlChar *name ATTRIBUTE_UNUSED) { + xmlFreeID((xmlIDPtr) id); +} + /** * xmlTextReaderFreeIDTable: * @table: An id table @@ -499,7 +504,7 @@ xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur) { */ static void xmlTextReaderFreeIDTable(xmlIDTablePtr table) { - xmlHashFree(table, (xmlHashDeallocator) xmlFreeID); + xmlHashFree(table, xmlTextReaderFreeIDTableEntry); } /** @@ -1706,10 +1711,11 @@ xmlTextReaderReadInnerXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED) if (xmlTextReaderExpand(reader) == NULL) { return NULL; } - doc = reader->doc; + doc = reader->node->doc; buff = xmlBufferCreate(); for (cur_node = reader->node->children; cur_node != NULL; cur_node = cur_node->next) { + /* XXX: Why is the node copied? */ node = xmlDocCopyNode(cur_node, doc, 1); buff2 = xmlBufferCreate(); if (xmlNodeDump(buff2, doc, node, 0, 0) == -1) { @@ -1750,10 +1756,11 @@ xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED) xmlDocPtr doc; node = reader->node; - doc = reader->doc; + doc = node->doc; if (xmlTextReaderExpand(reader) == NULL) { return NULL; } + /* XXX: Why is the node copied? */ if (node->type == XML_DTD_NODE) { node = (xmlNodePtr) xmlCopyDtd((xmlDtdPtr) node); } else { @@ -1912,12 +1919,9 @@ xmlTextReaderNextTree(xmlTextReaderPtr reader) /* if reader->node->next is NULL mean no subtree for current node, so need to move to sibling of parent node if present */ - if ((reader->node->type == XML_ELEMENT_NODE) || - (reader->node->type == XML_ATTRIBUTE_NODE)) { - reader->state = XML_TEXTREADER_BACKTRACK; - /* This will move to parent if present */ - xmlTextReaderRead(reader); - } + reader->state = XML_TEXTREADER_BACKTRACK; + /* This will move to parent if present */ + xmlTextReaderRead(reader); } if (reader->node->next != 0) { @@ -2158,7 +2162,7 @@ xmlNewTextReader(xmlParserInputBufferPtr input, const char *URI) { ret->ctxt->dictNames = 1; ret->allocs = XML_TEXTREADER_CTXT; /* - * use the parser dictionnary to allocate all elements and attributes names + * use the parser dictionary to allocate all elements and attributes names */ ret->ctxt->docdict = 1; ret->dict = ret->ctxt->dict; @@ -3001,7 +3005,7 @@ xmlTextReaderAttributeCount(xmlTextReaderPtr reader) { * Reference: * https://www.gnu.org/software/dotgnu/pnetlib-doc/System/Xml/XmlNodeType.html * - * Returns the xmlNodeType of the current node or -1 in case of error + * Returns the xmlReaderTypes of the current node or -1 in case of error */ int xmlTextReaderNodeType(xmlTextReaderPtr reader) { @@ -3982,7 +3986,7 @@ xmlTextReaderPreserve(xmlTextReaderPtr reader) { * pattern. The caller must also use xmlTextReaderCurrentDoc() to * keep an handle on the resulting document once parsing has finished * - * Returns a positive number in case of success and -1 in case of error + * Returns a non-negative number in case of success and -1 in case of error */ int xmlTextReaderPreservePattern(xmlTextReaderPtr reader, const xmlChar *pattern, @@ -4050,13 +4054,19 @@ xmlTextReaderCurrentDoc(xmlTextReaderPtr reader) { } #ifdef LIBXML_SCHEMAS_ENABLED -static char *xmlTextReaderBuildMessage(const char *msg, va_list ap); +static char *xmlTextReaderBuildMessage(const char *msg, va_list ap) LIBXML_ATTR_FORMAT(1,0); static void XMLCDECL -xmlTextReaderValidityError(void *ctxt, const char *msg, ...); +xmlTextReaderValidityError(void *ctxt, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3); static void XMLCDECL -xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...); +xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3); + +static void XMLCDECL +xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3); + +static void XMLCDECL +xmlTextReaderValidityWarningRelay(void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3); static void XMLCDECL xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...) @@ -4850,7 +4860,7 @@ xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error) } } -static void XMLCDECL +static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) xmlTextReaderError(void *ctxt, const char *msg, ...) { va_list ap; @@ -4863,7 +4873,7 @@ xmlTextReaderError(void *ctxt, const char *msg, ...) } -static void XMLCDECL +static void XMLCDECL LIBXML_ATTR_FORMAT(2,3) xmlTextReaderWarning(void *ctxt, const char *msg, ...) { va_list ap; @@ -5249,7 +5259,7 @@ xmlTextReaderSetup(xmlTextReaderPtr reader, reader->ctxt->linenumbers = 1; reader->ctxt->dictNames = 1; /* - * use the parser dictionnary to allocate all elements and attributes names + * use the parser dictionary to allocate all elements and attributes names */ reader->ctxt->docdict = 1; reader->ctxt->parseMode = XML_PARSE_READER; diff --git a/gnulib-local/lib/libxml/xmlreader.in.h b/gnulib-local/lib/libxml/xmlreader.in.h index 2c99e3a76..e8a8bcc9a 100644 --- a/gnulib-local/lib/libxml/xmlreader.in.h +++ b/gnulib-local/lib/libxml/xmlreader.in.h @@ -393,7 +393,7 @@ typedef void * xmlTextReaderLocatorPtr; * @arg: the user argument * @msg: the message * @severity: the severity of the error - * @locator: a locator indicating where the error occured + * @locator: a locator indicating where the error occurred * * Signature of an error callback from a reader parser */ diff --git a/gnulib-local/lib/libxml/xmlregexp.c b/gnulib-local/lib/libxml/xmlregexp.c index 3e912ab92..d255fbf06 100644 --- a/gnulib-local/lib/libxml/xmlregexp.c +++ b/gnulib-local/lib/libxml/xmlregexp.c @@ -1544,6 +1544,7 @@ static int xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, xmlRegStatePtr to, xmlRegAtomPtr atom) { xmlRegStatePtr end; + int nullable = 0; if (atom == NULL) { ERROR("genrate transition: atom == NULL"); @@ -1730,6 +1731,13 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, if (xmlRegAtomPush(ctxt, atom) < 0) { return(-1); } + if ((atom->quant == XML_REGEXP_QUANT_RANGE) && + (atom->min == 0) && (atom->max > 0)) { + nullable = 1; + atom->min = 1; + if (atom->max == 1) + atom->quant = XML_REGEXP_QUANT_OPT; + } xmlRegStateAddTrans(ctxt, from, atom, to, -1, -1); ctxt->state = end; switch (atom->quant) { @@ -1747,11 +1755,8 @@ xmlFAGenerateTransitions(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr from, xmlRegStateAddTrans(ctxt, to, atom, to, -1, -1); break; case XML_REGEXP_QUANT_RANGE: -#if DV_test - if (atom->min == 0) { + if (nullable) xmlFAGenerateEpsilonTransition(ctxt, from, to); - } -#endif break; default: break; @@ -2805,18 +2810,21 @@ xmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint, int neg, break; case XML_REGEXP_NOTSPACE: neg = !neg; + /* Falls through. */ case XML_REGEXP_ANYSPACE: ret = ((codepoint == '\n') || (codepoint == '\r') || (codepoint == '\t') || (codepoint == ' ')); break; case XML_REGEXP_NOTINITNAME: neg = !neg; + /* Falls through. */ case XML_REGEXP_INITNAME: ret = (IS_LETTER(codepoint) || (codepoint == '_') || (codepoint == ':')); break; case XML_REGEXP_NOTNAMECHAR: neg = !neg; + /* Falls through. */ case XML_REGEXP_NAMECHAR: ret = (IS_LETTER(codepoint) || IS_DIGIT(codepoint) || (codepoint == '.') || (codepoint == '-') || @@ -2825,11 +2833,13 @@ xmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint, int neg, break; case XML_REGEXP_NOTDECIMAL: neg = !neg; + /* Falls through. */ case XML_REGEXP_DECIMAL: ret = xmlUCSIsCatNd(codepoint); break; case XML_REGEXP_REALCHAR: neg = !neg; + /* Falls through. */ case XML_REGEXP_NOTREALCHAR: ret = xmlUCSIsCatP(codepoint); if (ret == 0) @@ -4084,8 +4094,9 @@ rollback: xmlFree(exec->errString); exec->errString = xmlStrdup(value); exec->errState = exec->state; - memcpy(exec->errCounts, exec->counts, - exec->comp->nbCounters * sizeof(int)); + if (exec->comp->nbCounters) + memcpy(exec->errCounts, exec->counts, + exec->comp->nbCounters * sizeof(int)); } /* @@ -4875,7 +4886,8 @@ xmlFAParseCharClassEsc(xmlRegParserCtxtPtr ctxt) { } NEXT; xmlFAParseCharProp(ctxt); - ctxt->atom->neg = 1; + if (ctxt->atom != NULL) + ctxt->atom->neg = 1; if (CUR != '}') { ERROR("Expecting '}'"); return; @@ -5046,17 +5058,18 @@ xmlFAParseCharRange(xmlRegParserCtxtPtr ctxt) { return; } len = 1; - } else if ((cur != 0x5B) && (cur != 0x5D)) { + } else if ((cur != '\0') && (cur != 0x5B) && (cur != 0x5D)) { end = CUR_SCHAR(ctxt->cur, len); } else { ERROR("Expecting the end of a char range"); return; } - NEXTL(len); + /* TODO check that the values are acceptable character ranges for XML */ if (end < start) { ERROR("End of range is before start of range"); } else { + NEXTL(len); xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg, XML_REGEXP_CHARVAL, start, end, NULL); } @@ -6345,7 +6358,7 @@ struct _xmlExpCtxt { /** * xmlExpNewCtxt: * @maxNodes: the maximum number of nodes - * @dict: optional dictionnary to use internally + * @dict: optional dictionary to use internally * * Creates a new context for manipulating expressions * @@ -7204,7 +7217,7 @@ xmlExpStringDerive(xmlExpCtxtPtr ctxt, xmlExpNodePtr exp, return(NULL); } /* - * check the string is in the dictionnary, if yes use an interned + * check the string is in the dictionary, if yes use an interned * copy, otherwise we know it's not an acceptable input */ input = xmlDictExists(ctxt->dict, str, len); diff --git a/gnulib-local/lib/libxml/xmlsave.c b/gnulib-local/lib/libxml/xmlsave.c index 774404b88..7a05d8324 100644 --- a/gnulib-local/lib/libxml/xmlsave.c +++ b/gnulib-local/lib/libxml/xmlsave.c @@ -1123,9 +1123,6 @@ xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur) { cur->encoding = BAD_CAST ctxt->encoding; } else if (cur->encoding != NULL) { encoding = cur->encoding; - } else if (cur->charset != XML_CHAR_ENCODING_UTF8) { - encoding = (const xmlChar *) - xmlGetCharEncodingName((xmlCharEncoding) cur->charset); } if (((cur->type == XML_HTML_DOCUMENT_NODE) && @@ -1595,31 +1592,31 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { if (cur->properties != NULL) xhtmlAttrListDumpOutput(ctxt, cur->properties); - if ((cur->type == XML_ELEMENT_NODE) && - (cur->parent != NULL) && - (cur->parent->parent == (xmlNodePtr) cur->doc) && - xmlStrEqual(cur->name, BAD_CAST"head") && - xmlStrEqual(cur->parent->name, BAD_CAST"html")) { - - tmp = cur->children; - while (tmp != NULL) { - if (xmlStrEqual(tmp->name, BAD_CAST"meta")) { - xmlChar *httpequiv; - - httpequiv = xmlGetProp(tmp, BAD_CAST"http-equiv"); - if (httpequiv != NULL) { - if (xmlStrcasecmp(httpequiv, BAD_CAST"Content-Type") == 0) { - xmlFree(httpequiv); - break; - } - xmlFree(httpequiv); - } - } - tmp = tmp->next; - } - if (tmp == NULL) - addmeta = 1; - } + if ((cur->type == XML_ELEMENT_NODE) && + (cur->parent != NULL) && + (cur->parent->parent == (xmlNodePtr) cur->doc) && + xmlStrEqual(cur->name, BAD_CAST"head") && + xmlStrEqual(cur->parent->name, BAD_CAST"html")) { + + tmp = cur->children; + while (tmp != NULL) { + if (xmlStrEqual(tmp->name, BAD_CAST"meta")) { + xmlChar *httpequiv; + + httpequiv = xmlGetProp(tmp, BAD_CAST"http-equiv"); + if (httpequiv != NULL) { + if (xmlStrcasecmp(httpequiv, BAD_CAST"Content-Type") == 0) { + xmlFree(httpequiv); + break; + } + xmlFree(httpequiv); + } + } + tmp = tmp->next; + } + if (tmp == NULL) + addmeta = 1; + } if ((cur->type == XML_ELEMENT_NODE) && (cur->children == NULL)) { if (((cur->ns == NULL) || (cur->ns->prefix == NULL)) && @@ -2097,8 +2094,8 @@ xmlBufAttrSerializeTxtContent(xmlBufPtr buf, xmlDocPtr doc, xmlBufAdd(buf, BAD_CAST "&", 5); cur++; base = cur; - } else if ((*cur >= 0x80) && ((doc == NULL) || - (doc->encoding == NULL))) { + } else if ((*cur >= 0x80) && (cur[1] != 0) && + ((doc == NULL) || (doc->encoding == NULL))) { /* * We assume we have UTF-8 content. */ @@ -2109,8 +2106,6 @@ xmlBufAttrSerializeTxtContent(xmlBufPtr buf, xmlDocPtr doc, xmlBufAdd(buf, base, cur - base); if (*cur < 0xC0) { xmlSaveErr(XML_SAVE_NOT_UTF8, (xmlNodePtr) attr, NULL); - if (doc != NULL) - doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1"); xmlSerializeHexCharRef(tmp, *cur); xmlBufAdd(buf, (xmlChar *) tmp, -1); cur++; @@ -2121,14 +2116,14 @@ xmlBufAttrSerializeTxtContent(xmlBufPtr buf, xmlDocPtr doc, val <<= 6; val |= (cur[1]) & 0x3F; l = 2; - } else if (*cur < 0xF0) { + } else if ((*cur < 0xF0) && (cur [2] != 0)) { val = (cur[0]) & 0x0F; val <<= 6; val |= (cur[1]) & 0x3F; val <<= 6; val |= (cur[2]) & 0x3F; l = 3; - } else if (*cur < 0xF8) { + } else if ((*cur < 0xF8) && (cur [2] != 0) && (cur[3] != 0)) { val = (cur[0]) & 0x07; val <<= 6; val |= (cur[1]) & 0x3F; @@ -2140,9 +2135,6 @@ xmlBufAttrSerializeTxtContent(xmlBufPtr buf, xmlDocPtr doc, } if ((l == 1) || (!IS_CHAR(val))) { xmlSaveErr(XML_SAVE_CHAR_INVALID, (xmlNodePtr) attr, NULL); - if (doc != NULL) - doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1"); - xmlSerializeHexCharRef(tmp, *cur); xmlBufAdd(buf, (xmlChar *) tmp, -1); cur++; @@ -2709,7 +2701,7 @@ xmlSaveFormatFileEnc( const char * filename, xmlDocPtr cur, return(-1); } -#ifdef HAVE_ZLIB_H +#ifdef LIBXML_ZLIB_ENABLED if (cur->compression < 0) cur->compression = xmlGetCompressMode(); #endif /* diff --git a/gnulib-local/lib/libxml/xmlschemas.c b/gnulib-local/lib/libxml/xmlschemas.c index fe533e6f6..019988aaf 100644 --- a/gnulib-local/lib/libxml/xmlschemas.c +++ b/gnulib-local/lib/libxml/xmlschemas.c @@ -44,6 +44,12 @@ * but is done here due to performance. Move it to an other layer * is schema construction via an API is implemented. */ + +/* To avoid EBCDIC trouble when parsing on zOS */ +#if defined(__MVS__) +#pragma convert("ISO8859-1") +#endif + #define IN_LIBXML #include "libxml.h" @@ -166,7 +172,7 @@ static const xmlChar *xmlNamespaceNs = (const xmlChar *) /* * Macros for attribute uses. */ -#define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl +#define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au)) @@ -363,6 +369,7 @@ typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt; typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr; struct _xmlSchemaAbstractCtxt { int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */ + void *dummy; /* Fix alignment issues */ }; typedef struct _xmlSchemaBucket xmlSchemaBucket; @@ -473,6 +480,7 @@ typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem; typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr; struct _xmlSchemaBasicItem { xmlSchemaTypeType type; + void *dummy; /* Fix alignment issues */ }; /** @@ -617,7 +625,7 @@ struct _xmlSchemaParserCtxt { xmlAutomataStatePtr end; xmlAutomataStatePtr state; - xmlDictPtr dict; /* dictionnary for interned string names */ + xmlDictPtr dict; /* dictionary for interned string names */ xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */ int options; xmlSchemaValidCtxtPtr vctxt; @@ -1085,7 +1093,7 @@ xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type); static void xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, const char *funcName, - const char *message); + const char *message) LIBXML_ATTR_FORMAT(3,0); static int xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt, xmlSchemaTypePtr type, @@ -1734,6 +1742,7 @@ xmlSchemaFormatItemForReport(xmlChar **buf, *buf = xmlStrcat(*buf, BAD_CAST "'"); FREE_AND_NULL(str); } + /* Falls through. */ default: named = 0; } @@ -1769,7 +1778,7 @@ xmlSchemaFormatItemForReport(xmlChar **buf, } FREE_AND_NULL(str) - return (*buf); + return (xmlEscapeFormatString(buf)); } /** @@ -1889,7 +1898,7 @@ xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt, * * Handle a parser error */ -static void +static void LIBXML_ATTR_FORMAT(4,0) xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, const char *msg, const xmlChar * str1, const xmlChar * str2) { @@ -1922,7 +1931,7 @@ xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, * * Handle a parser error */ -static void +static void LIBXML_ATTR_FORMAT(5,0) xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, xmlNodePtr child, int error, const char *msg, const xmlChar * str1, const xmlChar * str2) @@ -1951,7 +1960,7 @@ xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, * * Handle a parser error */ -static void +static void LIBXML_ATTR_FORMAT(7,0) xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error, const xmlChar * strData1, const xmlChar * strData2, const xmlChar * strData3, const char *msg, const xmlChar * str1, @@ -2002,7 +2011,7 @@ xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt, extra); } -static void +static void LIBXML_ATTR_FORMAT(2,0) xmlSchemaPSimpleInternalErr(xmlNodePtr node, const char *msg, const xmlChar *str) { @@ -2013,18 +2022,21 @@ xmlSchemaPSimpleInternalErr(xmlNodePtr node, #define WXS_ERROR_TYPE_ERROR 1 #define WXS_ERROR_TYPE_WARNING 2 /** - * xmlSchemaErr3: + * xmlSchemaErr4Line: * @ctxt: the validation context - * @node: the context node + * @errorLevel: the error level * @error: the error code + * @node: the context node + * @line: the line number * @msg: the error message * @str1: extra data * @str2: extra data * @str3: extra data + * @str4: extra data * * Handle a validation error */ -static void +static void LIBXML_ATTR_FORMAT(6,0) xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt, xmlErrorLevel errorLevel, int error, xmlNodePtr node, int line, const char *msg, @@ -2139,7 +2151,7 @@ xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt, * * Handle a validation error */ -static void +static void LIBXML_ATTR_FORMAT(4,0) xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt, int error, xmlNodePtr node, const char *msg, const xmlChar *str1, const xmlChar *str2, const xmlChar *str3) @@ -2148,7 +2160,7 @@ xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt, msg, str1, str2, str3, NULL); } -static void +static void LIBXML_ATTR_FORMAT(4,0) xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt, int error, xmlNodePtr node, const char *msg, const xmlChar *str1, const xmlChar *str2, @@ -2158,7 +2170,7 @@ xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt, msg, str1, str2, str3, str4); } -static void +static void LIBXML_ATTR_FORMAT(4,0) xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt, int error, xmlNodePtr node, const char *msg, const xmlChar *str1, const xmlChar *str2) @@ -2181,7 +2193,7 @@ xmlSchemaFormatNodeForError(xmlChar ** msg, /* * Don't try to format other nodes than element and * attribute nodes. - * Play save and return an empty string. + * Play safe and return an empty string. */ *msg = xmlStrdup(BAD_CAST ""); return(*msg); @@ -2246,6 +2258,13 @@ xmlSchemaFormatNodeForError(xmlChar ** msg, TODO return (NULL); } + + /* + * xmlSchemaFormatItemForReport() also returns an escaped format + * string, so do this before calling it below (in the future). + */ + xmlEscapeFormatString(msg); + /* * VAL TODO: The output of the given schema component is currently * disabled. @@ -2262,7 +2281,7 @@ xmlSchemaFormatNodeForError(xmlChar ** msg, return (*msg); } -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt, const char *funcName, const char *message, @@ -2273,24 +2292,21 @@ xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt, if (actxt == NULL) return; - msg = xmlStrdup(BAD_CAST "Internal error: "); - msg = xmlStrcat(msg, BAD_CAST funcName); - msg = xmlStrcat(msg, BAD_CAST ", "); + msg = xmlStrdup(BAD_CAST "Internal error: %s, "); msg = xmlStrcat(msg, BAD_CAST message); msg = xmlStrcat(msg, BAD_CAST ".\n"); if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) - xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL, - (const char *) msg, str1, str2); - + xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL, + (const char *) msg, (const xmlChar *) funcName, str1, str2); else if (actxt->type == XML_SCHEMA_CTXT_PARSER) - xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL, - (const char *) msg, str1, str2); + xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL, + (const char *) msg, (const xmlChar *) funcName, str1, str2); FREE_AND_NULL(msg) } -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, const char *funcName, const char *message) @@ -2299,7 +2315,7 @@ xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt, } #if 0 -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt, const char *funcName, const char *message, @@ -2311,7 +2327,7 @@ xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt, } #endif -static void +static void LIBXML_ATTR_FORMAT(5,0) xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt, xmlParserErrors error, xmlNodePtr node, @@ -2336,7 +2352,7 @@ xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt, FREE_AND_NULL(msg) } -static void +static void LIBXML_ATTR_FORMAT(5,0) xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt, xmlParserErrors error, xmlNodePtr node, @@ -2351,7 +2367,7 @@ xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt, -static void +static void LIBXML_ATTR_FORMAT(5,0) xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt, xmlParserErrors error, xmlNodePtr node, @@ -2376,7 +2392,7 @@ xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt, -static void +static void LIBXML_ATTR_FORMAT(5,0) xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt, xmlParserErrors error, xmlSchemaPSVIIDCNodePtr idcNode, @@ -2476,11 +2492,13 @@ xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt, msg = xmlStrcat(msg, BAD_CAST " '"); if (type->builtInType != 0) { msg = xmlStrcat(msg, BAD_CAST "xs:"); - msg = xmlStrcat(msg, type->name); - } else - msg = xmlStrcat(msg, - xmlSchemaFormatQName(&str, - type->targetNamespace, type->name)); + str = xmlStrdup(type->name); + } else { + const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name); + if (!str) + str = xmlStrdup(qName); + } + msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); msg = xmlStrcat(msg, BAD_CAST "'"); FREE_AND_NULL(str); } @@ -2525,7 +2543,7 @@ xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt, FREE_AND_NULL(msg) } -static void +static void LIBXML_ATTR_FORMAT(5,0) xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt, xmlParserErrors error, xmlNodePtr node, @@ -2617,7 +2635,7 @@ xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt, str = xmlStrcat(str, BAD_CAST ", "); } str = xmlStrcat(str, BAD_CAST " ).\n"); - msg = xmlStrcat(msg, BAD_CAST str); + msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); FREE_AND_NULL(str) } else msg = xmlStrcat(msg, BAD_CAST "\n"); @@ -2625,7 +2643,7 @@ xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt, xmlFree(msg); } -static void +static void LIBXML_ATTR_FORMAT(8,0) xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt, xmlParserErrors error, xmlNodePtr node, @@ -2824,7 +2842,7 @@ xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt, xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem); if (refTypeStr == NULL) refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType); - xmlSchemaPErrExt(ctxt, ownerElem, error, + xmlSchemaPErrExt(ctxt, ownerElem, error, NULL, NULL, NULL, "%s, attribute '%s': The QName value '%s' does not resolve to a(n) " "%s.\n", BAD_CAST des, BAD_CAST name, @@ -2916,7 +2934,7 @@ xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt, * * Reports an error during parsing. */ -static void +static void LIBXML_ATTR_FORMAT(5,0) xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt, xmlParserErrors error, xmlSchemaBasicItemPtr item, @@ -2952,7 +2970,7 @@ xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt, * * Reports an error during parsing. */ -static void +static void LIBXML_ATTR_FORMAT(5,0) xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt, xmlParserErrors error, xmlSchemaBasicItemPtr item, @@ -2977,7 +2995,7 @@ xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt, * * Reports an attribute use error during parsing. */ -static void +static void LIBXML_ATTR_FORMAT(6,0) xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt, xmlParserErrors error, xmlNodePtr node, @@ -3099,7 +3117,7 @@ xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt, * Reports a simple type validation error. * TODO: Should this report the value of an element as well? */ -static void +static void LIBXML_ATTR_FORMAT(8,0) xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt, xmlParserErrors error, xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED, @@ -3141,11 +3159,13 @@ xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt, msg = xmlStrcat(msg, BAD_CAST " '"); if (type->builtInType != 0) { msg = xmlStrcat(msg, BAD_CAST "xs:"); - msg = xmlStrcat(msg, type->name); - } else - msg = xmlStrcat(msg, - xmlSchemaFormatQName(&str, - type->targetNamespace, type->name)); + str = xmlStrdup(type->name); + } else { + const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name); + if (!str) + str = xmlStrdup(qName); + } + msg = xmlStrcat(msg, xmlEscapeFormatString(&str)); msg = xmlStrcat(msg, BAD_CAST "'."); FREE_AND_NULL(str); } @@ -3157,8 +3177,10 @@ xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt, "valid."); } if (expected) { + xmlChar *expectedEscaped = xmlCharStrdup(expected); msg = xmlStrcat(msg, BAD_CAST " Expected is '"); - msg = xmlStrcat(msg, BAD_CAST expected); + msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped)); + FREE_AND_NULL(expectedEscaped); msg = xmlStrcat(msg, BAD_CAST "'.\n"); } else msg = xmlStrcat(msg, BAD_CAST "\n"); @@ -3543,6 +3565,12 @@ xmlSchemaBucketFree(xmlSchemaBucketPtr bucket) xmlFree(bucket); } +static void +xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED) +{ + xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket); +} + static xmlSchemaBucketPtr xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt, int type, const xmlChar *targetNamespace) @@ -4137,8 +4165,7 @@ xmlSchemaFree(xmlSchemaPtr schema) xmlHashFree(schema->idcDef, NULL); if (schema->schemasImports != NULL) - xmlHashFree(schema->schemasImports, - (xmlHashDeallocator) xmlSchemaBucketFree); + xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry); if (schema->includes != NULL) { xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes; int i; @@ -4174,11 +4201,13 @@ xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */ * Dump the element */ static void -xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output, +xmlSchemaElementDump(void *payload, void *data, const xmlChar * name ATTRIBUTE_UNUSED, const xmlChar * namespace ATTRIBUTE_UNUSED, const xmlChar * context ATTRIBUTE_UNUSED) { + xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload; + FILE *output = (FILE *) data; if (elem == NULL) return; @@ -4493,6 +4522,13 @@ xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output) #endif } +static void +xmlSchemaTypeDumpEntry(void *type, void *output, + const xmlChar *name ATTRIBUTE_UNUSED) +{ + xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output); +} + /** * xmlSchemaDump: * @output: the file output @@ -4521,10 +4557,8 @@ xmlSchemaDump(FILE * output, xmlSchemaPtr schema) fprintf(output, "\n"); if (schema->annot != NULL) xmlSchemaAnnotDump(output, schema->annot); - xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump, - output); - xmlHashScanFull(schema->elemDecl, - (xmlHashScannerFull) xmlSchemaElementDump, output); + xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output); + xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output); } #ifdef DEBUG_IDC_NODE_TABLE @@ -5684,6 +5718,12 @@ xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group) xmlFree(group); } +static void +xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED) +{ + xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group); +} + static xmlSchemaSubstGroupPtr xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt, xmlSchemaElementPtr head) @@ -7351,8 +7391,8 @@ attr_next: */ if (defValue != NULL) use->defValue = defValue; - if (defValueType == WXS_ATTR_DEF_VAL_FIXED) - use->flags |= XML_SCHEMA_ATTR_USE_FIXED; + if (defValueType == WXS_ATTR_DEF_VAL_FIXED) + use->flags |= XML_SCHEMA_ATTR_USE_FIXED; } check_children: @@ -9896,8 +9936,7 @@ xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con) if (con->pending != NULL) xmlSchemaItemListFree(con->pending); if (con->substGroups != NULL) - xmlHashFree(con->substGroups, - (xmlHashDeallocator) xmlSchemaSubstGroupFree); + xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry); if (con->redefs != NULL) xmlSchemaRedefListFree(con->redefs); if (con->dict != NULL) @@ -15877,7 +15916,7 @@ xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt, * STATUS: (seems) complete * * Returns 0 if the constraints are satisfied, a positive - * error code if not and -1 if an internal error occured. + * error code if not and -1 if an internal error occurred. */ static int xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt, @@ -16124,7 +16163,7 @@ xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt, * (1.4.3.2.2.2) "Particle Valid (Extension)" * * Returns 0 if the constraints are satisfied, a positive - * error code if not and -1 if an internal error occured. + * error code if not and -1 if an internal error occurred. */ static int xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt, @@ -16381,7 +16420,7 @@ xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt, * Validation Rule: Checking complex type subsumption * * Returns 0 if the constraints are satisfied, a positive - * error code if not and -1 if an internal error occured. + * error code if not and -1 if an internal error occurred. */ static int xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt, @@ -16571,7 +16610,7 @@ xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt, * (3.4.6) Constraints on Complex Type Definition Schema Components * * Returns 0 if the constraints are satisfied, a positive - * error code if not and -1 if an internal error occured. + * error code if not and -1 if an internal error occurred. */ static int xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt, @@ -16601,7 +16640,7 @@ xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt, * Complex Type Definition Representation OK (src-ct) * * Returns 0 if the constraints are satisfied, a positive - * error code if not and -1 if an internal error occured. + * error code if not and -1 if an internal error occurred. */ static int xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt, @@ -16770,7 +16809,7 @@ xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt, * STATUS: complete * * Returns 0 if the constraints are satisfied, a positive - * error code if not and -1 if an internal error occured. + * error code if not and -1 if an internal error occurred. */ static int xmlSchemaCheckParticleRangeOK(int rmin, int rmax, @@ -16800,7 +16839,7 @@ xmlSchemaCheckParticleRangeOK(int rmin, int rmax, * CLARIFY: (3.2.2) * * Returns 0 if the constraints are satisfied, a positive - * error code if not and -1 if an internal error occured. + * error code if not and -1 if an internal error occurred. */ static int xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt, @@ -16905,7 +16944,7 @@ xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt, * STATUS: complete * * Returns 0 if the constraints are satisfied, a positive - * error code if not and -1 if an internal error occured. + * error code if not and -1 if an internal error occurred. */ static int xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt, @@ -16949,7 +16988,7 @@ xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt, * STATUS: TODO * * Returns 0 if the constraints are satisfied, a positive - * error code if not and -1 if an internal error occured. + * error code if not and -1 if an internal error occurred. */ static int xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt, @@ -16975,7 +17014,7 @@ xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt, * STATUS: complete * * Returns 0 if the constraints are satisfied, a positive - * error code if not and -1 if an internal error occured. + * error code if not and -1 if an internal error occurred. */ static int xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt, @@ -17025,7 +17064,7 @@ xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt, * STATUS: TODO * * Returns 0 if the constraints are satisfied, a positive - * error code if not and -1 if an internal error occured. + * error code if not and -1 if an internal error occurred. */ static int xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt, @@ -17066,7 +17105,7 @@ xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt, * STATUS: TODO: subst-groups * * Returns 0 if the constraints are satisfied, a positive - * error code if not and -1 if an internal error occured. + * error code if not and -1 if an internal error occurred. */ static int xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt, @@ -17121,7 +17160,7 @@ xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt, * TODO: subst-groups * * Returns 0 if the constraints are satisfied, a positive - * error code if not and -1 if an internal error occured. + * error code if not and -1 if an internal error occurred. */ static int xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt, @@ -17751,7 +17790,7 @@ xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt, return (0); internal_error: PERROR_INT("xmlSchemaDeriveAndValidateFacets", - "an error occured"); + "an error occurred"); return (-1); } @@ -21271,8 +21310,7 @@ exit: con->bucket = oldbucket; con->pending->nbItems = 0; if (con->substGroups != NULL) { - xmlHashFree(con->substGroups, - (xmlHashDeallocator) xmlSchemaSubstGroupFree); + xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry); con->substGroups = NULL; } if (con->redefs != NULL) { @@ -21400,7 +21438,7 @@ exit_failure: ctxt->ownsConstructor = 0; } PERROR_INT2("xmlSchemaParse", - "An internal error occured"); + "An internal error occurred"); ctxt->schema = NULL; return(NULL); } @@ -21980,9 +22018,11 @@ xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt, * Returns the item, or NULL on internal errors. */ static void -xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef, - xmlSchemaValidCtxtPtr vctxt) +xmlSchemaAugmentIDC(void *payload, void *data, + const xmlChar *name ATTRIBUTE_UNUSED) { + xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload; + xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data; xmlSchemaIDCAugPtr aidc; aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug)); @@ -22016,10 +22056,12 @@ xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef, * Creates an augmented IDC definition for the imported schema. */ static void -xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) { +xmlSchemaAugmentImportedIDC(void *payload, void *data, + const xmlChar *name ATTRIBUTE_UNUSED) { + xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload; + xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data; if (imported->schema->idcDef != NULL) { - xmlHashScan(imported->schema->idcDef , - (xmlHashScanner) xmlSchemaAugmentIDC, vctxt); + xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt); } } @@ -25944,11 +25986,12 @@ xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt, } static void -xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED, +xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED, const xmlChar * name ATTRIBUTE_UNUSED, - xmlSchemaElementPtr item, - xmlSchemaNodeInfoPtr inode) + void *transdata, void *inputdata) { + xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata; + xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata; inode->decl = item; #ifdef DEBUG_CONTENT { @@ -26053,8 +26096,7 @@ xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt) */ inode->regexCtxt = xmlRegNewExecCtxt(inode->typeDef->contModel, - (xmlRegExecCallbacks) xmlSchemaVContentModelCallback, - vctxt); + xmlSchemaVContentModelCallback, vctxt); if (inode->regexCtxt == NULL) { VERROR_INT("xmlSchemaValidatorPopElem", "failed to create a regex context"); @@ -26081,7 +26123,7 @@ xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt) /* * Get hold of the still expected content, since a further - * call to xmlRegExecPushString() will loose this information. + * call to xmlRegExecPushString() will lose this information. */ xmlRegExecNextValues(inode->regexCtxt, &nbval, &nbneg, &values[0], &terminal); @@ -26602,8 +26644,7 @@ xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt) * Create the regex context. */ regexCtxt = xmlRegNewExecCtxt(ptype->contModel, - (xmlRegExecCallbacks) xmlSchemaVContentModelCallback, - vctxt); + xmlSchemaVContentModelCallback, vctxt); if (regexCtxt == NULL) { VERROR_INT("xmlSchemaValidateChildElem", "failed to create a regex context"); @@ -26863,7 +26904,8 @@ xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt) * Augment the IDC definitions for the main schema and all imported ones * NOTE: main schema is the first in the imported list */ - xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt); + xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC, + vctxt); } if (vctxt->depth > 0) { /* @@ -27137,7 +27179,7 @@ root_found: } if (ret < 0) { /* - * VAL TODO: A reader error occured; what to do here? + * VAL TODO: A reader error occurred; what to do here? */ ret = 1; goto exit; @@ -27378,14 +27420,41 @@ xmlSchemaSAXHandleStartElementNs(void *ctx, * attributes yet. */ if (nb_attributes != 0) { + int valueLen, k, l; xmlChar *value; for (j = 0, i = 0; i < nb_attributes; i++, j += 5) { /* - * Duplicate the value. + * Duplicate the value, changing any & to a literal ampersand. + * + * libxml2 differs from normal SAX here in that it escapes all ampersands + * as & instead of delivering the raw converted string. Changing the + * behavior at this point would break applications that use this API, so + * we are forced to work around it. */ - value = xmlStrndup(attributes[j+3], - attributes[j+4] - attributes[j+3]); + valueLen = attributes[j+4] - attributes[j+3]; + value = xmlMallocAtomic(valueLen + 1); + if (value == NULL) { + xmlSchemaVErrMemory(vctxt, + "allocating string for decoded attribute", + NULL); + goto internal_error; + } + for (k = 0, l = 0; k < valueLen; l++) { + if (k < valueLen - 4 && + attributes[j+3][k+0] == '&' && + attributes[j+3][k+1] == '#' && + attributes[j+3][k+2] == '3' && + attributes[j+3][k+3] == '8' && + attributes[j+3][k+4] == ';') { + value[l] = '&'; + k += 5; + } else { + value[l] = attributes[j+3][k]; + k++; + } + } + value[l] = '\0'; /* * TODO: Set the node line. */ @@ -27584,6 +27653,17 @@ xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt) vctxt->nbIdcNodes = 0; vctxt->sizeIdcNodes = 0; } + + if (vctxt->idcKeys != NULL) { + int i; + for (i = 0; i < vctxt->nbIdcKeys; i++) + xmlSchemaIDCFreeKey(vctxt->idcKeys[i]); + xmlFree(vctxt->idcKeys); + vctxt->idcKeys = NULL; + vctxt->nbIdcKeys = 0; + vctxt->sizeIdcKeys = 0; + } + /* * Note that we won't delete the XPath state pool here. */ @@ -27768,7 +27848,7 @@ xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt, { if (ctxt == NULL) return; - ctxt->serror = serror; + ctxt->serror = serror; ctxt->error = NULL; ctxt->warning = NULL; ctxt->errCtxt = ctx; @@ -28078,7 +28158,8 @@ xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) { * Augment the IDC definitions for the main schema and all imported ones * NOTE: main schema if the first in the imported list */ - xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt); + xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC, + vctxt); return(0); } diff --git a/gnulib-local/lib/libxml/xmlschemastypes.c b/gnulib-local/lib/libxml/xmlschemastypes.c index ff64f50a6..ca381d380 100644 --- a/gnulib-local/lib/libxml/xmlschemastypes.c +++ b/gnulib-local/lib/libxml/xmlschemastypes.c @@ -7,6 +7,11 @@ * Daniel Veillard */ +/* To avoid EBCDIC trouble when parsing on zOS */ +#if defined(__MVS__) +#pragma convert("ISO8859-1") +#endif + #define IN_LIBXML #include "libxml.h" @@ -62,7 +67,7 @@ struct _xmlSchemaValDate { long year; unsigned int mon :4; /* 1 <= mon <= 12 */ unsigned int day :5; /* 1 <= day <= 31 */ - unsigned int hour :5; /* 0 <= hour <= 23 */ + unsigned int hour :5; /* 0 <= hour <= 24 */ unsigned int min :6; /* 0 <= min <= 59 */ double sec; unsigned int tz_flag :1; /* is tzo explicitely set? */ @@ -614,6 +619,11 @@ xmlSchemaInitTypes(void) xmlSchemaTypesInitialized = 1; } +static void +xmlSchemaFreeTypeEntry(void *type, const xmlChar *name ATTRIBUTE_UNUSED) { + xmlSchemaFreeType((xmlSchemaTypePtr) type); +} + /** * xmlSchemaCleanupTypes: * @@ -641,7 +651,7 @@ xmlSchemaCleanupTypes(void) { xmlFree((xmlSchemaParticlePtr) particle); xmlSchemaTypeAnyTypeDef->subtypes = NULL; } - xmlHashFree(xmlSchemaTypesBank, (xmlHashDeallocator) xmlSchemaFreeType); + xmlHashFree(xmlSchemaTypesBank, xmlSchemaFreeTypeEntry); xmlSchemaTypesInitialized = 0; } @@ -1139,9 +1149,13 @@ static const unsigned int daysInMonthLeap[12] = #define VALID_DATE(dt) \ (VALID_YEAR(dt->year) && VALID_MONTH(dt->mon) && VALID_MDAY(dt)) +#define VALID_END_OF_DAY(dt) \ + ((dt)->hour == 24 && (dt)->min == 0 && (dt)->sec == 0) + #define VALID_TIME(dt) \ - (VALID_HOUR(dt->hour) && VALID_MIN(dt->min) && \ - VALID_SEC(dt->sec) && VALID_TZO(dt->tzo)) + (((VALID_HOUR(dt->hour) && VALID_MIN(dt->min) && \ + VALID_SEC(dt->sec)) || VALID_END_OF_DAY(dt)) && \ + VALID_TZO(dt->tzo)) #define VALID_DATETIME(dt) \ (VALID_DATE(dt) && VALID_TIME(dt)) @@ -1355,7 +1369,7 @@ _xmlSchemaParseTime (xmlSchemaValDatePtr dt, const xmlChar **str) { return ret; if (*cur != ':') return 1; - if (!VALID_HOUR(value)) + if (!VALID_HOUR(value) && value != 24 /* Allow end-of-day hour */) return 2; cur++; @@ -1377,7 +1391,7 @@ _xmlSchemaParseTime (xmlSchemaValDatePtr dt, const xmlChar **str) { if (ret != 0) return ret; - if ((!VALID_SEC(dt->sec)) || (!VALID_TZO(dt->tzo))) + if (!VALID_TIME(dt)) return 2; *str = cur; @@ -5303,6 +5317,7 @@ xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet, xmlSchemaWhitespaceValueType ws) { int ret; + int stringType; if (facet == NULL) return(-1); @@ -5315,7 +5330,15 @@ xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet, */ if (value == NULL) return(-1); - ret = xmlRegexpExec(facet->regexp, value); + /* + * If string-derived type, regexp must be tested on the value space of + * the datatype. + * See https://www.w3.org/TR/xmlschema-2/#rf-pattern + */ + stringType = val && ((val->type >= XML_SCHEMAS_STRING && val->type <= XML_SCHEMAS_NORMSTRING) + || (val->type >= XML_SCHEMAS_TOKEN && val->type <= XML_SCHEMAS_NCNAME)); + ret = xmlRegexpExec(facet->regexp, + (stringType && val->value.str) ? val->value.str : value); if (ret == 1) return(0); if (ret == 0) @@ -5385,7 +5408,7 @@ xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet, if ((valType == XML_SCHEMAS_QNAME) || (valType == XML_SCHEMAS_NOTATION)) return (0); - /* No break on purpose. */ + /* Falls through. */ case XML_SCHEMA_FACET_MAXLENGTH: case XML_SCHEMA_FACET_MINLENGTH: { unsigned int len = 0; diff --git a/gnulib-local/lib/libxml/xmlstring.c b/gnulib-local/lib/libxml/xmlstring.c index a37220d78..8d2e06f66 100644 --- a/gnulib-local/lib/libxml/xmlstring.c +++ b/gnulib-local/lib/libxml/xmlstring.c @@ -440,8 +440,8 @@ xmlStrlen(const xmlChar *str) { * first bytes of @add. Note that if @len < 0 then this is an API error * and NULL will be returned. * - * Returns a new xmlChar *, the original @cur is reallocated if needed - * and should not be freed + * Returns a new xmlChar *, the original @cur is reallocated and should + * not be freed. */ xmlChar * @@ -457,6 +457,8 @@ xmlStrncat(xmlChar *cur, const xmlChar *add, int len) { return(xmlStrndup(add, len)); size = xmlStrlen(cur); + if (size < 0) + return(NULL); ret = (xmlChar *) xmlRealloc(cur, (size + len + 1) * sizeof(xmlChar)); if (ret == NULL) { xmlErrMemory(NULL, NULL); @@ -484,14 +486,19 @@ xmlStrncatNew(const xmlChar *str1, const xmlChar *str2, int len) { int size; xmlChar *ret; - if (len < 0) + if (len < 0) { len = xmlStrlen(str2); + if (len < 0) + return(NULL); + } if ((str2 == NULL) || (len == 0)) return(xmlStrdup(str1)); if (str1 == NULL) return(xmlStrndup(str2, len)); size = xmlStrlen(str1); + if (size < 0) + return(NULL); ret = (xmlChar *) xmlMalloc((size + len + 1) * sizeof(xmlChar)); if (ret == NULL) { xmlErrMemory(NULL, NULL); @@ -512,7 +519,8 @@ xmlStrncatNew(const xmlChar *str1, const xmlChar *str2, int len) { * encoded in UTF-8 or an encoding with 8bit based chars, we assume * a termination mark of '0'. * - * Returns a new xmlChar * containing the concatenated string. + * Returns a new xmlChar * containing the concatenated string. The original + * @cur is reallocated and should not be freed. */ xmlChar * xmlStrcat(xmlChar *cur, const xmlChar *add) { @@ -538,7 +546,7 @@ xmlStrcat(xmlChar *cur, const xmlChar *add) { * Returns the number of characters written to @buf or -1 if an error occurs. */ int XMLCDECL -xmlStrPrintf(xmlChar *buf, int len, const xmlChar *msg, ...) { +xmlStrPrintf(xmlChar *buf, int len, const char *msg, ...) { va_list args; int ret; @@ -566,7 +574,7 @@ xmlStrPrintf(xmlChar *buf, int len, const xmlChar *msg, ...) { * Returns the number of characters written to @buf or -1 if an error occurs. */ int -xmlStrVPrintf(xmlChar *buf, int len, const xmlChar *msg, va_list ap) { +xmlStrVPrintf(xmlChar *buf, int len, const char *msg, va_list ap) { int ret; if((buf == NULL) || (msg == NULL)) { @@ -815,7 +823,7 @@ xmlCheckUTF8(const unsigned char *utf) * @len: the number of characters in the array * * storage size of an UTF8 string - * the behaviour is not garanteed if the input string is not UTF-8 + * the behaviour is not guaranteed if the input string is not UTF-8 * * Returns the storage size of * the first 'len' characters of ARRAY @@ -837,8 +845,8 @@ xmlUTF8Strsize(const xmlChar *utf, int len) { break; if ( (ch = *ptr++) & 0x80) while ((ch<<=1) & 0x80 ) { - ptr++; if (*ptr == 0) break; + ptr++; } } return (ptr - utf); @@ -980,5 +988,60 @@ xmlUTF8Strsub(const xmlChar *utf, int start, int len) { return(xmlUTF8Strndup(utf, len)); } +/** + * xmlEscapeFormatString: + * @msg: a pointer to the string in which to escape '%' characters. + * Must be a heap-allocated buffer created by libxml2 that may be + * returned, or that may be freed and replaced. + * + * Replaces the string pointed to by 'msg' with an escaped string. + * Returns the same string with all '%' characters escaped. + */ +xmlChar * +xmlEscapeFormatString(xmlChar **msg) +{ + xmlChar *msgPtr = NULL; + xmlChar *result = NULL; + xmlChar *resultPtr = NULL; + size_t count = 0; + size_t msgLen = 0; + size_t resultLen = 0; + + if (!msg || !*msg) + return(NULL); + + for (msgPtr = *msg; *msgPtr != '\0'; ++msgPtr) { + ++msgLen; + if (*msgPtr == '%') + ++count; + } + + if (count == 0) + return(*msg); + + resultLen = msgLen + count + 1; + result = (xmlChar *) xmlMallocAtomic(resultLen * sizeof(xmlChar)); + if (result == NULL) { + /* Clear *msg to prevent format string vulnerabilities in + out-of-memory situations. */ + xmlFree(*msg); + *msg = NULL; + xmlErrMemory(NULL, NULL); + return(NULL); + } + + for (msgPtr = *msg, resultPtr = result; *msgPtr != '\0'; ++msgPtr, ++resultPtr) { + *resultPtr = *msgPtr; + if (*msgPtr == '%') + *(++resultPtr) = '%'; + } + result[resultLen - 1] = '\0'; + + xmlFree(*msg); + *msg = result; + + return *msg; +} + #define bottom_xmlstring #include "elfgcchack.h" diff --git a/gnulib-local/lib/libxml/xmlstring.in.h b/gnulib-local/lib/libxml/xmlstring.in.h index 203623658..2d0b2d166 100644 --- a/gnulib-local/lib/libxml/xmlstring.in.h +++ b/gnulib-local/lib/libxml/xmlstring.in.h @@ -97,13 +97,13 @@ XMLPUBFUN xmlChar * XMLCALL XMLPUBFUN int XMLCALL xmlStrPrintf (xmlChar *buf, int len, - const xmlChar *msg, - ...); + const char *msg, + ...) LIBXML_ATTR_FORMAT(3,4); XMLPUBFUN int XMLCALL xmlStrVPrintf (xmlChar *buf, int len, - const xmlChar *msg, - va_list ap); + const char *msg, + va_list ap) LIBXML_ATTR_FORMAT(3,0); XMLPUBFUN int XMLCALL xmlGetUTF8Char (const unsigned char *utf, diff --git a/gnulib-local/lib/libxml/xmlunicode.c b/gnulib-local/lib/libxml/xmlunicode.c index ce6e9a4f1..6d0a96a0e 100644 --- a/gnulib-local/lib/libxml/xmlunicode.c +++ b/gnulib-local/lib/libxml/xmlunicode.c @@ -29,14 +29,14 @@ typedef struct { } xmlUnicodeRange; typedef struct { - xmlUnicodeRange *table; + const xmlUnicodeRange *table; int numentries; } xmlUnicodeNameTable; static xmlIntFunc *xmlUnicodeLookup(xmlUnicodeNameTable *tptr, const char *tname); -static xmlUnicodeRange xmlUnicodeBlocks[] = { +static const xmlUnicodeRange xmlUnicodeBlocks[] = { {"AegeanNumbers", xmlUCSIsAegeanNumbers}, {"AlphabeticPresentationForms", xmlUCSIsAlphabeticPresentationForms}, {"Arabic", xmlUCSIsArabic}, @@ -945,7 +945,7 @@ static xmlUnicodeNameTable xmlUnicodeCatTbl = {xmlUnicodeCats, 36}; static xmlIntFunc *xmlUnicodeLookup(xmlUnicodeNameTable *tptr, const char *tname) { int low, high, mid, cmp; - xmlUnicodeRange *sptr; + const xmlUnicodeRange *sptr; if ((tptr == NULL) || (tname == NULL)) return(NULL); diff --git a/gnulib-local/lib/libxml/xmlversion.in.h b/gnulib-local/lib/libxml/xmlversion.in.h index f7b483ab8..85aa48311 100644 --- a/gnulib-local/lib/libxml/xmlversion.in.h +++ b/gnulib-local/lib/libxml/xmlversion.in.h @@ -29,28 +29,28 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version); * * the version string like "1.2.3" */ -#define LIBXML_DOTTED_VERSION "2.9.3" +#define LIBXML_DOTTED_VERSION "2.9.9" /** * LIBXML_VERSION: * * the version number: 1.2.3 value is 10203 */ -#define LIBXML_VERSION 20903 +#define LIBXML_VERSION 20909 /** * LIBXML_VERSION_STRING: * * the version number string, 1.2.3 value is "10203" */ -#define LIBXML_VERSION_STRING "20903" +#define LIBXML_VERSION_STRING "20909" /** * LIBXML_VERSION_EXTRA: * * extra version information, used to show a CVS compilation */ -#define LIBXML_VERSION_EXTRA "-GITCVE-2015-8242" +#define LIBXML_VERSION_EXTRA "-GITv2.9.9-rc2-2-g7c4949afa" /** * LIBXML_TEST_VERSION: @@ -58,7 +58,7 @@ XMLPUBFUN void XMLCALL 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(20903); +#define LIBXML_TEST_VERSION xmlCheckVersion(20909); #ifndef VMS #if 0 @@ -410,9 +410,6 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version); #endif #ifdef __GNUC__ -#ifdef HAVE_ANSIDECL_H -#include -#endif /** * ATTRIBUTE_UNUSED: diff --git a/gnulib-local/lib/libxml/xmlwriter.c b/gnulib-local/lib/libxml/xmlwriter.c index fac20ac04..b5cd171f5 100644 --- a/gnulib-local/lib/libxml/xmlwriter.c +++ b/gnulib-local/lib/libxml/xmlwriter.c @@ -110,10 +110,10 @@ static void xmlFreeTextWriterNsStackEntry(xmlLinkPtr lk); static int xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1); static int xmlTextWriterWriteDocCallback(void *context, - const xmlChar * str, int len); + const char *str, int len); static int xmlTextWriterCloseDocCallback(void *context); -static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr); +static xmlChar *xmlTextWriterVSprintf(const char *format, va_list argptr) LIBXML_ATTR_FORMAT(1,0); static int xmlOutputBufferWriteBase64(xmlOutputBufferPtr out, int len, const unsigned char *data); static void xmlTextWriterStartDocumentCallback(void *ctx); @@ -153,7 +153,7 @@ xmlWriterErrMsg(xmlTextWriterPtr ctxt, xmlParserErrors error, * * Handle a writer error */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error, const char *msg, int val) { @@ -190,9 +190,7 @@ xmlNewTextWriter(xmlOutputBufferPtr out) } memset(ret, 0, (size_t) sizeof(xmlTextWriter)); - ret->nodes = xmlListCreate((xmlListDeallocator) - xmlFreeTextWriterStackEntry, - (xmlListDataCompare) + ret->nodes = xmlListCreate(xmlFreeTextWriterStackEntry, xmlCmpTextWriterStackEntry); if (ret->nodes == NULL) { xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, @@ -201,9 +199,7 @@ xmlNewTextWriter(xmlOutputBufferPtr out) return NULL; } - ret->nsstack = xmlListCreate((xmlListDeallocator) - xmlFreeTextWriterNsStackEntry, - (xmlListDataCompare) + ret->nsstack = xmlListCreate(xmlFreeTextWriterNsStackEntry, xmlCmpTextWriterNsStackEntry); if (ret->nsstack == NULL) { xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY, @@ -329,9 +325,7 @@ xmlNewTextWriterPushParser(xmlParserCtxtPtr ctxt, return NULL; } - out = xmlOutputBufferCreateIO((xmlOutputWriteCallback) - xmlTextWriterWriteDocCallback, - (xmlOutputCloseCallback) + out = xmlOutputBufferCreateIO(xmlTextWriterWriteDocCallback, xmlTextWriterCloseDocCallback, (void *) ctxt, NULL); if (out == NULL) { @@ -3754,6 +3748,7 @@ xmlTextWriterEndDTDEntity(xmlTextWriterPtr writer) if (count < 0) return -1; sum += count; + /* Falls through. */ case XML_TEXTWRITER_DTD_ENTY: case XML_TEXTWRITER_DTD_PENT: count = xmlOutputBufferWriteString(writer->out, ">"); @@ -4421,12 +4416,12 @@ xmlCmpTextWriterNsStackEntry(const void *data0, const void *data1) * Returns -1, 0, 1 */ static int -xmlTextWriterWriteDocCallback(void *context, const xmlChar * str, int len) +xmlTextWriterWriteDocCallback(void *context, const char *str, int len) { xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) context; int rc; - if ((rc = xmlParseChunk(ctxt, (const char *) str, len, 0)) != 0) { + if ((rc = xmlParseChunk(ctxt, str, len, 0)) != 0) { xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR, "xmlTextWriterWriteDocCallback : XML error %d !\n", rc); @@ -4452,7 +4447,7 @@ xmlTextWriterCloseDocCallback(void *context) if ((rc = xmlParseChunk(ctxt, NULL, 0, 1)) != 0) { xmlWriterErrMsgInt(NULL, XML_ERR_INTERNAL_ERROR, - "xmlTextWriterWriteDocCallback : XML error %d !\n", + "xmlTextWriterCloseDocCallback : XML error %d !\n", rc); return -1; } diff --git a/gnulib-local/lib/libxml/xpath.c b/gnulib-local/lib/libxml/xpath.c index 935fcff02..5e3bb9ff6 100644 --- a/gnulib-local/lib/libxml/xpath.c +++ b/gnulib-local/lib/libxml/xpath.c @@ -2,7 +2,7 @@ * xpath.c: XML Path Language implementation * XPath is a language for addressing parts of an XML document, * designed to be used by both XSLT and XPointer - *f + * * Reference: W3C Recommendation 16 November 1999 * http://www.w3.org/TR/1999/REC-xpath-19991116 * Public reference: @@ -14,10 +14,17 @@ * */ +/* To avoid EBCDIC trouble when parsing on zOS */ +#if defined(__MVS__) +#pragma convert("ISO8859-1") +#endif + #define IN_LIBXML #include "libxml.h" +#include #include +#include #ifdef HAVE_SYS_TYPES_H #include @@ -153,7 +160,7 @@ xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) { int misc = 0, precedence1 = 0, precedence2 = 0; xmlNodePtr miscNode1 = NULL, miscNode2 = NULL; xmlNodePtr cur, root; - long l1, l2; + ptrdiff_t l1, l2; if ((node1 == NULL) || (node2 == NULL)) return(-2); @@ -167,12 +174,12 @@ xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) { switch (node1->type) { case XML_ELEMENT_NODE: if (node2->type == XML_ELEMENT_NODE) { - if ((0 > (long) node1->content) && /* TODO: Would a != 0 suffice here? */ - (0 > (long) node2->content) && + if ((0 > (ptrdiff_t) node1->content) && + (0 > (ptrdiff_t) node2->content) && (node1->doc == node2->doc)) { - l1 = -((long) node1->content); - l2 = -((long) node2->content); + l1 = -((ptrdiff_t) node1->content); + l2 = -((ptrdiff_t) node2->content); if (l1 < l2) return(1); if (l1 > l2) @@ -217,7 +224,7 @@ xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) { node1 = node1->parent; } if ((node1 == NULL) || (node1->type != XML_ELEMENT_NODE) || - (0 <= (long) node1->content)) { + (0 <= (ptrdiff_t) node1->content)) { /* * Fallback for whatever case. */ @@ -267,7 +274,7 @@ xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) { node2 = node2->parent; } if ((node2 == NULL) || (node2->type != XML_ELEMENT_NODE) || - (0 <= (long) node2->content)) + (0 <= (ptrdiff_t) node2->content)) { node2 = miscNode2; precedence2 = 0; @@ -340,12 +347,12 @@ xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) { */ if ((node1->type == XML_ELEMENT_NODE) && (node2->type == XML_ELEMENT_NODE) && - (0 > (long) node1->content) && - (0 > (long) node2->content) && + (0 > (ptrdiff_t) node1->content) && + (0 > (ptrdiff_t) node2->content) && (node1->doc == node2->doc)) { - l1 = -((long) node1->content); - l2 = -((long) node2->content); + l1 = -((ptrdiff_t) node1->content); + l2 = -((ptrdiff_t) node2->content); if (l1 < l2) return(1); if (l1 > l2) @@ -408,12 +415,12 @@ turtle_comparison: */ if ((node1->type == XML_ELEMENT_NODE) && (node2->type == XML_ELEMENT_NODE) && - (0 > (long) node1->content) && - (0 > (long) node2->content) && + (0 > (ptrdiff_t) node1->content) && + (0 > (ptrdiff_t) node2->content) && (node1->doc == node2->doc)) { - l1 = -((long) node1->content); - l2 = -((long) node2->content); + l1 = -((ptrdiff_t) node1->content); + l2 = -((ptrdiff_t) node2->content); if (l1 < l2) return(1); if (l1 > l2) @@ -470,19 +477,17 @@ int wrap_cmp( xmlNodePtr x, xmlNodePtr y ); * * ************************************************************************/ -#ifndef TRIO_REPLACE_STDIO -#define TRIO_PUBLIC static +#ifndef INFINITY +#define INFINITY (DBL_MAX * DBL_MAX) #endif -#include "trionan.c" -/* - * The lack of portability of this section of the libc is annoying ! - */ -double xmlXPathNAN = 0; -double xmlXPathPINF = 1; -double xmlXPathNINF = -1; -static double xmlXPathNZERO = 0; /* not exported from headers */ -static int xmlXPathInitialized = 0; +#ifndef NAN +#define NAN (INFINITY / INFINITY) +#endif + +double xmlXPathNAN; +double xmlXPathPINF; +double xmlXPathNINF; /** * xmlXPathInit: @@ -491,63 +496,48 @@ static int xmlXPathInitialized = 0; */ void xmlXPathInit(void) { - if (xmlXPathInitialized) return; - - xmlXPathPINF = trio_pinf(); - xmlXPathNINF = trio_ninf(); - xmlXPathNAN = trio_nan(); - xmlXPathNZERO = trio_nzero(); - - xmlXPathInitialized = 1; + xmlXPathNAN = NAN; + xmlXPathPINF = INFINITY; + xmlXPathNINF = -INFINITY; } /** * xmlXPathIsNaN: * @val: a double value * - * Provides a portable isnan() function to detect whether a double - * is a NotaNumber. Based on trio code - * http://sourceforge.net/projects/ctrio/ - * * Returns 1 if the value is a NaN, 0 otherwise */ int xmlXPathIsNaN(double val) { - return(trio_isnan(val)); +#ifdef isnan + return isnan(val); +#else + return !(val == val); +#endif } /** * xmlXPathIsInf: * @val: a double value * - * Provides a portable isinf() function to detect whether a double - * is a +Infinite or -Infinite. Based on trio code - * http://sourceforge.net/projects/ctrio/ - * - * Returns 1 vi the value is +Infinite, -1 if -Infinite, 0 otherwise + * Returns 1 if the value is +Infinite, -1 if -Infinite, 0 otherwise */ int xmlXPathIsInf(double val) { - return(trio_isinf(val)); +#ifdef isinf + return isinf(val) ? (val > 0 ? 1 : -1) : 0; +#else + if (val >= INFINITY) + return 1; + if (val <= -INFINITY) + return -1; + return 0; +#endif } #endif /* SCHEMAS or XPATH */ -#ifdef LIBXML_XPATH_ENABLED -/** - * xmlXPathGetSign: - * @val: a double value - * - * Provides a portable function to detect the sign of a double - * Modified from trio code - * http://sourceforge.net/projects/ctrio/ - * - * Returns 1 if the value is Negative, 0 if positive - */ -static int -xmlXPathGetSign(double val) { - return(trio_signbit(val)); -} +#ifdef LIBXML_XPATH_ENABLED /* * TODO: when compatibility allows remove all "fake node libxslt" strings @@ -639,7 +629,7 @@ xmlXPathErrMemory(xmlXPathContextPtr ctxt, const char *extra) xmlChar buf[200]; xmlStrPrintf(buf, 200, - BAD_CAST "Memory allocation failed : %s\n", + "Memory allocation failed : %s\n", extra); ctxt->lastError.message = (char *) xmlStrdup(buf); } else { @@ -878,15 +868,14 @@ typedef enum { XPATH_OP_UNION, XPATH_OP_ROOT, XPATH_OP_NODE, - XPATH_OP_RESET, /* 10 */ XPATH_OP_COLLECT, - XPATH_OP_VALUE, /* 12 */ + XPATH_OP_VALUE, /* 11 */ XPATH_OP_VARIABLE, XPATH_OP_FUNCTION, XPATH_OP_ARG, XPATH_OP_PREDICATE, - XPATH_OP_FILTER, /* 17 */ - XPATH_OP_SORT /* 18 */ + XPATH_OP_FILTER, /* 16 */ + XPATH_OP_SORT /* 17 */ #ifdef LIBXML_XPTR_ENABLED ,XPATH_OP_RANGETO #endif @@ -935,7 +924,7 @@ struct _xmlXPathStepOp { int value3; void *value4; void *value5; - void *cache; + xmlXPathFunction cache; void *cacheURI; }; @@ -945,7 +934,7 @@ struct _xmlXPathCompExpr { xmlXPathStepOp *steps; /* ops for computation of this expression */ int last; /* index of last step in expression */ xmlChar *expr; /* the expression being computed */ - xmlDictPtr dict; /* the dictionnary to use if any */ + xmlDictPtr dict; /* the dictionary to use if any */ #ifdef DEBUG_EVAL_COUNTS int nb; xmlChar *string; @@ -971,6 +960,8 @@ static int xmlXPathCompOpEvalToBoolean(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op, int isPredicate); +static void +xmlXPathFreeObjectEntry(void *obj, const xmlChar *name); /************************************************************************ * * @@ -1414,7 +1405,8 @@ xmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth) { default: if (xmlXPathIsNaN(cur->floatval)) { fprintf(output, "Object is a number : NaN\n"); - } else if (cur->floatval == 0 && xmlXPathGetSign(cur->floatval) != 0) { + } else if (cur->floatval == 0) { + /* Omit sign for negative zero. */ fprintf(output, "Object is a number : 0\n"); } else { fprintf(output, "Object is a number : %0g\n", cur->floatval); @@ -1533,8 +1525,6 @@ xmlXPathDebugDumpStepOp(FILE *output, xmlXPathCompExprPtr comp, fprintf(output, "ROOT"); break; case XPATH_OP_NODE: fprintf(output, "NODE"); break; - case XPATH_OP_RESET: - fprintf(output, "RESET"); break; case XPATH_OP_SORT: fprintf(output, "SORT"); break; case XPATH_OP_COLLECT: { @@ -1672,10 +1662,17 @@ xmlXPathDebugDumpCompExpr(FILE *output, xmlXPathCompExprPtr comp, fprintf(output, "%s", shift); - fprintf(output, "Compiled Expression : %d elements\n", - comp->nbStep); - i = comp->last; - xmlXPathDebugDumpStepOp(output, comp, &comp->steps[i], depth + 1); +#ifdef XPATH_STREAMING + if (comp->stream) { + fprintf(output, "Streaming Expression\n"); + } else +#endif + { + fprintf(output, "Compiled Expression : %d elements\n", + comp->nbStep); + i = comp->last; + xmlXPathDebugDumpStepOp(output, comp, &comp->steps[i], depth + 1); + } } #ifdef XP_DEBUG_OBJ_USAGE @@ -3103,9 +3100,11 @@ xmlXPathFormatNumber(double number, char buffer[], int buffersize) if (xmlXPathIsNaN(number)) { if (buffersize > (int)sizeof("NaN")) snprintf(buffer, buffersize, "NaN"); - } else if (number == 0 && xmlXPathGetSign(number) != 0) { + } else if (number == 0) { + /* Omit sign for negative zero. */ snprintf(buffer, buffersize, "0"); - } else if (number == ((int) number)) { + } else if ((number > INT_MIN) && (number < INT_MAX) && + (number == (int) number)) { char work[30]; char *ptr, *cur; int value = (int) number; @@ -3225,7 +3224,7 @@ xmlXPathFormatNumber(double number, char buffer[], int buffersize) */ long xmlXPathOrderDocElems(xmlDocPtr doc) { - long count = 0; + ptrdiff_t count = 0; xmlNodePtr cur; if (doc == NULL) @@ -3257,7 +3256,7 @@ xmlXPathOrderDocElems(xmlDocPtr doc) { } } while (cur != NULL); } - return(count); + return((long) count); } /** @@ -3325,13 +3324,13 @@ xmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) { */ if ((node1->type == XML_ELEMENT_NODE) && (node2->type == XML_ELEMENT_NODE) && - (0 > (long) node1->content) && - (0 > (long) node2->content) && + (0 > (ptrdiff_t) node1->content) && + (0 > (ptrdiff_t) node2->content) && (node1->doc == node2->doc)) { - long l1, l2; + ptrdiff_t l1, l2; - l1 = -((long) node1->content); - l2 = -((long) node2->content); + l1 = -((ptrdiff_t) node1->content); + l2 = -((ptrdiff_t) node2->content); if (l1 < l2) return(1); if (l1 > l2) @@ -3342,13 +3341,13 @@ xmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) { * compute depth to root */ for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) { - if (cur == node1) + if (cur->parent == node1) return(1); depth2++; } root = cur; for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) { - if (cur == node2) + if (cur->parent == node2) return(-1); depth1++; } @@ -3388,13 +3387,13 @@ xmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) { */ if ((node1->type == XML_ELEMENT_NODE) && (node2->type == XML_ELEMENT_NODE) && - (0 > (long) node1->content) && - (0 > (long) node2->content) && + (0 > (ptrdiff_t) node1->content) && + (0 > (ptrdiff_t) node2->content) && (node1->doc == node2->doc)) { - long l1, l2; + ptrdiff_t l1, l2; - l1 = -((long) node1->content); - l2 = -((long) node2->content); + l1 = -((ptrdiff_t) node1->content); + l2 = -((ptrdiff_t) node2->content); if (l1 < l2) return(1); if (l1 > l2) @@ -3706,7 +3705,7 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) { /* @@ with_ns to check whether namespace nodes should be looked at @@ */ /* - * prevent duplcates + * prevent duplicates */ for (i = 0;i < cur->nodeNr;i++) if (cur->nodeTab[i] == val) return(0); @@ -4021,13 +4020,7 @@ xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr set1, xmlNodeSetPtr set2, set1->nodeTab = temp; set1->nodeMax *= 2; } - if (n2->type == XML_NAMESPACE_DECL) { - xmlNsPtr ns = (xmlNsPtr) n2; - - set1->nodeTab[set1->nodeNr++] = - xmlXPathNodeSetDupNs((xmlNodePtr) ns->next, ns); - } else - set1->nodeTab[set1->nodeNr++] = n2; + set1->nodeTab[set1->nodeNr++] = n2; skip_node: {} } @@ -4195,33 +4188,6 @@ xmlXPathFreeNodeSet(xmlNodeSetPtr obj) { xmlFree(obj); } -/** - * xmlXPathNodeSetClear: - * @set: the node set to clear - * - * Clears the list from all temporary XPath objects (e.g. namespace nodes - * are feed), but does *not* free the list itself. Sets the length of the - * list to 0. - */ -static void -xmlXPathNodeSetClear(xmlNodeSetPtr set, int hasNsNodes) -{ - if ((set == NULL) || (set->nodeNr <= 0)) - return; - else if (hasNsNodes) { - int i; - xmlNodePtr node; - - for (i = 0; i < set->nodeNr; i++) { - node = set->nodeTab[i]; - if ((node != NULL) && - (node->type == XML_NAMESPACE_DECL)) - xmlXPathNodeSetFreeNs((xmlNsPtr) node); - } - } - set->nodeNr = 0; -} - /** * xmlXPathNodeSetClearFromPos: * @set: the node set to be cleared @@ -4234,7 +4200,7 @@ xmlXPathNodeSetClear(xmlNodeSetPtr set, int hasNsNodes) static void xmlXPathNodeSetClearFromPos(xmlNodeSetPtr set, int pos, int hasNsNodes) { - if ((set == NULL) || (set->nodeNr <= 0) || (pos >= set->nodeNr)) + if ((set == NULL) || (pos >= set->nodeNr)) return; else if ((hasNsNodes)) { int i; @@ -4250,6 +4216,46 @@ xmlXPathNodeSetClearFromPos(xmlNodeSetPtr set, int pos, int hasNsNodes) set->nodeNr = pos; } +/** + * xmlXPathNodeSetClear: + * @set: the node set to clear + * + * Clears the list from all temporary XPath objects (e.g. namespace nodes + * are feed), but does *not* free the list itself. Sets the length of the + * list to 0. + */ +static void +xmlXPathNodeSetClear(xmlNodeSetPtr set, int hasNsNodes) +{ + xmlXPathNodeSetClearFromPos(set, 0, hasNsNodes); +} + +/** + * xmlXPathNodeSetKeepLast: + * @set: the node set to be cleared + * + * Move the last node to the first position and clear temporary XPath objects + * (e.g. namespace nodes) from all other nodes. Sets the length of the list + * to 1. + */ +static void +xmlXPathNodeSetKeepLast(xmlNodeSetPtr set) +{ + int i; + xmlNodePtr node; + + if ((set == NULL) || (set->nodeNr <= 1)) + return; + for (i = 0; i < set->nodeNr - 1; i++) { + node = set->nodeTab[i]; + if ((node != NULL) && + (node->type == XML_NAMESPACE_DECL)) + xmlXPathNodeSetFreeNs((xmlNsPtr) node); + } + set->nodeTab[0] = set->nodeTab[set->nodeNr-1]; + set->nodeNr = 1; +} + /** * xmlXPathFreeValueTree: * @obj: the xmlNodeSetPtr to free @@ -4560,7 +4566,7 @@ xmlXPathDistinctSorted (xmlNodeSetPtr nodes) { xmlFree(strval); } } - xmlHashFree(hash, (xmlHashDeallocator) xmlFree); + xmlHashFree(hash, xmlHashDefaultDeallocator); return(ret); } @@ -4872,7 +4878,9 @@ xmlXPathRegisterFuncNS(xmlXPathContextPtr ctxt, const xmlChar *name, return(-1); if (f == NULL) return(xmlHashRemoveEntry2(ctxt->funcHash, name, ns_uri, NULL)); - return(xmlHashAddEntry2(ctxt->funcHash, name, ns_uri, XML_CAST_FPTR(f))); +XML_IGNORE_PEDANTIC_WARNINGS + return(xmlHashAddEntry2(ctxt->funcHash, name, ns_uri, (void *) f)); +XML_POP_WARNINGS } /** @@ -4953,7 +4961,9 @@ xmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name, if (ctxt->funcHash == NULL) return(NULL); - XML_CAST_FPTR(ret) = xmlHashLookup2(ctxt->funcHash, name, ns_uri); +XML_IGNORE_PEDANTIC_WARNINGS + ret = (xmlXPathFunction) xmlHashLookup2(ctxt->funcHash, name, ns_uri); +XML_POP_WARNINGS return(ret); } @@ -5022,10 +5032,9 @@ xmlXPathRegisterVariableNS(xmlXPathContextPtr ctxt, const xmlChar *name, return(-1); if (value == NULL) return(xmlHashRemoveEntry2(ctxt->varHash, name, ns_uri, - (xmlHashDeallocator)xmlXPathFreeObject)); + xmlXPathFreeObjectEntry)); return(xmlHashUpdateEntry2(ctxt->varHash, name, ns_uri, - (void *) value, - (xmlHashDeallocator)xmlXPathFreeObject)); + (void *) value, xmlXPathFreeObjectEntry)); } /** @@ -5115,7 +5124,7 @@ xmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) { if (ctxt == NULL) return; - xmlHashFree(ctxt->varHash, (xmlHashDeallocator)xmlXPathFreeObject); + xmlHashFree(ctxt->varHash, xmlXPathFreeObjectEntry); ctxt->varHash = NULL; } @@ -5146,9 +5155,9 @@ xmlXPathRegisterNs(xmlXPathContextPtr ctxt, const xmlChar *prefix, return(-1); if (ns_uri == NULL) return(xmlHashRemoveEntry(ctxt->nsHash, prefix, - (xmlHashDeallocator)xmlFree)); + xmlHashDefaultDeallocator)); return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) xmlStrdup(ns_uri), - (xmlHashDeallocator)xmlFree)); + xmlHashDefaultDeallocator)); } /** @@ -5197,7 +5206,7 @@ xmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) { if (ctxt == NULL) return; - xmlHashFree(ctxt->nsHash, (xmlHashDeallocator)xmlFree); + xmlHashFree(ctxt->nsHash, xmlHashDefaultDeallocator); ctxt->nsHash = NULL; } @@ -5511,6 +5520,11 @@ xmlXPathFreeObject(xmlXPathObjectPtr obj) { xmlFree(obj); } +static void +xmlXPathFreeObjectEntry(void *obj, const xmlChar *name ATTRIBUTE_UNUSED) { + xmlXPathFreeObject((xmlXPathObjectPtr) obj); +} + /** * xmlXPathReleaseObject: * @obj: the xmlXPathObjectPtr to free or to cache @@ -5700,7 +5714,8 @@ xmlXPathCastNumberToString (double val) { default: if (xmlXPathIsNaN(val)) { ret = xmlStrdup((const xmlChar *) "NaN"); - } else if (val == 0 && xmlXPathGetSign(val) != 0) { + } else if (val == 0) { + /* Omit sign for negative zero. */ ret = xmlStrdup((const xmlChar *) "0"); } else { /* could be improved */ @@ -5882,10 +5897,10 @@ xmlXPathCastNodeToNumber (xmlNodePtr node) { double ret; if (node == NULL) - return(xmlXPathNAN); + return(NAN); strval = xmlXPathCastNodeToString(node); if (strval == NULL) - return(xmlXPathNAN); + return(NAN); ret = xmlXPathCastStringToNumber(strval); xmlFree(strval); @@ -5906,7 +5921,7 @@ xmlXPathCastNodeSetToNumber (xmlNodeSetPtr ns) { double ret; if (ns == NULL) - return(xmlXPathNAN); + return(NAN); str = xmlXPathCastNodeSetToString(ns); ret = xmlXPathCastStringToNumber(str); xmlFree(str); @@ -5926,13 +5941,13 @@ xmlXPathCastToNumber(xmlXPathObjectPtr val) { double ret = 0.0; if (val == NULL) - return(xmlXPathNAN); + return(NAN); switch (val->type) { case XPATH_UNDEFINED: #ifdef DEGUB_EXPR xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n"); #endif - ret = xmlXPathNAN; + ret = NAN; break; case XPATH_NODESET: case XPATH_XSLT_TREE: @@ -5952,7 +5967,7 @@ xmlXPathCastToNumber(xmlXPathObjectPtr val) { case XPATH_RANGE: case XPATH_LOCATIONSET: TODO; - ret = xmlXPathNAN; + ret = NAN; break; } return(ret); @@ -6289,7 +6304,15 @@ xmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) { */ void xmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) { + int i; + if (ctxt->valueTab != NULL) { + for (i = 0; i < ctxt->valueNr; i++) { + if (ctxt->context) + xmlXPathReleaseObject(ctxt->context, ctxt->valueTab[i]); + else + xmlXPathFreeObject(ctxt->valueTab[i]); + } xmlFree(ctxt->valueTab); } if (ctxt->comp != NULL) { @@ -6371,16 +6394,12 @@ xmlXPathNodeValHash(xmlNodePtr node) { } while (tmp != NULL) { switch (tmp->type) { - case XML_COMMENT_NODE: - case XML_PI_NODE: case XML_CDATA_SECTION_NODE: case XML_TEXT_NODE: string = tmp->content; break; - case XML_NAMESPACE_DECL: - string = ((xmlNsPtr)tmp)->href; - break; default: + string = NULL; break; } if ((string != NULL) && (string[0] != 0)) { @@ -6702,7 +6721,13 @@ xmlXPathCompareNodeSetValue(xmlXPathParserContextPtr ctxt, int inf, int strict, valuePush(ctxt, val); return(xmlXPathCompareValues(ctxt, inf, strict)); default: - TODO + xmlGenericError(xmlGenericErrorContext, + "xmlXPathCompareNodeSetValue: Can't compare node set " + "and object of type %d\n", + val->type); + xmlXPathReleaseObject(ctxt->context, arg); + xmlXPathReleaseObject(ctxt->context, val); + XP_ERROR0(XPATH_INVALID_TYPE); } return(0); } @@ -7010,7 +7035,7 @@ xmlXPathEqualValuesCommon(xmlXPathParserContextPtr ctxt, valuePush(ctxt, arg2); xmlXPathNumberFunction(ctxt, 1); arg2 = valuePop(ctxt); - /* no break on purpose */ + /* Falls through. */ case XPATH_NUMBER: /* Hand check NaN and Infinity equalities */ if (xmlXPathIsNaN(arg1->floatval) || @@ -7446,20 +7471,7 @@ xmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt) { if ((ctxt == NULL) || (ctxt->context == NULL)) return; CAST_TO_NUMBER; CHECK_TYPE(XPATH_NUMBER); - if (xmlXPathIsNaN(ctxt->value->floatval)) - ctxt->value->floatval=xmlXPathNAN; - else if (xmlXPathIsInf(ctxt->value->floatval) == 1) - ctxt->value->floatval=xmlXPathNINF; - else if (xmlXPathIsInf(ctxt->value->floatval) == -1) - ctxt->value->floatval=xmlXPathPINF; - else if (ctxt->value->floatval == 0) { - if (xmlXPathGetSign(ctxt->value->floatval) == 0) - ctxt->value->floatval = xmlXPathNZERO; - else - ctxt->value->floatval = 0; - } - else - ctxt->value->floatval = - ctxt->value->floatval; + ctxt->value->floatval = -ctxt->value->floatval; } /** @@ -7551,25 +7563,7 @@ xmlXPathDivValues(xmlXPathParserContextPtr ctxt) { xmlXPathReleaseObject(ctxt->context, arg); CAST_TO_NUMBER; CHECK_TYPE(XPATH_NUMBER); - if (xmlXPathIsNaN(val) || xmlXPathIsNaN(ctxt->value->floatval)) - ctxt->value->floatval = xmlXPathNAN; - else if (val == 0 && xmlXPathGetSign(val) != 0) { - if (ctxt->value->floatval == 0) - ctxt->value->floatval = xmlXPathNAN; - else if (ctxt->value->floatval > 0) - ctxt->value->floatval = xmlXPathNINF; - else if (ctxt->value->floatval < 0) - ctxt->value->floatval = xmlXPathPINF; - } - else if (val == 0) { - if (ctxt->value->floatval == 0) - ctxt->value->floatval = xmlXPathNAN; - else if (ctxt->value->floatval > 0) - ctxt->value->floatval = xmlXPathPINF; - else if (ctxt->value->floatval < 0) - ctxt->value->floatval = xmlXPathNINF; - } else - ctxt->value->floatval /= val; + ctxt->value->floatval /= val; } /** @@ -7594,7 +7588,7 @@ xmlXPathModValues(xmlXPathParserContextPtr ctxt) { CHECK_TYPE(XPATH_NUMBER); arg1 = ctxt->value->floatval; if (arg2 == 0) - ctxt->value->floatval = xmlXPathNAN; + ctxt->value->floatval = NAN; else { ctxt->value->floatval = fmod(arg1, arg2); } @@ -8114,12 +8108,12 @@ xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { return(NULL); return(cur->parent); case XML_ATTRIBUTE_NODE: { - xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node; + xmlAttrPtr att = (xmlAttrPtr) cur; return(att->parent); } case XML_NAMESPACE_DECL: { - xmlNsPtr ns = (xmlNsPtr) ctxt->context->node; + xmlNsPtr ns = (xmlNsPtr) cur; if ((ns->next != NULL) && (ns->next->type != XML_NAMESPACE_DECL)) @@ -8236,10 +8230,16 @@ xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { if (cur == NULL) { cur = ctxt->context->node; - if (cur->type == XML_NAMESPACE_DECL) - return(NULL); - if (cur->type == XML_ATTRIBUTE_NODE) + if (cur->type == XML_ATTRIBUTE_NODE) { cur = cur->parent; + } else if (cur->type == XML_NAMESPACE_DECL) { + xmlNsPtr ns = (xmlNsPtr) cur; + + if ((ns->next == NULL) || + (ns->next->type == XML_NAMESPACE_DECL)) + return (NULL); + cur = (xmlNodePtr) ns->next; + } } if (cur == NULL) return(NULL) ; /* ERROR */ if (cur->next != NULL) return(cur->next) ; @@ -8300,10 +8300,16 @@ xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); if (cur == NULL) { cur = ctxt->context->node; - if (cur->type == XML_NAMESPACE_DECL) - return(NULL); - if (cur->type == XML_ATTRIBUTE_NODE) - return(cur->parent); + if (cur->type == XML_ATTRIBUTE_NODE) { + cur = cur->parent; + } else if (cur->type == XML_NAMESPACE_DECL) { + xmlNsPtr ns = (xmlNsPtr) cur; + + if ((ns->next == NULL) || + (ns->next->type == XML_NAMESPACE_DECL)) + return (NULL); + cur = (xmlNodePtr) ns->next; + } } if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) return (NULL); @@ -8348,8 +8354,16 @@ xmlXPathNextPrecedingInternal(xmlXPathParserContextPtr ctxt, cur = ctxt->context->node; if (cur == NULL) return (NULL); - if (cur->type == XML_NAMESPACE_DECL) - return (NULL); + if (cur->type == XML_ATTRIBUTE_NODE) { + cur = cur->parent; + } else if (cur->type == XML_NAMESPACE_DECL) { + xmlNsPtr ns = (xmlNsPtr) cur; + + if ((ns->next == NULL) || + (ns->next->type == XML_NAMESPACE_DECL)) + return (NULL); + cur = (xmlNodePtr) ns->next; + } ctxt->ancestor = cur->parent; } if (cur->type == XML_NAMESPACE_DECL) @@ -8390,7 +8404,7 @@ xmlNodePtr xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) { if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL); if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL); - if (ctxt->context->tmpNsList == NULL && cur != (xmlNodePtr) xmlXPathXMLNamespace) { + if (cur == NULL) { if (ctxt->context->tmpNsList != NULL) xmlFree(ctxt->context->tmpNsList); ctxt->context->tmpNsList = @@ -8463,9 +8477,8 @@ void xmlXPathRoot(xmlXPathParserContextPtr ctxt) { if ((ctxt == NULL) || (ctxt->context == NULL)) return; - ctxt->context->node = (xmlNodePtr) ctxt->context->doc; valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context, - ctxt->context->node)); + (xmlNodePtr) ctxt->context->doc)); } /************************************************************************ @@ -9634,18 +9647,6 @@ xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathReleaseObject(ctxt->context, cur); } -/* - * To assure working code on multiple platforms, we want to only depend - * upon the characteristic truncation of converting a floating point value - * to an integer. Unfortunately, because of the different storage sizes - * of our internal floating point value (double) and integer (int), we - * can't directly convert (see bug 301162). This macro is a messy - * 'workaround' - */ -#define XTRUNC(f, v) \ - f = fmod((v), INT_MAX); \ - f = (v) - (f) + (double)((int)(f)); - /** * xmlXPathFloorFunction: * @ctxt: the XPath Parser context @@ -9658,19 +9659,11 @@ xmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) { */ void xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) { - double f; - CHECK_ARITY(1); CAST_TO_NUMBER; CHECK_TYPE(XPATH_NUMBER); - XTRUNC(f, ctxt->value->floatval); - if (f != ctxt->value->floatval) { - if (ctxt->value->floatval > 0) - ctxt->value->floatval = f; - else - ctxt->value->floatval = f - 1; - } + ctxt->value->floatval = floor(ctxt->value->floatval); } /** @@ -9685,28 +9678,11 @@ xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) { */ void xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs) { - double f; - CHECK_ARITY(1); CAST_TO_NUMBER; CHECK_TYPE(XPATH_NUMBER); -#if 0 ctxt->value->floatval = ceil(ctxt->value->floatval); -#else - XTRUNC(f, ctxt->value->floatval); - if (f != ctxt->value->floatval) { - if (ctxt->value->floatval > 0) - ctxt->value->floatval = f + 1; - else { - if (ctxt->value->floatval < 0 && f == 0) - ctxt->value->floatval = xmlXPathNZERO; - else - ctxt->value->floatval = f; - } - - } -#endif } /** @@ -9718,7 +9694,7 @@ xmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs) { * number round(number) * The round function returns the number that is closest to the * argument and that is an integer. If there are two such numbers, - * then the one that is even is returned. + * then the one that is closest to positive infinity is returned. */ void xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) { @@ -9728,25 +9704,17 @@ xmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) { CAST_TO_NUMBER; CHECK_TYPE(XPATH_NUMBER); - if ((xmlXPathIsNaN(ctxt->value->floatval)) || - (xmlXPathIsInf(ctxt->value->floatval) == 1) || - (xmlXPathIsInf(ctxt->value->floatval) == -1) || - (ctxt->value->floatval == 0.0)) - return; + f = ctxt->value->floatval; - XTRUNC(f, ctxt->value->floatval); - if (ctxt->value->floatval < 0) { - if (ctxt->value->floatval < f - 0.5) - ctxt->value->floatval = f - 1; - else - ctxt->value->floatval = f; - if (ctxt->value->floatval == 0) - ctxt->value->floatval = xmlXPathNZERO; - } else { - if (ctxt->value->floatval < f + 0.5) - ctxt->value->floatval = f; - else - ctxt->value->floatval = f + 1; + if ((f >= -0.5) && (f < 0.5)) { + /* Handles negative zero. */ + ctxt->value->floatval *= 0.0; + } + else { + double rounded = floor(f); + if (f - rounded >= 0.5) + rounded += 1.0; + ctxt->value->floatval = rounded; } } @@ -9996,7 +9964,7 @@ xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) { (c == '[') || (c == ']') || (c == '@') || /* accelerators */ (c == '*') || /* accelerators */ (!IS_LETTER(c) && (c != '_') && - ((qualified) && (c != ':')))) { + ((!qualified) || (c != ':')))) { return(NULL); } @@ -10056,20 +10024,6 @@ xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) { #define MAX_FRAC 20 -/* - * These are used as divisors for the fractional part of a number. - * Since the table includes 1.0 (representing '0' fractional digits), - * it must be dimensioned at MAX_FRAC+1 (bug 133921) - */ -static double my_pow10[MAX_FRAC+1] = { - 1.0, 10.0, 100.0, 1000.0, 10000.0, - 100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0, - 10000000000.0, 100000000000.0, 1000000000000.0, 10000000000000.0, - 100000000000000.0, - 1000000000000000.0, 10000000000000000.0, 100000000000000000.0, - 1000000000000000000.0, 10000000000000000000.0, 100000000000000000000.0 -}; - /** * xmlXPathStringEvalNumber: * @str: A string to scan @@ -10101,7 +10055,7 @@ xmlXPathStringEvalNumber(const xmlChar *str) { if (cur == NULL) return(0); while (IS_BLANK_CH(*cur)) cur++; if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) { - return(xmlXPathNAN); + return(NAN); } if (*cur == '-') { isneg = 1; @@ -10132,20 +10086,25 @@ xmlXPathStringEvalNumber(const xmlChar *str) { #endif if (*cur == '.') { - int v, frac = 0; + int v, frac = 0, max; double fraction = 0; cur++; if (((*cur < '0') || (*cur > '9')) && (!ok)) { - return(xmlXPathNAN); + return(NAN); } - while (((*cur >= '0') && (*cur <= '9')) && (frac < MAX_FRAC)) { + while (*cur == '0') { + frac = frac + 1; + cur++; + } + max = frac + MAX_FRAC; + while (((*cur >= '0') && (*cur <= '9')) && (frac < max)) { v = (*cur - '0'); fraction = fraction * 10 + v; frac = frac + 1; cur++; } - fraction /= my_pow10[frac]; + fraction /= pow(10.0, frac); ret = ret + fraction; while ((*cur >= '0') && (*cur <= '9')) cur++; @@ -10159,12 +10118,13 @@ xmlXPathStringEvalNumber(const xmlChar *str) { cur++; } while ((*cur >= '0') && (*cur <= '9')) { - exponent = exponent * 10 + (*cur - '0'); + if (exponent < 1000000) + exponent = exponent * 10 + (*cur - '0'); cur++; } } while (IS_BLANK_CH(*cur)) cur++; - if (*cur != 0) return(xmlXPathNAN); + if (*cur != 0) return(NAN); if (isneg) ret = -ret; if (is_exponent_negative) exponent = -exponent; ret *= pow(10.0, (double)exponent); @@ -10221,20 +10181,25 @@ xmlXPathCompNumber(xmlXPathParserContextPtr ctxt) } #endif if (CUR == '.') { - int v, frac = 0; + int v, frac = 0, max; double fraction = 0; NEXT; if (((CUR < '0') || (CUR > '9')) && (!ok)) { XP_ERROR(XPATH_NUMBER_ERROR); } - while ((CUR >= '0') && (CUR <= '9') && (frac < MAX_FRAC)) { + while (CUR == '0') { + frac = frac + 1; + NEXT; + } + max = frac + MAX_FRAC; + while ((CUR >= '0') && (CUR <= '9') && (frac < max)) { v = (CUR - '0'); fraction = fraction * 10 + v; frac = frac + 1; NEXT; } - fraction /= my_pow10[frac]; + fraction /= pow(10.0, frac); ret = ret + fraction; while ((CUR >= '0') && (CUR <= '9')) NEXT; @@ -10248,7 +10213,8 @@ xmlXPathCompNumber(xmlXPathParserContextPtr ctxt) NEXT; } while ((CUR >= '0') && (CUR <= '9')) { - exponent = exponent * 10 + (CUR - '0'); + if (exponent < 1000000) + exponent = exponent * 10 + (CUR - '0'); NEXT; } if (is_exponent_negative) @@ -10379,6 +10345,7 @@ xmlXPathCompVariableReference(xmlXPathParserContextPtr ctxt) { NEXT; name = xmlXPathParseQName(ctxt, &prefix); if (name == NULL) { + xmlFree(prefix); XP_ERROR(XPATH_VARIABLE_REF_ERROR); } ctxt->comp->last = -1; @@ -10452,6 +10419,8 @@ xmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) { #endif if (CUR != '(') { + xmlFree(name); + xmlFree(prefix); XP_ERROR(XPATH_EXPR_ERROR); } NEXT; @@ -10480,6 +10449,8 @@ xmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) { nbargs++; if (CUR == ')') break; if (CUR != ',') { + xmlFree(name); + xmlFree(prefix); XP_ERROR(XPATH_EXPR_ERROR); } NEXT; @@ -10691,13 +10662,18 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) { lc = 1; break; } else if ((NXT(len) == '(')) { - /* Note Type or Function */ + /* Node Type or Function */ if (xmlXPathIsNodeType(name)) { #ifdef DEBUG_STEP xmlGenericError(xmlGenericErrorContext, "PathExpr: Type search\n"); #endif lc = 1; +#ifdef LIBXML_XPTR_ENABLED + } else if (ctxt->xptr && + xmlStrEqual(name, BAD_CAST "range-to")) { + lc = 1; +#endif } else { #ifdef DEBUG_STEP xmlGenericError(xmlGenericErrorContext, @@ -10755,7 +10731,6 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) { PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF, NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL); - PUSH_UNARY_EXPR(XPATH_OP_RESET, ctxt->comp->last, 1, 0); xmlXPathCompRelativeLocationPath(ctxt); } else if (CUR == '/') { @@ -11686,6 +11661,7 @@ xmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr ctxt, xmlXPathContextPtr xpctxt = ctxt->context; xmlNodePtr contextNode, oldContextNode; xmlDocPtr oldContextDoc; + int oldcs, oldpp; int i, res, contextPos = 0, newContextSize; xmlXPathStepOpPtr exprOp; xmlXPathObjectPtr contextObj = NULL, exprRes = NULL; @@ -11722,6 +11698,8 @@ xmlXPathCompOpEvalPredicate(xmlXPathParserContextPtr ctxt, */ oldContextNode = xpctxt->node; oldContextDoc = xpctxt->doc; + oldcs = xpctxt->contextSize; + oldpp = xpctxt->proximityPosition; /* * Get the expression of this predicate. */ @@ -11808,8 +11786,8 @@ evaluation_exit: */ xpctxt->node = oldContextNode; xpctxt->doc = oldContextDoc; - xpctxt->contextSize = -1; - xpctxt->proximityPosition = -1; + xpctxt->contextSize = oldcs; + xpctxt->proximityPosition = oldpp; return(newContextSize); } return(contextSize); @@ -11852,6 +11830,7 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt, return (contextSize); } else { xmlDocPtr oldContextDoc; + int oldcs, oldpp; int i, pos = 0, newContextSize = 0, contextPos = 0, res; xmlXPathStepOpPtr exprOp; xmlXPathObjectPtr contextObj = NULL, exprRes = NULL; @@ -11872,6 +11851,8 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt, */ oldContextNode = xpctxt->node; oldContextDoc = xpctxt->doc; + oldcs = xpctxt->contextSize; + oldpp = xpctxt->proximityPosition; /* * Get the expression of this predicate. */ @@ -11910,11 +11891,11 @@ xmlXPathCompOpEvalPositionalPredicate(xmlXPathParserContextPtr ctxt, } } - frame = xmlXPathSetFrame(ctxt); valuePush(ctxt, contextObj); + frame = xmlXPathSetFrame(ctxt); res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1); - tmp = valuePop(ctxt); xmlXPathPopFrame(ctxt, frame); + tmp = valuePop(ctxt); if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) { while (tmp != contextObj) { @@ -12008,8 +11989,8 @@ evaluation_exit: */ xpctxt->node = oldContextNode; xpctxt->doc = oldContextDoc; - xpctxt->contextSize = -1; - xpctxt->proximityPosition = -1; + xpctxt->contextSize = oldcs; + xpctxt->proximityPosition = oldpp; return(newContextSize); } return(contextSize); @@ -12049,6 +12030,8 @@ xmlXPathIsPositionalPredicate(xmlXPathParserContextPtr ctxt, (exprOp->value4 != NULL) && (((xmlXPathObjectPtr) exprOp->value4)->type == XPATH_NUMBER)) { + double floatval = ((xmlXPathObjectPtr) exprOp->value4)->floatval; + /* * We have a "[n]" predicate here. * TODO: Unfortunately this simplistic test here is not @@ -12059,13 +12042,12 @@ xmlXPathIsPositionalPredicate(xmlXPathParserContextPtr ctxt, * like it "[position() < 5]", is also not detected. * Maybe we could rewrite the AST to ease the optimization. */ - *maxPos = (int) ((xmlXPathObjectPtr) exprOp->value4)->floatval; - if (((xmlXPathObjectPtr) exprOp->value4)->floatval == - (float) *maxPos) - { - return(1); - } + if ((floatval > INT_MIN) && (floatval < INT_MAX)) { + *maxPos = (int) floatval; + if (floatval == (double) *maxPos) + return(1); + } } return(0); } @@ -12379,11 +12361,6 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, STRANGE goto error; case NODE_TEST_TYPE: - /* - * TODO: Don't we need to use - * xmlXPathNodeSetAddNs() for namespace nodes here? - * Surprisingly, some c14n tests fail, if we do this. - */ if (type == NODE_TYPE_NODE) { switch (cur->type) { case XML_DOCUMENT_NODE: @@ -12397,13 +12374,21 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, case XML_COMMENT_NODE: case XML_CDATA_SECTION_NODE: case XML_TEXT_NODE: - case XML_NAMESPACE_DECL: XP_TEST_HIT break; + case XML_NAMESPACE_DECL: { + if (axis == AXIS_NAMESPACE) { + XP_TEST_HIT_NS + } else { + hasNsNodes = 1; + XP_TEST_HIT + } + break; + } default: break; } - } else if (cur->type == type) { + } else if (cur->type == (xmlElementType) type) { if (cur->type == XML_NAMESPACE_DECL) XP_TEST_HIT_NS else @@ -12691,6 +12676,14 @@ error: * Reset the context node. */ xpctxt->node = oldContextNode; + /* + * When traversing the namespace axis in "toBool" mode, it's + * possible that tmpNsList wasn't freed. + */ + if (xpctxt->tmpNsList != NULL) { + xmlFree(xpctxt->tmpNsList); + xpctxt->tmpNsList = NULL; + } #ifdef DEBUG_STEP xmlGenericError(xmlGenericErrorContext, @@ -12756,11 +12749,15 @@ xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt, xmlXPathCompOpEvalFirst(ctxt, &comp->steps[op->ch2], first); CHECK_ERROR0; - CHECK_TYPE0(XPATH_NODESET); - arg2 = valuePop(ctxt); - CHECK_TYPE0(XPATH_NODESET); + arg2 = valuePop(ctxt); arg1 = valuePop(ctxt); + if ((arg1 == NULL) || (arg1->type != XPATH_NODESET) || + (arg2 == NULL) || (arg2->type != XPATH_NODESET)) { + xmlXPathReleaseObject(ctxt->context, arg1); + xmlXPathReleaseObject(ctxt->context, arg2); + XP_ERROR0(XPATH_INVALID_TYPE); + } arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, arg2->nodesetval); @@ -12783,15 +12780,6 @@ xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt, valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context, ctxt->context->node)); return (total); - case XPATH_OP_RESET: - if (op->ch1 != -1) - total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); - CHECK_ERROR0; - if (op->ch2 != -1) - total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); - CHECK_ERROR0; - ctxt->context->node = NULL; - return (total); case XPATH_OP_COLLECT:{ if (op->ch1 == -1) return (total); @@ -12847,10 +12835,6 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op, int total = 0, cur; xmlXPathCompExprPtr comp; xmlXPathObjectPtr arg1, arg2; - xmlNodePtr bak; - xmlDocPtr bakd; - int pp; - int cs; CHECK_ERROR0; comp = ctxt->comp; @@ -12858,10 +12842,6 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op, case XPATH_OP_END: return (0); case XPATH_OP_UNION: - bakd = ctxt->context->doc; - bak = ctxt->context->node; - pp = ctxt->context->proximityPosition; - cs = ctxt->context->contextSize; total = xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch1], last); CHECK_ERROR0; @@ -12879,10 +12859,6 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op, nodesetval->nodeNr - 1]; } - ctxt->context->doc = bakd; - ctxt->context->node = bak; - ctxt->context->proximityPosition = pp; - ctxt->context->contextSize = cs; cur = xmlXPathCompOpEvalLast(ctxt, &comp->steps[op->ch2], last); CHECK_ERROR0; @@ -12891,11 +12867,15 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op, && (ctxt->value->nodesetval != NULL) && (ctxt->value->nodesetval->nodeNr >= 1)) { /* TODO: NOP ? */ } - CHECK_TYPE0(XPATH_NODESET); - arg2 = valuePop(ctxt); - CHECK_TYPE0(XPATH_NODESET); + arg2 = valuePop(ctxt); arg1 = valuePop(ctxt); + if ((arg1 == NULL) || (arg1->type != XPATH_NODESET) || + (arg2 == NULL) || (arg2->type != XPATH_NODESET)) { + xmlXPathReleaseObject(ctxt->context, arg1); + xmlXPathReleaseObject(ctxt->context, arg2); + XP_ERROR0(XPATH_INVALID_TYPE); + } arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval, arg2->nodesetval); @@ -12918,15 +12898,6 @@ xmlXPathCompOpEvalLast(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op, valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context, ctxt->context->node)); return (total); - case XPATH_OP_RESET: - if (op->ch1 != -1) - total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); - CHECK_ERROR0; - if (op->ch2 != -1) - total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); - CHECK_ERROR0; - ctxt->context->node = NULL; - return (total); case XPATH_OP_COLLECT:{ if (op->ch1 == -1) return (0); @@ -12971,6 +12942,7 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, xmlNodeSetPtr oldset; xmlNodePtr oldnode; xmlDocPtr oldDoc; + int oldcs, oldpp; int i; CHECK_ERROR0; @@ -13006,13 +12978,7 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, (ctxt->value->nodesetval != NULL) && (ctxt->value->nodesetval->nodeTab != NULL) && (ctxt->value->nodesetval->nodeNr > 1)) { - ctxt->value->nodesetval->nodeTab[0] = - ctxt->value->nodesetval->nodeTab[ctxt-> - value-> - nodesetval-> - nodeNr - - 1]; - ctxt->value->nodesetval->nodeNr = 1; + xmlXPathNodeSetKeepLast(ctxt->value->nodesetval); *first = *(ctxt->value->nodesetval->nodeTab); } return (total); @@ -13028,7 +12994,6 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, return (total); #ifdef LIBXML_XPTR_ENABLED - oldnode = ctxt->context->node; /* * Hum are we filtering the result of an XPointer expression */ @@ -13043,23 +13008,17 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, * up a new locset. */ CHECK_TYPE0(XPATH_LOCATIONSET); + + if ((ctxt->value->user == NULL) || + (((xmlLocationSetPtr) ctxt->value->user)->locNr == 0)) + return (total); + obj = valuePop(ctxt); oldlocset = obj->user; - ctxt->context->node = NULL; + oldnode = ctxt->context->node; + oldcs = ctxt->context->contextSize; + oldpp = ctxt->context->proximityPosition; - if ((oldlocset == NULL) || (oldlocset->locNr == 0)) { - ctxt->context->contextSize = 0; - ctxt->context->proximityPosition = 0; - if (op->ch2 != -1) - total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); - res = valuePop(ctxt); - if (res != NULL) { - xmlXPathReleaseObject(ctxt->context, res); - } - valuePush(ctxt, obj); - CHECK_ERROR0; - return (total); - } newlocset = xmlXPtrLocationSetCreate(NULL); for (i = 0; i < oldlocset->locNr; i++) { @@ -13083,8 +13042,8 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, if (op->ch2 != -1) total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); if (ctxt->error != XPATH_EXPRESSION_OK) { - xmlXPathFreeObject(obj); - return(0); + xmlXPtrFreeLocationSet(newlocset); + goto xptr_error; } /* * The result of the evaluation need to be tested to @@ -13112,7 +13071,6 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, /* OLD: xmlXPathFreeObject(res); */ } else tmp = NULL; - ctxt->context->node = NULL; /* * Only put the first node in the result, then leave. */ @@ -13127,12 +13085,12 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, /* * The result is used as the new evaluation locset. */ - xmlXPathReleaseObject(ctxt->context, obj); - ctxt->context->node = NULL; - ctxt->context->contextSize = -1; - ctxt->context->proximityPosition = -1; valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset)); +xptr_error: + xmlXPathReleaseObject(ctxt->context, obj); ctxt->context->node = oldnode; + ctxt->context->contextSize = oldcs; + ctxt->context->proximityPosition = oldpp; return (total); } #endif /* LIBXML_XPTR_ENABLED */ @@ -13143,32 +13101,19 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, * up a new set. */ CHECK_TYPE0(XPATH_NODESET); - obj = valuePop(ctxt); - oldset = obj->nodesetval; - oldnode = ctxt->context->node; - oldDoc = ctxt->context->doc; - ctxt->context->node = NULL; - - if ((oldset == NULL) || (oldset->nodeNr == 0)) { - ctxt->context->contextSize = 0; - ctxt->context->proximityPosition = 0; - /* QUESTION TODO: Why was this code commented out? - if (op->ch2 != -1) - total += - xmlXPathCompOpEval(ctxt, - &comp->steps[op->ch2]); - CHECK_ERROR0; - res = valuePop(ctxt); - if (res != NULL) - xmlXPathFreeObject(res); - */ - valuePush(ctxt, obj); - ctxt->context->node = oldnode; - CHECK_ERROR0; - } else { + if ((ctxt->value->nodesetval != NULL) && + (ctxt->value->nodesetval->nodeNr != 0)) { xmlNodeSetPtr newset; xmlXPathObjectPtr tmp = NULL; + + obj = valuePop(ctxt); + oldset = obj->nodesetval; + oldnode = ctxt->context->node; + oldDoc = ctxt->context->doc; + oldcs = ctxt->context->contextSize; + oldpp = ctxt->context->proximityPosition; + /* * Initialize the new set. * Also set the xpath document in case things like @@ -13202,8 +13147,7 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); if (ctxt->error != XPATH_EXPRESSION_OK) { xmlXPathFreeNodeSet(newset); - xmlXPathFreeObject(obj); - return(0); + goto error; } /* * The result of the evaluation needs to be tested to @@ -13230,7 +13174,6 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, xmlXPathNodeSetClear(tmp->nodesetval, 1); } else tmp = NULL; - ctxt->context->node = NULL; /* * Only put the first node in the result, then leave. */ @@ -13245,15 +13188,14 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, /* * The result is used as the new evaluation set. */ + valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, newset)); +error: xmlXPathReleaseObject(ctxt->context, obj); - ctxt->context->node = NULL; - ctxt->context->contextSize = -1; - ctxt->context->proximityPosition = -1; - /* may want to move this past the '}' later */ + ctxt->context->node = oldnode; ctxt->context->doc = oldDoc; - valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, newset)); + ctxt->context->contextSize = oldcs; + ctxt->context->proximityPosition = oldpp; } - ctxt->context->node = oldnode; return(total); } #endif /* XP_OPTIMIZED_FILTER_FIRST */ @@ -13273,10 +13215,6 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) int equal, ret; xmlXPathCompExprPtr comp; xmlXPathObjectPtr arg1, arg2; - xmlNodePtr bak; - xmlDocPtr bakd; - int pp; - int cs; CHECK_ERROR0; comp = ctxt->comp; @@ -13284,68 +13222,42 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) case XPATH_OP_END: return (0); case XPATH_OP_AND: - bakd = ctxt->context->doc; - bak = ctxt->context->node; - pp = ctxt->context->proximityPosition; - cs = ctxt->context->contextSize; total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); CHECK_ERROR0; xmlXPathBooleanFunction(ctxt, 1); if ((ctxt->value == NULL) || (ctxt->value->boolval == 0)) return (total); arg2 = valuePop(ctxt); - ctxt->context->doc = bakd; - ctxt->context->node = bak; - ctxt->context->proximityPosition = pp; - ctxt->context->contextSize = cs; total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); if (ctxt->error) { xmlXPathFreeObject(arg2); return(0); } xmlXPathBooleanFunction(ctxt, 1); - arg1 = valuePop(ctxt); - arg1->boolval &= arg2->boolval; - valuePush(ctxt, arg1); + if (ctxt->value != NULL) + ctxt->value->boolval &= arg2->boolval; xmlXPathReleaseObject(ctxt->context, arg2); return (total); case XPATH_OP_OR: - bakd = ctxt->context->doc; - bak = ctxt->context->node; - pp = ctxt->context->proximityPosition; - cs = ctxt->context->contextSize; total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); CHECK_ERROR0; xmlXPathBooleanFunction(ctxt, 1); if ((ctxt->value == NULL) || (ctxt->value->boolval == 1)) return (total); arg2 = valuePop(ctxt); - ctxt->context->doc = bakd; - ctxt->context->node = bak; - ctxt->context->proximityPosition = pp; - ctxt->context->contextSize = cs; total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); if (ctxt->error) { xmlXPathFreeObject(arg2); return(0); } xmlXPathBooleanFunction(ctxt, 1); - arg1 = valuePop(ctxt); - arg1->boolval |= arg2->boolval; - valuePush(ctxt, arg1); + if (ctxt->value != NULL) + ctxt->value->boolval |= arg2->boolval; xmlXPathReleaseObject(ctxt->context, arg2); return (total); case XPATH_OP_EQUAL: - bakd = ctxt->context->doc; - bak = ctxt->context->node; - pp = ctxt->context->proximityPosition; - cs = ctxt->context->contextSize; total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); CHECK_ERROR0; - ctxt->context->doc = bakd; - ctxt->context->node = bak; - ctxt->context->proximityPosition = pp; - ctxt->context->contextSize = cs; total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); CHECK_ERROR0; if (op->value) @@ -13355,33 +13267,17 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, equal)); return (total); case XPATH_OP_CMP: - bakd = ctxt->context->doc; - bak = ctxt->context->node; - pp = ctxt->context->proximityPosition; - cs = ctxt->context->contextSize; total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); CHECK_ERROR0; - ctxt->context->doc = bakd; - ctxt->context->node = bak; - ctxt->context->proximityPosition = pp; - ctxt->context->contextSize = cs; total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); CHECK_ERROR0; ret = xmlXPathCompareValues(ctxt, op->value, op->value2); valuePush(ctxt, xmlXPathCacheNewBoolean(ctxt->context, ret)); return (total); case XPATH_OP_PLUS: - bakd = ctxt->context->doc; - bak = ctxt->context->node; - pp = ctxt->context->proximityPosition; - cs = ctxt->context->contextSize; total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); CHECK_ERROR0; if (op->ch2 != -1) { - ctxt->context->doc = bakd; - ctxt->context->node = bak; - ctxt->context->proximityPosition = pp; - ctxt->context->contextSize = cs; total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); } CHECK_ERROR0; @@ -13397,16 +13293,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) } return (total); case XPATH_OP_MULT: - bakd = ctxt->context->doc; - bak = ctxt->context->node; - pp = ctxt->context->proximityPosition; - cs = ctxt->context->contextSize; total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); CHECK_ERROR0; - ctxt->context->doc = bakd; - ctxt->context->node = bak; - ctxt->context->proximityPosition = pp; - ctxt->context->contextSize = cs; total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); CHECK_ERROR0; if (op->value == 0) @@ -13417,23 +13305,19 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) xmlXPathModValues(ctxt); return (total); case XPATH_OP_UNION: - bakd = ctxt->context->doc; - bak = ctxt->context->node; - pp = ctxt->context->proximityPosition; - cs = ctxt->context->contextSize; total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); CHECK_ERROR0; - ctxt->context->doc = bakd; - ctxt->context->node = bak; - ctxt->context->proximityPosition = pp; - ctxt->context->contextSize = cs; total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); CHECK_ERROR0; - CHECK_TYPE0(XPATH_NODESET); - arg2 = valuePop(ctxt); - CHECK_TYPE0(XPATH_NODESET); + arg2 = valuePop(ctxt); arg1 = valuePop(ctxt); + if ((arg1 == NULL) || (arg1->type != XPATH_NODESET) || + (arg2 == NULL) || (arg2->type != XPATH_NODESET)) { + xmlXPathReleaseObject(ctxt->context, arg1); + xmlXPathReleaseObject(ctxt->context, arg2); + XP_ERROR0(XPATH_INVALID_TYPE); + } if ((arg1->nodesetval == NULL) || ((arg2->nodesetval != NULL) && @@ -13459,15 +13343,6 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) valuePush(ctxt, xmlXPathCacheNewNodeSet(ctxt->context, ctxt->context->node)); return (total); - case XPATH_OP_RESET: - if (op->ch1 != -1) - total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); - CHECK_ERROR0; - if (op->ch2 != -1) - total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); - CHECK_ERROR0; - ctxt->context->node = NULL; - return (total); case XPATH_OP_COLLECT:{ if (op->ch1 == -1) return (total); @@ -13491,10 +13366,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); if (op->value5 == NULL) { val = xmlXPathVariableLookup(ctxt->context, op->value4); - if (val == NULL) { - ctxt->error = XPATH_UNDEF_VARIABLE_ERROR; - return(0); - } + if (val == NULL) + XP_ERROR0(XPATH_UNDEF_VARIABLE_ERROR); valuePush(ctxt, val); } else { const xmlChar *URI; @@ -13509,10 +13382,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) } val = xmlXPathVariableLookupNS(ctxt->context, op->value4, URI); - if (val == NULL) { - ctxt->error = XPATH_UNDEF_VARIABLE_ERROR; - return(0); - } + if (val == NULL) + XP_ERROR0(XPATH_UNDEF_VARIABLE_ERROR); valuePush(ctxt, val); } return (total); @@ -13549,7 +13420,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) } } if (op->cache != NULL) - XML_CAST_FPTR(func) = op->cache; + func = op->cache; else { const xmlChar *URI = NULL; @@ -13576,7 +13447,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) (char *)op->value4); XP_ERROR0(XPATH_UNKNOWN_FUNC_ERROR); } - op->cache = XML_CAST_FPTR(func); + op->cache = func; op->cacheURI = (void *) URI; } oldFunc = ctxt->context->function; @@ -13590,24 +13461,12 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) return (total); } case XPATH_OP_ARG: - bakd = ctxt->context->doc; - bak = ctxt->context->node; - pp = ctxt->context->proximityPosition; - cs = ctxt->context->contextSize; if (op->ch1 != -1) { total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); - ctxt->context->contextSize = cs; - ctxt->context->proximityPosition = pp; - ctxt->context->node = bak; - ctxt->context->doc = bakd; CHECK_ERROR0; } if (op->ch2 != -1) { total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); - ctxt->context->contextSize = cs; - ctxt->context->proximityPosition = pp; - ctxt->context->node = bak; - ctxt->context->doc = bakd; CHECK_ERROR0; } return (total); @@ -13619,6 +13478,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) xmlNodeSetPtr oldset; xmlNodePtr oldnode; xmlDocPtr oldDoc; + int oldcs, oldpp; int i; /* @@ -13661,7 +13521,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) (ctxt->value->type == XPATH_NODESET) && (ctxt->value->nodesetval != NULL) && (ctxt->value->nodesetval->nodeNr > 1)) - ctxt->value->nodesetval->nodeNr = 1; + xmlXPathNodeSetClearFromPos(ctxt->value->nodesetval, + 1, 1); return (total); } } @@ -13695,15 +13556,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) (ctxt->value->type == XPATH_NODESET) && (ctxt->value->nodesetval != NULL) && (ctxt->value->nodesetval->nodeTab != NULL) && - (ctxt->value->nodesetval->nodeNr > 1)) { - ctxt->value->nodesetval->nodeTab[0] = - ctxt->value->nodesetval->nodeTab[ctxt-> - value-> - nodesetval-> - nodeNr - - 1]; - ctxt->value->nodesetval->nodeNr = 1; - } + (ctxt->value->nodesetval->nodeNr > 1)) + xmlXPathNodeSetKeepLast(ctxt->value->nodesetval); return (total); } } @@ -13727,8 +13581,6 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) if (ctxt->value == NULL) return (total); - oldnode = ctxt->context->node; - #ifdef LIBXML_XPTR_ENABLED /* * Hum are we filtering the result of an XPointer expression @@ -13743,25 +13595,17 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) * up a new locset. */ CHECK_TYPE0(XPATH_LOCATIONSET); + + if ((ctxt->value->user == NULL) || + (((xmlLocationSetPtr) ctxt->value->user)->locNr == 0)) + return (total); + obj = valuePop(ctxt); oldlocset = obj->user; - ctxt->context->node = NULL; + oldnode = ctxt->context->node; + oldcs = ctxt->context->contextSize; + oldpp = ctxt->context->proximityPosition; - if ((oldlocset == NULL) || (oldlocset->locNr == 0)) { - ctxt->context->contextSize = 0; - ctxt->context->proximityPosition = 0; - if (op->ch2 != -1) - total += - xmlXPathCompOpEval(ctxt, - &comp->steps[op->ch2]); - res = valuePop(ctxt); - if (res != NULL) { - xmlXPathReleaseObject(ctxt->context, res); - } - valuePush(ctxt, obj); - CHECK_ERROR0; - return (total); - } newlocset = xmlXPtrLocationSetCreate(NULL); for (i = 0; i < oldlocset->locNr; i++) { @@ -13781,8 +13625,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); if (ctxt->error != XPATH_EXPRESSION_OK) { - xmlXPathFreeObject(obj); - return(0); + xmlXPtrFreeLocationSet(newlocset); + goto filter_xptr_error; } /* @@ -13806,19 +13650,17 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) res = valuePop(ctxt); xmlXPathReleaseObject(ctxt->context, res); } - - ctxt->context->node = NULL; } /* * The result is used as the new evaluation locset. */ - xmlXPathReleaseObject(ctxt->context, obj); - ctxt->context->node = NULL; - ctxt->context->contextSize = -1; - ctxt->context->proximityPosition = -1; valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset)); +filter_xptr_error: + xmlXPathReleaseObject(ctxt->context, obj); ctxt->context->node = oldnode; + ctxt->context->contextSize = oldcs; + ctxt->context->proximityPosition = oldpp; return (total); } #endif /* LIBXML_XPTR_ENABLED */ @@ -13829,30 +13671,15 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) * up a new set. */ CHECK_TYPE0(XPATH_NODESET); - obj = valuePop(ctxt); - oldset = obj->nodesetval; - - oldnode = ctxt->context->node; - oldDoc = ctxt->context->doc; - ctxt->context->node = NULL; - if ((oldset == NULL) || (oldset->nodeNr == 0)) { - ctxt->context->contextSize = 0; - ctxt->context->proximityPosition = 0; -/* - if (op->ch2 != -1) - total += - xmlXPathCompOpEval(ctxt, - &comp->steps[op->ch2]); - CHECK_ERROR0; - res = valuePop(ctxt); - if (res != NULL) - xmlXPathFreeObject(res); -*/ - valuePush(ctxt, obj); - ctxt->context->node = oldnode; - CHECK_ERROR0; - } else { + if ((ctxt->value->nodesetval != NULL) && + (ctxt->value->nodesetval->nodeNr != 0)) { + obj = valuePop(ctxt); + oldset = obj->nodesetval; + oldnode = ctxt->context->node; + oldDoc = ctxt->context->doc; + oldcs = ctxt->context->contextSize; + oldpp = ctxt->context->proximityPosition; tmp = NULL; /* * Initialize the new set. @@ -13918,8 +13745,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) &comp->steps[op->ch2]); if (ctxt->error != XPATH_EXPRESSION_OK) { xmlXPathFreeNodeSet(newset); - xmlXPathFreeObject(obj); - return(0); + goto filter_error; } /* @@ -13953,23 +13779,21 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) */ } else tmp = NULL; - ctxt->context->node = NULL; } if (tmp != NULL) xmlXPathReleaseObject(ctxt->context, tmp); /* * The result is used as the new evaluation set. */ - xmlXPathReleaseObject(ctxt->context, obj); - ctxt->context->node = NULL; - ctxt->context->contextSize = -1; - ctxt->context->proximityPosition = -1; - /* may want to move this past the '}' later */ - ctxt->context->doc = oldDoc; valuePush(ctxt, xmlXPathCacheWrapNodeSet(ctxt->context, newset)); +filter_error: + xmlXPathReleaseObject(ctxt->context, obj); + ctxt->context->node = oldnode; + ctxt->context->doc = oldDoc; + ctxt->context->contextSize = oldcs; + ctxt->context->proximityPosition = oldpp; } - ctxt->context->node = oldnode; return (total); } case XPATH_OP_SORT: @@ -13992,11 +13816,19 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) xmlLocationSetPtr newlocset = NULL; xmlLocationSetPtr oldlocset; xmlNodeSetPtr oldset; + xmlNodePtr oldnode = ctxt->context->node; + int oldcs = ctxt->context->contextSize; + int oldpp = ctxt->context->proximityPosition; int i, j; - if (op->ch1 != -1) + if (op->ch1 != -1) { total += xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]); + CHECK_ERROR0; + } + if (ctxt->value == NULL) { + XP_ERROR0(XPATH_INVALID_OPERAND); + } if (op->ch2 == -1) return (total); @@ -14007,22 +13839,14 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) * up a new locset. */ CHECK_TYPE0(XPATH_LOCATIONSET); + + if ((ctxt->value->user == NULL) || + (((xmlLocationSetPtr) ctxt->value->user)->locNr == 0)) + return (total); + obj = valuePop(ctxt); oldlocset = obj->user; - if ((oldlocset == NULL) || (oldlocset->locNr == 0)) { - ctxt->context->node = NULL; - ctxt->context->contextSize = 0; - ctxt->context->proximityPosition = 0; - total += xmlXPathCompOpEval(ctxt,&comp->steps[op->ch2]); - res = valuePop(ctxt); - if (res != NULL) { - xmlXPathReleaseObject(ctxt->context, res); - } - valuePush(ctxt, obj); - CHECK_ERROR0; - return (total); - } newlocset = xmlXPtrLocationSetCreate(NULL); for (i = 0; i < oldlocset->locNr; i++) { @@ -14042,8 +13866,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); if (ctxt->error != XPATH_EXPRESSION_OK) { - xmlXPathFreeObject(obj); - return(0); + xmlXPtrFreeLocationSet(newlocset); + goto rangeto_error; } res = valuePop(ctxt); @@ -14078,14 +13902,11 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) res = valuePop(ctxt); xmlXPathReleaseObject(ctxt->context, res); } - - ctxt->context->node = NULL; } } else { /* Not a location set */ CHECK_TYPE0(XPATH_NODESET); obj = valuePop(ctxt); oldset = obj->nodesetval; - ctxt->context->node = NULL; newlocset = xmlXPtrLocationSetCreate(NULL); @@ -14108,8 +13929,8 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]); if (ctxt->error != XPATH_EXPRESSION_OK) { - xmlXPathFreeObject(obj); - return(0); + xmlXPtrFreeLocationSet(newlocset); + goto rangeto_error; } res = valuePop(ctxt); @@ -14130,8 +13951,6 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) res = valuePop(ctxt); xmlXPathReleaseObject(ctxt->context, res); } - - ctxt->context->node = NULL; } } } @@ -14139,11 +13958,12 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) /* * The result is used as the new evaluation set. */ - xmlXPathReleaseObject(ctxt->context, obj); - ctxt->context->node = NULL; - ctxt->context->contextSize = -1; - ctxt->context->proximityPosition = -1; valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset)); +rangeto_error: + xmlXPathReleaseObject(ctxt->context, obj); + ctxt->context->node = oldnode; + ctxt->context->contextSize = oldcs; + ctxt->context->proximityPosition = oldpp; return (total); } #endif /* LIBXML_XPTR_ENABLED */ @@ -14784,6 +14604,10 @@ xmlXPathOptimizeExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op) } } + /* OP_VALUE has invalid ch1. */ + if (op->op == XPATH_OP_VALUE) + return; + /* Recurse */ if (op->ch1 != -1) xmlXPathOptimizeExpression(comp, &comp->steps[op->ch1]); @@ -14883,10 +14707,11 @@ xmlXPathCompile(const xmlChar *str) { static int xmlXPathCompiledEvalInternal(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt, - xmlXPathObjectPtr *resObj, + xmlXPathObjectPtr *resObjPtr, int toBool) { xmlXPathParserContextPtr pctxt; + xmlXPathObjectPtr resObj; #ifndef LIBXML_THREAD_ENABLED static int reentance = 0; #endif @@ -14914,43 +14739,26 @@ xmlXPathCompiledEvalInternal(xmlXPathCompExprPtr comp, pctxt = xmlXPathCompParserContext(comp, ctxt); res = xmlXPathRunEval(pctxt, toBool); - if (resObj) { - if (pctxt->value == NULL) { - xmlGenericError(xmlGenericErrorContext, - "xmlXPathCompiledEval: evaluation failed\n"); - *resObj = NULL; - } else { - *resObj = valuePop(pctxt); - } + if (pctxt->error != XPATH_EXPRESSION_OK) { + resObj = NULL; + } else { + resObj = valuePop(pctxt); + if (resObj == NULL) { + if (!toBool) + xmlGenericError(xmlGenericErrorContext, + "xmlXPathCompiledEval: No result on the stack.\n"); + } else if (pctxt->valueNr > 0) { + xmlGenericError(xmlGenericErrorContext, + "xmlXPathCompiledEval: %d object(s) left on the stack.\n", + pctxt->valueNr); + } } - /* - * Pop all remaining objects from the stack. - */ - if (pctxt->valueNr > 0) { - xmlXPathObjectPtr tmp; - int stack = 0; - - do { - tmp = valuePop(pctxt); - if (tmp != NULL) { - stack++; - xmlXPathReleaseObject(ctxt, tmp); - } - } while (tmp != NULL); - if ((stack != 0) && - ((toBool) || ((resObj) && (*resObj)))) - { - xmlGenericError(xmlGenericErrorContext, - "xmlXPathCompiledEval: %d objects left on the stack.\n", - stack); - } - } + if (resObjPtr) + *resObjPtr = resObj; + else + xmlXPathReleaseObject(ctxt, resObj); - if ((pctxt->error != XPATH_EXPRESSION_OK) && (resObj) && (*resObj)) { - xmlXPathFreeObject(*resObj); - *resObj = NULL; - } pctxt->comp = NULL; xmlXPathFreeParserContext(pctxt); #ifndef LIBXML_THREAD_ENABLED @@ -15018,22 +14826,21 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { if (ctxt->comp != NULL) xmlXPathFreeCompExpr(ctxt->comp); ctxt->comp = comp; - if (ctxt->cur != NULL) - while (*ctxt->cur != 0) ctxt->cur++; } else #endif { xmlXPathCompileExpr(ctxt, 1); - if ((ctxt->error == XPATH_EXPRESSION_OK) && - (ctxt->comp != NULL) && - (ctxt->comp->nbStep > 1) && - (ctxt->comp->last >= 0)) - { + CHECK_ERROR; + + /* Check for trailing characters. */ + if (*ctxt->cur != 0) + XP_ERROR(XPATH_EXPR_ERROR); + + if ((ctxt->comp->nbStep > 1) && (ctxt->comp->last >= 0)) xmlXPathOptimizeExpression(ctxt->comp, &ctxt->comp->steps[ctxt->comp->last]); - } } - CHECK_ERROR; + xmlXPathRunEval(ctxt, 0); } @@ -15050,8 +14857,7 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) { xmlXPathObjectPtr xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) { xmlXPathParserContextPtr ctxt; - xmlXPathObjectPtr res, tmp, init = NULL; - int stack = 0; + xmlXPathObjectPtr res; CHECK_CTXT(ctx) @@ -15062,37 +14868,18 @@ xmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) { return NULL; xmlXPathEvalExpr(ctxt); - if (ctxt->value == NULL) { - xmlGenericError(xmlGenericErrorContext, - "xmlXPathEval: evaluation failed\n"); - res = NULL; - } else if ((*ctxt->cur != 0) && (ctxt->comp != NULL) -#ifdef XPATH_STREAMING - && (ctxt->comp->stream == NULL) -#endif - ) { - xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); + if (ctxt->error != XPATH_EXPRESSION_OK) { res = NULL; } else { res = valuePop(ctxt); - } - - do { - tmp = valuePop(ctxt); - if (tmp != NULL) { - if (tmp != init) - stack++; - xmlXPathReleaseObject(ctx, tmp); + if (res == NULL) { + xmlGenericError(xmlGenericErrorContext, + "xmlXPathCompiledEval: No result on the stack.\n"); + } else if (ctxt->valueNr > 0) { + xmlGenericError(xmlGenericErrorContext, + "xmlXPathCompiledEval: %d object(s) left on the stack.\n", + ctxt->valueNr); } - } while (tmp != NULL); - if ((stack != 0) && (res != NULL)) { - xmlGenericError(xmlGenericErrorContext, - "xmlXPathEval: %d object left on the stack\n", - stack); - } - if (ctxt->error != XPATH_EXPRESSION_OK) { - xmlXPathFreeObject(res); - res = NULL; } xmlXPathFreeParserContext(ctxt); @@ -15147,46 +14934,14 @@ xmlXPathNodeEval(xmlNodePtr node, const xmlChar *str, xmlXPathContextPtr ctx) { * @str: the XPath expression * @ctxt: the XPath context * - * Evaluate the XPath expression in the given context. + * Alias for xmlXPathEval(). * * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. * the caller has to free the object. */ xmlXPathObjectPtr xmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt) { - xmlXPathParserContextPtr pctxt; - xmlXPathObjectPtr res, tmp; - int stack = 0; - - CHECK_CTXT(ctxt) - - xmlXPathInit(); - - pctxt = xmlXPathNewParserContext(str, ctxt); - if (pctxt == NULL) - return NULL; - xmlXPathEvalExpr(pctxt); - - if ((*pctxt->cur != 0) || (pctxt->error != XPATH_EXPRESSION_OK)) { - xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); - res = NULL; - } else { - res = valuePop(pctxt); - } - do { - tmp = valuePop(pctxt); - if (tmp != NULL) { - xmlXPathReleaseObject(ctxt, tmp); - stack++; - } - } while (tmp != NULL); - if ((stack != 0) && (res != NULL)) { - xmlGenericError(xmlGenericErrorContext, - "xmlXPathEvalExpression: %d object left on the stack\n", - stack); - } - xmlXPathFreeParserContext(pctxt); - return(res); + return(xmlXPathEval(str, ctxt)); } /************************************************************************ diff --git a/gnulib-local/lib/libxml/xpathInternals.in.h b/gnulib-local/lib/libxml/xpathInternals.in.h index 70c9db96f..76a6b4815 100644 --- a/gnulib-local/lib/libxml/xpathInternals.in.h +++ b/gnulib-local/lib/libxml/xpathInternals.in.h @@ -229,7 +229,7 @@ XMLPUBFUN void * XMLCALL * Empties a node-set. */ #define xmlXPathEmptyNodeSet(ns) \ - { while ((ns)->nodeNr > 0) (ns)->nodeTab[(ns)->nodeNr--] = NULL; } + { while ((ns)->nodeNr > 0) (ns)->nodeTab[--(ns)->nodeNr] = NULL; } /** * CHECK_ERROR: diff --git a/gnulib-local/lib/libxml/xpointer.c b/gnulib-local/lib/libxml/xpointer.c index 4b4ac2ee5..6a41f0797 100644 --- a/gnulib-local/lib/libxml/xpointer.c +++ b/gnulib-local/lib/libxml/xpointer.c @@ -14,6 +14,11 @@ * daniel@veillard.com */ +/* To avoid EBCDIC trouble when parsing on zOS */ +#if defined(__MVS__) +#pragma convert("ISO8859-1") +#endif + #define IN_LIBXML #include "libxml.h" @@ -85,7 +90,7 @@ xmlXPtrErrMemory(const char *extra) * * Handle a redefinition of attribute error */ -static void +static void LIBXML_ATTR_FORMAT(3,0) xmlXPtrErr(xmlXPathParserContextPtr ctxt, int error, const char * msg, const xmlChar *extra) { @@ -99,6 +104,10 @@ xmlXPtrErr(xmlXPathParserContextPtr ctxt, int error, msg, extra); return; } + + /* cleanup current last error */ + xmlResetError(&ctxt->context->lastError); + ctxt->context->lastError.domain = XML_FROM_XPOINTER; ctxt->context->lastError.code = error; ctxt->context->lastError.level = XML_ERR_ERROR; @@ -319,6 +328,45 @@ xmlXPtrRangesEqual(xmlXPathObjectPtr range1, xmlXPathObjectPtr range2) { return(1); } +/** + * xmlXPtrNewRangeInternal: + * @start: the starting node + * @startindex: the start index + * @end: the ending point + * @endindex: the ending index + * + * Internal function to create a new xmlXPathObjectPtr of type range + * + * Returns the newly created object. + */ +static xmlXPathObjectPtr +xmlXPtrNewRangeInternal(xmlNodePtr start, int startindex, + xmlNodePtr end, int endindex) { + xmlXPathObjectPtr ret; + + /* + * Namespace nodes must be copied (see xmlXPathNodeSetDupNs). + * Disallow them for now. + */ + if ((start != NULL) && (start->type == XML_NAMESPACE_DECL)) + return(NULL); + if ((end != NULL) && (end->type == XML_NAMESPACE_DECL)) + return(NULL); + + ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); + if (ret == NULL) { + xmlXPtrErrMemory("allocating range"); + return(NULL); + } + memset(ret, 0, sizeof(xmlXPathObject)); + ret->type = XPATH_RANGE; + ret->user = start; + ret->index = startindex; + ret->user2 = end; + ret->index2 = endindex; + return(ret); +} + /** * xmlXPtrNewRange: * @start: the starting node @@ -344,17 +392,7 @@ xmlXPtrNewRange(xmlNodePtr start, int startindex, if (endindex < 0) return(NULL); - ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); - if (ret == NULL) { - xmlXPtrErrMemory("allocating range"); - return(NULL); - } - memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); - ret->type = XPATH_RANGE; - ret->user = start; - ret->index = startindex; - ret->user2 = end; - ret->index2 = endindex; + ret = xmlXPtrNewRangeInternal(start, startindex, end, endindex); xmlXPtrRangeCheckOrder(ret); return(ret); } @@ -381,17 +419,8 @@ xmlXPtrNewRangePoints(xmlXPathObjectPtr start, xmlXPathObjectPtr end) { if (end->type != XPATH_POINT) return(NULL); - ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); - if (ret == NULL) { - xmlXPtrErrMemory("allocating range"); - return(NULL); - } - memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); - ret->type = XPATH_RANGE; - ret->user = start->user; - ret->index = start->index; - ret->user2 = end->user; - ret->index2 = end->index; + ret = xmlXPtrNewRangeInternal(start->user, start->index, end->user, + end->index); xmlXPtrRangeCheckOrder(ret); return(ret); } @@ -416,17 +445,7 @@ xmlXPtrNewRangePointNode(xmlXPathObjectPtr start, xmlNodePtr end) { if (start->type != XPATH_POINT) return(NULL); - ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); - if (ret == NULL) { - xmlXPtrErrMemory("allocating range"); - return(NULL); - } - memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); - ret->type = XPATH_RANGE; - ret->user = start->user; - ret->index = start->index; - ret->user2 = end; - ret->index2 = -1; + ret = xmlXPtrNewRangeInternal(start->user, start->index, end, -1); xmlXPtrRangeCheckOrder(ret); return(ret); } @@ -448,22 +467,10 @@ xmlXPtrNewRangeNodePoint(xmlNodePtr start, xmlXPathObjectPtr end) { return(NULL); if (end == NULL) return(NULL); - if (start->type != XPATH_POINT) - return(NULL); if (end->type != XPATH_POINT) return(NULL); - ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); - if (ret == NULL) { - xmlXPtrErrMemory("allocating range"); - return(NULL); - } - memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); - ret->type = XPATH_RANGE; - ret->user = start; - ret->index = -1; - ret->user2 = end->user; - ret->index2 = end->index; + ret = xmlXPtrNewRangeInternal(start, -1, end->user, end->index); xmlXPtrRangeCheckOrder(ret); return(ret); } @@ -486,17 +493,7 @@ xmlXPtrNewRangeNodes(xmlNodePtr start, xmlNodePtr end) { if (end == NULL) return(NULL); - ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); - if (ret == NULL) { - xmlXPtrErrMemory("allocating range"); - return(NULL); - } - memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); - ret->type = XPATH_RANGE; - ret->user = start; - ret->index = -1; - ret->user2 = end; - ret->index2 = -1; + ret = xmlXPtrNewRangeInternal(start, -1, end, -1); xmlXPtrRangeCheckOrder(ret); return(ret); } @@ -516,17 +513,7 @@ xmlXPtrNewCollapsedRange(xmlNodePtr start) { if (start == NULL) return(NULL); - ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); - if (ret == NULL) { - xmlXPtrErrMemory("allocating range"); - return(NULL); - } - memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); - ret->type = XPATH_RANGE; - ret->user = start; - ret->index = -1; - ret->user2 = NULL; - ret->index2 = -1; + ret = xmlXPtrNewRangeInternal(start, -1, NULL, -1); return(ret); } @@ -541,6 +528,8 @@ xmlXPtrNewCollapsedRange(xmlNodePtr start) { */ xmlXPathObjectPtr xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) { + xmlNodePtr endNode; + int endIndex; xmlXPathObjectPtr ret; if (start == NULL) @@ -549,47 +538,28 @@ xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) { return(NULL); switch (end->type) { case XPATH_POINT: + endNode = end->user; + endIndex = end->index; + break; case XPATH_RANGE: + endNode = end->user2; + endIndex = end->index2; break; case XPATH_NODESET: /* * Empty set ... */ - if (end->nodesetval->nodeNr <= 0) + if ((end->nodesetval == NULL) || (end->nodesetval->nodeNr <= 0)) return(NULL); + endNode = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1]; + endIndex = -1; break; default: /* TODO */ return(NULL); } - ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); - if (ret == NULL) { - xmlXPtrErrMemory("allocating range"); - return(NULL); - } - memset(ret, 0 , (size_t) sizeof(xmlXPathObject)); - ret->type = XPATH_RANGE; - ret->user = start; - ret->index = -1; - switch (end->type) { - case XPATH_POINT: - ret->user2 = end->user; - ret->index2 = end->index; - break; - case XPATH_RANGE: - ret->user2 = end->user2; - ret->index2 = end->index2; - break; - case XPATH_NODESET: { - ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1]; - ret->index2 = -1; - break; - } - default: - STRANGE - return(NULL); - } + ret = xmlXPtrNewRangeInternal(start, -1, endNode, endIndex); xmlXPtrRangeCheckOrder(ret); return(ret); } @@ -986,8 +956,10 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) { if (name == NULL) XP_ERROR(XPATH_EXPR_ERROR); - if (CUR != '(') + if (CUR != '(') { + xmlFree(name); XP_ERROR(XPATH_EXPR_ERROR); + } NEXT; level = 1; @@ -996,6 +968,7 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) { buffer = (xmlChar *) xmlMallocAtomic(len * sizeof (xmlChar)); if (buffer == NULL) { xmlXPtrErrMemory("allocating buffer"); + xmlFree(name); return; } @@ -1020,6 +993,7 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) { *cur = 0; if ((level != 0) && (CUR == 0)) { + xmlFree(name); xmlFree(buffer); XP_ERROR(XPTR_SYNTAX_ERROR); } @@ -1052,6 +1026,7 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) { if (name2 == NULL) { CUR_PTR = left; xmlFree(buffer); + xmlFree(name); XP_ERROR(XPATH_EXPR_ERROR); } xmlXPtrEvalChildSeq(ctxt, name2); @@ -1332,8 +1307,6 @@ xmlXPtrNewContext(xmlDocPtr doc, xmlNodePtr here, xmlNodePtr origin) { ret->here = here; ret->origin = origin; - xmlXPathRegisterFunc(ret, (xmlChar *)"range-to", - xmlXPtrRangeToFunction); xmlXPathRegisterFunc(ret, (xmlChar *)"range", xmlXPtrRangeFunction); xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside", @@ -1400,7 +1373,7 @@ xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) { */ xmlNodeSetPtr set; set = tmp->nodesetval; - if ((set->nodeNr != 1) || + if ((set == NULL) || (set->nodeNr != 1) || (set->nodeTab[0] != (xmlNodePtr) ctx->doc)) stack++; } else @@ -1835,8 +1808,8 @@ xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs) { case XPATH_RANGE: { xmlNodePtr node = tmp->user; if (node != NULL) { - if (node->type == XML_ATTRIBUTE_NODE) { - /* TODO: Namespace Nodes ??? */ + if ((node->type == XML_ATTRIBUTE_NODE) || + (node->type == XML_NAMESPACE_DECL)) { xmlXPathFreeObject(obj); xmlXPtrFreeLocationSet(newset); XP_ERROR(XPTR_SYNTAX_ERROR); @@ -1931,8 +1904,8 @@ xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs) { case XPATH_RANGE: { xmlNodePtr node = tmp->user2; if (node != NULL) { - if (node->type == XML_ATTRIBUTE_NODE) { - /* TODO: Namespace Nodes ??? */ + if ((node->type == XML_ATTRIBUTE_NODE) || + (node->type == XML_NAMESPACE_DECL)) { xmlXPathFreeObject(obj); xmlXPtrFreeLocationSet(newset); XP_ERROR(XPTR_SYNTAX_ERROR); @@ -2073,9 +2046,11 @@ xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathFreeObject(set); XP_ERROR(XPATH_MEMORY_ERROR); } - for (i = 0;i < oldset->locNr;i++) { - xmlXPtrLocationSetAdd(newset, - xmlXPtrCoveringRange(ctxt, oldset->locTab[i])); + if (oldset != NULL) { + for (i = 0;i < oldset->locNr;i++) { + xmlXPtrLocationSetAdd(newset, + xmlXPtrCoveringRange(ctxt, oldset->locTab[i])); + } } /* @@ -2243,76 +2218,14 @@ xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) { * @nargs: the number of args * * 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. */ void -xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs) { - xmlXPathObjectPtr range; - const xmlChar *cur; - xmlXPathObjectPtr res, obj; - xmlXPathObjectPtr tmp; - xmlLocationSetPtr newset = NULL; - xmlNodeSetPtr oldset; - int i; - - if (ctxt == NULL) return; - CHECK_ARITY(1); - /* - * Save the expression pointer since we will have to evaluate - * it multiple times. Initialize the new set. - */ - CHECK_TYPE(XPATH_NODESET); - obj = valuePop(ctxt); - oldset = obj->nodesetval; - ctxt->context->node = NULL; - - cur = ctxt->cur; - newset = xmlXPtrLocationSetCreate(NULL); - - for (i = 0; i < oldset->nodeNr; i++) { - ctxt->cur = cur; - - /* - * Run the evaluation with a node list made of a single item - * in the nodeset. - */ - ctxt->context->node = oldset->nodeTab[i]; - tmp = xmlXPathNewNodeSet(ctxt->context->node); - valuePush(ctxt, tmp); - - xmlXPathEvalExpr(ctxt); - CHECK_ERROR; - - /* - * The result of the evaluation need to be tested to - * decided whether the filter succeeded or not - */ - res = valuePop(ctxt); - range = xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], res); - if (range != NULL) { - xmlXPtrLocationSetAdd(newset, range); - } - - /* - * Cleanup - */ - if (res != NULL) - xmlXPathFreeObject(res); - if (ctxt->value == tmp) { - res = valuePop(ctxt); - xmlXPathFreeObject(res); - } - - ctxt->context->node = NULL; - } - - /* - * The result is used as the new evaluation set. - */ - xmlXPathFreeObject(obj); - ctxt->context->node = NULL; - ctxt->context->contextSize = -1; - ctxt->context->proximityPosition = -1; - valuePush(ctxt, xmlXPtrWrapLocationSet(newset)); +xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, + int nargs ATTRIBUTE_UNUSED) { + XP_ERROR(XPATH_EXPR_ERROR); } /** diff --git a/gnulib-local/m4/libxml.m4 b/gnulib-local/m4/libxml.m4 index 34ee6ab15..05b955077 100644 --- a/gnulib-local/m4/libxml.m4 +++ b/gnulib-local/m4/libxml.m4 @@ -1,4 +1,4 @@ -# libxml.m4 serial 7 +# libxml.m4 serial 8 dnl Copyright (C) 2006, 2008, 2011, 2013, 2016, 2019 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -202,7 +202,7 @@ AC_DEFUN([gl_LIBXML], # include #endif ]) - AC_CHECK_FUNCS([dlopen getaddrinfo localtime shlload stat _stat strftime]) + AC_CHECK_FUNCS([dlopen getaddrinfo localtime shlload stat strftime]) dnl This relies on the va_copy replacement from the stdarg module. AC_DEFINE([VA_COPY], [va_copy], [Define to a working va_copy macro or replacement.])