Update to libxml2 2.9.4 by merging commit 'd8083bf7' into klp-dev.
Bug: 32956747
Change-Id: I04c5bdea11733cc8dab6244f4a1bf33f0ff66277
(cherry-picked from 312a2fc2f0200bbb187771f25e08ed5afd447e40)
diff --git a/HTMLparser.c b/HTMLparser.c
index dd0c1ea..d1395fa 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -105,7 +105,7 @@
*
* 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 @@
*
* 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 @@
#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)) \
@@ -1177,7 +1178,7 @@
"onfocus",
"onblur",
"onsubmit",
- "onrest",
+ "onreset",
"onchange",
"onselect"
};
@@ -2471,6 +2472,10 @@
(*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 @@
int len = 0, l;
int c;
int count = 0;
+ const xmlChar *base = ctxt->input->base;
/*
* Handler for more complex cases
@@ -2513,7 +2519,18 @@
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->base > ctxt->input->cur - len)
+ return(NULL);
+
return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
}
@@ -2765,31 +2782,43 @@
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 +2842,47 @@
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 {
@@ -2948,8 +2992,9 @@
/**
- * htmlParseCharData:
+ * htmlParseCharDataInternal:
* @ctxt: an HTML parser context
+ * @readahead: optional read ahead character in ascii range
*
* parse a CharData section.
* if we are within a CDATA section ']]>' marks an end of section.
@@ -2958,12 +3003,15 @@
*/
static void
-htmlParseCharData(htmlParserCtxtPtr ctxt) {
- xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 5];
+htmlParseCharDataInternal(htmlParserCtxtPtr ctxt, int readahead) {
+ xmlChar buf[HTML_PARSER_BIG_BUFFER_SIZE + 6];
int nbchar = 0;
int cur, l;
int chunk = 0;
+ if (readahead)
+ buf[nbchar++] = readahead;
+
SHRINK;
cur = CUR_CHAR(l);
while (((cur != '<') || (ctxt->token == '<')) &&
@@ -3043,6 +3091,21 @@
}
/**
+ * htmlParseCharData:
+ * @ctxt: an HTML parser context
+ *
+ * parse a CharData section.
+ * if we are within a CDATA section ']]>' marks an end of section.
+ *
+ * [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
+ */
+
+static void
+htmlParseCharData(htmlParserCtxtPtr ctxt) {
+ htmlParseCharDataInternal(ctxt, 0);
+}
+
+/**
* htmlParseExternalID:
* @ctxt: an HTML parser context
* @publicID: a xmlChar** receiving PubidLiteral
@@ -3245,12 +3308,17 @@
ctxt->instate = state;
return;
}
+ len = 0;
+ buf[len] = 0;
q = CUR_CHAR(ql);
+ if (!IS_CHAR(q))
+ goto unfinished;
NEXTL(ql);
r = CUR_CHAR(rl);
+ if (!IS_CHAR(r))
+ goto unfinished;
NEXTL(rl);
cur = CUR_CHAR(l);
- len = 0;
while (IS_CHAR(cur) &&
((cur != '>') ||
(r != '-') || (q != '-'))) {
@@ -3281,18 +3349,20 @@
}
}
buf[len] = 0;
- if (!IS_CHAR(cur)) {
- htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
- "Comment not terminated \n<!--%.50s\n", buf, NULL);
- xmlFree(buf);
- } else {
+ if (IS_CHAR(cur)) {
NEXT;
if ((ctxt->sax != NULL) && (ctxt->sax->comment != NULL) &&
(!ctxt->disableSAX))
ctxt->sax->comment(ctxt->userData, buf);
xmlFree(buf);
+ ctxt->instate = state;
+ return;
}
- ctxt->instate = state;
+
+unfinished:
+ htmlParseErr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
+ "Comment not terminated \n<!--%.50s\n", buf, NULL);
+ xmlFree(buf);
}
/**
@@ -3671,13 +3741,13 @@
int i;
int discardtag = 0;
- if (ctxt->instate == XML_PARSER_EOF)
- return(-1);
if ((ctxt == NULL) || (ctxt->input == NULL)) {
htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
"htmlParseStartTag: context error\n", NULL, NULL);
return -1;
}
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(-1);
if (CUR != '<') return -1;
NEXT;
@@ -3690,6 +3760,14 @@
htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
"htmlParseStartTag: invalid element name\n",
NULL, NULL);
+ /* if recover preserve text on classic misconstructs */
+ if ((ctxt->recovery) && ((IS_BLANK_CH(CUR)) || (CUR == '<') ||
+ (CUR == '=') || (CUR == '>') || (((CUR >= '0') && (CUR <= '9'))))) {
+ htmlParseCharDataInternal(ctxt, '<');
+ return(-1);
+ }
+
+
/* Dump the bogus tag like browsers do */
while ((IS_CHAR_CH(CUR)) && (CUR != '>') &&
(ctxt->instate != XML_PARSER_EOF))
@@ -4366,7 +4444,7 @@
htmlParseElementInternal(htmlParserCtxtPtr ctxt) {
const xmlChar *name;
const htmlElemDesc * info;
- htmlParserNodeInfo node_info;
+ htmlParserNodeInfo node_info = { 0, };
int failed;
if ((ctxt == NULL) || (ctxt->input == NULL)) {
@@ -5701,17 +5779,17 @@
if (ctxt->keepBlanks) {
if (ctxt->sax->characters != NULL)
ctxt->sax->characters(
- ctxt->userData, &cur, 1);
+ ctxt->userData, &in->cur[0], 1);
} else {
if (ctxt->sax->ignorableWhitespace != NULL)
ctxt->sax->ignorableWhitespace(
- ctxt->userData, &cur, 1);
+ ctxt->userData, &in->cur[0], 1);
}
} else {
htmlCheckParagraph(ctxt);
if (ctxt->sax->characters != NULL)
ctxt->sax->characters(
- ctxt->userData, &cur, 1);
+ ctxt->userData, &in->cur[0], 1);
}
}
ctxt->token = 0;
@@ -5991,7 +6069,7 @@
ctxt->sax->endDocument(ctxt->userData);
}
}
- if ((ctxt->myDoc != NULL) &&
+ if ((!(ctxt->options & HTML_PARSE_NODEFDTD)) && (ctxt->myDoc != NULL) &&
((terminate) || (ctxt->instate == XML_PARSER_EOF) ||
(ctxt->instate == XML_PARSER_EPILOG))) {
xmlDtdPtr dtd;
@@ -6288,12 +6366,16 @@
/* set encoding */
if (encoding) {
- content = xmlMallocAtomic (xmlStrlen(content_line) + strlen(encoding) + 1);
- if (content) {
- strcpy ((char *)content, (char *)content_line);
- strcat ((char *)content, (char *)encoding);
- htmlCheckEncoding (ctxt, content);
- xmlFree (content);
+ size_t l = strlen(encoding);
+
+ if (l < 1000) {
+ content = xmlMallocAtomic (xmlStrlen(content_line) + l + 1);
+ if (content) {
+ strcpy ((char *)content, (char *)content_line);
+ strcat ((char *)content, (char *)encoding);
+ htmlCheckEncoding (ctxt, content);
+ xmlFree (content);
+ }
}
}
@@ -6499,7 +6581,7 @@
* 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) \
@@ -6808,6 +6890,7 @@
if (fd < 0)
return (NULL);
+ xmlInitParser();
xmlInitParser();
input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
@@ -6898,6 +6981,7 @@
return (NULL);
if (ctxt == NULL)
return (NULL);
+ xmlInitParser();
htmlCtxtReset(ctxt);
@@ -6931,6 +7015,7 @@
return (NULL);
if (ctxt == NULL)
return (NULL);
+ xmlInitParser();
htmlCtxtReset(ctxt);
@@ -6967,6 +7052,7 @@
return (NULL);
if (buffer == NULL)
return (NULL);
+ xmlInitParser();
htmlCtxtReset(ctxt);
@@ -7009,6 +7095,7 @@
return (NULL);
if (ctxt == NULL)
return (NULL);
+ xmlInitParser();
htmlCtxtReset(ctxt);
@@ -7053,6 +7140,7 @@
return (NULL);
if (ctxt == NULL)
return (NULL);
+ xmlInitParser();
htmlCtxtReset(ctxt);
diff --git a/HTMLtree.c b/HTMLtree.c
index 4d8e354..2fd0c9c 100644
--- a/HTMLtree.c
+++ b/HTMLtree.c
@@ -668,7 +668,8 @@
xmlOutputBufferWriteString(buf, " ");
xmlBufWriteQuotedString(buf->buffer, cur->SystemID);
}
- } else if (cur->SystemID != NULL) {
+ } else if (cur->SystemID != NULL &&
+ xmlStrcmp(cur->SystemID, BAD_CAST "about:legacy-compat")) {
xmlOutputBufferWriteString(buf, " SYSTEM ");
xmlBufWriteQuotedString(buf->buffer, cur->SystemID);
}
@@ -716,22 +717,49 @@
(!xmlStrcasecmp(cur->name, BAD_CAST "src")) ||
((!xmlStrcasecmp(cur->name, BAD_CAST "name")) &&
(!xmlStrcasecmp(cur->parent->name, BAD_CAST "a"))))) {
- xmlChar *escaped;
xmlChar *tmp = value;
+ /* xmlURIEscapeStr() escapes '"' so it can be safely used. */
+ xmlBufCCat(buf->buffer, "\"");
while (IS_BLANK_CH(*tmp)) tmp++;
- /*
- * the < and > have already been escaped at the entity level
- * And doing so here breaks server side includes
- */
- escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+<>");
- if (escaped != NULL) {
- xmlBufWriteQuotedString(buf->buffer, escaped);
- xmlFree(escaped);
- } else {
- xmlBufWriteQuotedString(buf->buffer, value);
+ /* URI Escape everything, except server side includes. */
+ for ( ; ; ) {
+ xmlChar *escaped;
+ xmlChar endChar;
+ xmlChar *end = NULL;
+ xmlChar *start = (xmlChar *)xmlStrstr(tmp, BAD_CAST "<!--");
+ if (start != NULL) {
+ end = (xmlChar *)xmlStrstr(tmp, BAD_CAST "-->");
+ if (end != NULL) {
+ *start = '\0';
+ }
+ }
+
+ /* Escape the whole string, or until start (set to '\0'). */
+ escaped = xmlURIEscapeStr(tmp, BAD_CAST"@/:=?;#%&,+");
+ if (escaped != NULL) {
+ xmlBufCat(buf->buffer, escaped);
+ xmlFree(escaped);
+ } else {
+ xmlBufCat(buf->buffer, tmp);
+ }
+
+ if (end == NULL) { /* Everything has been written. */
+ break;
+ }
+
+ /* Do not escape anything within server side includes. */
+ *start = '<'; /* Restore the first character of "<!--". */
+ end += 3; /* strlen("-->") */
+ endChar = *end;
+ *end = '\0';
+ xmlBufCat(buf->buffer, start);
+ *end = endChar;
+ tmp = end;
}
+
+ xmlBufCCat(buf->buffer, "\"");
} else {
xmlBufWriteQuotedString(buf->buffer, value);
}
diff --git a/SAX2.c b/SAX2.c
index 4adf202..5cbb700 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -55,7 +55,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 +93,7 @@
*
* 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 +133,7 @@
*
* 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 +164,7 @@
*
* 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 +189,7 @@
*
* 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 +213,7 @@
*
* 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)
{
@@ -994,12 +994,12 @@
#ifdef LIBXML_HTML_ENABLED
if (ctxt->myDoc == NULL)
ctxt->myDoc = htmlNewDocNoDtD(NULL, NULL);
- ctxt->myDoc->properties = XML_DOC_HTML;
- ctxt->myDoc->parseFlags = ctxt->options;
if (ctxt->myDoc == NULL) {
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartDocument");
return;
}
+ ctxt->myDoc->properties = XML_DOC_HTML;
+ ctxt->myDoc->parseFlags = ctxt->options;
#else
xmlGenericError(xmlGenericErrorContext,
"libxml2 built without HTML support\n");
@@ -1078,7 +1078,7 @@
}
}
-#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
/**
* xmlSAX2AttributeInternal:
* @ctx: the user data (XML parser context)
@@ -1177,6 +1177,12 @@
val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
0,0,0);
ctxt->depth--;
+ if (val == NULL) {
+ xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+ if (name != NULL)
+ xmlFree(name);
+ return;
+ }
} else {
val = (xmlChar *) value;
}
@@ -1822,7 +1828,7 @@
#endif
nodePop(ctxt);
}
-#endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLE */
+#endif /* LIBXML_SAX1_ENABLED || LIBXML_HTML_ENABLED || LIBXML_LEGACY_ENABLED */
/*
* xmlSAX2TextNode:
@@ -2145,6 +2151,7 @@
*/
if (dup == NULL)
dup = xmlStrndup(value, valueend - value);
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
#ifdef LIBXML_VALID_ENABLED
if (xmlValidateNCName(dup, 1) != 0) {
xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
@@ -2152,6 +2159,7 @@
(const char *) dup, NULL);
}
#endif
+#endif
xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
} else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
/* might be worth duplicate entry points and not copy */
@@ -2570,6 +2578,10 @@
(xmlDictOwns(ctxt->dict, lastChild->content))) {
lastChild->content = xmlStrdup(lastChild->content);
}
+ if (lastChild->content == NULL) {
+ xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: xmlStrdup returned NULL");
+ return;
+ }
if (((size_t)ctxt->nodelen + (size_t)len > XML_MAX_TEXT_LENGTH) &&
((ctxt->options & XML_PARSE_HUGE) == 0)) {
xmlSAX2ErrMemory(ctxt, "xmlSAX2Characters: huge text node");
diff --git a/buf.c b/buf.c
index d1756c4..07922ff 100644
--- a/buf.c
+++ b/buf.c
@@ -27,6 +27,7 @@
#include <libxml/tree.h>
#include <libxml/globals.h>
#include <libxml/tree.h>
+#include <libxml/parserInternals.h> /* for XML_MAX_TEXT_LENGTH */
#include "buf.h"
#define WITH_BUFFER_COMPAT
@@ -299,7 +300,8 @@
if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) ||
(scheme == XML_BUFFER_ALLOC_EXACT) ||
(scheme == XML_BUFFER_ALLOC_HYBRID) ||
- (scheme == XML_BUFFER_ALLOC_IMMUTABLE)) {
+ (scheme == XML_BUFFER_ALLOC_IMMUTABLE) ||
+ (scheme == XML_BUFFER_ALLOC_BOUNDED)) {
buf->alloc = scheme;
if (buf->buffer)
buf->buffer->alloc = scheme;
@@ -458,6 +460,18 @@
size = buf->use + len + 100;
#endif
+ if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
+ /*
+ * Used to provide parsing limits
+ */
+ if ((buf->use + len >= XML_MAX_TEXT_LENGTH) ||
+ (buf->size >= XML_MAX_TEXT_LENGTH)) {
+ xmlBufMemoryError(buf, "buffer error: text too long\n");
+ return(0);
+ }
+ if (size >= XML_MAX_TEXT_LENGTH)
+ size = XML_MAX_TEXT_LENGTH;
+ }
if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
size_t start_buf = buf->content - buf->contentIO;
@@ -565,7 +579,7 @@
*/
xmlChar *
-xmlBufContent(const xmlBufPtr buf)
+xmlBufContent(const xmlBuf *buf)
{
if ((!buf) || (buf->error))
return NULL;
@@ -583,7 +597,7 @@
*/
xmlChar *
-xmlBufEnd(const xmlBufPtr buf)
+xmlBufEnd(xmlBufPtr buf)
{
if ((!buf) || (buf->error))
return NULL;
@@ -739,6 +753,15 @@
CHECK_COMPAT(buf)
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
+ if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
+ /*
+ * Used to provide parsing limits
+ */
+ if (size >= XML_MAX_TEXT_LENGTH) {
+ xmlBufMemoryError(buf, "buffer error: text too long\n");
+ return(0);
+ }
+ }
/* Don't resize if we don't have to */
if (size < buf->size)
@@ -867,6 +890,15 @@
needSize = buf->use + len + 2;
if (needSize > buf->size){
+ if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
+ /*
+ * Used to provide parsing limits
+ */
+ if (needSize >= XML_MAX_TEXT_LENGTH) {
+ xmlBufMemoryError(buf, "buffer error: text too long\n");
+ return(-1);
+ }
+ }
if (!xmlBufResize(buf, needSize)){
xmlBufMemoryError(buf, "growing buffer");
return XML_ERR_NO_MEMORY;
@@ -938,6 +970,15 @@
}
needSize = buf->use + len + 2;
if (needSize > buf->size){
+ if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
+ /*
+ * Used to provide parsing limits
+ */
+ if (needSize >= XML_MAX_TEXT_LENGTH) {
+ xmlBufMemoryError(buf, "buffer error: text too long\n");
+ return(-1);
+ }
+ }
if (!xmlBufResize(buf, needSize)){
xmlBufMemoryError(buf, "growing buffer");
return XML_ERR_NO_MEMORY;
diff --git a/buf.h b/buf.h
index e8c7715..ebdc978 100644
--- a/buf.h
+++ b/buf.h
@@ -50,8 +50,8 @@
int xmlBufAddLen(xmlBufPtr buf, size_t len);
int xmlBufErase(xmlBufPtr buf, size_t len);
-/* const xmlChar * xmlBufContent(const xmlBufPtr buf); */
-/* const xmlChar * xmlBufEnd(const xmlBufPtr buf); */
+/* const xmlChar * xmlBufContent(const xmlBuf *buf); */
+/* const xmlChar * xmlBufEnd(xmlBufPtr buf); */
xmlChar * xmlBufDetach(xmlBufPtr buf);
diff --git a/c14n.c b/c14n.c
index afd95b3..ca77f92 100644
--- a/c14n.c
+++ b/c14n.c
@@ -547,14 +547,15 @@
if (ns->prefix != NULL) {
xmlOutputBufferWriteString(ctx->buf, " xmlns:");
xmlOutputBufferWriteString(ctx->buf, (const char *) ns->prefix);
- xmlOutputBufferWriteString(ctx->buf, "=\"");
+ xmlOutputBufferWriteString(ctx->buf, "=");
} else {
- xmlOutputBufferWriteString(ctx->buf, " xmlns=\"");
+ xmlOutputBufferWriteString(ctx->buf, " xmlns=");
}
if(ns->href != NULL) {
- xmlOutputBufferWriteString(ctx->buf, (const char *) ns->href);
+ xmlBufWriteQuotedString(ctx->buf->buffer, ns->href);
+ } else {
+ xmlOutputBufferWriteString(ctx->buf, "\"\"");
}
- xmlOutputBufferWriteString(ctx->buf, "\"");
return (1);
}
diff --git a/catalog.c b/catalog.c
index 8e34cd2..6dfdfbb 100644
--- a/catalog.c
+++ b/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 @@
*
* 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)
@@ -994,6 +994,11 @@
content = (xmlChar*)xmlMallocAtomic(size + 10);
if (content == NULL) {
xmlCatalogErrMemory("allocating catalog data");
+#ifdef HAVE_STAT
+ close(fd);
+#else
+ fclose(fd);
+#endif
return (NULL);
}
#ifdef HAVE_STAT
@@ -3242,7 +3247,7 @@
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
@@ -3258,7 +3263,7 @@
xmlFree(path);
}
}
- while (*cur == PATH_SEAPARATOR)
+ while (*cur == PATH_SEPARATOR)
cur++;
}
}
@@ -3550,8 +3555,8 @@
xmlGenericError(xmlGenericErrorContext,
"Setting catalog preference to SYSTEM\n");
break;
- case XML_CATA_PREFER_NONE:
- break;
+ default:
+ return(ret);
}
}
xmlCatalogDefaultPrefer = prefer;
diff --git a/config.h b/config.h
index df227b0..7449acd 100644
--- a/config.h
+++ b/config.h
@@ -1,5 +1,8 @@
/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.in by autoheader. */
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Type cast for the gethostbyname() argument */
+#define GETHOSTBYNAME_ARG_CAST /**/
/* Define to 1 if you have the <ansidecl.h> header file. */
/* #undef HAVE_ANSIDECL_H */
@@ -154,7 +157,7 @@
#define HAVE_RAND 1
/* Define to 1 if you have the `rand_r' function. */
-// #define HAVE_RAND_R 1
+/* #undef HAVE_RAND_R */
/* Define to 1 if you have the <resolv.h> header file. */
#define HAVE_RESOLV_H 1
@@ -261,7 +264,7 @@
#define HAVE_VSPRINTF 1
/* Define to 1 if you have the <zlib.h> header file. */
-/* #undef HAVE_ZLIB_H */
+/* #undef HAVE_ZLIB_H */ /* Because otherwise LIBXML_ZLIB_ENABLED is ignored! */
/* Define to 1 if you have the `_stat' function. */
/* #undef HAVE__STAT */
@@ -297,14 +300,20 @@
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
+/* Type cast for the send() function 2nd arg */
+#define SEND_ARG2_CAST /**/
+
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Support for IPv6 */
#define SUPPORT_IP6 /**/
+/* Define if va_list is an array type */
+#define VA_LIST_IS_ARRAY 1
+
/* Version number of package */
-#define VERSION "2.9.1"
+#define VERSION "2.9.2"
/* Determine what socket length (socklen_t) data type is */
#define XML_SOCKLEN_T socklen_t
diff --git a/debugXML.c b/debugXML.c
index c8efe6a..a1b550a 100644
--- a/debugXML.c
+++ b/debugXML.c
@@ -44,10 +44,10 @@
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 @@
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 @@
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 @@
* @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
@@ -254,16 +254,18 @@
xmlDebugErr(ctxt, XML_CHECK_NO_NAME, "Name is NULL");
return;
}
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
if (xmlValidateName(name, 0)) {
xmlDebugErr3(ctxt, XML_CHECK_NOT_NCNAME,
"Name is not an NCName '%s'", (const char *) name);
}
+#endif
if ((ctxt->dict != NULL) &&
(!xmlDictOwns(ctxt->dict, 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);
}
}
@@ -290,7 +292,7 @@
/* 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;
}
@@ -2946,7 +2948,7 @@
} else if (!strcmp(command, "save")) {
xmlShellSave(ctxt, arg, NULL, NULL);
} else if (!strcmp(command, "write")) {
- if ((arg == NULL) || (arg[0] == 0))
+ if (arg[0] == 0)
xmlGenericError(xmlGenericErrorContext,
"Write command requires a filename argument\n");
else
@@ -3241,7 +3243,12 @@
ctxt->node = (xmlNodePtr) ctxt->doc;
} else {
#ifdef LIBXML_XPATH_ENABLED
+ int l;
+
ctxt->pctxt->node = ctxt->node;
+ l = strlen(arg);
+ if ((l >= 2) && (arg[l - 1] == '/'))
+ arg[l - 1] = 0;
list = xmlXPathEval((xmlChar *) arg, ctxt->pctxt);
#else
list = NULL;
diff --git a/dict.c b/dict.c
index 5f71d55..c0585fe 100644
--- a/dict.c
+++ b/dict.c
@@ -87,7 +87,7 @@
#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 @@
xmlChar array[1];
};
/*
- * The entire dictionnary
+ * The entire dictionary
*/
struct _xmlDict {
int ref_counter;
@@ -229,7 +229,7 @@
/*
* xmlDictAddString:
- * @dict: the dictionnary
+ * @dict: the dictionary
* @name: the name of the userdata
* @len: the length of the name
*
@@ -291,7 +291,7 @@
/*
* xmlDictAddQString:
- * @dict: the dictionnary
+ * @dict: the dictionary
* @prefix: the prefix of the userdata
* @plen: the prefix length
* @name: the name of the userdata
@@ -486,7 +486,10 @@
value += 30 * (*prefix);
if (len > 10) {
- value += name[len - (plen + 1 + 1)];
+ int offset = len - (plen + 1 + 1);
+ if (offset < 0)
+ offset = len - (10 + 1);
+ value += name[offset];
len = 10;
if (plen > 10)
plen = 10;
@@ -530,7 +533,7 @@
*
* 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 occured.
*/
xmlDictPtr
xmlDictCreate(void) {
@@ -570,14 +573,14 @@
/**
* 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 occured.
*/
xmlDictPtr
xmlDictCreateSub(xmlDictPtr sub) {
@@ -596,7 +599,7 @@
/**
* xmlDictReference:
- * @dict: the dictionnary
+ * @dict: the dictionary
*
* Increment the reference counter of a dictionary
*
@@ -617,10 +620,10 @@
/**
* 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
*/
@@ -752,7 +755,7 @@
/**
* xmlDictFree:
- * @dict: the dictionnary
+ * @dict: the dictionary
*
* Free the hash @dict and its contents. The userdata is
* deallocated with @f if provided.
@@ -814,11 +817,11 @@
/**
* 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
*/
@@ -954,11 +957,11 @@
/**
* 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.
*/
@@ -1062,7 +1065,7 @@
/**
* xmlDictQLookup:
- * @dict: the dictionnary
+ * @dict: the dictionary
* @prefix: the prefix
* @name: the name
*
@@ -1167,7 +1170,7 @@
/**
* xmlDictOwns:
- * @dict: the dictionnary
+ * @dict: the dictionary
* @str: the string
*
* check if a string is owned by the disctionary
@@ -1194,11 +1197,11 @@
/**
* 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
@@ -1212,7 +1215,7 @@
/**
* xmlDictSetLimit:
- * @dict: the dictionnary
+ * @dict: the dictionary
* @limit: the limit in bytes
*
* Set a size limit for the dictionary
@@ -1233,7 +1236,7 @@
/**
* 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/elfgcchack.h b/elfgcchack.h
index 85c49d6..8c52884 100644
--- a/elfgcchack.h
+++ b/elfgcchack.h
@@ -1061,7 +1061,7 @@
#endif
#endif
-#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
#ifdef bottom_tree
#undef xmlAddPrevSibling
extern __typeof (xmlAddPrevSibling) xmlAddPrevSibling __attribute((alias("xmlAddPrevSibling__internal_alias")));
@@ -8885,7 +8885,7 @@
#endif
#endif
-#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
#ifdef bottom_SAX2
#undef xmlSAX2EndElement
extern __typeof (xmlSAX2EndElement) xmlSAX2EndElement __attribute((alias("xmlSAX2EndElement__internal_alias")));
@@ -9131,7 +9131,7 @@
#endif
#endif
-#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
#ifdef bottom_SAX2
#undef xmlSAX2StartElement
extern __typeof (xmlSAX2StartElement) xmlSAX2StartElement __attribute((alias("xmlSAX2StartElement__internal_alias")));
@@ -15363,7 +15363,7 @@
#endif
#endif
-#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
#ifdef bottom_tree
#undef xmlValidateNCName
extern __typeof (xmlValidateNCName) xmlValidateNCName __attribute((alias("xmlValidateNCName__internal_alias")));
@@ -16769,6 +16769,18 @@
#if defined(LIBXML_XPATH_ENABLED)
#ifdef bottom_xpath
+#undef xmlXPathNodeEval
+extern __typeof (xmlXPathNodeEval) xmlXPathNodeEval __attribute((alias("xmlXPathNodeEval__internal_alias")));
+#else
+#ifndef xmlXPathNodeEval
+extern __typeof (xmlXPathNodeEval) xmlXPathNodeEval__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathNodeEval xmlXPathNodeEval__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
#undef xmlXPathNodeLeading
extern __typeof (xmlXPathNodeLeading) xmlXPathNodeLeading __attribute((alias("xmlXPathNodeLeading__internal_alias")));
#else
@@ -17273,6 +17285,18 @@
#if defined(LIBXML_XPATH_ENABLED)
#ifdef bottom_xpath
+#undef xmlXPathSetContextNode
+extern __typeof (xmlXPathSetContextNode) xmlXPathSetContextNode __attribute((alias("xmlXPathSetContextNode__internal_alias")));
+#else
+#ifndef xmlXPathSetContextNode
+extern __typeof (xmlXPathSetContextNode) xmlXPathSetContextNode__internal_alias __attribute((visibility("hidden")));
+#define xmlXPathSetContextNode xmlXPathSetContextNode__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XPATH_ENABLED)
+#ifdef bottom_xpath
#undef xmlXPathStartsWithFunction
extern __typeof (xmlXPathStartsWithFunction) xmlXPathStartsWithFunction __attribute((alias("xmlXPathStartsWithFunction__internal_alias")));
#else
diff --git a/encoding.c b/encoding.c
index 7330e90..e49c7f8 100644
--- a/encoding.c
+++ b/encoding.c
@@ -93,7 +93,7 @@
*
* 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,
@@ -2384,6 +2384,7 @@
return (written? written : ret);
}
+#ifdef LIBXML_OUTPUT_ENABLED
/**
* xmlCharEncOutput:
* @output: a parser output buffer
@@ -2612,6 +2613,7 @@
}
return(ret);
}
+#endif
/**
* xmlCharEncOutFunc:
@@ -2851,14 +2853,25 @@
xmlCharEncCloseFunc(xmlCharEncodingHandler *handler) {
int ret = 0;
int tofree = 0;
+ int i, handler_in_list = 0;
+
if (handler == NULL) return(-1);
if (handler->name == NULL) return(-1);
+ if (handlers != NULL) {
+ for (i = 0;i < nbCharEncodingHandler; i++) {
+ if (handler == handlers[i]) {
+ handler_in_list = 1;
+ break;
+ }
+ }
+ }
#ifdef LIBXML_ICONV_ENABLED
/*
* Iconv handlers can be used only once, free the whole block.
* and the associated icon resources.
*/
- if ((handler->iconv_out != NULL) || (handler->iconv_in != NULL)) {
+ if ((handler_in_list == 0) &&
+ ((handler->iconv_out != NULL) || (handler->iconv_in != NULL))) {
tofree = 1;
if (handler->iconv_out != NULL) {
if (iconv_close(handler->iconv_out))
@@ -2873,7 +2886,8 @@
}
#endif /* LIBXML_ICONV_ENABLED */
#ifdef LIBXML_ICU_ENABLED
- if ((handler->uconv_out != NULL) || (handler->uconv_in != NULL)) {
+ if ((handler_in_list == 0) &&
+ ((handler->uconv_out != NULL) || (handler->uconv_in != NULL))) {
tofree = 1;
if (handler->uconv_out != NULL) {
closeIcuConverter(handler->uconv_out);
diff --git a/entities.c b/entities.c
index 0c484a7..64808ff 100644
--- a/entities.c
+++ b/entities.c
@@ -83,7 +83,7 @@
*
* 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);
@@ -502,7 +502,7 @@
* Returns A pointer to the entity structure or NULL if not found.
*/
xmlEntityPtr
-xmlGetDocEntity(xmlDocPtr doc, const xmlChar *name) {
+xmlGetDocEntity(const xmlDoc *doc, const xmlChar *name) {
xmlEntityPtr cur;
xmlEntitiesTablePtr table;
@@ -783,7 +783,7 @@
* Returns A newly allocated string with the substitution done.
*/
xmlChar *
-xmlEncodeSpecialChars(xmlDocPtr doc ATTRIBUTE_UNUSED, const xmlChar *input) {
+xmlEncodeSpecialChars(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlChar *input) {
const xmlChar *cur = input;
xmlChar *buffer = NULL;
xmlChar *out = NULL;
diff --git a/error.c b/error.c
index cbcf5c9..9606f13 100644
--- a/error.c
+++ b/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,7 +177,9 @@
xmlChar content[81]; /* space for 80 chars + line terminator */
xmlChar *ctnt;
- if (input == NULL) return;
+ if ((input == NULL) || (input->cur == NULL))
+ return;
+
cur = input->cur;
base = input->base;
/* skip backwards over any end-of-lines */
diff --git a/hash.c b/hash.c
index 0145109..f9a2017 100644
--- a/hash.c
+++ b/hash.c
@@ -984,6 +984,9 @@
return(NULL);
ret = xmlHashCreate(table->size);
+ if (ret == NULL)
+ return(NULL);
+
if (table->table) {
for(i = 0; i < table->size; i++) {
if (table->table[i].valid == 0)
diff --git a/include/libxml/SAX2.h b/include/libxml/SAX2.h
index daafd17..a55212e 100644
--- a/include/libxml/SAX2.h
+++ b/include/libxml/SAX2.h
@@ -98,7 +98,9 @@
xmlSAX2StartDocument (void *ctx);
XMLPUBFUN void XMLCALL
xmlSAX2EndDocument (void *ctx);
-#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
+ defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || \
+ defined(LIBXML_LEGACY_ENABLED)
XMLPUBFUN void XMLCALL
xmlSAX2StartElement (void *ctx,
const xmlChar *fullname,
@@ -106,7 +108,7 @@
XMLPUBFUN void XMLCALL
xmlSAX2EndElement (void *ctx,
const xmlChar *name);
-#endif /* LIBXML_SAX1_ENABLED or LIBXML_HTML_ENABLED */
+#endif /* LIBXML_SAX1_ENABLED or LIBXML_HTML_ENABLED or LIBXML_LEGACY_ENABLED */
XMLPUBFUN void XMLCALL
xmlSAX2StartElementNs (void *ctx,
const xmlChar *localname,
diff --git a/include/libxml/dict.h b/include/libxml/dict.h
index 7022ec8..b83db59 100644
--- a/include/libxml/dict.h
+++ b/include/libxml/dict.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 <limits.h>
#include <libxml/xmlversion.h>
#include <libxml/tree.h>
@@ -20,12 +32,6 @@
#endif
/*
- * The dictionnary.
- */
-typedef struct _xmlDict xmlDict;
-typedef xmlDict *xmlDictPtr;
-
-/*
* Initializer
*/
XMLPUBFUN int XMLCALL xmlInitializeDict(void);
@@ -48,7 +54,7 @@
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/include/libxml/entities.h b/include/libxml/entities.h
index 1e91189..47b4573 100644
--- a/include/libxml/entities.h
+++ b/include/libxml/entities.h
@@ -57,7 +57,7 @@
const xmlChar *URI; /* the full URI as computed */
int owner; /* does the entity own the childrens */
int checked; /* was the entity content checked */
- /* this is also used to count entites
+ /* this is also used to count entities
* references done from that entity
* and if it contains '<' */
};
@@ -103,7 +103,7 @@
XMLPUBFUN xmlEntityPtr XMLCALL
xmlGetPredefinedEntity (const xmlChar *name);
XMLPUBFUN xmlEntityPtr XMLCALL
- xmlGetDocEntity (xmlDocPtr doc,
+ xmlGetDocEntity (const xmlDoc *doc,
const xmlChar *name);
XMLPUBFUN xmlEntityPtr XMLCALL
xmlGetDtdEntity (xmlDocPtr doc,
@@ -120,7 +120,7 @@
xmlEncodeEntitiesReentrant(xmlDocPtr doc,
const xmlChar *input);
XMLPUBFUN xmlChar * XMLCALL
- xmlEncodeSpecialChars (xmlDocPtr doc,
+ xmlEncodeSpecialChars (const xmlDoc *doc,
const xmlChar *input);
XMLPUBFUN xmlEntitiesTablePtr XMLCALL
xmlCreateEntitiesTable (void);
diff --git a/include/libxml/globals.h b/include/libxml/globals.h
index 9d688e0..a9305aa 100644
--- a/include/libxml/globals.h
+++ b/include/libxml/globals.h
@@ -39,7 +39,9 @@
* Returns the new xmlParserInputBufferPtr in case of success or NULL if no
* method was found.
*/
-typedef xmlParserInputBufferPtr (*xmlParserInputBufferCreateFilenameFunc) (const char *URI, xmlCharEncoding enc);
+typedef xmlParserInputBufferPtr (*xmlParserInputBufferCreateFilenameFunc) (const char *URI,
+ xmlCharEncoding enc);
+
/**
* xmlOutputBufferCreateFilenameFunc:
@@ -52,7 +54,9 @@
* Returns the new xmlOutputBufferPtr in case of success or NULL if no
* method was found.
*/
-typedef xmlOutputBufferPtr (*xmlOutputBufferCreateFilenameFunc) (const char *URI, xmlCharEncodingHandlerPtr encoder, int compression);
+typedef xmlOutputBufferPtr (*xmlOutputBufferCreateFilenameFunc) (const char *URI,
+ xmlCharEncodingHandlerPtr encoder,
+ int compression);
XMLPUBFUN xmlParserInputBufferCreateFilenameFunc
XMLCALL xmlParserInputBufferCreateFilenameDefault (xmlParserInputBufferCreateFilenameFunc func);
@@ -185,7 +189,8 @@
XMLPUBFUN xmlOutputBufferCreateFilenameFunc XMLCALL
xmlThrDefOutputBufferCreateFilenameDefault(xmlOutputBufferCreateFilenameFunc func);
XMLPUBFUN xmlParserInputBufferCreateFilenameFunc XMLCALL
- xmlThrDefParserInputBufferCreateFilenameDefault(xmlParserInputBufferCreateFilenameFunc func);
+ xmlThrDefParserInputBufferCreateFilenameDefault(
+ xmlParserInputBufferCreateFilenameFunc func);
/** DOC_DISABLE */
/*
@@ -297,7 +302,8 @@
#else
XMLPUBVAR xmlBufferAllocationScheme xmlBufferAllocScheme;
#endif
-XMLPUBFUN xmlBufferAllocationScheme XMLCALL xmlThrDefBufferAllocScheme(xmlBufferAllocationScheme v);
+XMLPUBFUN xmlBufferAllocationScheme XMLCALL
+ xmlThrDefBufferAllocScheme(xmlBufferAllocationScheme v);
XMLPUBFUN int * XMLCALL __xmlDefaultBufferSize(void);
#ifdef LIBXML_THREAD_ENABLED
@@ -479,7 +485,8 @@
XMLPUBVAR xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue;
#endif
-XMLPUBFUN xmlParserInputBufferCreateFilenameFunc * XMLCALL __xmlParserInputBufferCreateFilenameValue(void);
+XMLPUBFUN xmlParserInputBufferCreateFilenameFunc * XMLCALL \
+ __xmlParserInputBufferCreateFilenameValue(void);
#ifdef LIBXML_THREAD_ENABLED
#define xmlParserInputBufferCreateFilenameValue \
(*(__xmlParserInputBufferCreateFilenameValue()))
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index 3f5730d..47fbec0 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -260,7 +260,7 @@
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 @@
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/include/libxml/parserInternals.h b/include/libxml/parserInternals.h
index 6065320..f30fc68 100644
--- a/include/libxml/parserInternals.h
+++ b/include/libxml/parserInternals.h
@@ -351,7 +351,7 @@
xmlParserErrors xmlerr,
const char *msg,
const xmlChar * str1,
- const xmlChar * str2);
+ const xmlChar * str2) LIBXML_ATTR_FORMAT(3,0);
#endif
/**
diff --git a/include/libxml/relaxng.h b/include/libxml/relaxng.h
index bdb0a7d..f269c9e 100644
--- a/include/libxml/relaxng.h
+++ b/include/libxml/relaxng.h
@@ -32,7 +32,9 @@
*
* Signature of an error callback from a Relax-NG validation
*/
-typedef void (XMLCDECL *xmlRelaxNGValidityErrorFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+typedef void (XMLCDECL *xmlRelaxNGValidityErrorFunc) (void *ctx,
+ const char *msg,
+ ...) LIBXML_ATTR_FORMAT(2,3);
/**
* xmlRelaxNGValidityWarningFunc:
@@ -42,7 +44,9 @@
*
* Signature of a warning callback from a Relax-NG validation
*/
-typedef void (XMLCDECL *xmlRelaxNGValidityWarningFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
+typedef void (XMLCDECL *xmlRelaxNGValidityWarningFunc) (void *ctx,
+ const char *msg,
+ ...) LIBXML_ATTR_FORMAT(2,3);
/**
* A schemas validation context
diff --git a/include/libxml/schemasInternals.h b/include/libxml/schemasInternals.h
index 4f0ca9a..c7cf552 100644
--- a/include/libxml/schemasInternals.h
+++ b/include/libxml/schemasInternals.h
@@ -28,52 +28,52 @@
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/include/libxml/tree.h b/include/libxml/tree.h
index 7e06686..4a9b3bc 100644
--- a/include/libxml/tree.h
+++ b/include/libxml/tree.h
@@ -76,7 +76,8 @@
XML_BUFFER_ALLOC_EXACT, /* grow only to the minimal size */
XML_BUFFER_ALLOC_IMMUTABLE, /* immutable buffer */
XML_BUFFER_ALLOC_IO, /* special allocation scheme used for I/O */
- XML_BUFFER_ALLOC_HYBRID /* exact up to a threshold, and doubleit thereafter */
+ XML_BUFFER_ALLOC_HYBRID, /* exact up to a threshold, and doubleit thereafter */
+ XML_BUFFER_ALLOC_BOUNDED /* limit the upper size of the buffer */
} xmlBufferAllocationScheme;
/**
@@ -116,8 +117,8 @@
* A few public routines for xmlBuf. As those are expected to be used
* mostly internally the bulk of the routines are internal in buf.h
*/
-XMLPUBFUN xmlChar* XMLCALL xmlBufContent (const xmlBufPtr buf);
-XMLPUBFUN xmlChar* XMLCALL xmlBufEnd (const xmlBufPtr buf);
+XMLPUBFUN xmlChar* XMLCALL xmlBufContent (const xmlBuf* buf);
+XMLPUBFUN xmlChar* XMLCALL xmlBufEnd (xmlBufPtr buf);
XMLPUBFUN size_t XMLCALL xmlBufUse (const xmlBufPtr buf);
XMLPUBFUN size_t XMLCALL xmlBufShrink (xmlBufPtr buf, size_t len);
@@ -654,7 +655,11 @@
/*
* Some helper functions
*/
-#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || \
+ defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || \
+ defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || \
+ defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || \
+ defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
XMLPUBFUN int XMLCALL
xmlValidateNCName (const xmlChar *value,
int space);
@@ -731,14 +736,14 @@
XMLPUBFUN void XMLCALL
xmlBufferEmpty (xmlBufferPtr buf);
XMLPUBFUN const xmlChar* XMLCALL
- xmlBufferContent (const xmlBufferPtr buf);
+ xmlBufferContent (const xmlBuffer *buf);
XMLPUBFUN xmlChar* XMLCALL
xmlBufferDetach (xmlBufferPtr buf);
XMLPUBFUN void XMLCALL
xmlBufferSetAllocationScheme(xmlBufferPtr buf,
xmlBufferAllocationScheme scheme);
XMLPUBFUN int XMLCALL
- xmlBufferLength (const xmlBufferPtr buf);
+ xmlBufferLength (const xmlBuffer *buf);
/*
* Creating/freeing new structures.
@@ -754,7 +759,7 @@
const xmlChar *ExternalID,
const xmlChar *SystemID);
XMLPUBFUN xmlDtdPtr XMLCALL
- xmlGetIntSubset (xmlDocPtr doc);
+ xmlGetIntSubset (const xmlDoc *doc);
XMLPUBFUN void XMLCALL
xmlFreeDtd (xmlDtdPtr cur);
#ifdef LIBXML_LEGACY_ENABLED
@@ -842,7 +847,7 @@
const xmlChar *content);
#endif
XMLPUBFUN xmlNodePtr XMLCALL
- xmlNewDocText (xmlDocPtr doc,
+ xmlNewDocText (const xmlDoc *doc,
const xmlChar *content);
XMLPUBFUN xmlNodePtr XMLCALL
xmlNewText (const xmlChar *content);
@@ -873,20 +878,20 @@
xmlNewCharRef (xmlDocPtr doc,
const xmlChar *name);
XMLPUBFUN xmlNodePtr XMLCALL
- xmlNewReference (xmlDocPtr doc,
+ xmlNewReference (const xmlDoc *doc,
const xmlChar *name);
XMLPUBFUN xmlNodePtr XMLCALL
- xmlCopyNode (const xmlNodePtr node,
+ xmlCopyNode (xmlNodePtr node,
int recursive);
XMLPUBFUN xmlNodePtr XMLCALL
- xmlDocCopyNode (const xmlNodePtr node,
+ xmlDocCopyNode (xmlNodePtr node,
xmlDocPtr doc,
int recursive);
XMLPUBFUN xmlNodePtr XMLCALL
xmlDocCopyNodeList (xmlDocPtr doc,
- const xmlNodePtr node);
+ xmlNodePtr node);
XMLPUBFUN xmlNodePtr XMLCALL
- xmlCopyNodeList (const xmlNodePtr node);
+ xmlCopyNodeList (xmlNodePtr node);
#ifdef LIBXML_TREE_ENABLED
XMLPUBFUN xmlNodePtr XMLCALL
xmlNewTextChild (xmlNodePtr parent,
@@ -906,19 +911,19 @@
* Navigating.
*/
XMLPUBFUN long XMLCALL
- xmlGetLineNo (xmlNodePtr node);
+ xmlGetLineNo (const xmlNode *node);
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
XMLPUBFUN xmlChar * XMLCALL
- xmlGetNodePath (xmlNodePtr node);
+ xmlGetNodePath (const xmlNode *node);
#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED) */
XMLPUBFUN xmlNodePtr XMLCALL
- xmlDocGetRootElement (xmlDocPtr doc);
+ xmlDocGetRootElement (const xmlDoc *doc);
XMLPUBFUN xmlNodePtr XMLCALL
- xmlGetLastChild (xmlNodePtr parent);
+ xmlGetLastChild (const xmlNode *parent);
XMLPUBFUN int XMLCALL
- xmlNodeIsText (xmlNodePtr node);
+ xmlNodeIsText (const xmlNode *node);
XMLPUBFUN int XMLCALL
- xmlIsBlankNode (xmlNodePtr node);
+ xmlIsBlankNode (const xmlNode *node);
/*
* Changing the structure.
@@ -945,7 +950,7 @@
xmlNodePtr cur);
#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED) */
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
- defined(LIBXML_SCHEMAS_ENABLED)
+ defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
XMLPUBFUN xmlNodePtr XMLCALL
xmlAddPrevSibling (xmlNodePtr cur,
xmlNodePtr elem);
@@ -986,10 +991,11 @@
xmlSearchNsByHref (xmlDocPtr doc,
xmlNodePtr node,
const xmlChar *href);
-#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || \
+ defined(LIBXML_SCHEMAS_ENABLED)
XMLPUBFUN xmlNsPtr * XMLCALL
- xmlGetNsList (xmlDocPtr doc,
- xmlNodePtr node);
+ xmlGetNsList (const xmlDoc *doc,
+ const xmlNode *node);
#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) */
XMLPUBFUN void XMLCALL
@@ -1003,7 +1009,8 @@
/*
* Changing the content.
*/
-#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED)
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || \
+ defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED)
XMLPUBFUN xmlAttrPtr XMLCALL
xmlSetProp (xmlNodePtr node,
const xmlChar *name,
@@ -1013,39 +1020,40 @@
xmlNsPtr ns,
const xmlChar *name,
const xmlChar *value);
-#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED) */
+#endif /* defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || \
+ defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED) */
XMLPUBFUN xmlChar * XMLCALL
- xmlGetNoNsProp (xmlNodePtr node,
+ xmlGetNoNsProp (const xmlNode *node,
const xmlChar *name);
XMLPUBFUN xmlChar * XMLCALL
- xmlGetProp (xmlNodePtr node,
+ xmlGetProp (const xmlNode *node,
const xmlChar *name);
XMLPUBFUN xmlAttrPtr XMLCALL
- xmlHasProp (xmlNodePtr node,
+ xmlHasProp (const xmlNode *node,
const xmlChar *name);
XMLPUBFUN xmlAttrPtr XMLCALL
- xmlHasNsProp (xmlNodePtr node,
+ xmlHasNsProp (const xmlNode *node,
const xmlChar *name,
const xmlChar *nameSpace);
XMLPUBFUN xmlChar * XMLCALL
- xmlGetNsProp (xmlNodePtr node,
+ xmlGetNsProp (const xmlNode *node,
const xmlChar *name,
const xmlChar *nameSpace);
XMLPUBFUN xmlNodePtr XMLCALL
- xmlStringGetNodeList (xmlDocPtr doc,
+ xmlStringGetNodeList (const xmlDoc *doc,
const xmlChar *value);
XMLPUBFUN xmlNodePtr XMLCALL
- xmlStringLenGetNodeList (xmlDocPtr doc,
+ xmlStringLenGetNodeList (const xmlDoc *doc,
const xmlChar *value,
int len);
XMLPUBFUN xmlChar * XMLCALL
xmlNodeListGetString (xmlDocPtr doc,
- xmlNodePtr list,
+ const xmlNode *list,
int inLine);
#ifdef LIBXML_TREE_ENABLED
XMLPUBFUN xmlChar * XMLCALL
- xmlNodeListGetRawString (xmlDocPtr doc,
- xmlNodePtr list,
+ xmlNodeListGetRawString (const xmlDoc *doc,
+ const xmlNode *list,
int inLine);
#endif /* LIBXML_TREE_ENABLED */
XMLPUBFUN void XMLCALL
@@ -1065,19 +1073,19 @@
const xmlChar *content,
int len);
XMLPUBFUN xmlChar * XMLCALL
- xmlNodeGetContent (xmlNodePtr cur);
+ xmlNodeGetContent (const xmlNode *cur);
XMLPUBFUN int XMLCALL
xmlNodeBufGetContent (xmlBufferPtr buffer,
- xmlNodePtr cur);
+ const xmlNode *cur);
XMLPUBFUN int XMLCALL
xmlBufGetNodeContent (xmlBufPtr buf,
- xmlNodePtr cur);
+ const xmlNode *cur);
XMLPUBFUN xmlChar * XMLCALL
- xmlNodeGetLang (xmlNodePtr cur);
+ xmlNodeGetLang (const xmlNode *cur);
XMLPUBFUN int XMLCALL
- xmlNodeGetSpacePreserve (xmlNodePtr cur);
+ xmlNodeGetSpacePreserve (const xmlNode *cur);
#ifdef LIBXML_TREE_ENABLED
XMLPUBFUN void XMLCALL
xmlNodeSetLang (xmlNodePtr cur,
@@ -1087,8 +1095,8 @@
int val);
#endif /* LIBXML_TREE_ENABLED */
XMLPUBFUN xmlChar * XMLCALL
- xmlNodeGetBase (xmlDocPtr doc,
- xmlNodePtr cur);
+ xmlNodeGetBase (const xmlDoc *doc,
+ const xmlNode *cur);
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
XMLPUBFUN void XMLCALL
xmlNodeSetBase (xmlNodePtr cur,
@@ -1234,7 +1242,7 @@
* Compression.
*/
XMLPUBFUN int XMLCALL
- xmlGetDocCompressMode (xmlDocPtr doc);
+ xmlGetDocCompressMode (const xmlDoc *doc);
XMLPUBFUN void XMLCALL
xmlSetDocCompressMode (xmlDocPtr doc,
int mode);
diff --git a/include/libxml/xmlIO.h b/include/libxml/xmlIO.h
index 6c241a8..3e41744 100644
--- a/include/libxml/xmlIO.h
+++ b/include/libxml/xmlIO.h
@@ -209,7 +209,7 @@
xmlParserInputBufferPtr
__xmlParserInputBufferCreateFilename(const char *URI,
- xmlCharEncoding enc);
+ xmlCharEncoding enc);
#ifdef LIBXML_OUTPUT_ENABLED
/*
diff --git a/include/libxml/xmlerror.h b/include/libxml/xmlerror.h
index 537a396..037c16d 100644
--- a/include/libxml/xmlerror.h
+++ b/include/libxml/xmlerror.h
@@ -86,7 +86,7 @@
char *str2; /* extra string information */
char *str3; /* extra string information */
int int1; /* extra number information */
- int int2; /* column number of the error or 0 if N/A (todo: rename this field when we would break ABI) */
+ int int2; /* error column # or 0 if N/A (todo: rename field when we would brk ABI) */
void *ctxt; /* the parser context if available */
void *node; /* the node in the tree */
};
@@ -937,7 +937,7 @@
int code,
xmlNodePtr node,
const char *msg,
- const char *extra);
+ const char *extra) LIBXML_ATTR_FORMAT(4,0);
#endif
#ifdef __cplusplus
}
diff --git a/include/libxml/xmlstring.h b/include/libxml/xmlstring.h
index 2036236..2d0b2d1 100644
--- a/include/libxml/xmlstring.h
+++ b/include/libxml/xmlstring.h
@@ -97,13 +97,13 @@
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/include/libxml/xmlversion.h b/include/libxml/xmlversion.h
index 1264867..321d5eb 100644
--- a/include/libxml/xmlversion.h
+++ b/include/libxml/xmlversion.h
@@ -29,28 +29,28 @@
*
* the version string like "1.2.3"
*/
-#define LIBXML_DOTTED_VERSION "2.9.1"
+#define LIBXML_DOTTED_VERSION "2.9.2"
/**
* LIBXML_VERSION:
*
* the version number: 1.2.3 value is 10203
*/
-#define LIBXML_VERSION 20901
+#define LIBXML_VERSION 20902
/**
* LIBXML_VERSION_STRING:
*
* the version number string, 1.2.3 value is "10203"
*/
-#define LIBXML_VERSION_STRING "20901"
+#define LIBXML_VERSION_STRING "20902"
/**
* LIBXML_VERSION_EXTRA:
*
* extra version information, used to show a CVS compilation
*/
-#define LIBXML_VERSION_EXTRA "-GITv2.9.1"
+#define LIBXML_VERSION_EXTRA "-GITv2.9.2-48-g4b31d61"
/**
* LIBXML_TEST_VERSION:
@@ -58,7 +58,7 @@
* 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(20901);
+#define LIBXML_TEST_VERSION xmlCheckVersion(20902);
#ifndef VMS
#if 0
@@ -435,7 +435,7 @@
*/
#ifndef LIBXML_ATTR_ALLOC_SIZE
-# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
+# if (!defined(__clang__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))))
# define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
# else
# define LIBXML_ATTR_ALLOC_SIZE(x)
diff --git a/include/libxml/xpathInternals.h b/include/libxml/xpathInternals.h
index 70c9db9..76a6b48 100644
--- a/include/libxml/xpathInternals.h
+++ b/include/libxml/xpathInternals.h
@@ -229,7 +229,7 @@
* 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/legacy.c b/legacy.c
index e941cb0..86362bf 100644
--- a/legacy.c
+++ b/legacy.c
@@ -1151,7 +1151,7 @@
endElement(void *ctx, const xmlChar * name ATTRIBUTE_UNUSED)
{
DEPRECATED("endElement")
- xmlSAX2EndElement(ctx, name);
+ xmlSAX2EndElement(ctx, name);
}
/**
diff --git a/libxml.h b/libxml.h
index 2da9044..88e515f 100644
--- a/libxml.h
+++ b/libxml.h
@@ -9,6 +9,8 @@
#ifndef __XML_LIBXML_H__
#define __XML_LIBXML_H__
+#include <libxml/xmlstring.h>
+
#ifndef NO_LARGEFILE_SOURCE
#ifndef _LARGEFILE_SOURCE
#define _LARGEFILE_SOURCE
@@ -68,7 +70,7 @@
* 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,6 +95,7 @@
int __xmlRandom(void);
#endif
+XMLPUBFUN xmlChar * XMLCALL xmlEscapeFormatString(xmlChar **msg);
int xmlNop(void);
#ifdef IN_LIBXML
diff --git a/nanoftp.c b/nanoftp.c
index 077bfe2..2135ab9 100644
--- a/nanoftp.c
+++ b/nanoftp.c
@@ -775,7 +775,7 @@
#ifdef DEBUG_FTP
xmlGenericError(xmlGenericErrorContext, "%s", buf);
#endif
- res = send(ctxt->controlFd, buf, len, 0);
+ res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
return(res);
@@ -803,7 +803,7 @@
#ifdef DEBUG_FTP
xmlGenericError(xmlGenericErrorContext, "%s", buf);
#endif
- res = send(ctxt->controlFd, buf, len, 0);
+ res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
return(res);
@@ -834,7 +834,7 @@
#ifdef DEBUG_FTP
xmlGenericError(xmlGenericErrorContext, "%s", buf); /* Just to be consistent, even though we know it can't have a % in it */
#endif
- res = send(ctxt->controlFd, buf, len, 0);
+ res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
return(res);
@@ -908,6 +908,8 @@
return (-1);
}
if (tmp->ai_addrlen > sizeof(ctxt->ftpAddr)) {
+ if (result)
+ freeaddrinfo (result);
__xmlIOErr(XML_FROM_FTP, 0, "gethostbyname address mismatch");
return (-1);
}
@@ -928,9 +930,9 @@
#endif
{
if (proxy)
- hp = gethostbyname (proxy);
+ hp = gethostbyname (GETHOSTBYNAME_ARG_CAST proxy);
else
- hp = gethostbyname (ctxt->hostname);
+ hp = gethostbyname (GETHOSTBYNAME_ARG_CAST ctxt->hostname);
if (hp == NULL) {
__xmlIOErr(XML_FROM_FTP, 0, "gethostbyname failed");
return (-1);
@@ -1028,7 +1030,7 @@
#ifdef DEBUG_FTP
xmlGenericError(xmlGenericErrorContext, "%s", buf);
#endif
- res = send(ctxt->controlFd, buf, len, 0);
+ res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
closesocket(ctxt->controlFd);
@@ -1050,7 +1052,7 @@
#ifdef DEBUG_FTP
xmlGenericError(xmlGenericErrorContext, "%s", buf);
#endif
- res = send(ctxt->controlFd, buf, len, 0);
+ res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
closesocket(ctxt->controlFd);
@@ -1091,7 +1093,7 @@
#ifdef DEBUG_FTP
xmlGenericError(xmlGenericErrorContext, "%s", buf);
#endif
- res = send(ctxt->controlFd, buf, len, 0);
+ res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
@@ -1122,7 +1124,7 @@
#ifdef DEBUG_FTP
xmlGenericError(xmlGenericErrorContext, "%s", buf);
#endif
- res = send(ctxt->controlFd, buf, len, 0);
+ res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
@@ -1144,7 +1146,7 @@
#ifdef DEBUG_FTP
xmlGenericError(xmlGenericErrorContext, "%s", buf);
#endif
- res = send(ctxt->controlFd, buf, len, 0);
+ res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
@@ -1244,7 +1246,13 @@
if (port <= 0)
return(NULL);
ctxt = (xmlNanoFTPCtxtPtr) xmlNanoFTPNewCtxt(NULL);
+ if (ctxt == NULL)
+ return(NULL);
ctxt->hostname = xmlMemStrdup(server);
+ if (ctxt->hostname == NULL) {
+ xmlNanoFTPFreeCtxt(ctxt);
+ return(NULL);
+ }
if (port != 0)
ctxt->port = port;
res = xmlNanoFTPConnect(ctxt);
@@ -1288,7 +1296,7 @@
#ifdef DEBUG_FTP
xmlGenericError(xmlGenericErrorContext, "%s", buf);
#endif
- res = send(ctxt->controlFd, buf, len, 0);
+ res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
return(res);
@@ -1321,8 +1329,8 @@
int len;
int res;
- if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET) || (file == NULL)) return(-1);
- if (file == NULL) return (0);
+ if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET) ||
+ (file == NULL)) return(-1);
/*
* Expected response code for DELE:
@@ -1339,7 +1347,7 @@
#ifdef DEBUG_FTP
xmlGenericError(xmlGenericErrorContext, "%s", buf);
#endif
- res = send(ctxt->controlFd, buf, len, 0);
+ res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
return(res);
@@ -1411,7 +1419,7 @@
#ifdef DEBUG_FTP
xmlGenericError(xmlGenericErrorContext, "%s", buf);
#endif
- res = send(ctxt->controlFd, buf, len, 0);
+ res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
@@ -1512,7 +1520,7 @@
xmlGenericError(xmlGenericErrorContext, "%s", buf);
#endif
- res = send(ctxt->controlFd, buf, len, 0);
+ res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
@@ -1749,7 +1757,7 @@
#ifdef DEBUG_FTP
xmlGenericError(xmlGenericErrorContext, "%s", buf);
#endif
- res = send(ctxt->controlFd, buf, len, 0);
+ res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
@@ -1844,7 +1852,7 @@
#ifdef DEBUG_FTP
xmlGenericError(xmlGenericErrorContext, "%s", buf);
#endif
- res = send(ctxt->controlFd, buf, len, 0);
+ res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
@@ -1864,7 +1872,7 @@
#ifdef DEBUG_FTP
xmlGenericError(xmlGenericErrorContext, "%s", buf);
#endif
- res = send(ctxt->controlFd, buf, len, 0);
+ res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
diff --git a/nanohttp.c b/nanohttp.c
index ac47ea6..e109ad7 100644
--- a/nanohttp.c
+++ b/nanohttp.c
@@ -461,7 +461,7 @@
if ((ctxt->state & XML_NANO_HTTP_WRITE) && (xmt_ptr != NULL)) {
while (total_sent < outlen) {
- int nsent = send(ctxt->fd, xmt_ptr + total_sent,
+ int nsent = send(ctxt->fd, SEND_ARG2_CAST (xmt_ptr + total_sent),
outlen - total_sent, 0);
if (nsent > 0)
@@ -1003,6 +1003,7 @@
0) {
/* Solaris error code */
__xmlIOErr(XML_FROM_HTTP, 0, "getsockopt failed\n");
+ closesocket(s);
return INVALID_SOCKET;
}
#endif
@@ -1121,7 +1122,7 @@
#endif
#if !defined(HAVE_GETADDRINFO) || !defined(_WIN32)
{
- h = gethostbyname (host);
+ h = gethostbyname (GETHOSTBYNAME_ARG_CAST host);
if (h == NULL) {
/*
@@ -1362,17 +1363,17 @@
xmlNanoHTTPInit();
retry:
- if (redirURL == NULL)
+ if (redirURL == NULL) {
ctxt = xmlNanoHTTPNewCtxt(URL);
- else {
+ if (ctxt == NULL)
+ return(NULL);
+ } else {
ctxt = xmlNanoHTTPNewCtxt(redirURL);
+ if (ctxt == NULL)
+ return(NULL);
ctxt->location = xmlMemStrdup(redirURL);
}
- if ( ctxt == NULL ) {
- return ( NULL );
- }
-
if ((ctxt->protocol == NULL) || (strcmp(ctxt->protocol, "http"))) {
__xmlIOErr(XML_FROM_HTTP, XML_HTTP_URL_SYNTAX, "Not a valid HTTP URI");
xmlNanoHTTPFreeCtxt(ctxt);
diff --git a/parser.c b/parser.c
index ee429f3..53a6b7f 100644
--- a/parser.c
+++ b/parser.c
@@ -94,6 +94,8 @@
xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
const xmlChar *base, xmlParserCtxtPtr pctx);
+static void xmlHaltParser(xmlParserCtxtPtr ctxt);
+
/************************************************************************
* *
* Arbitrary limits set in the parser. See XML_PARSE_HUGE *
@@ -130,6 +132,35 @@
return (0);
if (ctxt->lastError.code == XML_ERR_ENTITY_LOOP)
return (1);
+
+ /*
+ * This may look absurd but is needed to detect
+ * entities problems
+ */
+ if ((ent != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) &&
+ (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 (ctxt->errNo == XML_ERR_ENTITY_LOOP) {
+ ent->content[0] = 0;
+ }
+
+ ent->checked = (ctxt->nbentities - oldnbent + 1) * 2;
+ if (rep != NULL) {
+ if (xmlStrchr(rep, '<'))
+ ent->checked |= 1;
+ xmlFree(rep);
+ rep = NULL;
+ }
+ }
if (replacement != 0) {
if (replacement < XML_MAX_TEXT_LENGTH)
return(0);
@@ -189,9 +220,12 @@
return (0);
} else {
/*
- * strange we got no data for checking just return
+ * strange we got no data for checking
*/
- return (0);
+ if (((ctxt->lastError.code != XML_ERR_UNDECLARED_ENTITY) &&
+ (ctxt->lastError.code != XML_WAR_UNDECLARED_ENTITY)) ||
+ (ctxt->nbentities <= 10000))
+ return (0);
}
xmlFatalErr(ctxt, XML_ERR_ENTITY_LOOP, NULL);
return (1);
@@ -316,7 +350,6 @@
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))
@@ -503,15 +536,17 @@
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)
@@ -527,7 +562,7 @@
*
* 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)
{
@@ -555,7 +590,7 @@
*
* 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)
{
@@ -593,7 +628,7 @@
*
* 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)
{
@@ -633,7 +668,7 @@
*
* 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)
{
@@ -663,7 +698,7 @@
*
* 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)
@@ -693,7 +728,7 @@
*
* 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)
{
@@ -722,7 +757,7 @@
*
* 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)
{
@@ -747,7 +782,7 @@
*
* 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,
@@ -776,7 +811,7 @@
*
* 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,
@@ -1745,7 +1780,7 @@
xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
"Excessive depth in document: %d use XML_PARSE_HUGE option\n",
xmlParserMaxDepth);
- ctxt->instate = XML_PARSER_EOF;
+ xmlHaltParser(ctxt);
return(-1);
}
ctxt->nodeTab[ctxt->nodeNr] = value;
@@ -1980,6 +2015,7 @@
#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 && \
@@ -2039,14 +2075,24 @@
xmlGROW (ctxt);
static void xmlGROW (xmlParserCtxtPtr ctxt) {
- if ((((ctxt->input->end - ctxt->input->cur) > XML_MAX_LOOKUP_LIMIT) ||
- ((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
+ unsigned long curEnd = ctxt->input->end - ctxt->input->cur;
+ unsigned long curBase = ctxt->input->cur - ctxt->input->base;
+
+ 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->options & XML_PARSE_HUGE) == 0)) {
xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
- ctxt->instate = XML_PARSER_EOF;
+ xmlHaltParser(ctxt);
+ return;
}
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+ if ((ctxt->input->cur > ctxt->input->end) ||
+ (ctxt->input->cur < ctxt->input->base)) {
+ xmlHaltParser(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);
@@ -2106,6 +2152,8 @@
while (IS_BLANK_CH(*cur)) {
if (*cur == '\n') {
ctxt->input->line++; ctxt->input->col = 1;
+ } else {
+ ctxt->input->col++;
}
cur++;
res++;
@@ -2120,7 +2168,8 @@
int cur;
do {
cur = CUR;
- while (IS_BLANK_CH(cur)) { /* CHECKED tstblanks.xml */
+ while ((IS_BLANK_CH(cur) && /* CHECKED tstblanks.xml */
+ (ctxt->instate != XML_PARSER_EOF))) {
NEXT;
cur = CUR;
res++;
@@ -2134,7 +2183,8 @@
* Need to handle support of entities branching here
*/
if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);
- } while (IS_BLANK(cur)); /* CHECKED tstblanks.xml */
+ } while ((IS_BLANK(cur)) && /* CHECKED tstblanks.xml */
+ (ctxt->instate != XML_PARSER_EOF));
}
return(res);
}
@@ -2584,6 +2634,7 @@
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)
@@ -2595,6 +2646,23 @@
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.
@@ -2737,6 +2805,7 @@
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;
if ((ent != NULL) &&
@@ -2756,6 +2825,10 @@
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 */
@@ -2788,11 +2861,26 @@
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,
@@ -3404,6 +3492,7 @@
int len = 0, l;
int c;
int count = 0;
+ size_t startPosition = 0;
#ifdef DEBUG
nbParseNCNameComplex++;
@@ -3413,6 +3502,7 @@
* Handler for more complex cases
*/
GROW;
+ startPosition = CUR_PTR - BASE_PTR;
c = CUR_CHAR(l);
if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
(!xmlIsNameStartChar(ctxt, c) || (c == ':'))) {
@@ -3437,7 +3527,14 @@
c = CUR_CHAR(l);
if (c == 0) {
count = 0;
+ /*
+ * when shrinking to extend the buffer we really need to preserve
+ * the part of the name we already parsed. Hence rolling back
+ * by current lenght.
+ */
+ ctxt->input->cur -= l;
GROW;
+ ctxt->input->cur += l;
if (ctxt->instate == XML_PARSER_EOF)
return(NULL);
c = CUR_CHAR(l);
@@ -3448,7 +3545,7 @@
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
return(NULL);
}
- return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
+ return(xmlDictLookup(ctxt->dict, (BASE_PTR + startPosition), len));
}
/**
@@ -3468,7 +3565,7 @@
static const xmlChar *
xmlParseNCName(xmlParserCtxtPtr ctxt) {
- const xmlChar *in;
+ const xmlChar *in, *e;
const xmlChar *ret;
int count = 0;
@@ -3480,16 +3577,19 @@
* Accelerator for simple ASCII names
*/
in = ctxt->input->cur;
- if (((*in >= 0x61) && (*in <= 0x7A)) ||
- ((*in >= 0x41) && (*in <= 0x5A)) ||
- (*in == '_')) {
+ e = ctxt->input->end;
+ if ((((*in >= 0x61) && (*in <= 0x7A)) ||
+ ((*in >= 0x41) && (*in <= 0x5A)) ||
+ (*in == '_')) && (in < e)) {
in++;
- while (((*in >= 0x61) && (*in <= 0x7A)) ||
- ((*in >= 0x41) && (*in <= 0x5A)) ||
- ((*in >= 0x30) && (*in <= 0x39)) ||
- (*in == '_') || (*in == '-') ||
- (*in == '.'))
+ while ((((*in >= 0x61) && (*in <= 0x7A)) ||
+ ((*in >= 0x41) && (*in <= 0x5A)) ||
+ ((*in >= 0x30) && (*in <= 0x39)) ||
+ (*in == '_') || (*in == '-') ||
+ (*in == '.')) && (in < e))
in++;
+ if (in >= e)
+ goto complex;
if ((*in > 0) && (*in < 0x80)) {
count = in - ctxt->input->cur;
if ((count > XML_MAX_NAME_LENGTH) &&
@@ -3507,6 +3607,7 @@
return(ret);
}
}
+complex:
return(xmlParseNCNameComplex(ctxt));
}
@@ -3544,7 +3645,7 @@
}
/* 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;
}
@@ -3885,8 +3986,10 @@
* an entity declaration, it is bypassed and left as is.
* so XML_SUBSTITUTE_REF is not set here.
*/
+ ++ctxt->depth;
ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF,
0, 0, 0);
+ --ctxt->depth;
if (orig != NULL)
*orig = buf;
else
@@ -4011,9 +4114,11 @@
} 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 */
@@ -4049,8 +4154,10 @@
(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) {
@@ -5075,7 +5182,7 @@
}
if ((name != NULL) && (xmlStrchr(name, ':') != NULL)) {
xmlNsErr(ctxt, XML_NS_ERR_COLON,
- "colon are forbidden from PI names '%s'\n", name, NULL, NULL);
+ "colons are forbidden from PI names '%s'\n", name, NULL, NULL);
}
return(name);
}
@@ -5344,7 +5451,7 @@
}
if (xmlStrchr(name, ':') != NULL) {
xmlNsErr(ctxt, XML_NS_ERR_COLON,
- "colon are forbidden from notation names '%s'\n",
+ "colons are forbidden from notation names '%s'\n",
name, NULL, NULL);
}
SKIP_BLANKS;
@@ -5420,7 +5527,7 @@
skipped = SKIP_BLANKS;
if (skipped == 0) {
xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
- "Space required after '%'\n");
+ "Space required after '%%'\n");
}
isParameter = 1;
}
@@ -5433,7 +5540,7 @@
}
if (xmlStrchr(name, ':') != NULL) {
xmlNsErr(ctxt, XML_NS_ERR_COLON,
- "colon are forbidden from entities names '%s'\n",
+ "colons are forbidden from entities names '%s'\n",
name, NULL, NULL);
}
skipped = SKIP_BLANKS;
@@ -5603,6 +5710,7 @@
if (RAW != '>') {
xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
"xmlParseEntityDecl: entity %s not terminated\n", name);
+ xmlHaltParser(ctxt);
} else {
if (input != ctxt->input) {
xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_BOUNDARY,
@@ -6604,6 +6712,7 @@
if (!IS_BLANK_CH(CUR)) {
xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
"Space required after 'ELEMENT'\n");
+ return(-1);
}
SKIP_BLANKS;
name = xmlParseName(ctxt);
@@ -6714,6 +6823,8 @@
SKIP_BLANKS;
if (RAW != '[') {
xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
+ xmlHaltParser(ctxt);
+ return;
} else {
if (ctxt->input->id != id) {
xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
@@ -6753,6 +6864,7 @@
if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
+ xmlHaltParser(ctxt);
break;
}
}
@@ -6774,6 +6886,8 @@
SKIP_BLANKS;
if (RAW != '[') {
xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID, NULL);
+ xmlHaltParser(ctxt);
+ return;
} else {
if (ctxt->input->id != id) {
xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
@@ -6829,6 +6943,8 @@
} else {
xmlFatalErr(ctxt, XML_ERR_CONDSEC_INVALID_KEYWORD, NULL);
+ xmlHaltParser(ctxt);
+ return;
}
if (RAW == 0)
@@ -6842,7 +6958,9 @@
"All markup of the conditional section is not in the same entity\n",
NULL, NULL);
}
- SKIP(3);
+ if ((ctxt-> instate != XML_PARSER_EOF) &&
+ ((ctxt->input->cur + 3) <= ctxt->input->end))
+ SKIP(3);
}
}
@@ -6897,6 +7015,14 @@
xmlParsePI(ctxt);
}
}
+
+ /*
+ * detect requirement to exit there and act accordingly
+ * and avoid having instate overriden later on
+ */
+ if (ctxt->instate == XML_PARSER_EOF)
+ return;
+
/*
* This is only for internal subset. On external entities,
* the replacement is done before parsing stage
@@ -7028,7 +7154,7 @@
/*
* The XML REC instructs us to stop parsing right here
*/
- ctxt->instate = XML_PARSER_EOF;
+ xmlHaltParser(ctxt);
return;
}
}
@@ -7180,7 +7306,8 @@
* far more secure as the parser will only process data coming from
* the document entity by default.
*/
- if ((ent->checked == 0) &&
+ if (((ent->checked == 0) ||
+ ((ent->children == NULL) && (ctxt->options & XML_PARSE_NOENT))) &&
((ent->etype != XML_EXTERNAL_GENERAL_PARSED_ENTITY) ||
(ctxt->options & (XML_PARSE_NOENT | XML_PARSE_DTDVALID)))) {
unsigned long oldnbent = ctxt->nbentities;
@@ -7286,6 +7413,7 @@
(ret != XML_WAR_UNDECLARED_ENTITY)) {
xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY,
"Entity '%s' failed to parse\n", ent->name);
+ xmlParserEntityCheck(ctxt, 0, ent, 0);
} else if (list != NULL) {
xmlFreeNodeList(list);
list = NULL;
@@ -7392,7 +7520,7 @@
/*
* We are copying here, make sure there is no abuse
*/
- ctxt->sizeentcopy += ent->length;
+ ctxt->sizeentcopy += ent->length + 5;
if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
return;
@@ -7440,7 +7568,7 @@
/*
* We are copying here, make sure there is no abuse
*/
- ctxt->sizeentcopy += ent->length;
+ ctxt->sizeentcopy += ent->length + 5;
if (xmlParserEntityCheck(ctxt, 0, ent, ctxt->sizeentcopy))
return;
@@ -7626,6 +7754,7 @@
ctxt->sax->reference(ctxt->userData, name);
}
}
+ xmlParserEntityCheck(ctxt, 0, ent, 0);
ctxt->valid = 0;
}
@@ -7658,8 +7787,8 @@
else if ((ctxt->instate == XML_PARSER_ATTRIBUTE_VALUE) &&
(ent != NULL) &&
(ent->etype != XML_INTERNAL_PREDEFINED_ENTITY)) {
- if ((ent->checked & 1) || ((ent->checked == 0) &&
- (ent->content != NULL) &&(xmlStrchr(ent->content, '<')))) {
+ if (((ent->checked & 1) || (ent->checked == 0)) &&
+ (ent->content != NULL) && (xmlStrchr(ent->content, '<'))) {
xmlFatalErrMsgStr(ctxt, XML_ERR_LT_IN_ATTRIBUTE,
"'<' in entity '%s' is not allowed in attributes values\n", name);
}
@@ -7753,7 +7882,7 @@
/*
- * Predefined entites override any extra definition
+ * Predefined entities override any extra definition
*/
if ((ctxt->options & XML_PARSE_OLDSAX) == 0) {
ent = xmlGetPredefinedEntity(name);
@@ -7819,6 +7948,7 @@
"Entity '%s' not defined\n",
name);
}
+ xmlParserEntityCheck(ctxt, 0, ent, 0);
/* TODO ? check regressions ctxt->valid = 0; */
}
@@ -7978,6 +8108,7 @@
name, NULL);
ctxt->valid = 0;
}
+ xmlParserEntityCheck(ctxt, 0, NULL, 0);
} else {
/*
* Internal checking in case the entity quest barfed
@@ -8010,7 +8141,7 @@
* The XML REC instructs us to stop parsing
* right here
*/
- ctxt->instate = XML_PARSER_EOF;
+ xmlHaltParser(ctxt);
return;
}
}
@@ -8217,6 +8348,7 @@
name, NULL);
ctxt->valid = 0;
}
+ xmlParserEntityCheck(ctxt, 0, NULL, 0);
} else {
/*
* Internal checking in case the entity quest barfed
@@ -8364,6 +8496,7 @@
*/
if (RAW != '>') {
xmlFatalErr(ctxt, XML_ERR_DOCTYPE_NOT_FINISHED, NULL);
+ return;
}
NEXT;
}
@@ -8714,7 +8847,7 @@
* @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
*/
@@ -8906,9 +9039,12 @@
xmlChar limit = 0;
const xmlChar *in = NULL, *start, *end, *last;
xmlChar *ret = NULL;
+ int line, col;
GROW;
in = (xmlChar *) CUR_PTR;
+ line = ctxt->input->line;
+ col = ctxt->input->col;
if (*in != '"' && *in != '\'') {
xmlFatalErr(ctxt, XML_ERR_ATTRIBUTE_NOT_STARTED, NULL);
return (NULL);
@@ -8921,6 +9057,7 @@
* pure ASCII.
*/
limit = *in++;
+ col++;
end = ctxt->input->end;
start = in;
if (in >= end) {
@@ -8940,6 +9077,11 @@
while ((in < end) && (*in != limit) &&
((*in == 0x20) || (*in == 0x9) ||
(*in == 0xA) || (*in == 0xD))) {
+ if (*in == 0xA) {
+ line++; col = 1;
+ } else {
+ col++;
+ }
in++;
start = in;
if (in >= end) {
@@ -8963,6 +9105,7 @@
}
while ((in < end) && (*in != limit) && (*in >= 0x20) &&
(*in <= 0x7f) && (*in != '&') && (*in != '<')) {
+ col++;
if ((*in++ == 0x20) && (*in == 0x20)) break;
if (in >= end) {
const xmlChar *oldbase = ctxt->input->base;
@@ -8991,6 +9134,11 @@
while ((in < end) && (*in != limit) &&
((*in == 0x20) || (*in == 0x9) ||
(*in == 0xA) || (*in == 0xD))) {
+ if (*in == 0xA) {
+ line++, col = 1;
+ } else {
+ col++;
+ }
in++;
if (in >= end) {
const xmlChar *oldbase = ctxt->input->base;
@@ -9023,6 +9171,7 @@
while ((in < end) && (*in != limit) && (*in >= 0x20) &&
(*in <= 0x7f) && (*in != '&') && (*in != '<')) {
in++;
+ col++;
if (in >= end) {
const xmlChar *oldbase = ctxt->input->base;
GROW;
@@ -9052,6 +9201,7 @@
if (*in != limit) goto need_complex;
}
in++;
+ col++;
if (len != NULL) {
*len = last - start;
ret = (xmlChar *) start;
@@ -9060,6 +9210,8 @@
ret = xmlStrndup(start, last - start);
}
CUR_PTR = in;
+ ctxt->input->line = line;
+ ctxt->input->col = col;
if (alloc) *alloc = 0;
return ret;
need_complex:
@@ -9225,7 +9377,7 @@
const xmlChar **atts = ctxt->atts;
int maxatts = ctxt->maxatts;
int nratts, nbatts, nbdef;
- int i, j, nbNs, attval, oldline, oldcol;
+ int i, j, nbNs, attval, oldline, oldcol, inputNr;
const xmlChar *base;
unsigned long cur;
int nsNr = ctxt->nsNr;
@@ -9244,6 +9396,7 @@
SHRINK;
base = ctxt->input->base;
cur = ctxt->input->cur - ctxt->input->base;
+ inputNr = ctxt->inputNr;
oldline = ctxt->input->line;
oldcol = ctxt->input->col;
nbatts = 0;
@@ -9269,7 +9422,8 @@
*/
SKIP_BLANKS;
GROW;
- if (ctxt->input->base != base) goto base_changed;
+ if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
+ goto base_changed;
while (((RAW != '>') &&
((RAW != '/') || (NXT(1) != '>')) &&
@@ -9280,7 +9434,7 @@
attname = xmlParseAttribute2(ctxt, prefix, localname,
&aprefix, &attvalue, &len, &alloc);
- if (ctxt->input->base != base) {
+ if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr)) {
if ((attvalue != NULL) && (alloc != 0))
xmlFree(attvalue);
attvalue = NULL;
@@ -9292,6 +9446,12 @@
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) {
@@ -9334,8 +9494,20 @@
else
if (nsPush(ctxt, NULL, URL) > 0) nbNs++;
skip_default_ns:
- if (alloc != 0) xmlFree(attvalue);
+ if ((attvalue != NULL) && (alloc != 0)) {
+ xmlFree(attvalue);
+ attvalue = NULL;
+ }
+ 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 (aprefix == ctxt->str_xmlns) {
@@ -9407,9 +9579,20 @@
else
if (nsPush(ctxt, attname, URL) > 0) nbNs++;
skip_ns:
- if (alloc != 0) xmlFree(attvalue);
+ if ((attvalue != NULL) && (alloc != 0)) {
+ xmlFree(attvalue);
+ attvalue = NULL;
+ }
+ 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) goto base_changed;
+ if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
+ goto base_changed;
continue;
}
@@ -9446,7 +9629,8 @@
GROW
if (ctxt->instate == XML_PARSER_EOF)
break;
- if (ctxt->input->base != base) goto base_changed;
+ if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
+ goto base_changed;
if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>'))))
break;
if (!IS_BLANK_CH(RAW)) {
@@ -9462,7 +9646,8 @@
break;
}
GROW;
- if (ctxt->input->base != base) goto base_changed;
+ if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr))
+ goto base_changed;
}
/*
@@ -9629,6 +9814,17 @@
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;
@@ -9657,6 +9853,7 @@
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) != '/')) {
@@ -9665,12 +9862,17 @@
}
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;
}
ctxt->input->cur += tlen;
+ ctxt->input->col += tlen;
name = (xmlChar*)1;
} else {
if (prefix == NULL)
@@ -9908,7 +10110,7 @@
if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
"detected an error in element content\n");
- ctxt->instate = XML_PARSER_EOF;
+ xmlHaltParser(ctxt);
break;
}
}
@@ -9943,7 +10145,7 @@
xmlFatalErrMsgInt(ctxt, XML_ERR_INTERNAL_ERROR,
"Excessive depth in document: %d use XML_PARSE_HUGE option\n",
xmlParserMaxDepth);
- ctxt->instate = XML_PARSER_EOF;
+ xmlHaltParser(ctxt);
return;
}
@@ -10295,6 +10497,8 @@
encoding = xmlParseEncName(ctxt);
if (RAW != '"') {
xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
+ xmlFree((xmlChar *) encoding);
+ return(NULL);
} else
NEXT;
} else if (RAW == '\''){
@@ -10302,6 +10506,8 @@
encoding = xmlParseEncName(ctxt);
if (RAW != '\'') {
xmlFatalErr(ctxt, XML_ERR_STRING_NOT_CLOSED, NULL);
+ xmlFree((xmlChar *) encoding);
+ return(NULL);
} else
NEXT;
} else {
@@ -10311,8 +10517,10 @@
/*
* Non standard parsing, allowing the user to ignore encoding
*/
- if (ctxt->options & XML_PARSE_IGNORE_ENC)
- return(encoding);
+ if (ctxt->options & XML_PARSE_IGNORE_ENC) {
+ xmlFree((xmlChar *) encoding);
+ return(NULL);
+ }
/*
* UTF-16 encoding stwich has already taken place at this stage,
@@ -10356,7 +10564,11 @@
handler = xmlFindCharEncodingHandler((const char *) encoding);
if (handler != NULL) {
- xmlSwitchToEncoding(ctxt, handler);
+ if (xmlSwitchToEncoding(ctxt, handler) < 0) {
+ /* failed to convert */
+ ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
+ return(NULL);
+ }
} else {
xmlFatalErrMsgStr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
"Unsupported encoding %s\n", encoding);
@@ -10525,7 +10737,8 @@
xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
}
xmlParseEncodingDecl(ctxt);
- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
+ if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
+ (ctxt->instate == XML_PARSER_EOF)) {
/*
* The XML REC instructs us to stop parsing right here
*/
@@ -10649,6 +10862,7 @@
if (CUR == 0) {
xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
+ return(-1);
}
/*
@@ -10666,7 +10880,8 @@
* Note that we will switch encoding on the fly.
*/
xmlParseXMLDecl(ctxt);
- if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
+ if ((ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) ||
+ (ctxt->instate == XML_PARSER_EOF)) {
/*
* The XML REC instructs us to stop parsing right here
*/
@@ -10681,6 +10896,10 @@
ctxt->sax->startDocument(ctxt->userData);
if (ctxt->instate == XML_PARSER_EOF)
return(-1);
+ if ((ctxt->myDoc != NULL) && (ctxt->input != NULL) &&
+ (ctxt->input->buf != NULL) && (ctxt->input->buf->compressed >= 0)) {
+ ctxt->myDoc->compression = ctxt->input->buf->compressed;
+ }
/*
* The Misc part of the Prolog
@@ -11031,8 +11250,9 @@
}
/**
* 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]
*
@@ -11040,7 +11260,7 @@
* UTF-8 error occured otherwise
*/
static int
-xmlCheckCdataPush(const xmlChar *utf, int len) {
+xmlCheckCdataPush(const xmlChar *utf, int len, int complete) {
int ix;
unsigned char c;
int codepoint;
@@ -11058,7 +11278,7 @@
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;
@@ -11067,7 +11287,7 @@
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);
@@ -11078,7 +11298,7 @@
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))
@@ -11256,7 +11476,7 @@
ctxt->sax->setDocumentLocator(ctxt->userData,
&xmlDefaultSAXLocator);
xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
- ctxt->instate = XML_PARSER_EOF;
+ xmlHaltParser(ctxt);
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
"PP: entering EOF\n");
@@ -11289,7 +11509,7 @@
* The XML REC instructs us to stop parsing right
* here
*/
- ctxt->instate = XML_PARSER_EOF;
+ xmlHaltParser(ctxt);
return(0);
}
ctxt->standalone = ctxt->input->standalone;
@@ -11345,7 +11565,7 @@
cur = ctxt->input->cur[0];
if (cur != '<') {
xmlFatalErr(ctxt, XML_ERR_DOCUMENT_EMPTY, NULL);
- ctxt->instate = XML_PARSER_EOF;
+ xmlHaltParser(ctxt);
if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
ctxt->sax->endDocument(ctxt->userData);
goto done;
@@ -11377,7 +11597,7 @@
goto done;
if (name == NULL) {
spacePop(ctxt);
- ctxt->instate = XML_PARSER_EOF;
+ xmlHaltParser(ctxt);
if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
ctxt->sax->endDocument(ctxt->userData);
goto done;
@@ -11544,7 +11764,7 @@
if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
"detected an error in element content\n");
- ctxt->instate = XML_PARSER_EOF;
+ xmlHaltParser(ctxt);
break;
}
break;
@@ -11593,7 +11813,7 @@
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;
@@ -11616,7 +11836,7 @@
} 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;
@@ -11865,7 +12085,7 @@
goto done;
} else {
xmlFatalErr(ctxt, XML_ERR_DOCUMENT_END, NULL);
- ctxt->instate = XML_PARSER_EOF;
+ xmlHaltParser(ctxt);
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
"PP: entering EOF\n");
@@ -12229,7 +12449,7 @@
res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
if (res < 0) {
ctxt->errNo = XML_PARSER_EOF;
- ctxt->disableSAX = 1;
+ xmlHaltParser(ctxt);
return (XML_PARSER_EOF);
}
xmlBufSetInputBaseCur(ctxt->input->buf->buffer, ctxt->input, base, cur);
@@ -12283,7 +12503,7 @@
((ctxt->input->cur - ctxt->input->base) > XML_MAX_LOOKUP_LIMIT)) &&
((ctxt->options & XML_PARSE_HUGE) == 0)) {
xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR, "Huge input lookup");
- ctxt->instate = XML_PARSER_EOF;
+ xmlHaltParser(ctxt);
}
if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
return(ctxt->errNo);
@@ -12471,6 +12691,33 @@
#endif /* LIBXML_PUSH_ENABLED */
/**
+ * xmlHaltParser:
+ * @ctxt: an XML parser context
+ *
+ * Blocks further parser processing don't override error
+ * for internal use
+ */
+static void
+xmlHaltParser(xmlParserCtxtPtr ctxt) {
+ if (ctxt == NULL)
+ return;
+ ctxt->instate = XML_PARSER_EOF;
+ ctxt->disableSAX = 1;
+ if (ctxt->input != NULL) {
+ /*
+ * in case there was a specific allocation deallocate before
+ * overriding base
+ */
+ if (ctxt->input->free != NULL) {
+ ctxt->input->free((xmlChar *) ctxt->input->base);
+ ctxt->input->free = NULL;
+ }
+ ctxt->input->cur = BAD_CAST"";
+ ctxt->input->base = ctxt->input->cur;
+ }
+}
+
+/**
* xmlStopParser:
* @ctxt: an XML parser context
*
@@ -12480,13 +12727,8 @@
xmlStopParser(xmlParserCtxtPtr ctxt) {
if (ctxt == NULL)
return;
- ctxt->instate = XML_PARSER_EOF;
+ xmlHaltParser(ctxt);
ctxt->errNo = XML_ERR_USER_STOP;
- ctxt->disableSAX = 1;
- if (ctxt->input != NULL) {
- ctxt->input->cur = BAD_CAST"";
- ctxt->input->base = ctxt->input->cur;
- }
}
/**
@@ -12591,6 +12833,9 @@
return(NULL);
}
+ /* We are loading a DTD */
+ ctxt->options |= XML_PARSE_DTDLOAD;
+
/*
* Set-up the SAX context
*/
@@ -12718,6 +12963,9 @@
return(NULL);
}
+ /* We are loading a DTD */
+ ctxt->options |= XML_PARSE_DTDLOAD;
+
/*
* Set-up the SAX context
*/
@@ -13227,7 +13475,7 @@
/*
* Also record the size of the entity parsed
*/
- if (ctxt->input != NULL) {
+ if (ctxt->input != NULL && oldctxt != NULL) {
oldctxt->sizeentities += ctxt->input->consumed;
oldctxt->sizeentities += (ctxt->input->cur - ctxt->input->base);
}
@@ -13239,9 +13487,11 @@
if (sax != NULL)
ctxt->sax = oldsax;
- oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
- oldctxt->node_seq.length = ctxt->node_seq.length;
- oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
+ if (oldctxt != NULL) {
+ oldctxt->node_seq.maximum = ctxt->node_seq.maximum;
+ oldctxt->node_seq.length = ctxt->node_seq.length;
+ oldctxt->node_seq.buffer = ctxt->node_seq.buffer;
+ }
ctxt->node_seq.maximum = 0;
ctxt->node_seq.length = 0;
ctxt->node_seq.buffer = NULL;
@@ -13607,7 +13857,7 @@
xmlFree((xmlChar *) ctxt->encoding);
ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
- hdlr = xmlFindCharEncodingHandler(doc->encoding);
+ hdlr = xmlFindCharEncodingHandler((const char *) doc->encoding);
if (hdlr != NULL) {
xmlSwitchToEncoding(ctxt, hdlr);
} else {
@@ -13618,6 +13868,8 @@
xmlCtxtUseOptionsInternal(ctxt, options, NULL);
xmlDetectSAX2(ctxt);
ctxt->myDoc = doc;
+ /* parsing in context, i.e. as within existing content */
+ ctxt->instate = XML_PARSER_CONTENT;
fake = xmlNewComment(NULL);
if (fake == NULL) {
@@ -13653,7 +13905,6 @@
}
cur = cur->parent;
}
- ctxt->instate = XML_PARSER_CONTENT;
}
if ((ctxt->validate) || (ctxt->replaceEntities != 0)) {
@@ -14763,8 +15014,8 @@
xmlSchemaCleanupTypes();
xmlRelaxNGCleanupTypes();
#endif
- xmlCleanupGlobals();
xmlResetLastError();
+ xmlCleanupGlobals();
xmlCleanupThreads(); /* must be last if called not from the main thread */
xmlCleanupMemory();
xmlParserInitialized = 0;
@@ -14780,7 +15031,7 @@
* 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) \
@@ -15213,6 +15464,7 @@
if (cur == NULL)
return (NULL);
+ xmlInitParser();
ctxt = xmlCreateDocParserCtxt(cur);
if (ctxt == NULL)
@@ -15235,6 +15487,7 @@
{
xmlParserCtxtPtr ctxt;
+ xmlInitParser();
ctxt = xmlCreateURLParserCtxt(filename, options);
if (ctxt == NULL)
return (NULL);
@@ -15258,6 +15511,7 @@
{
xmlParserCtxtPtr ctxt;
+ xmlInitParser();
ctxt = xmlCreateMemoryParserCtxt(buffer, size);
if (ctxt == NULL)
return (NULL);
@@ -15286,6 +15540,7 @@
if (fd < 0)
return (NULL);
+ xmlInitParser();
input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
if (input == NULL)
@@ -15329,6 +15584,7 @@
if (ioread == NULL)
return (NULL);
+ xmlInitParser();
input = xmlParserInputBufferCreateIO(ioread, ioclose, ioctx,
XML_CHAR_ENCODING_NONE);
@@ -15375,6 +15631,7 @@
return (NULL);
if (ctxt == NULL)
return (NULL);
+ xmlInitParser();
xmlCtxtReset(ctxt);
@@ -15408,6 +15665,7 @@
return (NULL);
if (ctxt == NULL)
return (NULL);
+ xmlInitParser();
xmlCtxtReset(ctxt);
@@ -15444,6 +15702,7 @@
return (NULL);
if (buffer == NULL)
return (NULL);
+ xmlInitParser();
xmlCtxtReset(ctxt);
@@ -15488,6 +15747,7 @@
return (NULL);
if (ctxt == NULL)
return (NULL);
+ xmlInitParser();
xmlCtxtReset(ctxt);
@@ -15533,6 +15793,7 @@
return (NULL);
if (ctxt == NULL)
return (NULL);
+ xmlInitParser();
xmlCtxtReset(ctxt);
diff --git a/parserInternals.c b/parserInternals.c
index f8a7041..bfc778a 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -55,6 +55,10 @@
#include <libxml/globals.h>
#include <libxml/chvalid.h>
+#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 @@
*
* 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 @@
*
* 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 @@
*/
int
xmlParserInputGrow(xmlParserInputPtr in, int len) {
- size_t ret;
+ int ret;
size_t indx;
const xmlChar *content;
@@ -422,103 +426,105 @@
(ctxt->input == NULL))
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
- */
+ 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)) {
+ if ((ctxt->instate != XML_PARSER_COMMENT))
xmlPopInput(ctxt);
- } else {
- const unsigned char *cur;
- unsigned char c;
+ return;
+ }
- /*
- * 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++;
+ if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
+ const unsigned char *cur;
+ unsigned char c;
- /*
- * 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;
+ /*
+ * 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++;
- c = *cur;
- if (c & 0x80) {
- if (c == 0xC0)
- goto encoding_error;
- if (cur[1] == 0) {
+ /*
+ * 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) {
+ 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++;
+ if (*ctxt->input->cur == 0)
+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
} else {
/*
* Assume it's a fixed length encoding (1) with
@@ -937,6 +943,7 @@
{
xmlCharEncodingHandlerPtr handler;
int len = -1;
+ int ret;
if (ctxt == NULL) return(-1);
switch (enc) {
@@ -1097,7 +1104,15 @@
if (handler == NULL)
return(-1);
ctxt->charset = XML_CHAR_ENCODING_UTF8;
- return(xmlSwitchToEncodingInt(ctxt, handler, len));
+ ret = xmlSwitchToEncodingInt(ctxt, handler, len);
+ if ((ret < 0) || (ctxt->errNo == XML_I18N_CONV_FAILED)) {
+ /*
+ * on encoding conversion errors, stop the parser
+ */
+ xmlStopParser(ctxt);
+ ctxt->errNo = XML_I18N_CONV_FAILED;
+ }
+ return(ret);
}
/**
@@ -1450,6 +1465,8 @@
if (entity->URI != NULL)
input->filename = (char *) xmlStrdup((xmlChar *) entity->URI);
input->base = entity->content;
+ if (entity->length == 0)
+ entity->length = xmlStrlen(entity->content);
input->cur = entity->content;
input->length = entity->length;
input->end = &entity->content[input->length];
@@ -1691,12 +1708,20 @@
ctxt->nsWellFormed = 1;
ctxt->valid = 1;
ctxt->loadsubset = xmlLoadExtDtdDefaultValue;
+ if (ctxt->loadsubset) {
+ ctxt->options |= XML_PARSE_DTDLOAD;
+ }
ctxt->validate = xmlDoValidityCheckingDefaultValue;
ctxt->pedantic = xmlPedanticParserDefaultValue;
+ if (ctxt->pedantic) {
+ ctxt->options |= XML_PARSE_PEDANTIC;
+ }
ctxt->linenumbers = xmlLineNumbersDefaultValue;
ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
- if (ctxt->keepBlanks == 0)
+ if (ctxt->keepBlanks == 0) {
ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
+ ctxt->options |= XML_PARSE_NOBLANKS;
+ }
ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_0;
ctxt->vctxt.userData = ctxt;
@@ -1708,8 +1733,12 @@
else
ctxt->vctxt.warning = xmlParserValidityWarning;
ctxt->vctxt.nodeMax = 0;
+ ctxt->options |= XML_PARSE_DTDVALID;
}
ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
+ if (ctxt->replaceEntities) {
+ ctxt->options |= XML_PARSE_NOENT;
+ }
ctxt->record_info = 0;
ctxt->nbChars = 0;
ctxt->checkIndex = 0;
@@ -1990,7 +2019,8 @@
/* Otherwise, we need to add new node to buffer */
else {
- if (ctxt->node_seq.length + 1 > ctxt->node_seq.maximum) {
+ if ((ctxt->node_seq.length + 1 > ctxt->node_seq.maximum) ||
+ (ctxt->node_seq.buffer == NULL)) {
xmlParserNodeInfo *tmp_buffer;
unsigned int byte_size;
diff --git a/relaxng.c b/relaxng.c
index 370e314..3d3e69c 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -507,7 +507,7 @@
*
* 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 +541,7 @@
*
* 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)
{
@@ -1095,7 +1095,7 @@
{
int i;
- if (state == NULL) {
+ if (state == NULL || states == NULL) {
return (-1);
}
if (states->nbState >= states->maxState) {
@@ -2088,6 +2088,7 @@
const xmlChar * arg2)
{
char msg[1000];
+ xmlChar *result;
if (arg1 == NULL)
arg1 = BAD_CAST "";
@@ -2215,7 +2216,8 @@
snprintf(msg, 1000, "Unknown error code %d\n", err);
}
msg[1000 - 1] = 0;
- return (xmlStrdup((xmlChar *) msg));
+ result = xmlCharStrdup(msg);
+ return (xmlEscapeFormatString(&result));
}
/**
@@ -2595,13 +2597,10 @@
}
ret = xmlSchemaValPredefTypeNode(typ, value2, &res2, ctxt2);
if (ret != 0) {
- if ((comp1 == NULL) && (res1 != NULL))
+ if (res1 != (xmlSchemaValPtr) comp1)
xmlSchemaFreeValue(res1);
return (-1);
}
- if (res1 == NULL) {
- return (-1);
- }
ret = xmlSchemaCompareValues(res1, res2);
if (res1 != (xmlSchemaValPtr) comp1)
xmlSchemaFreeValue(res1);
@@ -3822,7 +3821,11 @@
return (0);
return (1);
} else if (def1->type == XML_RELAXNG_EXCEPT) {
- TODO ret = 0;
+ ret = xmlRelaxNGCompareNameClasses(def1->content, def2);
+ if (ret == 0)
+ ret = 1;
+ else if (ret == 1)
+ ret = 0;
} else {
TODO ret = 0;
}
@@ -6603,7 +6606,7 @@
}
/*
- * Apply 4.17 mergingd rules to defines and starts
+ * Apply 4.17 merging rules to defines and starts
*/
xmlRelaxNGCombineStart(ctxt, ret);
if (ret->defs != NULL) {
@@ -6655,12 +6658,17 @@
ctxt->define = NULL;
if (IS_RELAXNG(node, "grammar")) {
schema->topgrammar = xmlRelaxNGParseGrammar(ctxt, node->children);
+ if (schema->topgrammar == NULL) {
+ xmlRelaxNGFree(schema);
+ return (NULL);
+ }
} else {
xmlRelaxNGGrammarPtr tmp, ret;
schema->topgrammar = ret = xmlRelaxNGNewGrammar(ctxt);
if (schema->topgrammar == NULL) {
- return (schema);
+ xmlRelaxNGFree(schema);
+ return (NULL);
}
/*
* Link the new grammar in the tree
@@ -7317,7 +7325,7 @@
}
}
/*
- * Thisd is not an else since "include" is transformed
+ * This is not an else since "include" is transformed
* into a div
*/
if (xmlStrEqual(cur->name, BAD_CAST "div")) {
@@ -7346,13 +7354,13 @@
if (ns != NULL)
xmlFree(ns);
/*
- * Since we are about to delete cur, if it's nsDef is non-NULL we
+ * Since we are about to delete cur, if its nsDef is non-NULL we
* need to preserve it (it contains the ns definitions for the
* children we just moved). We'll just stick it on to the end
* of cur->parent's list, since it's never going to be re-serialized
* (bug 143738).
*/
- if (cur->nsDef != NULL) {
+ if ((cur->nsDef != NULL) && (cur->parent != NULL)) {
xmlNsPtr parDef = (xmlNsPtr)&cur->parent->nsDef;
while (parDef->next != NULL)
parDef = parDef->next;
@@ -7370,7 +7378,8 @@
else if ((cur->type == XML_TEXT_NODE) ||
(cur->type == XML_CDATA_SECTION_NODE)) {
if (IS_BLANK_NODE(cur)) {
- if (cur->parent->type == XML_ELEMENT_NODE) {
+ if ((cur->parent != NULL) &&
+ (cur->parent->type == XML_ELEMENT_NODE)) {
if ((!xmlStrEqual(cur->parent->name, BAD_CAST "value"))
&&
(!xmlStrEqual
@@ -9050,6 +9059,19 @@
return (ret);
list = list->next;
}
+ } else if (define->type == XML_RELAXNG_CHOICE) {
+ xmlRelaxNGDefinePtr list;
+
+ list = define->nameClass;
+ while (list != NULL) {
+ ret = xmlRelaxNGAttributeMatch(ctxt, list, prop);
+ if (ret == 1)
+ return (1);
+ if (ret < 0)
+ return (ret);
+ list = list->next;
+ }
+ return (0);
} else {
TODO}
return (1);
@@ -9409,6 +9431,10 @@
oldstate = ctxt->state;
for (i = 0; i < nbgroups; i++) {
ctxt->state = xmlRelaxNGCopyValidState(ctxt, oldstate);
+ if (ctxt->state == NULL) {
+ ret = -1;
+ break;
+ }
group = partitions->groups[i];
if (lasts[i] != NULL) {
last = lasts[i]->next;
@@ -9839,7 +9865,7 @@
ctxt->depth++;
switch (define->type) {
case XML_RELAXNG_EMPTY:
- node = xmlRelaxNGSkipIgnored(ctxt, node);
+ xmlRelaxNGSkipIgnored(ctxt, node);
ret = 0;
break;
case XML_RELAXNG_NOT_ALLOWED:
diff --git a/schematron.c b/schematron.c
index 537b868..6200f2d 100644
--- a/schematron.c
+++ b/schematron.c
@@ -133,7 +133,7 @@
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 */
@@ -165,8 +165,10 @@
FILE *outputFile; /* if using XML_SCHEMATRON_OUT_FILE */
xmlBufferPtr outputBuffer; /* if using XML_SCHEMATRON_OUT_BUFFER */
+#ifdef LIBXML_OUTPUT_ENABLED
xmlOutputWriteCallback iowrite; /* if using XML_SCHEMATRON_OUT_IO */
xmlOutputCloseCallback ioclose;
+#endif
void *ioctx;
/* error reporting data */
@@ -184,7 +186,7 @@
const char *buffer;
int size;
- xmlDictPtr dict; /* dictionnary for interned string names */
+ xmlDictPtr dict; /* dictionary for interned string names */
int nberrors;
int err;
@@ -243,7 +245,7 @@
*
* 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/testlimits.c b/testlimits.c
new file mode 100644
index 0000000..577f593
--- /dev/null
+++ b/testlimits.c
@@ -0,0 +1,1637 @@
+/*
+ * testlimits.c: C program to run libxml2 regression tests checking various
+ * limits in document size. Will consume a lot of RAM and CPU cycles
+ *
+ * To compile on Unixes:
+ * cc -o testlimits `xml2-config --cflags` testlimits.c `xml2-config --libs` -lpthread
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#include "libxml.h"
+#include <stdio.h>
+
+#if !defined(_WIN32) || defined(__CYGWIN__)
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/tree.h>
+#include <libxml/uri.h>
+#ifdef LIBXML_READER_ENABLED
+#include <libxml/xmlreader.h>
+#endif
+
+static int verbose = 0;
+static int tests_quiet = 0;
+
+/************************************************************************
+ * *
+ * time handling *
+ * *
+ ************************************************************************/
+
+/* maximum time for one parsing before declaring a timeout */
+#define MAX_TIME 2 /* seconds */
+
+static clock_t t0;
+int timeout = 0;
+
+static void reset_timout(void) {
+ timeout = 0;
+ t0 = clock();
+}
+
+static int check_time(void) {
+ clock_t tnow = clock();
+ if (((tnow - t0) / CLOCKS_PER_SEC) > MAX_TIME) {
+ timeout = 1;
+ return(0);
+ }
+ return(1);
+}
+
+/************************************************************************
+ * *
+ * Huge document generator *
+ * *
+ ************************************************************************/
+
+#include <libxml/xmlIO.h>
+
+/*
+ * Huge documents are built using fixed start and end chunks
+ * and filling between the two an unconventional amount of char data
+ */
+typedef struct hugeTest hugeTest;
+typedef hugeTest *hugeTestPtr;
+struct hugeTest {
+ const char *description;
+ const char *name;
+ const char *start;
+ const char *end;
+};
+
+static struct hugeTest hugeTests[] = {
+ { "Huge text node", "huge:textNode", "<foo>", "</foo>" },
+ { "Huge attribute node", "huge:attrNode", "<foo bar='", "'/>" },
+ { "Huge comment node", "huge:commentNode", "<foo><!--", "--></foo>" },
+ { "Huge PI node", "huge:piNode", "<foo><?bar ", "?></foo>" },
+};
+
+static const char *current;
+static int rlen;
+static unsigned int currentTest = 0;
+static int instate = 0;
+
+/**
+ * hugeMatch:
+ * @URI: an URI to test
+ *
+ * Check for an huge: query
+ *
+ * Returns 1 if yes and 0 if another Input module should be used
+ */
+static int
+hugeMatch(const char * URI) {
+ if ((URI != NULL) && (!strncmp(URI, "huge:", 5)))
+ return(1);
+ return(0);
+}
+
+/**
+ * hugeOpen:
+ * @URI: an URI to test
+ *
+ * Return a pointer to the huge: query handler, in this example simply
+ * the current pointer...
+ *
+ * Returns an Input context or NULL in case or error
+ */
+static void *
+hugeOpen(const char * URI) {
+ if ((URI == NULL) || (strncmp(URI, "huge:", 5)))
+ return(NULL);
+
+ for (currentTest = 0;currentTest < sizeof(hugeTests)/sizeof(hugeTests[0]);
+ currentTest++)
+ if (!strcmp(hugeTests[currentTest].name, URI))
+ goto found;
+
+ return(NULL);
+
+found:
+ rlen = strlen(hugeTests[currentTest].start);
+ current = hugeTests[currentTest].start;
+ instate = 0;
+ return((void *) current);
+}
+
+/**
+ * hugeClose:
+ * @context: the read context
+ *
+ * Close the huge: query handler
+ *
+ * Returns 0 or -1 in case of error
+ */
+static int
+hugeClose(void * context) {
+ if (context == NULL) return(-1);
+ fprintf(stderr, "\n");
+ return(0);
+}
+
+#define CHUNK 4096
+
+char filling[CHUNK + 1];
+
+static void fillFilling(void) {
+ int i;
+
+ for (i = 0;i < CHUNK;i++) {
+ filling[i] = 'a';
+ }
+ filling[CHUNK] = 0;
+}
+
+size_t maxlen = 64 * 1024 * 1024;
+size_t curlen = 0;
+size_t dotlen;
+
+/**
+ * hugeRead:
+ * @context: the read context
+ * @buffer: where to store data
+ * @len: number of bytes to read
+ *
+ * Implement an huge: query read.
+ *
+ * Returns the number of bytes read or -1 in case of error
+ */
+static int
+hugeRead(void *context, char *buffer, int len)
+{
+ if ((context == NULL) || (buffer == NULL) || (len < 0))
+ return (-1);
+
+ if (instate == 0) {
+ if (len >= rlen) {
+ len = rlen;
+ rlen = 0;
+ memcpy(buffer, current, len);
+ instate = 1;
+ curlen = 0;
+ dotlen = maxlen / 10;
+ } else {
+ memcpy(buffer, current, len);
+ rlen -= len;
+ current += len;
+ }
+ } else if (instate == 2) {
+ if (len >= rlen) {
+ len = rlen;
+ rlen = 0;
+ memcpy(buffer, current, len);
+ instate = 3;
+ curlen = 0;
+ } else {
+ memcpy(buffer, current, len);
+ rlen -= len;
+ current += len;
+ }
+ } else if (instate == 1) {
+ if (len > CHUNK) len = CHUNK;
+ memcpy(buffer, &filling[0], len);
+ curlen += len;
+ if (curlen >= maxlen) {
+ rlen = strlen(hugeTests[currentTest].end);
+ current = hugeTests[currentTest].end;
+ instate = 2;
+ } else {
+ if (curlen > dotlen) {
+ fprintf(stderr, ".");
+ dotlen += maxlen / 10;
+ }
+ }
+ } else
+ len = 0;
+ return (len);
+}
+
+/************************************************************************
+ * *
+ * Crazy document generator *
+ * *
+ ************************************************************************/
+
+unsigned int crazy_indx = 0;
+
+const char *crazy = "<?xml version='1.0' encoding='UTF-8'?>\
+<?tst ?>\
+<!-- tst -->\
+<!DOCTYPE foo [\
+<?tst ?>\
+<!-- tst -->\
+<!ELEMENT foo (#PCDATA)>\
+<!ELEMENT p (#PCDATA|emph)* >\
+]>\
+<?tst ?>\
+<!-- tst -->\
+<foo bar='foo'>\
+<?tst ?>\
+<!-- tst -->\
+foo\
+<![CDATA[ ]]>\
+</foo>\
+<?tst ?>\
+<!-- tst -->";
+
+/**
+ * crazyMatch:
+ * @URI: an URI to test
+ *
+ * Check for a crazy: query
+ *
+ * Returns 1 if yes and 0 if another Input module should be used
+ */
+static int
+crazyMatch(const char * URI) {
+ if ((URI != NULL) && (!strncmp(URI, "crazy:", 6)))
+ return(1);
+ return(0);
+}
+
+/**
+ * crazyOpen:
+ * @URI: an URI to test
+ *
+ * Return a pointer to the crazy: query handler, in this example simply
+ * the current pointer...
+ *
+ * Returns an Input context or NULL in case or error
+ */
+static void *
+crazyOpen(const char * URI) {
+ if ((URI == NULL) || (strncmp(URI, "crazy:", 6)))
+ return(NULL);
+
+ if (crazy_indx > strlen(crazy))
+ return(NULL);
+ reset_timout();
+ rlen = crazy_indx;
+ current = &crazy[0];
+ instate = 0;
+ return((void *) current);
+}
+
+/**
+ * crazyClose:
+ * @context: the read context
+ *
+ * Close the crazy: query handler
+ *
+ * Returns 0 or -1 in case of error
+ */
+static int
+crazyClose(void * context) {
+ if (context == NULL) return(-1);
+ return(0);
+}
+
+
+/**
+ * crazyRead:
+ * @context: the read context
+ * @buffer: where to store data
+ * @len: number of bytes to read
+ *
+ * Implement an crazy: query read.
+ *
+ * Returns the number of bytes read or -1 in case of error
+ */
+static int
+crazyRead(void *context, char *buffer, int len)
+{
+ if ((context == NULL) || (buffer == NULL) || (len < 0))
+ return (-1);
+
+ if ((check_time() <= 0) && (instate == 1)) {
+ fprintf(stderr, "\ntimeout in crazy(%d)\n", crazy_indx);
+ rlen = strlen(crazy) - crazy_indx;
+ current = &crazy[crazy_indx];
+ instate = 2;
+ }
+ if (instate == 0) {
+ if (len >= rlen) {
+ len = rlen;
+ rlen = 0;
+ memcpy(buffer, current, len);
+ instate = 1;
+ curlen = 0;
+ } else {
+ memcpy(buffer, current, len);
+ rlen -= len;
+ current += len;
+ }
+ } else if (instate == 2) {
+ if (len >= rlen) {
+ len = rlen;
+ rlen = 0;
+ memcpy(buffer, current, len);
+ instate = 3;
+ curlen = 0;
+ } else {
+ memcpy(buffer, current, len);
+ rlen -= len;
+ current += len;
+ }
+ } else if (instate == 1) {
+ if (len > CHUNK) len = CHUNK;
+ memcpy(buffer, &filling[0], len);
+ curlen += len;
+ if (curlen >= maxlen) {
+ rlen = strlen(crazy) - crazy_indx;
+ current = &crazy[crazy_indx];
+ instate = 2;
+ }
+ } else
+ len = 0;
+ return (len);
+}
+/************************************************************************
+ * *
+ * Libxml2 specific routines *
+ * *
+ ************************************************************************/
+
+static int nb_tests = 0;
+static int nb_errors = 0;
+static int nb_leaks = 0;
+static int extraMemoryFromResolver = 0;
+
+/*
+ * We need to trap calls to the resolver to not account memory for the catalog
+ * which is shared to the current running test. We also don't want to have
+ * network downloads modifying tests.
+ */
+static xmlParserInputPtr
+testExternalEntityLoader(const char *URL, const char *ID,
+ xmlParserCtxtPtr ctxt) {
+ xmlParserInputPtr ret;
+ int memused = xmlMemUsed();
+
+ ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
+ extraMemoryFromResolver += xmlMemUsed() - memused;
+
+ return(ret);
+}
+
+/*
+ * Trapping the error messages at the generic level to grab the equivalent of
+ * stderr messages on CLI tools.
+ */
+static char testErrors[32769];
+static int testErrorsSize = 0;
+
+static void XMLCDECL
+channel(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...) {
+ va_list args;
+ int res;
+
+ if (testErrorsSize >= 32768)
+ return;
+ va_start(args, msg);
+ res = vsnprintf(&testErrors[testErrorsSize],
+ 32768 - testErrorsSize,
+ msg, args);
+ va_end(args);
+ if (testErrorsSize + res >= 32768) {
+ /* buffer is full */
+ testErrorsSize = 32768;
+ testErrors[testErrorsSize] = 0;
+ } else {
+ testErrorsSize += res;
+ }
+ testErrors[testErrorsSize] = 0;
+}
+
+/**
+ * xmlParserPrintFileContext:
+ * @input: an xmlParserInputPtr input
+ *
+ * Displays current context within the input content for error tracking
+ */
+
+static void
+xmlParserPrintFileContextInternal(xmlParserInputPtr input ,
+ xmlGenericErrorFunc chanl, void *data ) {
+ const xmlChar *cur, *base;
+ unsigned int n, col; /* GCC warns if signed, because compared with sizeof() */
+ xmlChar content[81]; /* space for 80 chars + line terminator */
+ xmlChar *ctnt;
+
+ if (input == NULL) return;
+ cur = input->cur;
+ base = input->base;
+ /* skip backwards over any end-of-lines */
+ while ((cur > base) && ((*(cur) == '\n') || (*(cur) == '\r'))) {
+ cur--;
+ }
+ n = 0;
+ /* search backwards for beginning-of-line (to max buff size) */
+ while ((n++ < (sizeof(content)-1)) && (cur > base) &&
+ (*(cur) != '\n') && (*(cur) != '\r'))
+ cur--;
+ if ((*(cur) == '\n') || (*(cur) == '\r')) cur++;
+ /* calculate the error position in terms of the current position */
+ col = input->cur - cur;
+ /* search forward for end-of-line (to max buff size) */
+ n = 0;
+ ctnt = content;
+ /* copy selected text to our buffer */
+ while ((*cur != 0) && (*(cur) != '\n') &&
+ (*(cur) != '\r') && (n < sizeof(content)-1)) {
+ *ctnt++ = *cur++;
+ n++;
+ }
+ *ctnt = 0;
+ /* print out the selected text */
+ chanl(data ,"%s\n", content);
+ /* create blank line with problem pointer */
+ n = 0;
+ ctnt = content;
+ /* (leave buffer space for pointer + line terminator) */
+ while ((n<col) && (n++ < sizeof(content)-2) && (*ctnt != 0)) {
+ if (*(ctnt) != '\t')
+ *(ctnt) = ' ';
+ ctnt++;
+ }
+ *ctnt++ = '^';
+ *ctnt = 0;
+ chanl(data ,"%s\n", content);
+}
+
+static void
+testStructuredErrorHandler(void *ctx ATTRIBUTE_UNUSED, xmlErrorPtr err) {
+ char *file = NULL;
+ int line = 0;
+ int code = -1;
+ int domain;
+ void *data = NULL;
+ const char *str;
+ const xmlChar *name = NULL;
+ xmlNodePtr node;
+ xmlErrorLevel level;
+ xmlParserInputPtr input = NULL;
+ xmlParserInputPtr cur = NULL;
+ xmlParserCtxtPtr ctxt = NULL;
+
+ if (err == NULL)
+ return;
+
+ file = err->file;
+ line = err->line;
+ code = err->code;
+ domain = err->domain;
+ level = err->level;
+ node = err->node;
+ if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
+ (domain == XML_FROM_DTD) || (domain == XML_FROM_NAMESPACE) ||
+ (domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
+ ctxt = err->ctxt;
+ }
+ str = err->message;
+
+ if (code == XML_ERR_OK)
+ return;
+
+ if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
+ name = node->name;
+
+ /*
+ * Maintain the compatibility with the legacy error handling
+ */
+ if (ctxt != NULL) {
+ input = ctxt->input;
+ if ((input != NULL) && (input->filename == NULL) &&
+ (ctxt->inputNr > 1)) {
+ cur = input;
+ input = ctxt->inputTab[ctxt->inputNr - 2];
+ }
+ if (input != NULL) {
+ if (input->filename)
+ channel(data, "%s:%d: ", input->filename, input->line);
+ else if ((line != 0) && (domain == XML_FROM_PARSER))
+ channel(data, "Entity: line %d: ", input->line);
+ }
+ } else {
+ if (file != NULL)
+ channel(data, "%s:%d: ", file, line);
+ else if ((line != 0) && (domain == XML_FROM_PARSER))
+ channel(data, "Entity: line %d: ", line);
+ }
+ if (name != NULL) {
+ channel(data, "element %s: ", name);
+ }
+ if (code == XML_ERR_OK)
+ return;
+ switch (domain) {
+ case XML_FROM_PARSER:
+ channel(data, "parser ");
+ break;
+ case XML_FROM_NAMESPACE:
+ channel(data, "namespace ");
+ break;
+ case XML_FROM_DTD:
+ case XML_FROM_VALID:
+ channel(data, "validity ");
+ break;
+ case XML_FROM_HTML:
+ channel(data, "HTML parser ");
+ break;
+ case XML_FROM_MEMORY:
+ channel(data, "memory ");
+ break;
+ case XML_FROM_OUTPUT:
+ channel(data, "output ");
+ break;
+ case XML_FROM_IO:
+ channel(data, "I/O ");
+ break;
+ case XML_FROM_XINCLUDE:
+ channel(data, "XInclude ");
+ break;
+ case XML_FROM_XPATH:
+ channel(data, "XPath ");
+ break;
+ case XML_FROM_XPOINTER:
+ channel(data, "parser ");
+ break;
+ case XML_FROM_REGEXP:
+ channel(data, "regexp ");
+ break;
+ case XML_FROM_MODULE:
+ channel(data, "module ");
+ break;
+ case XML_FROM_SCHEMASV:
+ channel(data, "Schemas validity ");
+ break;
+ case XML_FROM_SCHEMASP:
+ channel(data, "Schemas parser ");
+ break;
+ case XML_FROM_RELAXNGP:
+ channel(data, "Relax-NG parser ");
+ break;
+ case XML_FROM_RELAXNGV:
+ channel(data, "Relax-NG validity ");
+ break;
+ case XML_FROM_CATALOG:
+ channel(data, "Catalog ");
+ break;
+ case XML_FROM_C14N:
+ channel(data, "C14N ");
+ break;
+ case XML_FROM_XSLT:
+ channel(data, "XSLT ");
+ break;
+ default:
+ break;
+ }
+ if (code == XML_ERR_OK)
+ return;
+ switch (level) {
+ case XML_ERR_NONE:
+ channel(data, ": ");
+ break;
+ case XML_ERR_WARNING:
+ channel(data, "warning : ");
+ break;
+ case XML_ERR_ERROR:
+ channel(data, "error : ");
+ break;
+ case XML_ERR_FATAL:
+ channel(data, "error : ");
+ break;
+ }
+ if (code == XML_ERR_OK)
+ return;
+ if (str != NULL) {
+ int len;
+ len = xmlStrlen((const xmlChar *)str);
+ if ((len > 0) && (str[len - 1] != '\n'))
+ channel(data, "%s\n", str);
+ else
+ channel(data, "%s", str);
+ } else {
+ channel(data, "%s\n", "out of memory error");
+ }
+ if (code == XML_ERR_OK)
+ return;
+
+ if (ctxt != NULL) {
+ xmlParserPrintFileContextInternal(input, channel, data);
+ if (cur != NULL) {
+ if (cur->filename)
+ channel(data, "%s:%d: \n", cur->filename, cur->line);
+ else if ((line != 0) && (domain == XML_FROM_PARSER))
+ channel(data, "Entity: line %d: \n", cur->line);
+ xmlParserPrintFileContextInternal(cur, channel, data);
+ }
+ }
+ if ((domain == XML_FROM_XPATH) && (err->str1 != NULL) &&
+ (err->int1 < 100) &&
+ (err->int1 < xmlStrlen((const xmlChar *)err->str1))) {
+ xmlChar buf[150];
+ int i;
+
+ channel(data, "%s\n", err->str1);
+ for (i=0;i < err->int1;i++)
+ buf[i] = ' ';
+ buf[i++] = '^';
+ buf[i] = 0;
+ channel(data, "%s\n", buf);
+ }
+}
+
+static void
+initializeLibxml2(void) {
+ xmlGetWarningsDefaultValue = 0;
+ xmlPedanticParserDefault(0);
+
+ xmlMemSetup(xmlMemFree, xmlMemMalloc, xmlMemRealloc, xmlMemoryStrdup);
+ xmlInitParser();
+ xmlSetExternalEntityLoader(testExternalEntityLoader);
+ xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
+ /*
+ * register the new I/O handlers
+ */
+ if (xmlRegisterInputCallbacks(hugeMatch, hugeOpen,
+ hugeRead, hugeClose) < 0) {
+ fprintf(stderr, "failed to register Huge handlers\n");
+ exit(1);
+ }
+ if (xmlRegisterInputCallbacks(crazyMatch, crazyOpen,
+ crazyRead, crazyClose) < 0) {
+ fprintf(stderr, "failed to register Crazy handlers\n");
+ exit(1);
+ }
+}
+
+/************************************************************************
+ * *
+ * SAX empty callbacks *
+ * *
+ ************************************************************************/
+
+unsigned long callbacks = 0;
+
+/**
+ * isStandaloneCallback:
+ * @ctxt: An XML parser context
+ *
+ * Is this document tagged standalone ?
+ *
+ * Returns 1 if true
+ */
+static int
+isStandaloneCallback(void *ctx ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return (0);
+}
+
+/**
+ * hasInternalSubsetCallback:
+ * @ctxt: An XML parser context
+ *
+ * Does this document has an internal subset
+ *
+ * Returns 1 if true
+ */
+static int
+hasInternalSubsetCallback(void *ctx ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return (0);
+}
+
+/**
+ * hasExternalSubsetCallback:
+ * @ctxt: An XML parser context
+ *
+ * Does this document has an external subset
+ *
+ * Returns 1 if true
+ */
+static int
+hasExternalSubsetCallback(void *ctx ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return (0);
+}
+
+/**
+ * internalSubsetCallback:
+ * @ctxt: An XML parser context
+ *
+ * Does this document has an internal subset
+ */
+static void
+internalSubsetCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * name ATTRIBUTE_UNUSED,
+ const xmlChar * ExternalID ATTRIBUTE_UNUSED,
+ const xmlChar * SystemID ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * externalSubsetCallback:
+ * @ctxt: An XML parser context
+ *
+ * Does this document has an external subset
+ */
+static void
+externalSubsetCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * name ATTRIBUTE_UNUSED,
+ const xmlChar * ExternalID ATTRIBUTE_UNUSED,
+ const xmlChar * SystemID ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * resolveEntityCallback:
+ * @ctxt: An XML parser context
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * Special entity resolver, better left to the parser, it has
+ * more context than the application layer.
+ * The default behaviour is to NOT resolve the entities, in that case
+ * the ENTITY_REF nodes are built in the structure (and the parameter
+ * values).
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+static xmlParserInputPtr
+resolveEntityCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * publicId ATTRIBUTE_UNUSED,
+ const xmlChar * systemId ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return (NULL);
+}
+
+/**
+ * getEntityCallback:
+ * @ctxt: An XML parser context
+ * @name: The entity name
+ *
+ * Get an entity by name
+ *
+ * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
+ */
+static xmlEntityPtr
+getEntityCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * name ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return (NULL);
+}
+
+/**
+ * getParameterEntityCallback:
+ * @ctxt: An XML parser context
+ * @name: The entity name
+ *
+ * Get a parameter entity by name
+ *
+ * Returns the xmlParserInputPtr
+ */
+static xmlEntityPtr
+getParameterEntityCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * name ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return (NULL);
+}
+
+
+/**
+ * entityDeclCallback:
+ * @ctxt: An XML parser context
+ * @name: the entity name
+ * @type: the entity type
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ * @content: the entity value (without processing).
+ *
+ * An entity definition has been parsed
+ */
+static void
+entityDeclCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * name ATTRIBUTE_UNUSED,
+ int type ATTRIBUTE_UNUSED,
+ const xmlChar * publicId ATTRIBUTE_UNUSED,
+ const xmlChar * systemId ATTRIBUTE_UNUSED,
+ xmlChar * content ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * attributeDeclCallback:
+ * @ctxt: An XML parser context
+ * @name: the attribute name
+ * @type: the attribute type
+ *
+ * An attribute definition has been parsed
+ */
+static void
+attributeDeclCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * elem ATTRIBUTE_UNUSED,
+ const xmlChar * name ATTRIBUTE_UNUSED,
+ int type ATTRIBUTE_UNUSED, int def ATTRIBUTE_UNUSED,
+ const xmlChar * defaultValue ATTRIBUTE_UNUSED,
+ xmlEnumerationPtr tree ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * elementDeclCallback:
+ * @ctxt: An XML parser context
+ * @name: the element name
+ * @type: the element type
+ * @content: the element value (without processing).
+ *
+ * An element definition has been parsed
+ */
+static void
+elementDeclCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * name ATTRIBUTE_UNUSED,
+ int type ATTRIBUTE_UNUSED,
+ xmlElementContentPtr content ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * notationDeclCallback:
+ * @ctxt: An XML parser context
+ * @name: The name of the notation
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ *
+ * What to do when a notation declaration has been parsed.
+ */
+static void
+notationDeclCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * name ATTRIBUTE_UNUSED,
+ const xmlChar * publicId ATTRIBUTE_UNUSED,
+ const xmlChar * systemId ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * unparsedEntityDeclCallback:
+ * @ctxt: An XML parser context
+ * @name: The name of the entity
+ * @publicId: The public ID of the entity
+ * @systemId: The system ID of the entity
+ * @notationName: the name of the notation
+ *
+ * What to do when an unparsed entity declaration is parsed
+ */
+static void
+unparsedEntityDeclCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * name ATTRIBUTE_UNUSED,
+ const xmlChar * publicId ATTRIBUTE_UNUSED,
+ const xmlChar * systemId ATTRIBUTE_UNUSED,
+ const xmlChar * notationName ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * setDocumentLocatorCallback:
+ * @ctxt: An XML parser context
+ * @loc: A SAX Locator
+ *
+ * Receive the document locator at startup, actually xmlDefaultSAXLocator
+ * Everything is available on the context, so this is useless in our case.
+ */
+static void
+setDocumentLocatorCallback(void *ctx ATTRIBUTE_UNUSED,
+ xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * startDocumentCallback:
+ * @ctxt: An XML parser context
+ *
+ * called when the document start being processed.
+ */
+static void
+startDocumentCallback(void *ctx ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * endDocumentCallback:
+ * @ctxt: An XML parser context
+ *
+ * called when the document end has been detected.
+ */
+static void
+endDocumentCallback(void *ctx ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+#if 0
+/**
+ * startElementCallback:
+ * @ctxt: An XML parser context
+ * @name: The element name
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+startElementCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * name ATTRIBUTE_UNUSED,
+ const xmlChar ** atts ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * endElementCallback:
+ * @ctxt: An XML parser context
+ * @name: The element name
+ *
+ * called when the end of an element has been detected.
+ */
+static void
+endElementCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * name ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+#endif
+
+/**
+ * charactersCallback:
+ * @ctxt: An XML parser context
+ * @ch: a xmlChar string
+ * @len: the number of xmlChar
+ *
+ * receiving some chars from the parser.
+ * Question: how much at a time ???
+ */
+static void
+charactersCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * ch ATTRIBUTE_UNUSED,
+ int len ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * referenceCallback:
+ * @ctxt: An XML parser context
+ * @name: The entity name
+ *
+ * called when an entity reference is detected.
+ */
+static void
+referenceCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * name ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * ignorableWhitespaceCallback:
+ * @ctxt: An XML parser context
+ * @ch: a xmlChar string
+ * @start: the first char in the string
+ * @len: the number of xmlChar
+ *
+ * receiving some ignorable whitespaces from the parser.
+ * Question: how much at a time ???
+ */
+static void
+ignorableWhitespaceCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * ch ATTRIBUTE_UNUSED,
+ int len ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * processingInstructionCallback:
+ * @ctxt: An XML parser context
+ * @target: the target name
+ * @data: the PI data's
+ * @len: the number of xmlChar
+ *
+ * A processing instruction has been parsed.
+ */
+static void
+processingInstructionCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * target ATTRIBUTE_UNUSED,
+ const xmlChar * data ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * cdataBlockCallback:
+ * @ctx: the user data (XML parser context)
+ * @value: The pcdata content
+ * @len: the block length
+ *
+ * called when a pcdata block has been parsed
+ */
+static void
+cdataBlockCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * value ATTRIBUTE_UNUSED,
+ int len ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * commentCallback:
+ * @ctxt: An XML parser context
+ * @value: the comment content
+ *
+ * A comment has been parsed.
+ */
+static void
+commentCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * value ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * warningCallback:
+ * @ctxt: An XML parser context
+ * @msg: the message to display/transmit
+ * @...: extra parameters for the message display
+ *
+ * Display and format a warning messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+warningCallback(void *ctx ATTRIBUTE_UNUSED,
+ const char *msg ATTRIBUTE_UNUSED, ...)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * errorCallback:
+ * @ctxt: An XML parser context
+ * @msg: the message to display/transmit
+ * @...: extra parameters for the message display
+ *
+ * Display and format a error messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+errorCallback(void *ctx ATTRIBUTE_UNUSED, const char *msg ATTRIBUTE_UNUSED,
+ ...)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * fatalErrorCallback:
+ * @ctxt: An XML parser context
+ * @msg: the message to display/transmit
+ * @...: extra parameters for the message display
+ *
+ * Display and format a fatalError messages, gives file, line, position and
+ * extra parameters.
+ */
+static void XMLCDECL
+fatalErrorCallback(void *ctx ATTRIBUTE_UNUSED,
+ const char *msg ATTRIBUTE_UNUSED, ...)
+{
+ return;
+}
+
+
+/*
+ * SAX2 specific callbacks
+ */
+
+/**
+ * startElementNsCallback:
+ * @ctxt: An XML parser context
+ * @name: The element name
+ *
+ * called when an opening tag has been processed.
+ */
+static void
+startElementNsCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * localname ATTRIBUTE_UNUSED,
+ const xmlChar * prefix ATTRIBUTE_UNUSED,
+ const xmlChar * URI ATTRIBUTE_UNUSED,
+ int nb_namespaces ATTRIBUTE_UNUSED,
+ const xmlChar ** namespaces ATTRIBUTE_UNUSED,
+ int nb_attributes ATTRIBUTE_UNUSED,
+ int nb_defaulted ATTRIBUTE_UNUSED,
+ const xmlChar ** attributes ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+/**
+ * endElementCallback:
+ * @ctxt: An XML parser context
+ * @name: The element name
+ *
+ * called when the end of an element has been detected.
+ */
+static void
+endElementNsCallback(void *ctx ATTRIBUTE_UNUSED,
+ const xmlChar * localname ATTRIBUTE_UNUSED,
+ const xmlChar * prefix ATTRIBUTE_UNUSED,
+ const xmlChar * URI ATTRIBUTE_UNUSED)
+{
+ callbacks++;
+ return;
+}
+
+static xmlSAXHandler callbackSAX2HandlerStruct = {
+ internalSubsetCallback,
+ isStandaloneCallback,
+ hasInternalSubsetCallback,
+ hasExternalSubsetCallback,
+ resolveEntityCallback,
+ getEntityCallback,
+ entityDeclCallback,
+ notationDeclCallback,
+ attributeDeclCallback,
+ elementDeclCallback,
+ unparsedEntityDeclCallback,
+ setDocumentLocatorCallback,
+ startDocumentCallback,
+ endDocumentCallback,
+ NULL,
+ NULL,
+ referenceCallback,
+ charactersCallback,
+ ignorableWhitespaceCallback,
+ processingInstructionCallback,
+ commentCallback,
+ warningCallback,
+ errorCallback,
+ fatalErrorCallback,
+ getParameterEntityCallback,
+ cdataBlockCallback,
+ externalSubsetCallback,
+ XML_SAX2_MAGIC,
+ NULL,
+ startElementNsCallback,
+ endElementNsCallback,
+ NULL
+};
+
+static xmlSAXHandlerPtr callbackSAX2Handler = &callbackSAX2HandlerStruct;
+
+/************************************************************************
+ * *
+ * The tests front-ends *
+ * *
+ ************************************************************************/
+
+/**
+ * readerTest:
+ * @filename: the file to parse
+ * @max_size: size of the limit to test
+ * @options: parsing options
+ * @fail: should a failure be reported
+ *
+ * Parse a memory generated file using SAX
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+saxTest(const char *filename, size_t limit, int options, int fail) {
+ int res = 0;
+ xmlParserCtxtPtr ctxt;
+ xmlDocPtr doc;
+ xmlSAXHandlerPtr old_sax;
+
+ nb_tests++;
+
+ maxlen = limit;
+ ctxt = xmlNewParserCtxt();
+ if (ctxt == NULL) {
+ fprintf(stderr, "Failed to create parser context\n");
+ return(1);
+ }
+ old_sax = ctxt->sax;
+ ctxt->sax = callbackSAX2Handler;
+ ctxt->userData = NULL;
+ doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
+
+ if (doc != NULL) {
+ fprintf(stderr, "SAX parsing generated a document !\n");
+ xmlFreeDoc(doc);
+ res = 0;
+ } else if (ctxt->wellFormed == 0) {
+ if (fail)
+ res = 0;
+ else {
+ fprintf(stderr, "Failed to parse '%s' %lu\n", filename, limit);
+ res = 1;
+ }
+ } else {
+ if (fail) {
+ fprintf(stderr, "Failed to get failure for '%s' %lu\n",
+ filename, limit);
+ res = 1;
+ } else
+ res = 0;
+ }
+ ctxt->sax = old_sax;
+ xmlFreeParserCtxt(ctxt);
+
+ return(res);
+}
+#ifdef LIBXML_READER_ENABLED
+/**
+ * readerTest:
+ * @filename: the file to parse
+ * @max_size: size of the limit to test
+ * @options: parsing options
+ * @fail: should a failure be reported
+ *
+ * Parse a memory generated file using the xmlReader
+ *
+ * Returns 0 in case of success, an error code otherwise
+ */
+static int
+readerTest(const char *filename, size_t limit, int options, int fail) {
+ xmlTextReaderPtr reader;
+ int res = 0;
+ int ret;
+
+ nb_tests++;
+
+ maxlen = limit;
+ reader = xmlReaderForFile(filename , NULL, options);
+ if (reader == NULL) {
+ fprintf(stderr, "Failed to open '%s' test\n", filename);
+ return(1);
+ }
+ ret = xmlTextReaderRead(reader);
+ while (ret == 1) {
+ ret = xmlTextReaderRead(reader);
+ }
+ if (ret != 0) {
+ if (fail)
+ res = 0;
+ else {
+ if (strncmp(filename, "crazy:", 6) == 0)
+ fprintf(stderr, "Failed to parse '%s' %u\n",
+ filename, crazy_indx);
+ else
+ fprintf(stderr, "Failed to parse '%s' %lu\n",
+ filename, limit);
+ res = 1;
+ }
+ } else {
+ if (fail) {
+ if (strncmp(filename, "crazy:", 6) == 0)
+ fprintf(stderr, "Failed to get failure for '%s' %u\n",
+ filename, crazy_indx);
+ else
+ fprintf(stderr, "Failed to get failure for '%s' %lu\n",
+ filename, limit);
+ res = 1;
+ } else
+ res = 0;
+ }
+ if (timeout)
+ res = 1;
+ xmlFreeTextReader(reader);
+
+ return(res);
+}
+#endif
+
+/************************************************************************
+ * *
+ * Tests descriptions *
+ * *
+ ************************************************************************/
+
+typedef int (*functest) (const char *filename, size_t limit, int options,
+ int fail);
+
+typedef struct limitDesc limitDesc;
+typedef limitDesc *limitDescPtr;
+struct limitDesc {
+ const char *name; /* the huge generator name */
+ size_t limit; /* the limit to test */
+ int options; /* extra parser options */
+ int fail; /* whether the test should fail */
+};
+
+static limitDesc limitDescriptions[] = {
+ /* max length of a text node in content */
+ {"huge:textNode", XML_MAX_TEXT_LENGTH - CHUNK, 0, 0},
+ {"huge:textNode", XML_MAX_TEXT_LENGTH + CHUNK, 0, 1},
+ {"huge:textNode", XML_MAX_TEXT_LENGTH + CHUNK, XML_PARSE_HUGE, 0},
+ /* max length of a text node in content */
+ {"huge:attrNode", XML_MAX_TEXT_LENGTH - CHUNK, 0, 0},
+ {"huge:attrNode", XML_MAX_TEXT_LENGTH + CHUNK, 0, 1},
+ {"huge:attrNode", XML_MAX_TEXT_LENGTH + CHUNK, XML_PARSE_HUGE, 0},
+ /* max length of a comment node */
+ {"huge:commentNode", XML_MAX_TEXT_LENGTH - CHUNK, 0, 0},
+ {"huge:commentNode", XML_MAX_TEXT_LENGTH + CHUNK, 0, 1},
+ {"huge:commentNode", XML_MAX_TEXT_LENGTH + CHUNK, XML_PARSE_HUGE, 0},
+ /* max length of a PI node */
+ {"huge:piNode", XML_MAX_TEXT_LENGTH - CHUNK, 0, 0},
+ {"huge:piNode", XML_MAX_TEXT_LENGTH + CHUNK, 0, 1},
+ {"huge:piNode", XML_MAX_TEXT_LENGTH + CHUNK, XML_PARSE_HUGE, 0},
+};
+
+typedef struct testDesc testDesc;
+typedef testDesc *testDescPtr;
+struct testDesc {
+ const char *desc; /* descripton of the test */
+ functest func; /* function implementing the test */
+};
+
+static
+testDesc testDescriptions[] = {
+ { "Parsing of huge files with the sax parser", saxTest},
+/* { "Parsing of huge files with the tree parser", treeTest}, */
+#ifdef LIBXML_READER_ENABLED
+ { "Parsing of huge files with the reader", readerTest},
+#endif
+ {NULL, NULL}
+};
+
+typedef struct testException testException;
+typedef testException *testExceptionPtr;
+struct testException {
+ unsigned int test; /* the parser test number */
+ unsigned int limit; /* the limit test number */
+ int fail; /* new fail value or -1*/
+ size_t size; /* new limit value or 0 */
+};
+
+static
+testException testExceptions[] = {
+ /* the SAX parser doesn't hit a limit of XML_MAX_TEXT_LENGTH text nodes */
+ { 0, 1, 0, 0},
+};
+
+static int
+launchTests(testDescPtr tst, unsigned int test) {
+ int res = 0, err = 0;
+ unsigned int i, j;
+ size_t limit;
+ int fail;
+
+ if (tst == NULL) return(-1);
+
+ for (i = 0;i < sizeof(limitDescriptions)/sizeof(limitDescriptions[0]);i++) {
+ limit = limitDescriptions[i].limit;
+ fail = limitDescriptions[i].fail;
+ /*
+ * Handle exceptions if any
+ */
+ for (j = 0;j < sizeof(testExceptions)/sizeof(testExceptions[0]);j++) {
+ if ((testExceptions[j].test == test) &&
+ (testExceptions[j].limit == i)) {
+ if (testExceptions[j].fail != -1)
+ fail = testExceptions[j].fail;
+ if (testExceptions[j].size != 0)
+ limit = testExceptions[j].size;
+ break;
+ }
+ }
+ res = tst->func(limitDescriptions[i].name, limit,
+ limitDescriptions[i].options, fail);
+ if (res != 0) {
+ nb_errors++;
+ err++;
+ }
+ }
+ return(err);
+}
+
+
+static int
+runtest(unsigned int i) {
+ int ret = 0, res;
+ int old_errors, old_tests, old_leaks;
+
+ old_errors = nb_errors;
+ old_tests = nb_tests;
+ old_leaks = nb_leaks;
+ if ((tests_quiet == 0) && (testDescriptions[i].desc != NULL))
+ printf("## %s\n", testDescriptions[i].desc);
+ res = launchTests(&testDescriptions[i], i);
+ if (res != 0)
+ ret++;
+ if (verbose) {
+ if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
+ printf("Ran %d tests, no errors\n", nb_tests - old_tests);
+ else
+ printf("Ran %d tests, %d errors, %d leaks\n",
+ nb_tests - old_tests,
+ nb_errors - old_errors,
+ nb_leaks - old_leaks);
+ }
+ return(ret);
+}
+
+static int
+launchCrazySAX(unsigned int test, int fail) {
+ int res = 0, err = 0;
+
+ crazy_indx = test;
+
+ res = saxTest("crazy::test", XML_MAX_LOOKUP_LIMIT - CHUNK, 0, fail);
+ if (res != 0) {
+ nb_errors++;
+ err++;
+ }
+ if (tests_quiet == 0)
+ fprintf(stderr, "%c", crazy[test]);
+
+ return(err);
+}
+
+#ifdef LIBXML_READER_ENABLED
+static int
+launchCrazy(unsigned int test, int fail) {
+ int res = 0, err = 0;
+
+ crazy_indx = test;
+
+ res = readerTest("crazy::test", XML_MAX_LOOKUP_LIMIT - CHUNK, 0, fail);
+ if (res != 0) {
+ nb_errors++;
+ err++;
+ }
+ if (tests_quiet == 0)
+ fprintf(stderr, "%c", crazy[test]);
+
+ return(err);
+}
+#endif
+
+static int get_crazy_fail(int test) {
+ /*
+ * adding 1000000 of character 'a' leads to parser failure mostly
+ * everywhere except in those special spots. Need to be updated
+ * each time crazy is updated
+ */
+ int fail = 1;
+ if ((test == 44) || /* PI in Misc */
+ ((test >= 50) && (test <= 55)) || /* Comment in Misc */
+ (test == 79) || /* PI in DTD */
+ ((test >= 85) && (test <= 90)) || /* Comment in DTD */
+ (test == 154) || /* PI in Misc */
+ ((test >= 160) && (test <= 165)) || /* Comment in Misc */
+ ((test >= 178) && (test <= 181)) || /* attribute value */
+ (test == 183) || /* Text */
+ (test == 189) || /* PI in Content */
+ (test == 191) || /* Text */
+ ((test >= 195) && (test <= 200)) || /* Comment in Content */
+ ((test >= 203) && (test <= 206)) || /* Text */
+ (test == 215) || (test == 216) || /* in CDATA */
+ (test == 219) || /* Text */
+ (test == 231) || /* PI in Misc */
+ ((test >= 237) && (test <= 242))) /* Comment in Misc */
+ fail = 0;
+ return(fail);
+}
+
+static int
+runcrazy(void) {
+ int ret = 0, res = 0;
+ int old_errors, old_tests, old_leaks;
+ unsigned int i;
+
+ old_errors = nb_errors;
+ old_tests = nb_tests;
+ old_leaks = nb_leaks;
+
+#ifdef LIBXML_READER_ENABLED
+ if (tests_quiet == 0) {
+ printf("## Crazy tests on reader\n");
+ }
+ for (i = 0;i < strlen(crazy);i++) {
+ res += launchCrazy(i, get_crazy_fail(i));
+ if (res != 0)
+ ret++;
+ }
+#endif
+
+ if (tests_quiet == 0) {
+ printf("\n## Crazy tests on SAX\n");
+ }
+ for (i = 0;i < strlen(crazy);i++) {
+ res += launchCrazySAX(i, get_crazy_fail(i));
+ if (res != 0)
+ ret++;
+ }
+ if (tests_quiet == 0)
+ fprintf(stderr, "\n");
+ if (verbose) {
+ if ((nb_errors == old_errors) && (nb_leaks == old_leaks))
+ printf("Ran %d tests, no errors\n", nb_tests - old_tests);
+ else
+ printf("Ran %d tests, %d errors, %d leaks\n",
+ nb_tests - old_tests,
+ nb_errors - old_errors,
+ nb_leaks - old_leaks);
+ }
+ return(ret);
+}
+
+
+int
+main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
+ int i, a, ret = 0;
+ int subset = 0;
+
+ fillFilling();
+ initializeLibxml2();
+
+ for (a = 1; a < argc;a++) {
+ if (!strcmp(argv[a], "-v"))
+ verbose = 1;
+ else if (!strcmp(argv[a], "-quiet"))
+ tests_quiet = 1;
+ else if (!strcmp(argv[a], "-crazy"))
+ subset = 1;
+ }
+ if (subset == 0) {
+ for (i = 0; testDescriptions[i].func != NULL; i++) {
+ ret += runtest(i);
+ }
+ }
+ ret += runcrazy();
+ if ((nb_errors == 0) && (nb_leaks == 0)) {
+ ret = 0;
+ printf("Total %d tests, no errors\n",
+ nb_tests);
+ } else {
+ ret = 1;
+ printf("Total %d tests, %d errors, %d leaks\n",
+ nb_tests, nb_errors, nb_leaks);
+ }
+ xmlCleanupParser();
+ xmlMemoryDump();
+
+ return(ret);
+}
diff --git a/threads.c b/threads.c
index f2f2703..b9d6cae 100644
--- a/threads.c
+++ b/threads.c
@@ -47,7 +47,7 @@
#ifdef HAVE_PTHREAD_H
static int libxml_is_threaded = -1;
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(__GLIBC__)
#ifdef linux
#if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || (__GNUC__ > 3)
extern int pthread_once (pthread_once_t *__once_control,
@@ -89,7 +89,7 @@
__attribute((weak));
#endif
#endif /* linux */
-#endif /* __GNUC__ */
+#endif /* defined(__GNUC__) && defined(__GLIBC__) */
#endif /* HAVE_PTHREAD_H */
/*
@@ -378,7 +378,7 @@
pthread_mutex_unlock(&tok->lock);
#elif defined HAVE_WIN32_THREADS
EnterCriticalSection(&tok->cs);
- ++tok->count;
+ tok->count++;
#elif defined HAVE_BEOS_THREADS
if (tok->lock->tid == find_thread(NULL)) {
tok->count++;
@@ -414,8 +414,10 @@
}
pthread_mutex_unlock(&tok->lock);
#elif defined HAVE_WIN32_THREADS
- if (!--tok->count)
+ if (tok->count > 0) {
+ tok->count--;
LeaveCriticalSection(&tok->cs);
+ }
#elif defined HAVE_BEOS_THREADS
if (tok->lock->tid == find_thread(NULL)) {
tok->count--;
diff --git a/timsort.h b/timsort.h
index 99697a0..795f272 100644
--- a/timsort.h
+++ b/timsort.h
@@ -61,12 +61,12 @@
if (x == 0) return(64);
n = 0;
- 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;}
+ 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;}
return n;
}
/* }}} */
@@ -392,62 +392,66 @@
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;
+ while (1) {
+ int64_t A, B, C, D;
+ int ABC, BCD, BD, CD;
+
/* if the stack only has one thing on it, we are done with the collapse */
- if (stack_curr <= 1) break;
+ if (stack_curr <= 1) {
+ break;
+ }
+
/* if this is the last merge, just do it */
- if ((stack_curr == 2) &&
- (stack[0].length + stack[1].length == (int64_t) size))
- {
+ if ((stack_curr == 2) && (stack[0].length + stack[1].length == size)) {
TIM_SORT_MERGE(dst, stack, stack_curr, store);
stack[0].length += stack[1].length;
stack_curr--;
break;
}
/* check if the invariant is off for a stack of 2 elements */
- else if ((stack_curr == 2) && (stack[0].length <= stack[1].length))
- {
+ else if ((stack_curr == 2) && (stack[0].length <= stack[1].length)) {
TIM_SORT_MERGE(dst, stack, stack_curr, store);
stack[0].length += stack[1].length;
stack_curr--;
break;
- }
- else if (stack_curr == 2)
+ } else if (stack_curr == 2) {
break;
-
- A = stack[stack_curr - 3].length;
- B = stack[stack_curr - 2].length;
- C = stack[stack_curr - 1].length;
-
- /* check first invariant */
- if (A <= B + C)
- {
- if (A < C)
- {
- TIM_SORT_MERGE(dst, stack, stack_curr - 1, store);
- stack[stack_curr - 3].length += stack[stack_curr - 2].length;
- stack[stack_curr - 2] = stack[stack_curr - 1];
- stack_curr--;
- }
- else
- {
- TIM_SORT_MERGE(dst, stack, stack_curr, store);
- stack[stack_curr - 2].length += stack[stack_curr - 1].length;
- stack_curr--;
- }
}
- /* check second invariant */
- else if (B <= C)
- {
+
+ B = stack[stack_curr - 3].length;
+ C = stack[stack_curr - 2].length;
+ D = stack[stack_curr - 1].length;
+
+ if (stack_curr >= 4) {
+ A = stack[stack_curr - 4].length;
+ ABC = (A <= B + C);
+ } else {
+ ABC = 0;
+ }
+
+ BCD = (B <= C + D) || ABC;
+ CD = (C <= D);
+ BD = (B < D);
+
+ /* Both invariants are good */
+ if (!BCD && !CD) {
+ break;
+ }
+
+ /* left merge */
+ if (BCD && !CD) {
+ TIM_SORT_MERGE(dst, stack, stack_curr - 1, store);
+ stack[stack_curr - 3].length += stack[stack_curr - 2].length;
+ stack[stack_curr - 2] = stack[stack_curr - 1];
+ stack_curr--;
+ } else {
+ /* right merge */
TIM_SORT_MERGE(dst, stack, stack_curr, store);
stack[stack_curr - 2].length += stack[stack_curr - 1].length;
stack_curr--;
}
- else
- break;
}
+
return stack_curr;
}
diff --git a/tree.c b/tree.c
index 7e5af26..9d330b8 100644
--- a/tree.c
+++ b/tree.c
@@ -55,7 +55,7 @@
static xmlNsPtr
xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns);
-static xmlChar* xmlGetPropNodeValueInternal(xmlAttrPtr prop);
+static xmlChar* xmlGetPropNodeValueInternal(const xmlAttr *prop);
/************************************************************************
* *
@@ -160,7 +160,7 @@
* Returns A pointer to the entity structure or NULL if not found.
*/
static xmlEntityPtr
-xmlGetEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) {
+xmlGetEntityFromDtd(const xmlDtd *dtd, const xmlChar *name) {
xmlEntitiesTablePtr table;
if((dtd != NULL) && (dtd->entities != NULL)) {
@@ -181,7 +181,7 @@
* Returns A pointer to the entity structure or NULL if not found.
*/
static xmlEntityPtr
-xmlGetParameterEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) {
+xmlGetParameterEntityFromDtd(const xmlDtd *dtd, const xmlChar *name) {
xmlEntitiesTablePtr table;
if ((dtd != NULL) && (dtd->pentities != NULL)) {
@@ -352,7 +352,7 @@
#define CUR_SCHAR(s, l) xmlStringCurrentChar(NULL, s, &l)
-#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
/**
* xmlValidateNCName:
* @value: the value to check
@@ -717,8 +717,11 @@
* Creation of a new Namespace. This function will refuse to create
* a namespace with a similar prefix than an existing one present on this
* node.
+ * Note that for a default namespace, @prefix should be NULL.
+ *
* We use href==NULL in the case of an element creation where the namespace
* was not defined.
+ *
* Returns a new namespace pointer or NULL
*/
xmlNsPtr
@@ -803,7 +806,9 @@
#endif
return;
}
- node->ns = ns;
+ if ((node->type == XML_ELEMENT_NODE) ||
+ (node->type == XML_ATTRIBUTE_NODE))
+ node->ns = ns;
}
/**
@@ -911,7 +916,7 @@
*/
xmlDtdPtr
-xmlGetIntSubset(xmlDocPtr doc) {
+xmlGetIntSubset(const xmlDoc *doc) {
xmlNodePtr cur;
if (doc == NULL)
@@ -1039,7 +1044,7 @@
* 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) \
@@ -1052,7 +1057,7 @@
* 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) \
@@ -1069,7 +1074,7 @@
* 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) \
@@ -1261,7 +1266,7 @@
* Returns a pointer to the first child
*/
xmlNodePtr
-xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *value, int len) {
+xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) {
xmlNodePtr ret = NULL, last = NULL;
xmlNodePtr node;
xmlChar *val;
@@ -1446,9 +1451,9 @@
node->content = xmlBufDetach(buf);
if (last == NULL) {
- last = ret = node;
+ ret = node;
} else {
- last = xmlAddNextSibling(last, node);
+ xmlAddNextSibling(last, node);
}
} else if (ret == NULL) {
ret = xmlNewDocText(doc, BAD_CAST "");
@@ -1469,7 +1474,7 @@
* Returns a pointer to the first child
*/
xmlNodePtr
-xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *value) {
+xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
xmlNodePtr ret = NULL, last = NULL;
xmlNodePtr node;
xmlChar *val;
@@ -1588,6 +1593,7 @@
else if ((ent != NULL) && (ent->children == NULL)) {
xmlNodePtr temp;
+ ent->children = (xmlNodePtr) -1;
ent->children = xmlStringGetNodeList(doc,
(const xmlChar*)node->content);
ent->owner = 1;
@@ -1634,9 +1640,9 @@
node->content = xmlBufDetach(buf);
if (last == NULL) {
- last = ret = node;
+ ret = node;
} else {
- last = xmlAddNextSibling(last, node);
+ xmlAddNextSibling(last, node);
}
}
@@ -1657,9 +1663,9 @@
* Returns a pointer to the string copy, the caller must free it with xmlFree().
*/
xmlChar *
-xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine)
+xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
{
- xmlNodePtr node = list;
+ const xmlNode *node = list;
xmlChar *ret = NULL;
xmlEntityPtr ent;
int attr;
@@ -1747,9 +1753,9 @@
* Returns a pointer to the string copy, the caller must free it with xmlFree().
*/
xmlChar *
-xmlNodeListGetRawString(xmlDocPtr doc, xmlNodePtr list, int inLine)
+xmlNodeListGetRawString(const xmlDoc *doc, const xmlNode *list, int inLine)
{
- xmlNodePtr node = list;
+ const xmlNode *node = list;
xmlChar *ret = NULL;
xmlEntityPtr ent;
@@ -2265,7 +2271,7 @@
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));
@@ -2345,7 +2351,7 @@
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);
@@ -2578,7 +2584,7 @@
* Returns a pointer to the new node object.
*/
xmlNodePtr
-xmlNewReference(xmlDocPtr doc, const xmlChar *name) {
+xmlNewReference(const xmlDoc *doc, const xmlChar *name) {
xmlNodePtr cur;
xmlEntityPtr ent;
@@ -2596,7 +2602,7 @@
memset(cur, 0, sizeof(xmlNode));
cur->type = XML_ENTITY_REF_NODE;
- cur->doc = doc;
+ cur->doc = (xmlDoc *)doc;
if (name[0] == '&') {
int len;
name++;
@@ -2634,11 +2640,11 @@
* Returns a pointer to the new node object.
*/
xmlNodePtr
-xmlNewDocText(xmlDocPtr doc, const xmlChar *content) {
+xmlNewDocText(const xmlDoc *doc, const xmlChar *content) {
xmlNodePtr cur;
cur = xmlNewText(content);
- if (cur != NULL) cur->doc = doc;
+ if (cur != NULL) cur->doc = (xmlDoc *)doc;
return(cur);
}
@@ -2794,8 +2800,27 @@
if(tree->type == XML_ELEMENT_NODE) {
prop = tree->properties;
while (prop != NULL) {
+ if (prop->atype == XML_ATTRIBUTE_ID) {
+ xmlRemoveID(tree->doc, prop);
+ }
+
prop->doc = doc;
xmlSetListDoc(prop->children, doc);
+
+ /*
+ * TODO: ID attributes should be also added to the new
+ * document, but this breaks things like xmlReplaceNode.
+ * The underlying problem is that xmlRemoveID is only called
+ * if a node is destroyed, not if it's unlinked.
+ */
+#if 0
+ if (xmlIsID(doc, tree, prop)) {
+ xmlChar *idVal = xmlNodeListGetString(doc, prop->children,
+ 1);
+ xmlAddID(NULL, doc, idVal, prop);
+ }
+#endif
+
prop = prop->next;
}
}
@@ -3034,7 +3059,7 @@
}
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
- defined(LIBXML_SCHEMAS_ENABLED)
+ defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
/**
* xmlAddPrevSibling:
* @cur: the child node
@@ -3412,7 +3437,7 @@
* Returns the last child or NULL if none.
*/
xmlNodePtr
-xmlGetLastChild(xmlNodePtr parent) {
+xmlGetLastChild(const xmlNode *parent) {
if ((parent == NULL) || (parent->type == XML_NAMESPACE_DECL)) {
#ifdef DEBUG_TREE
xmlGenericError(xmlGenericErrorContext,
@@ -3451,6 +3476,7 @@
case XML_ELEMENT_NODE:
case XML_ENTITY_NODE:
case XML_DOCUMENT_NODE:
+ case XML_DOCUMENT_FRAG_NODE:
case XML_HTML_DOCUMENT_NODE:
cur = parent->children;
break;
@@ -3486,6 +3512,7 @@
case XML_ELEMENT_NODE:
case XML_ENTITY_NODE:
case XML_DOCUMENT_NODE:
+ case XML_DOCUMENT_FRAG_NODE:
case XML_HTML_DOCUMENT_NODE:
cur = parent->children;
break;
@@ -3521,6 +3548,7 @@
case XML_ELEMENT_NODE:
case XML_ENTITY_NODE:
case XML_DOCUMENT_NODE:
+ case XML_DOCUMENT_FRAG_NODE:
case XML_HTML_DOCUMENT_NODE:
cur = parent->last;
break;
@@ -3674,7 +3702,7 @@
* 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) &&
@@ -3743,7 +3771,7 @@
/*
* 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) &&
@@ -4128,7 +4156,7 @@
*/
static xmlNodePtr
-xmlStaticCopyNode(const xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
+xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
int extended) {
xmlNodePtr ret;
@@ -4294,6 +4322,7 @@
}
if (doc->intSubset == NULL) {
q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
+ if (q == NULL) return(NULL);
q->doc = doc;
q->parent = parent;
doc->intSubset = (xmlDtdPtr) q;
@@ -4305,6 +4334,7 @@
} else
#endif /* LIBXML_TREE_ENABLED */
q = xmlStaticCopyNode(node, doc, parent, 1);
+ if (q == NULL) return(NULL);
if (ret == NULL) {
q->prev = NULL;
ret = p = q;
@@ -4331,7 +4361,7 @@
* Returns: a new #xmlNodePtr, or NULL in case of error.
*/
xmlNodePtr
-xmlCopyNode(const xmlNodePtr node, int extended) {
+xmlCopyNode(xmlNodePtr node, int extended) {
xmlNodePtr ret;
ret = xmlStaticCopyNode(node, NULL, NULL, extended);
@@ -4351,7 +4381,7 @@
* Returns: a new #xmlNodePtr, or NULL in case of error.
*/
xmlNodePtr
-xmlDocCopyNode(const xmlNodePtr node, xmlDocPtr doc, int extended) {
+xmlDocCopyNode(xmlNodePtr node, xmlDocPtr doc, int extended) {
xmlNodePtr ret;
ret = xmlStaticCopyNode(node, doc, NULL, extended);
@@ -4367,7 +4397,7 @@
*
* Returns: a new #xmlNodePtr, or NULL in case of error.
*/
-xmlNodePtr xmlDocCopyNodeList(xmlDocPtr doc, const xmlNodePtr node) {
+xmlNodePtr xmlDocCopyNodeList(xmlDocPtr doc, xmlNodePtr node) {
xmlNodePtr ret = xmlStaticCopyNodeList(node, doc, NULL);
return(ret);
}
@@ -4381,7 +4411,7 @@
*
* Returns: a new #xmlNodePtr, or NULL in case of error.
*/
-xmlNodePtr xmlCopyNodeList(const xmlNodePtr node) {
+xmlNodePtr xmlCopyNodeList(xmlNodePtr node) {
xmlNodePtr ret = xmlStaticCopyNodeList(node, NULL, NULL);
return(ret);
}
@@ -4507,6 +4537,10 @@
#ifdef LIBXML_TREE_ENABLED
if (doc->intSubset != NULL) {
ret->intSubset = xmlCopyDtd(doc->intSubset);
+ if (ret->intSubset == NULL) {
+ xmlFreeDoc(ret);
+ return(NULL);
+ }
xmlSetTreeDoc((xmlNodePtr)ret->intSubset, ret);
ret->intSubset->parent = ret;
}
@@ -4547,7 +4581,7 @@
* Returns the line number if successful, -1 otherwise
*/
static long
-xmlGetLineNoInternal(xmlNodePtr node, int depth)
+xmlGetLineNoInternal(const xmlNode *node, int depth)
{
long result = -1;
@@ -4597,7 +4631,7 @@
* Returns the line number if successful, -1 otherwise
*/
long
-xmlGetLineNo(xmlNodePtr node)
+xmlGetLineNo(const xmlNode *node)
{
return(xmlGetLineNoInternal(node, 0));
}
@@ -4613,9 +4647,9 @@
* the returned string
*/
xmlChar *
-xmlGetNodePath(xmlNodePtr node)
+xmlGetNodePath(const xmlNode *node)
{
- xmlNodePtr cur, tmp, next;
+ const xmlNode *cur, *tmp, *next;
xmlChar *buffer = NULL, *temp;
size_t buf_len;
xmlChar *buf;
@@ -4859,7 +4893,7 @@
* Returns the #xmlNodePtr for the root or NULL
*/
xmlNodePtr
-xmlDocGetRootElement(xmlDocPtr doc) {
+xmlDocGetRootElement(const xmlDoc *doc) {
xmlNodePtr ret;
if (doc == NULL) return(NULL);
@@ -4973,7 +5007,7 @@
* It's up to the caller to free the memory with xmlFree().
*/
xmlChar *
-xmlNodeGetLang(xmlNodePtr cur) {
+xmlNodeGetLang(const xmlNode *cur) {
xmlChar *lang;
if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
@@ -5054,7 +5088,7 @@
* Returns -1 if xml:space is not inherited, 0 if "default", 1 if "preserve"
*/
int
-xmlNodeGetSpacePreserve(xmlNodePtr cur) {
+xmlNodeGetSpacePreserve(const xmlNode *cur) {
xmlChar *space;
if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))
@@ -5089,6 +5123,7 @@
xmlNodeSetName(xmlNodePtr cur, const xmlChar *name) {
xmlDocPtr doc;
xmlDictPtr dict;
+ const xmlChar *freeme = NULL;
if (cur == NULL) return;
if (name == NULL) return;
@@ -5126,12 +5161,16 @@
dict = NULL;
if (dict != NULL) {
if ((cur->name != NULL) && (!xmlDictOwns(dict, cur->name)))
- xmlFree((xmlChar *) cur->name);
+ freeme = cur->name;
cur->name = xmlDictLookup(dict, name, -1);
} else {
- if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
+ if (cur->name != NULL)
+ freeme = cur->name;
cur->name = xmlStrdup(name);
}
+
+ if (freeme)
+ xmlFree((xmlChar *) freeme);
}
#endif
@@ -5219,7 +5258,7 @@
* It's up to the caller to free the memory with xmlFree().
*/
xmlChar *
-xmlNodeGetBase(xmlDocPtr doc, xmlNodePtr cur) {
+xmlNodeGetBase(const xmlDoc *doc, const xmlNode *cur) {
xmlChar *oldbase = NULL;
xmlChar *base, *newbase;
@@ -5304,7 +5343,7 @@
* Returns 0 in case of success and -1 in case of error.
*/
int
-xmlNodeBufGetContent(xmlBufferPtr buffer, xmlNodePtr cur)
+xmlNodeBufGetContent(xmlBufferPtr buffer, const xmlNode *cur)
{
xmlBufPtr buf;
int ret;
@@ -5327,12 +5366,12 @@
* directly by this node if it's a TEXT node or the aggregate string
* of the values carried by this node child's (TEXT and ENTITY_REF).
* Entity references are substituted.
- * Fills up the buffer @buffer with this value
+ * Fills up the buffer @buf with this value
*
* Returns 0 in case of success and -1 in case of error.
*/
int
-xmlBufGetNodeContent(xmlBufPtr buf, xmlNodePtr cur)
+xmlBufGetNodeContent(xmlBufPtr buf, const xmlNode *cur)
{
if ((cur == NULL) || (buf == NULL)) return(-1);
switch (cur->type) {
@@ -5342,7 +5381,7 @@
break;
case XML_DOCUMENT_FRAG_NODE:
case XML_ELEMENT_NODE:{
- xmlNodePtr tmp = cur;
+ const xmlNode *tmp = cur;
while (tmp != NULL) {
switch (tmp->type) {
@@ -5473,7 +5512,7 @@
* It's up to the caller to free the memory with xmlFree().
*/
xmlChar *
-xmlNodeGetContent(xmlNodePtr cur)
+xmlNodeGetContent(const xmlNode *cur)
{
if (cur == NULL)
return (NULL);
@@ -5853,7 +5892,7 @@
* namespace if defined
*/
xmlNsPtr *
-xmlGetNsList(xmlDocPtr doc ATTRIBUTE_UNUSED, xmlNodePtr node)
+xmlGetNsList(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlNode *node)
{
xmlNsPtr cur;
xmlNsPtr *ret = NULL;
@@ -5960,7 +5999,7 @@
xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace) {
xmlNsPtr cur;
- xmlNodePtr orig = node;
+ const xmlNode *orig = node;
if ((node == NULL) || (node->type == XML_NAMESPACE_DECL)) return(NULL);
if ((nameSpace != NULL) &&
@@ -6429,7 +6468,7 @@
#endif /* LIBXML_TREE_ENABLED */
static xmlAttrPtr
-xmlGetPropNodeInternal(xmlNodePtr node, const xmlChar *name,
+xmlGetPropNodeInternal(const xmlNode *node, const xmlChar *name,
const xmlChar *nsName, int useDTD)
{
xmlAttrPtr prop;
@@ -6543,7 +6582,7 @@
}
static xmlChar*
-xmlGetPropNodeValueInternal(xmlAttrPtr prop)
+xmlGetPropNodeValueInternal(const xmlAttr *prop)
{
if (prop == NULL)
return(NULL);
@@ -6589,7 +6628,7 @@
* neither was found.
*/
xmlAttrPtr
-xmlHasProp(xmlNodePtr node, const xmlChar *name) {
+xmlHasProp(const xmlNode *node, const xmlChar *name) {
xmlAttrPtr prop;
xmlDocPtr doc;
@@ -6644,7 +6683,7 @@
* if neither was found.
*/
xmlAttrPtr
-xmlHasNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) {
+xmlHasNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace) {
return(xmlGetPropNodeInternal(node, name, nameSpace, xmlCheckDTD));
}
@@ -6666,7 +6705,7 @@
* It's up to the caller to free the memory with xmlFree().
*/
xmlChar *
-xmlGetProp(xmlNodePtr node, const xmlChar *name) {
+xmlGetProp(const xmlNode *node, const xmlChar *name) {
xmlAttrPtr prop;
prop = xmlHasProp(node, name);
@@ -6691,7 +6730,7 @@
* It's up to the caller to free the memory with xmlFree().
*/
xmlChar *
-xmlGetNoNsProp(xmlNodePtr node, const xmlChar *name) {
+xmlGetNoNsProp(const xmlNode *node, const xmlChar *name) {
xmlAttrPtr prop;
prop = xmlGetPropNodeInternal(node, name, NULL, xmlCheckDTD);
@@ -6716,7 +6755,7 @@
* It's up to the caller to free the memory with xmlFree().
*/
xmlChar *
-xmlGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) {
+xmlGetNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace) {
xmlAttrPtr prop;
prop = xmlGetPropNodeInternal(node, name, nameSpace, xmlCheckDTD);
@@ -6881,7 +6920,7 @@
* Returns 1 yes, 0 no
*/
int
-xmlNodeIsText(xmlNodePtr node) {
+xmlNodeIsText(const xmlNode *node) {
if (node == NULL) return(0);
if (node->type == XML_TEXT_NODE) return(1);
@@ -6898,7 +6937,7 @@
* Returns 1 yes, 0 no
*/
int
-xmlIsBlankNode(xmlNodePtr node) {
+xmlIsBlankNode(const xmlNode *node) {
const xmlChar *cur;
if (node == NULL) return(0);
@@ -7301,7 +7340,7 @@
*/
const xmlChar *
-xmlBufferContent(const xmlBufferPtr buf)
+xmlBufferContent(const xmlBuffer *buf)
{
if(!buf)
return NULL;
@@ -7319,7 +7358,7 @@
*/
int
-xmlBufferLength(const xmlBufferPtr buf)
+xmlBufferLength(const xmlBuffer *buf)
{
if(!buf)
return 0;
@@ -7703,7 +7742,7 @@
* Returns 0 (uncompressed) to 9 (max compression)
*/
int
-xmlGetDocCompressMode (xmlDocPtr doc) {
+xmlGetDocCompressMode (const xmlDoc *doc) {
if (doc == NULL) return(-1);
return(doc->compression);
}
@@ -7894,8 +7933,7 @@
map->first->prev = ret;
ret->next = map->first;
map->first = ret;
- } else
- return(NULL);
+ }
ret->oldNs = oldNs;
ret->newNs = newNs;
@@ -7955,7 +7993,7 @@
*
* Allocates and initializes a new DOM-wrapper context.
*
-* Returns the xmlDOMWrapCtxtPtr or NULL in case of an internal errror.
+* Returns the xmlDOMWrapCtxtPtr or NULL in case of an internal error.
*/
xmlDOMWrapCtxtPtr
xmlDOMWrapNewCtxt(void)
@@ -9780,7 +9818,8 @@
if (clone->parent != NULL)
clone->parent->last = clone;
clone = clone->parent;
- parentClone = clone->parent;
+ if (clone != NULL)
+ parentClone = clone->parent;
/*
* Process parent --> next;
*/
@@ -9962,7 +10001,7 @@
* References of out-of scope ns-decls are remapped to point to @destDoc:
* 1) If @destParent is given, then nsDef entries on element-nodes are used
* 2) If *no* @destParent is given, then @destDoc->oldNs entries are used
-* This is the case when you have an unliked node and just want to move it
+* This is the case when you have an unlinked node and just want to move it
* to the context of
*
* If @destParent is given, it ensures that the tree is namespace
diff --git a/trio.c b/trio.c
index d885db9..c8b9c84 100644
--- a/trio.c
+++ b/trio.c
@@ -99,7 +99,7 @@
#endif
#include <stddef.h>
-#ifdef HAVE_ERRNO_H
+#if defined( HAVE_ERRNO_H ) || defined( __VMS )
#include <errno.h>
#endif
@@ -126,13 +126,23 @@
# define TRIO_ERROR_RETURN(x,y) (-1)
#endif
+#ifndef VA_LIST_IS_ARRAY
+#define TRIO_VA_LIST_PTR va_list *
+#define TRIO_VA_LIST_ADDR(l) (&(l))
+#define TRIO_VA_LIST_DEREF(l) (*(l))
+#else
+#define TRIO_VA_LIST_PTR va_list
+#define TRIO_VA_LIST_ADDR(l) (l)
+#define TRIO_VA_LIST_DEREF(l) (l)
+#endif
+
typedef unsigned long trio_flags_t;
/*************************************************************************
* Platform specific definitions
*/
-#if defined(TRIO_PLATFORM_UNIX)
+#if defined(TRIO_PLATFORM_UNIX) || defined(TRIO_PLATFORM_OS400)
# include <unistd.h>
# include <signal.h>
# include <locale.h>
@@ -208,7 +218,7 @@
#endif
/* Maximal and fixed integer types */
-#if defined(TRIO_COMPILER_SUPPORTS_C99)
+#if defined(TRIO_COMPILER_SUPPORTS_C99) && !defined( __VMS )
# include <stdint.h>
typedef intmax_t trio_intmax_t;
typedef uintmax_t trio_uintmax_t;
@@ -216,8 +226,12 @@
typedef int16_t trio_int16_t;
typedef int32_t trio_int32_t;
typedef int64_t trio_int64_t;
-#elif defined(TRIO_COMPILER_SUPPORTS_UNIX98)
+#elif defined(TRIO_COMPILER_SUPPORTS_UNIX98) || defined( __VMS )
# include <inttypes.h>
+#ifdef __VMS
+typedef long long int intmax_t;
+typedef unsigned long long int uintmax_t;
+#endif
typedef intmax_t trio_intmax_t;
typedef uintmax_t trio_uintmax_t;
typedef int8_t trio_int8_t;
@@ -308,7 +322,9 @@
#define NAN_UPPER "NAN"
#if !defined(HAVE_ISASCII) && !defined(isascii)
-# define isascii(x) ((unsigned int)(x) < 128)
+#ifndef __VMS
+# define isascii(x) ((unsigned int)(x) < 128)
+#endif
#endif
/* Various constants */
@@ -1167,7 +1183,7 @@
int type,
TRIO_CONST char *format,
trio_parameter_t *parameters,
- va_list *arglist,
+ TRIO_VA_LIST_PTR arglist,
trio_pointer_t *argarray)
{
/* Count the number of times a parameter is referenced */
@@ -1945,14 +1961,14 @@
if (flags & FLAGS_WIDECHAR)
{
parameters[i].data.wstring = (argarray == NULL)
- ? va_arg(*arglist, trio_wchar_t *)
+ ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_wchar_t *)
: (trio_wchar_t *)(argarray[num]);
}
else
#endif
{
parameters[i].data.string = (argarray == NULL)
- ? va_arg(*arglist, char *)
+ ? va_arg(TRIO_VA_LIST_DEREF(arglist), char *)
: (char *)(argarray[num]);
}
break;
@@ -1964,7 +1980,7 @@
case FORMAT_COUNT:
case FORMAT_UNKNOWN:
parameters[i].data.pointer = (argarray == NULL)
- ? va_arg(*arglist, trio_pointer_t )
+ ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_pointer_t )
: argarray[num];
break;
@@ -1974,7 +1990,7 @@
{
if (argarray == NULL)
parameters[i].data.pointer =
- (trio_pointer_t)va_arg(*arglist, trio_pointer_t);
+ (trio_pointer_t)va_arg(TRIO_VA_LIST_DEREF(arglist), trio_pointer_t);
else
{
if (parameters[i].type == FORMAT_CHAR)
@@ -2032,36 +2048,36 @@
#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
if (parameters[i].flags & FLAGS_SIZE_T)
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, size_t)
+ ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), size_t)
: (trio_uintmax_t)(*((size_t *)argarray[num]));
else
#endif
#if defined(QUALIFIER_PTRDIFF_T)
if (parameters[i].flags & FLAGS_PTRDIFF_T)
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, ptrdiff_t)
+ ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), ptrdiff_t)
: (trio_uintmax_t)(*((ptrdiff_t *)argarray[num]));
else
#endif
#if defined(QUALIFIER_INTMAX_T)
if (parameters[i].flags & FLAGS_INTMAX_T)
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, trio_intmax_t)
+ ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), trio_intmax_t)
: (trio_uintmax_t)(*((trio_intmax_t *)argarray[num]));
else
#endif
if (parameters[i].flags & FLAGS_QUAD)
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, trio_ulonglong_t)
+ ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), trio_ulonglong_t)
: (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num]));
else if (parameters[i].flags & FLAGS_LONG)
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, long)
+ ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), long)
: (trio_uintmax_t)(*((long *)argarray[num]));
else
{
if (argarray == NULL)
- parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(*arglist, int);
+ parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), int);
else
{
if (parameters[i].type == FORMAT_CHAR)
@@ -2082,11 +2098,11 @@
*/
if (parameters[i].flags & FLAGS_USER_DEFINED)
parameters[i].data.pointer = (argarray == NULL)
- ? va_arg(*arglist, trio_pointer_t )
+ ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_pointer_t )
: argarray[num];
else
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, int)
+ ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), int)
: (trio_uintmax_t)(*((int *)argarray[num]));
break;
@@ -2095,17 +2111,17 @@
{
if (parameters[i].flags & FLAGS_LONGDOUBLE)
parameters[i].data.longdoublePointer = (argarray == NULL)
- ? va_arg(*arglist, trio_long_double_t *)
+ ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_long_double_t *)
: (trio_long_double_t *)argarray[num];
else
{
if (parameters[i].flags & FLAGS_LONG)
parameters[i].data.doublePointer = (argarray == NULL)
- ? va_arg(*arglist, double *)
+ ? va_arg(TRIO_VA_LIST_DEREF(arglist), double *)
: (double *)argarray[num];
else
parameters[i].data.doublePointer = (argarray == NULL)
- ? (double *)va_arg(*arglist, float *)
+ ? (double *)va_arg(TRIO_VA_LIST_DEREF(arglist), float *)
: (double *)((float *)argarray[num]);
}
}
@@ -2113,13 +2129,13 @@
{
if (parameters[i].flags & FLAGS_LONGDOUBLE)
parameters[i].data.longdoubleNumber = (argarray == NULL)
- ? va_arg(*arglist, trio_long_double_t)
+ ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_long_double_t)
: (trio_long_double_t)(*((trio_long_double_t *)argarray[num]));
else
{
if (argarray == NULL)
parameters[i].data.longdoubleNumber =
- (trio_long_double_t)va_arg(*arglist, double);
+ (trio_long_double_t)va_arg(TRIO_VA_LIST_DEREF(arglist), double);
else
{
if (parameters[i].flags & FLAGS_SHORT)
@@ -3384,7 +3400,7 @@
TRIO_ARGS4((reference, format, arglist, argarray),
trio_reference_t *reference,
TRIO_CONST char *format,
- va_list *arglist,
+ TRIO_VA_LIST_PTR arglist,
trio_pointer_t *argarray)
{
int status;
@@ -3412,7 +3428,7 @@
size_t destinationSize,
void (*OutStream) TRIO_PROTO((trio_class_t *, int)),
TRIO_CONST char *format,
- va_list *arglist,
+ TRIO_VA_LIST_PTR arglist,
trio_pointer_t *argarray)
{
int status;
@@ -3638,7 +3654,7 @@
assert(VALID(format));
TRIO_VA_START(args, format);
- status = TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL);
+ status = TrioFormat(stdout, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
@@ -3658,7 +3674,7 @@
{
assert(VALID(format));
- return TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL);
+ return TrioFormat(stdout, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
}
/**
@@ -3705,7 +3721,7 @@
assert(VALID(format));
TRIO_VA_START(args, format);
- status = TrioFormat(file, 0, TrioOutStreamFile, format, &args, NULL);
+ status = TrioFormat(file, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
@@ -3728,7 +3744,7 @@
assert(VALID(file));
assert(VALID(format));
- return TrioFormat(file, 0, TrioOutStreamFile, format, &args, NULL);
+ return TrioFormat(file, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
}
/**
@@ -3777,7 +3793,7 @@
assert(VALID(format));
TRIO_VA_START(args, format);
- status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, &args, NULL);
+ status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
@@ -3799,7 +3815,7 @@
{
assert(VALID(format));
- return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, &args, NULL);
+ return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, TRIO_VA_LIST_ADDR(args), NULL);
}
/**
@@ -3843,7 +3859,7 @@
TRIO_VA_START(args, format);
data.stream.out = stream;
data.closure = closure;
- status = TrioFormat(&data, 0, TrioOutStreamCustom, format, &args, NULL);
+ status = TrioFormat(&data, 0, TrioOutStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
@@ -3863,7 +3879,7 @@
data.stream.out = stream;
data.closure = closure;
- return TrioFormat(&data, 0, TrioOutStreamCustom, format, &args, NULL);
+ return TrioFormat(&data, 0, TrioOutStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
}
TRIO_PUBLIC int
@@ -3910,7 +3926,7 @@
assert(VALID(format));
TRIO_VA_START(args, format);
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, &args, NULL);
+ status = TrioFormat(&buffer, 0, TrioOutStreamString, format, TRIO_VA_LIST_ADDR(args), NULL);
*buffer = NIL; /* Terminate with NIL character */
TRIO_VA_END(args);
return status;
@@ -3936,7 +3952,7 @@
assert(VALID(buffer));
assert(VALID(format));
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, &args, NULL);
+ status = TrioFormat(&buffer, 0, TrioOutStreamString, format, TRIO_VA_LIST_ADDR(args), NULL);
*buffer = NIL;
return status;
}
@@ -3995,7 +4011,7 @@
TRIO_VA_START(args, format);
status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, &args, NULL);
+ TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
if (max > 0)
*buffer = NIL;
TRIO_VA_END(args);
@@ -4025,7 +4041,7 @@
assert(VALID(format));
status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, &args, NULL);
+ TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
if (max > 0)
*buffer = NIL;
return status;
@@ -4086,7 +4102,7 @@
buffer = &buffer[buf_len];
status = TrioFormat(&buffer, max - 1 - buf_len,
- TrioOutStreamStringMax, format, &args, NULL);
+ TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
*buffer = NIL;
return status;
@@ -4109,7 +4125,7 @@
buf_len = trio_length(buffer);
buffer = &buffer[buf_len];
status = TrioFormat(&buffer, max - 1 - buf_len,
- TrioOutStreamStringMax, format, &args, NULL);
+ TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
*buffer = NIL;
return status;
}
@@ -4136,7 +4152,7 @@
{
TRIO_VA_START(args, format);
(void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
trio_string_terminate(info);
@@ -4162,7 +4178,7 @@
if (info)
{
(void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
trio_string_terminate(info);
result = trio_string_extract(info);
trio_string_destroy(info);
@@ -4194,7 +4210,7 @@
{
TRIO_VA_START(args, format);
status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
if (status >= 0)
{
@@ -4228,7 +4244,7 @@
else
{
status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
if (status >= 0)
{
trio_string_terminate(info);
@@ -4930,7 +4946,7 @@
assert(VALID(format));
TRIO_VA_START(arglist, format);
- status = TrioFormatRef((trio_reference_t *)ref, format, &arglist, NULL);
+ status = TrioFormatRef((trio_reference_t *)ref, format, TRIO_VA_LIST_ADDR(arglist), NULL);
TRIO_VA_END(arglist);
return status;
}
@@ -4947,7 +4963,7 @@
{
assert(VALID(format));
- return TrioFormatRef((trio_reference_t *)ref, format, &arglist, NULL);
+ return TrioFormatRef((trio_reference_t *)ref, format, TRIO_VA_LIST_ADDR(arglist), NULL);
}
/*************************************************************************
@@ -6374,7 +6390,7 @@
size_t sourceSize,
void (*InStream) TRIO_PROTO((trio_class_t *, int *)),
TRIO_CONST char *format,
- va_list *arglist,
+ TRIO_VA_LIST_PTR arglist,
trio_pointer_t *argarray)
{
int status;
@@ -6418,11 +6434,14 @@
trio_class_t *self,
int *intPointer)
{
- FILE *file = (FILE *)self->location;
+ FILE *file;
assert(VALID(self));
+ assert(VALID(self->location));
assert(VALID(file));
+ file = (FILE *)self->location;
+
self->current = fgetc(file);
if (self->current == EOF)
{
@@ -6451,11 +6470,14 @@
trio_class_t *self,
int *intPointer)
{
- int fd = *((int *)self->location);
+ int fd;
int size;
unsigned char input;
assert(VALID(self));
+ assert(VALID(self->location));
+
+ fd = *((int *)self->location);
size = read(fd, &input, sizeof(char));
if (size == -1)
@@ -6586,7 +6608,7 @@
TRIO_VA_START(args, format);
status = TrioScan((trio_pointer_t)stdin, 0,
TrioInStreamFile,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
@@ -6601,7 +6623,7 @@
return TrioScan((trio_pointer_t)stdin, 0,
TrioInStreamFile,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
}
TRIO_PUBLIC int
@@ -6636,7 +6658,7 @@
TRIO_VA_START(args, format);
status = TrioScan((trio_pointer_t)file, 0,
TrioInStreamFile,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
@@ -6653,7 +6675,7 @@
return TrioScan((trio_pointer_t)file, 0,
TrioInStreamFile,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
}
TRIO_PUBLIC int
@@ -6689,7 +6711,7 @@
TRIO_VA_START(args, format);
status = TrioScan((trio_pointer_t)&fd, 0,
TrioInStreamFileDescriptor,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
@@ -6705,7 +6727,7 @@
return TrioScan((trio_pointer_t)&fd, 0,
TrioInStreamFileDescriptor,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
}
TRIO_PUBLIC int
@@ -6743,7 +6765,7 @@
TRIO_VA_START(args, format);
data.stream.in = stream;
data.closure = closure;
- status = TrioScan(&data, 0, TrioInStreamCustom, format, &args, NULL);
+ status = TrioScan(&data, 0, TrioInStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
@@ -6763,7 +6785,7 @@
data.stream.in = stream;
data.closure = closure;
- return TrioScan(&data, 0, TrioInStreamCustom, format, &args, NULL);
+ return TrioScan(&data, 0, TrioInStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
}
TRIO_PUBLIC int
@@ -6803,7 +6825,7 @@
TRIO_VA_START(args, format);
status = TrioScan((trio_pointer_t)&buffer, 0,
TrioInStreamString,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
@@ -6820,7 +6842,7 @@
return TrioScan((trio_pointer_t)&buffer, 0,
TrioInStreamString,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
}
TRIO_PUBLIC int
diff --git a/trio.h b/trio.h
index 108a709..99d2127 100644
--- a/trio.h
+++ b/trio.h
@@ -155,45 +155,59 @@
#ifdef TRIO_REPLACE_STDIO
/* Replace the <stdio.h> functions */
#ifndef HAVE_PRINTF
+# undef printf
# define printf trio_printf
#endif
#ifndef HAVE_VPRINTF
+# undef vprintf
# define vprintf trio_vprintf
#endif
#ifndef HAVE_FPRINTF
+# undef fprintf
# define fprintf trio_fprintf
#endif
#ifndef HAVE_VFPRINTF
+# undef vfprintf
# define vfprintf trio_vfprintf
#endif
#ifndef HAVE_SPRINTF
+# undef sprintf
# define sprintf trio_sprintf
#endif
#ifndef HAVE_VSPRINTF
+# undef vsprintf
# define vsprintf trio_vsprintf
#endif
#ifndef HAVE_SNPRINTF
+# undef snprintf
# define snprintf trio_snprintf
#endif
#ifndef HAVE_VSNPRINTF
+# undef vsnprintf
# define vsnprintf trio_vsnprintf
#endif
#ifndef HAVE_SCANF
+# undef scanf
# define scanf trio_scanf
#endif
#ifndef HAVE_VSCANF
+# undef vscanf
# define vscanf trio_vscanf
#endif
#ifndef HAVE_FSCANF
+# undef fscanf
# define fscanf trio_fscanf
#endif
#ifndef HAVE_VFSCANF
+# undef vfscanf
# define vfscanf trio_vfscanf
#endif
#ifndef HAVE_SSCANF
+# undef sscanf
# define sscanf trio_sscanf
#endif
#ifndef HAVE_VSSCANF
+# undef vsscanf
# define vsscanf trio_vsscanf
#endif
/* These aren't stdio functions, but we make them look similar */
diff --git a/triodef.h b/triodef.h
index fa89416..46772ee 100644
--- a/triodef.h
+++ b/triodef.h
@@ -48,6 +48,8 @@
* based on the DECC compiler later on.
*/
# define TRIO_PLATFORM_VMS
+#elif defined(__OS400__)
+# define TRIO_PLATFORM_OS400
#elif defined(unix) || defined(__unix) || defined(__unix__)
# define TRIO_PLATFORM_UNIX
#elif defined(TRIO_COMPILER_XLC) || defined(_AIX)
@@ -98,6 +100,10 @@
# define TRIO_COMPILER_SUPPORTS_C94
# endif
# endif
+#elif defined(TRIO_COMPILER_XLC) && defined(__EXTENDED__)
+# define TRIO_COMPILER_SUPPORTS_C89
+# define TRIO_COMPILER_SUPPORTS_C90
+# define TRIO_COMPILER_SUPPORTS_C94
#endif
#if defined(_XOPEN_SOURCE)
diff --git a/triostr.c b/triostr.c
index e507645..123bbeb 100644
--- a/triostr.c
+++ b/triostr.c
@@ -52,7 +52,9 @@
# define BOOLEAN_T int
#endif
-#if defined(TRIO_COMPILER_SUPPORTS_C99)
+#ifdef __VMS
+# define USE_STRTOD
+#elif defined(TRIO_COMPILER_SUPPORTS_C99)
# define USE_STRTOD
# define USE_STRTOF
#elif defined(TRIO_COMPILER_MSVC)
@@ -78,6 +80,10 @@
# else
# define strcasecmp(x,y) strcmpi(x,y)
# endif
+#elif defined(TRIO_PLATFORM_OS400)
+# define USE_STRCASECMP
+# define USE_STRNCASECMP
+# include <strings.h>
#endif
#if !(defined(TRIO_PLATFORM_SUNOS))
diff --git a/uri.c b/uri.c
index 4ab0ce2..d7f32fc 100644
--- a/uri.c
+++ b/uri.c
@@ -314,7 +314,7 @@
* @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 @@
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);
}
@@ -759,6 +760,8 @@
cur += 2;
ret = xmlParse3986Authority(uri, &cur);
if (ret != 0) return(ret);
+ if (uri->server == NULL)
+ uri->port = -1;
ret = xmlParse3986PathAbEmpty(uri, &cur);
if (ret != 0) return(ret);
*str = cur;
@@ -1106,7 +1109,7 @@
}
}
} else {
- if (uri->server != NULL) {
+ if ((uri->server != NULL) || (uri->port == -1)) {
if (len + 3 >= max) {
temp = xmlSaveUriRealloc(ret, &max);
if (temp == NULL) goto mem_error;
@@ -1143,22 +1146,24 @@
}
ret[len++] = '@';
}
- p = uri->server;
- while (*p != 0) {
- if (len >= max) {
- temp = xmlSaveUriRealloc(ret, &max);
- if (temp == NULL) goto mem_error;
- ret = temp;
+ if (uri->server != NULL) {
+ p = uri->server;
+ while (*p != 0) {
+ if (len >= max) {
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
+ }
+ ret[len++] = *p++;
}
- ret[len++] = *p++;
- }
- if (uri->port > 0) {
- if (len + 10 >= max) {
- temp = xmlSaveUriRealloc(ret, &max);
- if (temp == NULL) goto mem_error;
- ret = temp;
+ if (uri->port > 0) {
+ if (len + 10 >= max) {
+ temp = xmlSaveUriRealloc(ret, &max);
+ if (temp == NULL) goto mem_error;
+ ret = temp;
+ }
+ len += snprintf((char *) &ret[len], max - len, ":%d", uri->port);
}
- len += snprintf((char *) &ret[len], max - len, ":%d", uri->port);
}
} else if (uri->authority != NULL) {
if (len + 3 >= max) {
@@ -1194,8 +1199,6 @@
if (temp == NULL) goto mem_error;
ret = temp;
}
- ret[len++] = '/';
- ret[len++] = '/';
}
if (uri->path != NULL) {
p = uri->path;
@@ -1529,11 +1532,10 @@
break;
}
/* Valgrind complained, strcpy(cur, segp + 3); */
- /* string will overlap, do not use strcpy */
- tmp = cur;
- segp += 3;
- while ((*tmp++ = *segp++) != 0)
- ;
+ /* string will overlap, do not use strcpy */
+ tmp = cur;
+ segp += 3;
+ while ((*tmp++ = *segp++) != 0);
/* If there are no previous segments, then keep going from here. */
segp = cur;
diff --git a/valid.c b/valid.c
index 6e53a76..19f84b8 100644
--- a/valid.c
+++ b/valid.c
@@ -93,7 +93,7 @@
*
* 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 @@
*
* 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,
@@ -180,7 +180,7 @@
*
* 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 @@
*
* 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,
@@ -1798,6 +1798,7 @@
if (cur == NULL) return(NULL);
ret = xmlCreateEnumeration((xmlChar *) cur->name);
+ if (ret == NULL) return(NULL);
if (cur->next != NULL) ret->next = xmlCopyEnumeration(cur->next);
else ret->next = NULL;
@@ -2531,7 +2532,7 @@
* 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) \
@@ -2633,10 +2634,9 @@
/*
* The id is already defined in this DTD.
*/
- if ((ctxt != NULL) && (ctxt->error != NULL)) {
+ if (ctxt != NULL) {
xmlErrValidNode(ctxt, attr->parent, XML_DTD_ID_REDEFINED,
- "ID %s already defined\n",
- value, NULL, NULL);
+ "ID %s already defined\n", value, NULL, NULL);
}
#endif /* LIBXML_VALID_ENABLED */
xmlFreeID(ret);
@@ -2740,23 +2740,24 @@
if (doc == NULL) return(-1);
if (attr == NULL) return(-1);
+
table = (xmlIDTablePtr) doc->ids;
if (table == NULL)
return(-1);
- if (attr == NULL)
- return(-1);
ID = xmlNodeListGetString(doc, attr->children, 1);
if (ID == NULL)
- return(-1);
+ return(-1);
+
id = xmlHashLookup(table, ID);
if (id == NULL || id->attr != attr) {
- xmlFree(ID);
- return(-1);
+ xmlFree(ID);
+ return(-1);
}
+
xmlHashRemoveEntry(table, ID, (xmlHashDeallocator) xmlFreeID);
xmlFree(ID);
- attr->atype = 0;
+ attr->atype = 0;
return(0);
}
@@ -3059,21 +3060,21 @@
if (doc == NULL) return(-1);
if (attr == NULL) return(-1);
+
table = (xmlRefTablePtr) doc->refs;
if (table == NULL)
return(-1);
- if (attr == NULL)
- return(-1);
ID = xmlNodeListGetString(doc, attr->children, 1);
if (ID == NULL)
return(-1);
- ref_list = xmlHashLookup(table, ID);
+ ref_list = xmlHashLookup(table, ID);
if(ref_list == NULL) {
xmlFree(ID);
return (-1);
}
+
/* At this point, ref_list refers to a list of references which
* have the same key as the supplied attr. Our list of references
* is ordered by reference address and we don't have that information
@@ -5236,7 +5237,7 @@
xmlElementContentPtr cont;
const xmlChar *name;
- if ((elemDecl == NULL) || (parent == NULL))
+ if ((elemDecl == NULL) || (parent == NULL) || (ctxt == NULL))
return(-1);
cont = elemDecl->content;
name = elemDecl->name;
@@ -6948,7 +6949,7 @@
int max) {
xmlValidCtxt vctxt;
int nb_valid_elements = 0;
- const xmlChar *elements[256];
+ const xmlChar *elements[256]={0};
int nb_elements = 0, i;
const xmlChar *name;
@@ -6998,6 +6999,9 @@
* Creates a dummy node and insert it into the tree
*/
test_node = xmlNewDocNode (ref_node->doc, NULL, BAD_CAST "<!dummy?>", NULL);
+ if (test_node == NULL)
+ return(-1);
+
test_node->parent = parent;
test_node->prev = prev;
test_node->next = next;
diff --git a/xinclude.c b/xinclude.c
index ace005b..e3bb43e 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -17,6 +17,7 @@
#include <libxml/tree.h>
#include <libxml/parser.h>
#include <libxml/uri.h>
+#include <libxml/xpath.h>
#include <libxml/xpointer.h>
#include <libxml/parserInternals.h>
#include <libxml/xmlerror.h>
@@ -124,7 +125,7 @@
*
* 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)
{
@@ -146,7 +147,7 @@
*
* 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)
{
@@ -1207,6 +1208,7 @@
}
break;
}
+#ifdef LIBXML_XPTR_ENABLED
case XPATH_LOCATIONSET: {
xmlLocationSetPtr set = (xmlLocationSetPtr) obj->user;
if (set == NULL)
@@ -1226,7 +1228,6 @@
}
break;
}
-#ifdef LIBXML_XPTR_ENABLED
case XPATH_RANGE:
return(xmlXIncludeCopyRange(ctxt, target, source, obj));
#endif
@@ -1687,7 +1688,7 @@
/*
* Do the xml:base fixup if needed
*/
- if ((doc != NULL) && (URL != NULL) && (xmlStrchr(URL, (xmlChar) '/')) &&
+ if ((doc != NULL) && (URL != NULL) &&
(!(ctxt->parseFlags & XML_PARSE_NOBASEFIX)) &&
(!(doc->parseFlags & XML_PARSE_NOBASEFIX))) {
xmlNodePtr node;
diff --git a/xlink.c b/xlink.c
index 3566e06..c0e4ff3 100644
--- a/xlink.c
+++ b/xlink.c
@@ -150,7 +150,7 @@
if (type != NULL) {
if (xmlStrEqual(type, BAD_CAST "simple")) {
ret = XLINK_TYPE_SIMPLE;
- } if (xmlStrEqual(type, BAD_CAST "extended")) {
+ } else if (xmlStrEqual(type, BAD_CAST "extended")) {
role = xmlGetNsProp(node, BAD_CAST "role", XLINK_NAMESPACE);
if (role != NULL) {
xmlNsPtr xlink;
diff --git a/xmlIO.c b/xmlIO.c
index 847cb7e..1a79c09 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -800,6 +800,13 @@
return 1;
}
+/**
+ * xmlNop:
+ *
+ * No Operation function, does nothing, no input
+ *
+ * Returns zero
+ */
int
xmlNop(void) {
return(0);
@@ -887,7 +894,7 @@
*/
static void *
xmlFileOpen_real (const char *filename) {
- const char *path = NULL;
+ const char *path = filename;
FILE *fd;
if (filename == NULL)
@@ -917,11 +924,8 @@
#else
path = &filename[5];
#endif
- } else
- path = filename;
+ }
- if (path == NULL)
- return(NULL);
if (!xmlCheckFilename(path))
return(NULL);
@@ -1159,7 +1163,12 @@
gzFile fd;
if (!strcmp(filename, "-")) {
- fd = gzdopen(dup(0), "rb");
+ int duped_fd = dup(fileno(stdin));
+ fd = gzdopen(duped_fd, "rb");
+ if (fd == Z_NULL && duped_fd >= 0) {
+ close(duped_fd); /* gzdOpen() does not close on failure */
+ }
+
return((void *) fd);
}
@@ -1233,7 +1242,12 @@
snprintf(mode, sizeof(mode), "wb%d", compression);
if (!strcmp(filename, "-")) {
- fd = gzdopen(dup(1), mode);
+ int duped_fd = dup(fileno(stdout));
+ fd = gzdopen(duped_fd, "rb");
+ if (fd == Z_NULL && duped_fd >= 0) {
+ close(duped_fd); /* gzdOpen() does not close on failure */
+ }
+
return((void *) fd);
}
@@ -1320,7 +1334,7 @@
}
#endif /* HAVE_ZLIB_H */
-#ifdef HAVE_LZMA_H
+#ifdef LIBXML_LZMA_ENABLED
/************************************************************************
* *
* I/O for compressed file accesses *
@@ -1355,7 +1369,7 @@
xzFile fd;
if (!strcmp(filename, "-")) {
- fd = __libxml2_xzdopen(dup(0), "rb");
+ fd = __libxml2_xzdopen(dup(fileno(stdin)), "rb");
return((void *) fd);
}
@@ -1437,7 +1451,7 @@
if (ret < 0) xmlIOErr(0, "xzclose()");
return(ret);
}
-#endif /* HAVE_LZMA_H */
+#endif /* LIBXML_LZMA_ENABLED */
#ifdef LIBXML_HTTP_ENABLED
/************************************************************************
@@ -1590,7 +1604,7 @@
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);
@@ -1658,7 +1672,7 @@
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 );
xmlIOErr(XML_IO_WRITE, (const char *) msg);
@@ -1704,7 +1718,7 @@
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);
@@ -1777,7 +1791,7 @@
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);
}
@@ -1982,7 +1996,7 @@
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 );
@@ -2054,7 +2068,7 @@
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);
@@ -2126,7 +2140,7 @@
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 );
@@ -2314,10 +2328,10 @@
xmlRegisterInputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
xmlGzfileRead, xmlGzfileClose);
#endif /* HAVE_ZLIB_H */
-#ifdef HAVE_LZMA_H
+#ifdef LIBXML_LZMA_ENABLED
xmlRegisterInputCallbacks(xmlXzfileMatch, xmlXzfileOpen,
xmlXzfileRead, xmlXzfileClose);
-#endif /* HAVE_ZLIB_H */
+#endif /* LIBXML_LZMA_ENABLED */
#ifdef LIBXML_HTTP_ENABLED
xmlRegisterInputCallbacks(xmlIOHTTPMatch, xmlIOHTTPOpen,
@@ -2669,6 +2683,12 @@
#endif
}
#endif
+#ifdef LIBXML_LZMA_ENABLED
+ if ((xmlInputCallbackTable[i].opencallback == xmlXzfileOpen) &&
+ (strcmp(URI, "-") != 0)) {
+ ret->compressed = __libxml2_xzcompressed(context);
+ }
+#endif
}
else
xmlInputCallbackTable[i].closecallback (context);
@@ -3325,6 +3345,17 @@
if (res < 0) {
return(-1);
}
+
+ /*
+ * try to establish compressed status of input if not done already
+ */
+ if (in->compressed == -1) {
+#ifdef LIBXML_LZMA_ENABLED
+ if (in->readcallback == xmlXzfileRead)
+ in->compressed = __libxml2_xzcompressed(in->context);
+#endif
+ }
+
len = res;
if (in->encoder != NULL) {
unsigned int use;
diff --git a/xmlcatalog.c b/xmlcatalog.c
index 43f455a..006f0cc 100644
--- a/xmlcatalog.c
+++ b/xmlcatalog.c
@@ -80,6 +80,7 @@
if (prompt != NULL)
fprintf(stdout, "%s", prompt);
+ fflush(stdout);
if (!fgets(line_read, 500, stdin))
return(NULL);
line_read[500] = 0;
@@ -181,12 +182,13 @@
/*
* start interpreting the command
*/
- if (!strcmp(command, "exit"))
+ if (!strcmp(command, "exit") ||
+ !strcmp(command, "quit") ||
+ !strcmp(command, "bye")) {
+ free(cmdline);
break;
- if (!strcmp(command, "quit"))
- break;
- if (!strcmp(command, "bye"))
- break;
+ }
+
if (!strcmp(command, "public")) {
if (nbargs != 1) {
printf("public requires 1 arguments\n");
diff --git a/xmllint.c b/xmllint.c
index 26d8db1..67f7adb 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -449,7 +449,7 @@
* message about the timing performed; format is a printf
* type argument
*/
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
endTimer(const char *fmt, ...)
{
long msec;
@@ -485,7 +485,7 @@
{
begin = clock();
}
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
endTimer(const char *fmt, ...)
{
long msec;
@@ -514,7 +514,7 @@
* Do nothing
*/
}
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
endTimer(char *format, ...)
{
/*
@@ -634,7 +634,7 @@
* Display and format an error messages, gives file, line, position and
* extra parameters.
*/
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
xmlHTMLError(void *ctx, const char *msg, ...)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
@@ -671,7 +671,7 @@
* Display and format a warning messages, gives file, line, position and
* extra parameters.
*/
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
xmlHTMLWarning(void *ctx, const char *msg, ...)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
@@ -709,7 +709,7 @@
* Display and format an validity error messages, gives file,
* line, position and extra parameters.
*/
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
xmlHTMLValidityError(void *ctx, const char *msg, ...)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
@@ -746,7 +746,7 @@
* Display and format a validity warning messages, gives file, line,
* position and extra parameters.
*/
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
{
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
@@ -809,6 +809,7 @@
if (prompt != NULL)
fprintf(stdout, "%s", prompt);
+ fflush(stdout);
if (!fgets(line_read, 500, stdin))
return(NULL);
line_read[500] = 0;
@@ -1410,7 +1411,7 @@
* Display and format a warning messages, gives file, line, position and
* extra parameters.
*/
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
{
va_list args;
@@ -1433,7 +1434,7 @@
* Display and format a error messages, gives file, line, position and
* extra parameters.
*/
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
{
va_list args;
@@ -1456,7 +1457,7 @@
* Display and format a fatalError messages, gives file, line, position and
* extra parameters.
*/
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
{
va_list args;
@@ -1837,8 +1838,12 @@
if ((fd = open(filename, O_RDONLY)) < 0)
return;
base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
- if (base == (void *) MAP_FAILED)
+ if (base == (void *) MAP_FAILED) {
+ close(fd);
+ fprintf(stderr, "mmap failure for file %s\n", filename);
+ progresult = XMLLINT_ERR_RDFILE;
return;
+ }
reader = xmlReaderForMemory(base, info.st_size, filename,
NULL, options);
@@ -1997,6 +2002,12 @@
xmlNsPtr ns;
root = xmlDocGetRootElement(doc);
+ if (root == NULL ) {
+ xmlGenericError(xmlGenericErrorContext,
+ "Document does not have a root element");
+ progresult = XMLLINT_ERR_UNCLASS;
+ return;
+ }
for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
namespaces[i++] = ns->href;
namespaces[i++] = ns->prefix;
@@ -2190,6 +2201,8 @@
#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
f = fopen(filename, "rb");
+#elif defined(__OS400__)
+ f = fopen(filename, "rb");
#else
f = fopen(filename, "r");
#endif
@@ -2202,6 +2215,7 @@
if (res > 0) {
ctxt = htmlCreatePushParserCtxt(NULL, NULL,
chars, res, filename, XML_CHAR_ENCODING_NONE);
+ xmlCtxtUseOptions(ctxt, options);
while ((res = fread(chars, 1, pushsize, f)) > 0) {
htmlParseChunk(ctxt, chars, res, 0);
}
@@ -2223,8 +2237,12 @@
if ((fd = open(filename, O_RDONLY)) < 0)
return;
base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
- if (base == (void *) MAP_FAILED)
+ if (base == (void *) MAP_FAILED) {
+ close(fd);
+ fprintf(stderr, "mmap failure for file %s\n", filename);
+ progresult = XMLLINT_ERR_RDFILE;
return;
+ }
doc = htmlReadMemory((char *) base, info.st_size, filename,
NULL, options);
@@ -2251,6 +2269,8 @@
} else {
#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
f = fopen(filename, "rb");
+#elif defined(__OS400__)
+ f = fopen(filename, "rb");
#else
f = fopen(filename, "r");
#endif
@@ -2292,6 +2312,8 @@
#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
f = fopen(filename, "rb");
+#elif defined(__OS400__)
+ f = fopen(filename, "rb");
#else
f = fopen(filename, "r");
#endif
@@ -2338,8 +2360,12 @@
if ((fd = open(filename, O_RDONLY)) < 0)
return;
base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
- if (base == (void *) MAP_FAILED)
+ if (base == (void *) MAP_FAILED) {
+ close(fd);
+ fprintf(stderr, "mmap failure for file %s\n", filename);
+ progresult = XMLLINT_ERR_RDFILE;
return;
+ }
if (rectxt == NULL)
doc = xmlReadMemory((char *) base, info.st_size,
@@ -2561,7 +2587,7 @@
fprintf(stderr, "Failed to canonicalize\n");
progresult = XMLLINT_ERR_OUT;
}
- } else if (canonical) {
+ } else if (canonical_11) {
xmlChar *result = NULL;
int size;
@@ -2948,6 +2974,7 @@
if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
+ if (xmlHasFeature(XML_WITH_ICU)) fprintf(stderr, "ICU ");
if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
@@ -2990,7 +3017,7 @@
printf("\t--noenc : ignore any encoding specified inside the document\n");
printf("\t--noout : don't output the result tree\n");
printf("\t--path 'paths': provide a set of paths for resources\n");
- printf("\t--load-trace : print trace of all external entites loaded\n");
+ printf("\t--load-trace : print trace of all external entities loaded\n");
printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
printf("\t--nocompact : do not generate compact text nodes\n");
printf("\t--htmlout : output results as HTML\n");
@@ -3027,7 +3054,7 @@
printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
printf("\t--nocdata : replace cdata section with text nodes\n");
#ifdef LIBXML_OUTPUT_ENABLED
- printf("\t--format : reformat/reindent the input\n");
+ printf("\t--format : reformat/reindent the output\n");
printf("\t--encode encoding : output in the given encoding\n");
printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
printf("\t--pretty STYLE : pretty-print in a particular style\n");
@@ -3087,6 +3114,10 @@
static void registerNode(xmlNodePtr node)
{
node->_private = malloc(sizeof(long));
+ if (node->_private == NULL) {
+ fprintf(stderr, "Out of memory in xmllint:registerNode()\n");
+ exit(XMLLINT_ERR_MEM);
+ }
*(long*)node->_private = (long) 0x81726354;
nbregister++;
}
@@ -3372,11 +3403,13 @@
(!strcmp(argv[i], "--pretty"))) {
i++;
#ifdef LIBXML_OUTPUT_ENABLED
- format = atoi(argv[i]);
- if (format == 1) {
- noblanks++;
- xmlKeepBlanksDefault(0);
- }
+ if (argv[i] != NULL) {
+ format = atoi(argv[i]);
+ if (format == 1) {
+ noblanks++;
+ xmlKeepBlanksDefault(0);
+ }
+ }
#endif /* LIBXML_OUTPUT_ENABLED */
}
#ifdef LIBXML_READER_ENABLED
diff --git a/xmlmemory.c b/xmlmemory.c
index 25d9318..f08c8c3 100644
--- a/xmlmemory.c
+++ b/xmlmemory.c
@@ -109,6 +109,7 @@
#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 HDR_2_CLIENT(a) ((void *) (((char *) (a)) + RESERVE_SIZE))
@@ -217,7 +218,7 @@
/**
* 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 +241,18 @@
TEST_POINT
+ if (size > (MAX_SIZE_T - RESERVE_SIZE)) {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlMallocAtomicLoc : Unsigned overflow prevented\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);
}
@@ -313,7 +321,7 @@
void *
xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
{
- MEMHDR *p;
+ MEMHDR *p, *tmp;
unsigned long number;
#ifdef DEBUG_MEMORY
size_t oldsize;
@@ -344,10 +352,12 @@
#endif
xmlMutexUnlock(xmlMemMutex);
- p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
- if (!p) {
+ tmp = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
+ if (!tmp) {
+ free(p);
goto error;
}
+ p = tmp;
if (xmlMemTraceBlockAt == ptr) {
xmlGenericError(xmlGenericErrorContext,
"%p : Realloced(%lu -> %lu) Ok\n",
@@ -512,10 +522,7 @@
if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
- if (s != NULL)
- strcpy(s,str);
- else
- goto error;
+ strcpy(s,str);
TEST_POINT
@@ -555,7 +562,12 @@
int
xmlMemUsed(void) {
- return(debugMemSize);
+ int res;
+
+ xmlMutexLock(xmlMemMutex);
+ res = debugMemSize;
+ xmlMutexUnlock(xmlMemMutex);
+ return(res);
}
/**
@@ -568,7 +580,12 @@
int
xmlMemBlocks(void) {
- return(debugMemBlocks);
+ int res;
+
+ xmlMutexLock(xmlMemMutex);
+ res = debugMemBlocks;
+ xmlMutexUnlock(xmlMemMutex);
+ return(res);
}
#ifdef MEM_LIST
@@ -583,13 +600,15 @@
static void
xmlMemContentShow(FILE *fp, MEMHDR *p)
{
- int i,j,k,len = p->mh_size;
- const char *buf = (const char *) HDR_2_CLIENT(p);
+ int i,j,k,len;
+ const char *buf;
if (p == NULL) {
fprintf(fp, " NULL");
return;
}
+ len = p->mh_size;
+ buf = (const char *) HDR_2_CLIENT(p);
for (i = 0;i < len;i++) {
if (buf[i] == 0) break;
diff --git a/xmlmodule.c b/xmlmodule.c
index 7fe5bc2..50ed666 100644
--- a/xmlmodule.c
+++ b/xmlmodule.c
@@ -115,7 +115,7 @@
{
int rc = -1;
- if ((NULL == module) || (symbol == NULL)) {
+ if ((NULL == module) || (symbol == NULL) || (name == NULL)) {
__xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_MODULE,
XML_MODULE_OPEN, XML_ERR_FATAL, NULL, 0, 0,
NULL, NULL, 0, 0, "null parameter\n");
diff --git a/xmlreader.c b/xmlreader.c
index 00083d0..f285790 100644
--- a/xmlreader.c
+++ b/xmlreader.c
@@ -51,9 +51,8 @@
/*
* The following VA_COPY was coded following an example in
* the Samba project. It may not be sufficient for some
- * esoteric implementations of va_list (i.e. it may need
- * something involving a memcpy) but (hopefully) will be
- * sufficient for libxml2.
+ * esoteric implementations of va_list but (hopefully) will
+ * be sufficient for libxml2.
*/
#ifndef VA_COPY
#ifdef HAVE_VA_COPY
@@ -62,7 +61,12 @@
#ifdef HAVE___VA_COPY
#define VA_COPY(dest,src) __va_copy(dest, src)
#else
- #define VA_COPY(dest,src) (dest) = (src)
+ #ifndef VA_LIST_IS_ARRAY
+ #define VA_COPY(dest,src) (dest) = (src)
+ #else
+ #include <string.h>
+ #define VA_COPY(dest,src) memcpy((char *)(dest),(char *)(src),sizeof(va_list))
+ #endif
#endif
#endif
#endif
@@ -138,7 +142,7 @@
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 */
@@ -206,7 +210,7 @@
* 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) \
@@ -282,7 +286,10 @@
xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) {
xmlDictPtr dict;
- dict = reader->ctxt->dict;
+ if ((reader != NULL) && (reader->ctxt != NULL))
+ dict = reader->ctxt->dict;
+ else
+ dict = NULL;
if (cur == NULL) return;
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
@@ -319,7 +326,7 @@
static void
xmlTextReaderFreePropList(xmlTextReaderPtr reader, xmlAttrPtr cur) {
xmlAttrPtr next;
- if (cur == NULL) return;
+
while (cur != NULL) {
next = cur->next;
xmlTextReaderFreeProp(reader, cur);
@@ -340,7 +347,10 @@
xmlNodePtr next;
xmlDictPtr dict;
- dict = reader->ctxt->dict;
+ if ((reader != NULL) && (reader->ctxt != NULL))
+ dict = reader->ctxt->dict;
+ else
+ dict = NULL;
if (cur == NULL) return;
if (cur->type == XML_NAMESPACE_DECL) {
xmlFreeNsList((xmlNsPtr) cur);
@@ -417,7 +427,10 @@
xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur) {
xmlDictPtr dict;
- dict = reader->ctxt->dict;
+ if ((reader != NULL) && (reader->ctxt != NULL))
+ dict = reader->ctxt->dict;
+ else
+ dict = NULL;
if (cur->type == XML_DTD_NODE) {
xmlFreeDtd((xmlDtdPtr) cur);
return;
@@ -1427,7 +1440,7 @@
goto node_found;
}
#ifdef LIBXML_REGEXP_ENABLED
- if ((reader->validate) && (reader->node->type == XML_ELEMENT_NODE))
+ if ((reader->validate != XML_TEXTREADER_NOT_VALIDATE) && (reader->node->type == XML_ELEMENT_NODE))
xmlTextReaderValidatePop(reader);
#endif /* LIBXML_REGEXP_ENABLED */
if ((reader->preserves > 0) &&
@@ -1560,7 +1573,7 @@
goto get_next_node;
}
#ifdef LIBXML_REGEXP_ENABLED
- if ((reader->validate) && (reader->node != NULL)) {
+ if ((reader->validate != XML_TEXTREADER_NOT_VALIDATE) && (reader->node != NULL)) {
xmlNodePtr node = reader->node;
if ((node->type == XML_ELEMENT_NODE) &&
@@ -1790,6 +1803,7 @@
if (xmlTextReaderDoExpand(reader) != -1) {
return xmlTextReaderCollectSiblings(node->children);
}
+ break;
case XML_ATTRIBUTE_NODE:
TODO
break;
@@ -2077,6 +2091,9 @@
"xmlNewTextReader : malloc failed\n");
return(NULL);
}
+ /* no operation on a reader should require a huge buffer */
+ xmlBufSetAllocationScheme(ret->buffer,
+ XML_BUFFER_ALLOC_BOUNDED);
ret->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
if (ret->sax == NULL) {
xmlBufFree(ret->buffer);
@@ -2141,7 +2158,7 @@
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;
@@ -3602,6 +3619,7 @@
return(((xmlNsPtr) node)->href);
case XML_ATTRIBUTE_NODE:{
xmlAttrPtr attr = (xmlAttrPtr) node;
+ const xmlChar *ret;
if ((attr->children != NULL) &&
(attr->children->type == XML_TEXT_NODE) &&
@@ -3615,10 +3633,21 @@
"xmlTextReaderSetup : malloc failed\n");
return (NULL);
}
+ xmlBufSetAllocationScheme(reader->buffer,
+ XML_BUFFER_ALLOC_BOUNDED);
} else
xmlBufEmpty(reader->buffer);
xmlBufGetNodeContent(reader->buffer, node);
- return(xmlBufContent(reader->buffer));
+ ret = xmlBufContent(reader->buffer);
+ if (ret == NULL) {
+ /* error on the buffer best to reallocate */
+ xmlBufFree(reader->buffer);
+ reader->buffer = xmlBufCreateSize(100);
+ xmlBufSetAllocationScheme(reader->buffer,
+ XML_BUFFER_ALLOC_BOUNDED);
+ ret = BAD_CAST "";
+ }
+ return(ret);
}
break;
}
@@ -4021,13 +4050,19 @@
}
#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, ...)
@@ -4821,7 +4856,7 @@
}
}
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
xmlTextReaderError(void *ctxt, const char *msg, ...)
{
va_list ap;
@@ -4834,7 +4869,7 @@
}
-static void XMLCDECL
+static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
xmlTextReaderWarning(void *ctxt, const char *msg, ...)
{
va_list ap;
@@ -5117,6 +5152,9 @@
"xmlTextReaderSetup : malloc failed\n");
return (-1);
}
+ /* no operation on a reader should require a huge buffer */
+ xmlBufSetAllocationScheme(reader->buffer,
+ XML_BUFFER_ALLOC_BOUNDED);
if (reader->sax == NULL)
reader->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
if (reader->sax == NULL) {
@@ -5217,7 +5255,7 @@
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/xmlregexp.c b/xmlregexp.c
index 1f9911c..ca3b4f4 100644
--- a/xmlregexp.c
+++ b/xmlregexp.c
@@ -1544,6 +1544,7 @@
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 @@
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 @@
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;
@@ -3162,8 +3167,10 @@
exec->status = -6;
return;
}
- memcpy(exec->counts, exec->rollbacks[exec->nbRollbacks].counts,
+ if (exec->counts) {
+ memcpy(exec->counts, exec->rollbacks[exec->nbRollbacks].counts,
exec->comp->nbCounters * sizeof(int));
+ }
}
#ifdef DEBUG_REGEXP_EXEC
@@ -4091,7 +4098,7 @@
*/
exec->determinist = 0;
xmlFARegExecRollBack(exec);
- if (exec->status == 0) {
+ if ((exec->inputStack != NULL ) && (exec->status == 0)) {
value = exec->inputStack[exec->index].value;
data = exec->inputStack[exec->index].data;
#ifdef DEBUG_PUSH
@@ -4306,7 +4313,7 @@
(*nbval)++;
}
} else {
- if ((exec->comp->states[trans->to] != NULL) &&
+ if ((exec->comp != NULL) && (exec->comp->states[trans->to] != NULL) &&
(exec->comp->states[trans->to]->type !=
XML_REGEXP_SINK_STATE)) {
if (atom->neg)
@@ -5050,11 +5057,12 @@
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);
}
@@ -5707,8 +5715,6 @@
if (atom == NULL)
return(NULL);
atom->data = data;
- if (atom == NULL)
- return(NULL);
atom->valuep = xmlStrdup(token);
if (xmlFAGenerateTransitions(am, from, to, atom) < 0) {
@@ -6345,7 +6351,7 @@
/**
* 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 +7210,7 @@
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/xmlsave.c b/xmlsave.c
index 774404b..4a8e3f3 100644
--- a/xmlsave.c
+++ b/xmlsave.c
@@ -2097,8 +2097,8 @@
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.
*/
@@ -2121,14 +2121,14 @@
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;
diff --git a/xmlschemas.c b/xmlschemas.c
index 121533f..7afe2eb 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -617,7 +617,7 @@
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 +1085,7 @@
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,
@@ -1471,7 +1471,7 @@
* @retValue: the returned value
* @ws: the whitespace type of the value
*
- * Get a the cononical representation of the value.
+ * Get a the canonical representation of the value.
* The caller has to free the returned retValue.
*
* Returns 0 if the value could be built and -1 in case of
@@ -1769,7 +1769,7 @@
}
FREE_AND_NULL(str)
- return (*buf);
+ return (xmlEscapeFormatString(buf));
}
/**
@@ -1889,7 +1889,7 @@
*
* 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 +1922,7 @@
*
* 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 +1951,7 @@
*
* 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 +2002,7 @@
extra);
}
-static void
+static void LIBXML_ATTR_FORMAT(2,0)
xmlSchemaPSimpleInternalErr(xmlNodePtr node,
const char *msg, const xmlChar *str)
{
@@ -2013,18 +2013,21 @@
#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,
@@ -2039,6 +2042,7 @@
if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
const char *file = NULL;
+ int col = 0;
if (errorLevel != XML_ERR_WARNING) {
vctxt->nberrors++;
vctxt->err = error;
@@ -2067,6 +2071,7 @@
(vctxt->parserCtxt->input != NULL)) {
file = vctxt->parserCtxt->input->filename;
line = vctxt->parserCtxt->input->line;
+ col = vctxt->parserCtxt->input->col;
}
} else {
/*
@@ -2101,7 +2106,7 @@
node, XML_FROM_SCHEMASV,
error, errorLevel, file, line,
(const char *) str1, (const char *) str2,
- (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
+ (const char *) str3, 0, col, msg, str1, str2, str3, str4);
} else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
@@ -2137,7 +2142,7 @@
*
* 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)
@@ -2146,7 +2151,7 @@
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,
@@ -2156,7 +2161,7 @@
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)
@@ -2179,7 +2184,7 @@
/*
* 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);
@@ -2244,6 +2249,13 @@
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.
@@ -2260,7 +2272,7 @@
return (*msg);
}
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
const char *funcName,
const char *message,
@@ -2271,24 +2283,21 @@
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)
@@ -2297,7 +2306,7 @@
}
#if 0
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
const char *funcName,
const char *message,
@@ -2309,7 +2318,7 @@
}
#endif
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
xmlParserErrors error,
xmlNodePtr node,
@@ -2334,7 +2343,7 @@
FREE_AND_NULL(msg)
}
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
xmlParserErrors error,
xmlNodePtr node,
@@ -2349,7 +2358,7 @@
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
xmlParserErrors error,
xmlNodePtr node,
@@ -2374,7 +2383,7 @@
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
xmlParserErrors error,
xmlSchemaPSVIIDCNodePtr idcNode,
@@ -2474,11 +2483,13 @@
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);
}
@@ -2523,7 +2534,7 @@
FREE_AND_NULL(msg)
}
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
xmlParserErrors error,
xmlNodePtr node,
@@ -2615,7 +2626,7 @@
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");
@@ -2623,7 +2634,7 @@
xmlFree(msg);
}
-static void
+static void LIBXML_ATTR_FORMAT(8,0)
xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
xmlParserErrors error,
xmlNodePtr node,
@@ -2914,7 +2925,7 @@
*
* Reports an error during parsing.
*/
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
xmlParserErrors error,
xmlSchemaBasicItemPtr item,
@@ -2950,7 +2961,7 @@
*
* Reports an error during parsing.
*/
-static void
+static void LIBXML_ATTR_FORMAT(5,0)
xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
xmlParserErrors error,
xmlSchemaBasicItemPtr item,
@@ -2975,7 +2986,7 @@
*
* Reports an attribute use error during parsing.
*/
-static void
+static void LIBXML_ATTR_FORMAT(6,0)
xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
xmlParserErrors error,
xmlNodePtr node,
@@ -3097,7 +3108,7 @@
* 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,
@@ -3139,11 +3150,13 @@
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);
}
@@ -3155,8 +3168,10 @@
"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");
@@ -6139,7 +6154,7 @@
value = xmlNodeGetContent(node);
/*
* 3.2.2.1 Lexical representation
- * An instance of a datatype that is defined as �boolean�
+ * An instance of a datatype that is defined as `boolean`
* can have the following legal literals {true, false, 1, 0}.
*/
if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
@@ -6187,7 +6202,7 @@
return (def);
/*
* 3.2.2.1 Lexical representation
- * An instance of a datatype that is defined as �boolean�
+ * An instance of a datatype that is defined as `boolean`
* can have the following legal literals {true, false, 1, 0}.
*/
if (xmlStrEqual(val, BAD_CAST "true"))
@@ -7717,8 +7732,8 @@
/*
* SPEC src-redefine:
* (7.1) "If it has an <attributeGroup> among its contents
- * the �actual value� of whose ref [attribute] is the same
- * as the �actual value� of its own name attribute plus
+ * the `actual value` of whose ref [attribute] is the same
+ * as the `actual value` of its own name attribute plus
* target namespace, then it must have exactly one such group."
*/
if (pctxt->redefCounter != 0) {
@@ -8867,7 +8882,7 @@
type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
/*
* SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
- * then the �simple ur-type definition�."
+ * then the `simple ur-type definition`."
*/
type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
/*
@@ -9035,7 +9050,7 @@
type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
/*
* SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
- * then the �simple ur-type definition�."
+ * then the `simple ur-type definition`."
*/
type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
/*
@@ -9180,9 +9195,9 @@
}
/*
* TargetNamespace:
- * SPEC "The �actual value� of the targetNamespace [attribute]
+ * SPEC "The `actual value` of the targetNamespace [attribute]
* of the <schema> ancestor element information item if present,
- * otherwise �absent�.
+ * otherwise `absent`.
*/
if (topLevel == 0) {
#ifdef ENABLE_NAMED_LOCALS
@@ -9317,8 +9332,8 @@
/*
* REDEFINE: SPEC src-redefine (5)
* "Within the [children], each <simpleType> must have a
- * <restriction> among its [children] ... the �actual value� of whose
- * base [attribute] must be the same as the �actual value� of its own
+ * <restriction> among its [children] ... the `actual value` of whose
+ * base [attribute] must be the same as the `actual value` of its own
* name attribute plus target namespace;"
*/
if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
@@ -10402,7 +10417,7 @@
/*
* Given that the schemaLocation [attribute] is only a hint, it is open
* to applications to ignore all but the first <import> for a given
- * namespace, regardless of the �actual value� of schemaLocation, but
+ * namespace, regardless of the `actual value` of schemaLocation, but
* such a strategy risks missing useful information when new
* schemaLocations are offered.
*
@@ -10755,7 +10770,7 @@
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
NULL, node,
xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
- NULL, namespaceName, NULL, NULL, NULL);
+ NULL, schemaLocation, NULL, NULL, NULL);
return (pctxt->err);
}
/*
@@ -10786,8 +10801,8 @@
thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
if (namespaceName != NULL) {
/*
- * 1.1 If the namespace [attribute] is present, then its �actual value�
- * must not match the �actual value� of the enclosing <schema>'s
+ * 1.1 If the namespace [attribute] is present, then its `actual value`
+ * must not match the `actual value` of the enclosing <schema>'s
* targetNamespace [attribute].
*/
if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
@@ -10988,7 +11003,7 @@
* for inclusions, since the that was the feedback from the
* schema people. I.e. the following spec piece will *not* be
* satisfied:
- * SPEC src-include: "It is not an error for the �actual value� of the
+ * SPEC src-include: "It is not an error for the `actual value` of the
* schemaLocation [attribute] to fail to resolve it all, in which
* case no corresponding inclusion is performed.
* So do we need a warning report here?"
@@ -11005,7 +11020,7 @@
*
* SPEC src-redefine (1)
* "If there are any element information items among the [children]
- * other than <annotation> then the �actual value� of the
+ * other than <annotation> then the `actual value` of the
* schemaLocation [attribute] must successfully resolve."
* TODO: Ask the WG if a the location has always to resolve
* here as well!
@@ -11025,9 +11040,9 @@
if (bucket->origTargetNamespace != NULL) {
/*
* SPEC src-include (2.1)
- * "SII has a targetNamespace [attribute], and its �actual
- * value� is identical to the �actual value� of the targetNamespace
- * [attribute] of SII� (which must have such an [attribute])."
+ * "SII has a targetNamespace [attribute], and its `actual
+ * value` is identical to the `actual value` of the targetNamespace
+ * [attribute] of SII' (which must have such an [attribute])."
*/
if (pctxt->targetNamespace == NULL) {
xmlSchemaCustomErr(ACTXT_CAST pctxt,
@@ -11375,8 +11390,8 @@
/*
* SPEC src-redefine:
* (6.1) "If it has a <group> among its contents at
- * some level the �actual value� of whose ref
- * [attribute] is the same as the �actual value� of
+ * some level the `actual value` of whose ref
+ * [attribute] is the same as the `actual value` of
* its own name attribute plus target namespace, then
* all of the following must be true:"
* (6.1.1) "It must have exactly one such group."
@@ -11401,9 +11416,9 @@
xmlChar *str = NULL;
/*
* SPEC src-redefine:
- * (6.1.2) "The �actual value� of both that
+ * (6.1.2) "The `actual value` of both that
* group's minOccurs and maxOccurs [attribute]
- * must be 1 (or �absent�).
+ * must be 1 (or `absent`).
*/
xmlSchemaCustomErr(ACTXT_CAST ctxt,
XML_SCHEMAP_SRC_REDEFINE, child, NULL,
@@ -11517,8 +11532,8 @@
*
* SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
* among its [children]), the simple type definition which is
- * the {content type} of the type definition �resolved� to by
- * the �actual value� of the base [attribute]"
+ * the {content type} of the type definition `resolved` to by
+ * the `actual value` of the base [attribute]"
*/
if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
&(type->baseNs), &(type->base)) == 0)
@@ -11541,8 +11556,8 @@
/*
* REDEFINE: SPEC src-redefine (5)
* "Within the [children], each <simpleType> must have a
- * <restriction> among its [children] ... the �actual value� of
- * whose base [attribute] must be the same as the �actual value�
+ * <restriction> among its [children] ... the `actual value` of
+ * whose base [attribute] must be the same as the `actual value`
* of its own name attribute plus target namespace;"
*/
xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
@@ -12303,7 +12318,7 @@
* SPEC
* "...the third alternative (neither <simpleContent> nor
* <complexContent>) is chosen. This case is understood as shorthand
- * for complex content restricting the �ur-type definition�, and the
+ * for complex content restricting the `ur-type definition`, and the
* details of the mappings should be modified as necessary.
*/
type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
@@ -13211,8 +13226,8 @@
if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
xmlSchemaTypePtr type;
- /* (type definition) ... otherwise the type definition �resolved�
- * to by the �actual value� of the type [attribute] ...
+ /* (type definition) ... otherwise the type definition `resolved`
+ * to by the `actual value` of the type [attribute] ...
*/
type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
elemDecl->namedTypeNs);
@@ -13250,7 +13265,7 @@
/*
* The type definitions is set to:
* SPEC "...the {type definition} of the element
- * declaration �resolved� to by the �actual value�
+ * declaration `resolved` to by the `actual value`
* of the substitutionGroup [attribute], if present"
*/
if (elemDecl->subtypes == NULL)
@@ -13288,8 +13303,8 @@
/*
* SPEC (1) "If the <union> alternative is chosen, then [Definition:]
- * define the explicit members as the type definitions �resolved�
- * to by the items in the �actual value� of the memberTypes [attribute],
+ * define the explicit members as the type definitions `resolved`
+ * to by the items in the `actual value` of the memberTypes [attribute],
* if any, followed by the type definitions corresponding to the
* <simpleType>s among the [children] of <union>, if any."
*/
@@ -13584,7 +13599,7 @@
return (0);
}
/*
- * 3 If both O1 and O2 are sets of (namespace names or �absent�),
+ * 3 If both O1 and O2 are sets of (namespace names or `absent`),
* then the union of those sets must be the value.
*/
if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
@@ -13618,7 +13633,7 @@
}
/*
* 4 If the two are negations of different values (namespace names
- * or �absent�), then a pair of not and �absent� must be the value.
+ * or `absent`), then a pair of not and `absent` must be the value.
*/
if ((completeWild->negNsSet != NULL) &&
(curWild->negNsSet != NULL) &&
@@ -13660,7 +13675,7 @@
if (nsFound && absentFound) {
/*
* 5.1 If the set S includes both the negated namespace
- * name and �absent�, then any must be the value.
+ * name and `absent`, then any must be the value.
*/
completeWild->any = 1;
if (completeWild->nsSet != NULL) {
@@ -13674,7 +13689,7 @@
} else if (nsFound && (!absentFound)) {
/*
* 5.2 If the set S includes the negated namespace name
- * but not �absent�, then a pair of not and �absent� must
+ * but not `absent`, then a pair of not and `absent` must
* be the value.
*/
if (completeWild->nsSet != NULL) {
@@ -13689,7 +13704,7 @@
completeWild->negNsSet->value = NULL;
} else if ((!nsFound) && absentFound) {
/*
- * 5.3 If the set S includes �absent� but not the negated
+ * 5.3 If the set S includes `absent` but not the negated
* namespace name, then the union is not expressible.
*/
xmlSchemaPErr(ctxt, completeWild->node,
@@ -13700,7 +13715,7 @@
} else if ((!nsFound) && (!absentFound)) {
/*
* 5.4 If the set S does not include either the negated namespace
- * name or �absent�, then whichever of O1 or O2 is a pair of not
+ * name or `absent`, then whichever of O1 or O2 is a pair of not
* and a namespace name must be the value.
*/
if (completeWild->negNsSet == NULL) {
@@ -13734,7 +13749,7 @@
while (cur != NULL) {
if (cur->value == NULL) {
/*
- * 6.1 If the set S includes �absent�, then any must be the
+ * 6.1 If the set S includes `absent`, then any must be the
* value.
*/
completeWild->any = 1;
@@ -13752,8 +13767,8 @@
}
if (completeWild->negNsSet == NULL) {
/*
- * 6.2 If the set S does not include �absent�, then a pair of not
- * and �absent� must be the value.
+ * 6.2 If the set S does not include `absent`, then a pair of not
+ * and `absent` must be the value.
*/
if (completeWild->nsSet != NULL) {
xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
@@ -13836,9 +13851,9 @@
}
/*
* 3 If either O1 or O2 is a pair of not and a value (a namespace
- * name or �absent�) and the other is a set of (namespace names or
- * �absent�), then that set, minus the negated value if it was in
- * the set, minus �absent� if it was in the set, must be the value.
+ * name or `absent`) and the other is a set of (namespace names or
+ * `absent`), then that set, minus the negated value if it was in
+ * the set, minus `absent` if it was in the set, must be the value.
*/
if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
@@ -13887,7 +13902,7 @@
return(0);
}
/*
- * 4 If both O1 and O2 are sets of (namespace names or �absent�),
+ * 4 If both O1 and O2 are sets of (namespace names or `absent`),
* then the intersection of those sets must be the value.
*/
if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
@@ -13937,7 +13952,7 @@
}
/*
* 6 If the one is a negation of a namespace name and the other
- * is a negation of �absent�, then the one which is the negation
+ * is a negation of `absent`, then the one which is the negation
* of a namespace name must be the value.
*/
if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
@@ -13969,7 +13984,7 @@
if (super->any)
return (0);
/*
- * 2.1 sub must be a pair of not and a namespace name or �absent�.
+ * 2.1 sub must be a pair of not and a namespace name or `absent`.
* 2.2 super must be a pair of not and the same value.
*/
if ((sub->negNsSet != NULL) &&
@@ -13977,7 +13992,7 @@
(sub->negNsSet->value == super->negNsSet->value))
return (0);
/*
- * 3.1 sub must be a set whose members are either namespace names or �absent�.
+ * 3.1 sub must be a set whose members are either namespace names or `absent`.
*/
if (sub->nsSet != NULL) {
/*
@@ -14008,7 +14023,7 @@
xmlSchemaWildcardNsPtr cur;
/*
* 3.2.2 super must be a pair of not and a namespace name or
- * �absent� and that value must not be in sub's set.
+ * `absent` and that value must not be in sub's set.
*/
cur = sub->nsSet;
while (cur != NULL) {
@@ -14170,7 +14185,7 @@
* SPEC (2.1.2) "R's {attribute declaration}'s
* {type definition} must be validly derived from
* B's {type definition} given the empty set as
- * defined in Type Derivation OK (Simple) (�3.14.6)."
+ * defined in Type Derivation OK (Simple) ($3.14.6)."
*/
xmlSchemaPAttrUseErr4(pctxt,
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
@@ -14202,8 +14217,8 @@
/*
* 2.1.3 ... one of the following must be true
*
- * 2.1.3.1 B's �effective value constraint� is
- * �absent� or default.
+ * 2.1.3.1 B's `effective value constraint` is
+ * `absent` or default.
*/
if ((bEffValue != NULL) &&
(effFixed == 1)) {
@@ -14212,7 +14227,7 @@
xmlSchemaGetEffectiveValueConstraint(bcur,
&effFixed, &rEffValue, NULL);
/*
- * 2.1.3.2 R's �effective value constraint� is
+ * 2.1.3.2 R's `effective value constraint` is
* fixed with the same string as B's.
* MAYBE TODO: Compare the computed values.
* Hmm, it says "same string" so
@@ -14246,9 +14261,9 @@
/*
* (2.2) "otherwise the {base type definition} must have an
* {attribute wildcard} and the {target namespace} of the
- * R's {attribute declaration} must be �valid� with respect
+ * R's {attribute declaration} must be `valid` with respect
* to that wildcard, as defined in Wildcard allows Namespace
- * Name (�3.10.4)."
+ * Name ($3.10.4)."
*/
if ((baseWild == NULL) ||
(xmlSchemaCheckCVCWildcardNamespace(baseWild,
@@ -14346,7 +14361,7 @@
* (4.2) "The complex type definition's {attribute wildcard}'s
* {namespace constraint} must be a subset of the {base type
* definition}'s {attribute wildcard}'s {namespace constraint},
- * as defined by Wildcard Subset (�3.10.6)."
+ * as defined by Wildcard Subset ($3.10.6)."
*/
xmlSchemaCustomErr4(ACTXT_CAST pctxt,
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
@@ -14360,8 +14375,8 @@
FREE_AND_NULL(str);
return(pctxt->err);
}
- /* 4.3 Unless the {base type definition} is the �ur-type
- * definition�, the complex type definition's {attribute
+ /* 4.3 Unless the {base type definition} is the `ur-type
+ * definition`, the complex type definition's {attribute
* wildcard}'s {process contents} must be identical to or
* stronger than the {base type definition}'s {attribute
* wildcard}'s {process contents}, where strict is stronger
@@ -14547,7 +14562,7 @@
if (WXS_IS_EXTENSION(type)) {
if (baseType->attributeWildcard != NULL) {
/*
- * (3.2.2.1) "If the �base wildcard� is non-�absent�, then
+ * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
* the appropriate case among the following:"
*/
if (type->attributeWildcard != NULL) {
@@ -14555,26 +14570,26 @@
* Union the complete wildcard with the base wildcard.
* SPEC {attribute wildcard}
* (3.2.2.1.2) "otherwise a wildcard whose {process contents}
- * and {annotation} are those of the �complete wildcard�,
+ * and {annotation} are those of the `complete wildcard`,
* and whose {namespace constraint} is the intensional union
- * of the {namespace constraint} of the �complete wildcard�
- * and of the �base wildcard�, as defined in Attribute
- * Wildcard Union (�3.10.6)."
+ * of the {namespace constraint} of the `complete wildcard`
+ * and of the `base wildcard`, as defined in Attribute
+ * Wildcard Union ($3.10.6)."
*/
if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
baseType->attributeWildcard) == -1)
goto exit_failure;
} else {
/*
- * (3.2.2.1.1) "If the �complete wildcard� is �absent�,
- * then the �base wildcard�."
+ * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
+ * then the `base wildcard`."
*/
type->attributeWildcard = baseType->attributeWildcard;
}
} else {
/*
- * (3.2.2.2) "otherwise (the �base wildcard� is �absent�) the
- * �complete wildcard"
+ * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
+ * `complete wildcard`"
* NOOP
*/
}
@@ -14582,7 +14597,7 @@
/*
* SPEC {attribute wildcard}
* (3.1) "If the <restriction> alternative is chosen, then the
- * �complete wildcard�;"
+ * `complete wildcard`;"
* NOOP
*/
}
@@ -14831,12 +14846,12 @@
/* 2.2 */
if (type->baseType == baseType) {
/*
- * 2.2.1 D's �base type definition� is B.
+ * 2.2.1 D's `base type definition` is B.
*/
return (0);
}
/*
- * 2.2.2 D's �base type definition� is not the �ur-type definition�
+ * 2.2.2 D's `base type definition` is not the `ur-type definition`
* and is validly derived from B given the subset, as defined by this
* constraint.
*/
@@ -14846,8 +14861,8 @@
return (0);
}
/*
- * 2.2.3 D's {variety} is list or union and B is the �simple ur-type
- * definition�.
+ * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
+ * definition`.
*/
if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
(WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
@@ -15159,14 +15174,14 @@
* NOTE: This is somehow redundant, since we actually built a simple type
* to have all the needed information; this acts as an self test.
*/
- /* Base type: If the datatype has been �derived� by �restriction�
- * then the Simple Type Definition component from which it is �derived�,
- * otherwise the Simple Type Definition for anySimpleType (�4.1.6).
+ /* Base type: If the datatype has been `derived` by `restriction`
+ * then the Simple Type Definition component from which it is `derived`,
+ * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
*/
if (baseType == NULL) {
/*
* TODO: Think about: "modulo the impact of Missing
- * Sub-components (�5.3)."
+ * Sub-components ($5.3)."
*/
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_ST_PROPS_CORRECT_1,
@@ -15226,10 +15241,10 @@
}
/*
- * 2 All simple type definitions must be derived ultimately from the �simple
- * ur-type definition (so� circular definitions are disallowed). That is, it
- * must be possible to reach a built-in primitive datatype or the �simple
- * ur-type definition� by repeatedly following the {base type definition}.
+ * 2 All simple type definitions must be derived ultimately from the `simple
+ * ur-type definition` (so circular definitions are disallowed). That is, it
+ * must be possible to reach a built-in primitive datatype or the `simple
+ * ur-type definition` by repeatedly following the {base type definition}.
*
* NOTE: this is done in xmlSchemaCheckTypeDefCircular().
*/
@@ -15413,10 +15428,10 @@
}
/*
* MAYBE TODO: (Hmm, not really) Datatypes states:
- * A �list� datatype can be �derived� from an �atomic� datatype
- * whose �lexical space� allows space (such as string or anyURI)or
- * a �union� datatype any of whose {member type definitions}'s
- * �lexical space� allows space.
+ * A `list` datatype can be `derived` from an `atomic` datatype
+ * whose `lexical space` allows space (such as string or anyURI)or
+ * a `union` datatype any of whose {member type definitions}'s
+ * `lexical space` allows space.
*/
} else {
/*
@@ -15453,7 +15468,7 @@
/*
* 2.3.2.3 The {item type definition} must be validly derived
* from the {base type definition}'s {item type definition} given
- * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6).
+ * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
*/
{
xmlSchemaTypePtr baseItemType;
@@ -15500,7 +15515,7 @@
case XML_SCHEMA_FACET_WHITESPACE:
/*
* TODO: 2.5.1.2 List datatypes
- * The value of �whiteSpace� is fixed to the value collapse.
+ * The value of `whiteSpace` is fixed to the value collapse.
*/
case XML_SCHEMA_FACET_PATTERN:
case XML_SCHEMA_FACET_ENUMERATION:
@@ -15553,8 +15568,8 @@
member = member->next;
}
/*
- * 3.3.1 If the {base type definition} is the �simple ur-type
- * definition�
+ * 3.3.1 If the {base type definition} is the `simple ur-type
+ * definition`
*/
if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
/*
@@ -15616,7 +15631,7 @@
* 3.3.2.3 The {member type definitions}, in order, must be validly
* derived from the corresponding type definitions in the {base
* type definition}'s {member type definitions} given the empty set,
- * as defined in Type Derivation OK (Simple) (�3.14.6).
+ * as defined in Type Derivation OK (Simple) ($3.14.6).
*/
{
xmlSchemaTypeLinkPtr baseMember;
@@ -15723,7 +15738,7 @@
/*
* src-simple-type.1 The corresponding simple type definition, if any,
* must satisfy the conditions set out in Constraints on Simple Type
- * Definition Schema Components (�3.14.6).
+ * Definition Schema Components ($3.14.6).
*/
if (WXS_IS_RESTRICTION(type)) {
/*
@@ -15821,8 +15836,8 @@
* SPEC (2.1) "its {content type} must be a simple type definition
* or mixed."
* SPEC (2.2.2) "If the {content type} is mixed, then the {content
- * type}'s particle must be �emptiable� as defined by
- * Particle Emptiable (�3.9.6)."
+ * type}'s particle must be `emptiable` as defined by
+ * Particle Emptiable ($3.9.6)."
*/
if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
@@ -15838,14 +15853,14 @@
}
/*
* 1 If the type definition is a simple type definition, then the string
- * must be �valid� with respect to that definition as defined by String
- * Valid (�3.14.4).
+ * must be `valid` with respect to that definition as defined by String
+ * Valid ($3.14.4).
*
* AND
*
* 2.2.1 If the {content type} is a simple type definition, then the
- * string must be �valid� with respect to that simple type definition
- * as defined by String Valid (�3.14.4).
+ * string must be `valid` with respect to that simple type definition
+ * as defined by String Valid ($3.14.4).
*/
if (WXS_IS_SIMPLE(type))
ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
@@ -15886,8 +15901,8 @@
*
* SPEC (1) "The values of the properties of a complex type definition must
* be as described in the property tableau in The Complex Type Definition
- * Schema Component (�3.4.1), modulo the impact of Missing
- * Sub-components (�5.3)."
+ * Schema Component ($3.4.1), modulo the impact of Missing
+ * Sub-components ($5.3)."
*/
if ((type->baseType != NULL) &&
(WXS_IS_SIMPLE(type->baseType)) &&
@@ -15904,9 +15919,9 @@
return (XML_SCHEMAP_SRC_CT_1);
}
/*
- * SPEC (3) "Circular definitions are disallowed, except for the �ur-type
- * definition�. That is, it must be possible to reach the �ur-type
- * definition by repeatedly following the {base type definition}."
+ * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
+ * definition`. That is, it must be possible to reach the `ur-type
+ * definition` by repeatedly following the {base type definition}."
*
* NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
*/
@@ -16058,8 +16073,8 @@
if (type->baseType == baseType)
return (0);
/*
- * SPEC (2.3.1) "D's {base type definition} must not be the �ur-type
- * definition�."
+ * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
+ * definition`."
*/
if (WXS_IS_ANYTYPE(type->baseType))
return (1);
@@ -16076,7 +16091,7 @@
/*
* SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
* must be validly derived from B given the subset as defined in Type
- * Derivation OK (Simple) (�3.14.6).
+ * Derivation OK (Simple) ($3.14.6).
*/
return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
baseType, set));
@@ -16216,7 +16231,7 @@
* definition must also have one, and the base type definition's
* {attribute wildcard}'s {namespace constraint} must be a subset
* of the complex type definition's {attribute wildcard}'s {namespace
- * constraint}, as defined by Wildcard Subset (�3.10.6)."
+ * constraint}, as defined by Wildcard Subset ($3.10.6)."
*/
/*
@@ -16313,9 +16328,9 @@
}
/*
* URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
- * complex type definition must be a �valid extension�
+ * complex type definition must be a `valid extension`
* of the {base type definition}'s particle, as defined
- * in Particle Valid (Extension) (�3.9.6)."
+ * in Particle Valid (Extension) ($3.9.6)."
*
* NOTE that we won't check "Particle Valid (Extension)",
* since it is ensured by the derivation process in
@@ -16432,7 +16447,7 @@
if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
/*
* SPEC (5.1) "The {base type definition} must be the
- * �ur-type definition�."
+ * `ur-type definition`."
* PASS
*/
} else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
@@ -16451,7 +16466,7 @@
* SPEC (5.2.2.1) "The {content type} of the {base type
* definition} must be a simple type definition from which
* the {content type} is validly derived given the empty
- * set as defined in Type Derivation OK (Simple) (�3.14.6)."
+ * set as defined in Type Derivation OK (Simple) ($3.14.6)."
*
* ATTENTION TODO: This seems not needed if the type implicitely
* derived from the base type.
@@ -16482,8 +16497,8 @@
(xmlSchemaParticlePtr) base->subtypes))) {
/*
* SPEC (5.2.2.2) "The {base type definition} must be mixed
- * and have a particle which is �emptiable� as defined in
- * Particle Emptiable (�3.9.6)."
+ * and have a particle which is `emptiable` as defined in
+ * Particle Emptiable ($3.9.6)."
* PASS
*/
} else {
@@ -16512,7 +16527,7 @@
/*
* SPEC (5.3.2.2) "The {content type} of the {base type
* definition} must be elementOnly or mixed and have a particle
- * which is �emptiable� as defined in Particle Emptiable (�3.9.6)."
+ * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
* PASS
*/
} else {
@@ -16545,9 +16560,9 @@
}
/*
* SPEC (5.4.2) "The particle of the complex type definition itself
- * must be a �valid restriction� of the particle of the {content
+ * must be a `valid restriction` of the particle of the {content
* type} of the {base type definition} as defined in Particle Valid
- * (Restriction) (�3.9.6).
+ * (Restriction) ($3.9.6).
*
* URGENT TODO: (5.4.2)
*/
@@ -16616,7 +16631,7 @@
if (! WXS_HAS_SIMPLE_CONTENT(type)) {
/*
* 1 If the <complexContent> alternative is chosen, the type definition
- * �resolved� to by the �actual value� of the base [attribute]
+ * `resolved` to by the `actual value` of the base [attribute]
* must be a complex type definition;
*/
if (! WXS_IS_COMPLEX(base)) {
@@ -16636,7 +16651,7 @@
* SPEC
* 2 If the <simpleContent> alternative is chosen, all of the
* following must be true:
- * 2.1 The type definition �resolved� to by the �actual value� of the
+ * 2.1 The type definition `resolved` to by the `actual value` of the
* base [attribute] must be one of the following:
*/
if (WXS_IS_SIMPLE(base)) {
@@ -16742,14 +16757,14 @@
/*
* SPEC (3) "The corresponding complex type definition component must
* satisfy the conditions set out in Constraints on Complex Type
- * Definition Schema Components (�3.4.6);"
+ * Definition Schema Components ($3.4.6);"
* NOTE (3) will be done in xmlSchemaTypeFixup().
*/
/*
* SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
* above for {attribute wildcard} is satisfied, the intensional
* intersection must be expressible, as defined in Attribute Wildcard
- * Intersection (�3.10.6).
+ * Intersection ($3.10.6).
* NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
*/
return (ret);
@@ -16820,7 +16835,7 @@
return (1);
/*
* SPEC (2) "R's occurrence range is a valid restriction of B's
- * occurrence range as defined by Occurrence Range OK (�3.9.6)."
+ * occurrence range as defined by Occurrence Range OK ($3.9.6)."
*/
if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
b->minOccurs, b->maxOccurs) != 0)
@@ -16912,19 +16927,19 @@
{
/* TODO:Error codes (rcase-NSCompat). */
/*
- * SPEC "For an element declaration particle to be a �valid restriction�
+ * SPEC "For an element declaration particle to be a `valid restriction`
* of a wildcard particle all of the following must be true:"
*
- * SPEC (1) "The element declaration's {target namespace} is �valid�
+ * SPEC (1) "The element declaration's {target namespace} is `valid`
* with respect to the wildcard's {namespace constraint} as defined by
- * Wildcard allows Namespace Name (�3.10.4)."
+ * Wildcard allows Namespace Name ($3.10.4)."
*/
if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
return (1);
/*
* SPEC (2) "R's occurrence range is a valid restriction of B's
- * occurrence range as defined by Occurrence Range OK (�3.9.6)."
+ * occurrence range as defined by Occurrence Range OK ($3.9.6)."
*/
if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
b->minOccurs, b->maxOccurs) != 0)
@@ -16984,21 +16999,21 @@
/* TODO: Error codes (rcase-NSSubset). */
/*
* SPEC (1) "R's occurrence range is a valid restriction of B's
- * occurrence range as defined by Occurrence Range OK (�3.9.6)."
+ * occurrence range as defined by Occurrence Range OK ($3.9.6)."
*/
if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
b->minOccurs, b->maxOccurs))
return (1);
/*
* SPEC (2) "R's {namespace constraint} must be an intensional subset
- * of B's {namespace constraint} as defined by Wildcard Subset (�3.10.6)."
+ * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
*/
if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
(xmlSchemaWildcardPtr) b->children))
return (1);
/*
- * SPEC (3) "Unless B is the content model wildcard of the �ur-type
- * definition�, R's {process contents} must be identical to or stronger
+ * SPEC (3) "Unless B is the content model wildcard of the `ur-type
+ * definition`, R's {process contents} must be identical to or stronger
* than B's {process contents}, where strict is stronger than lax is
* stronger than skip."
*/
@@ -17076,12 +17091,12 @@
if ((r->children == NULL) || (r->children->children == NULL))
return (-1);
/*
- * SPEC "For a group particle to be a �valid restriction� of a
+ * SPEC "For a group particle to be a `valid restriction` of a
* wildcard particle..."
*
- * SPEC (1) "Every member of the {particles} of the group is a �valid
- * restriction� of the wildcard as defined by
- * Particle Valid (Restriction) (�3.9.6)."
+ * SPEC (1) "Every member of the {particles} of the group is a `valid
+ * restriction` of the wildcard as defined by
+ * Particle Valid (Restriction) ($3.9.6)."
*/
part = (xmlSchemaParticlePtr) r->children->children;
do {
@@ -17092,7 +17107,7 @@
/*
* SPEC (2) "The effective total range of the group [...] is a
* valid restriction of B's occurrence range as defined by
- * Occurrence Range OK (�3.9.6)."
+ * Occurrence Range OK ($3.9.6)."
*/
if (xmlSchemaCheckParticleRangeOK(
xmlSchemaGetParticleTotalRangeMin(r),
@@ -17132,11 +17147,11 @@
(r->children->type != b->children->type))
return (-1);
/*
- * SPEC "For an all or sequence group particle to be a �valid
- * restriction� of another group particle with the same {compositor}..."
+ * SPEC "For an all or sequence group particle to be a `valid
+ * restriction` of another group particle with the same {compositor}..."
*
* SPEC (1) "R's occurrence range is a valid restriction of B's
- * occurrence range as defined by Occurrence Range OK (�3.9.6)."
+ * occurrence range as defined by Occurrence Range OK ($3.9.6)."
*/
if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
b->minOccurs, b->maxOccurs))
@@ -17760,7 +17775,7 @@
xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
/*
* The actual value is then formed by replacing any union type
- * definition in the �explicit members� with the members of their
+ * definition in the `explicit members` with the members of their
* {member type definitions}, in order.
*
* TODO: There's a bug entry at
@@ -17894,8 +17909,8 @@
}
}
/*
- * For all �atomic� datatypes other than string (and types �derived�
- * by �restriction� from it) the value of whiteSpace is fixed to
+ * For all `atomic` datatypes other than string (and types `derived`
+ * by `restriction` from it) the value of whiteSpace is fixed to
* collapse
*/
{
@@ -18084,7 +18099,7 @@
* SPEC src-simple-type 1
* "The corresponding simple type definition, if any, must satisfy
* the conditions set out in Constraints on Simple Type Definition
- * Schema Components (�3.14.6)."
+ * Schema Components ($3.14.6)."
*/
/*
* Schema Component Constraint: Simple Type Definition Properties Correct
@@ -18344,7 +18359,7 @@
( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
/*
- * SPEC (2.1.4) "If the �effective mixed� is true, then
+ * SPEC (2.1.4) "If the `effective mixed` is true, then
* a particle whose properties are as follows:..."
*
* Empty sequence model group with
@@ -18406,7 +18421,7 @@
if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
/*
* SPEC (3.2.1)
- * "If the �effective content� is empty, then the
+ * "If the `effective content` is empty, then the
* {content type} of the [...] base ..."
*/
type->contentType = baseType->contentType;
@@ -18513,7 +18528,7 @@
particle->children =
((xmlSchemaParticlePtr) baseType->subtypes)->children;
/*
- * SPEC "followed by the �effective content�."
+ * SPEC "followed by the `effective content`."
*/
particle->next = effectiveContent;
/*
@@ -18657,12 +18672,12 @@
/* 4.3.5.5 Constraints on enumeration Schema Components
* Schema Component Constraint: enumeration valid restriction
- * It is an �error� if any member of {value} is not in the
- * �value space� of {base type definition}.
+ * It is an `error` if any member of {value} is not in the
+ * `value space` of {base type definition}.
*
* minInclusive, maxInclusive, minExclusive, maxExclusive:
- * The value �must� be in the
- * �value space� of the �base type�.
+ * The value `must` be in the
+ * `value space` of the `base type`.
*/
/*
* This function is intended to deliver a compiled value
@@ -19097,9 +19112,9 @@
* not be an <attributeGroup> with ref [attribute] which resolves
* to the component corresponding to this <attributeGroup>. Indirect
* circularity is also ruled out. That is, when QName resolution
- * (Schema Document) (�3.15.3) is applied to a �QName� arising from
+ * (Schema Document) ($3.15.3) is applied to a `QName` arising from
* any <attributeGroup>s with a ref [attribute] among the [children],
- * it must not be the case that a �QName� is encountered at any depth
+ * it must not be the case that a `QName` is encountered at any depth
* which resolves to the component corresponding to this <attributeGroup>.
*/
if (attrGr->attrUses == NULL)
@@ -19356,8 +19371,8 @@
* SPEC ag-props-correct
* (1) "The values of the properties of an attribute group definition
* must be as described in the property tableau in The Attribute
- * Group Definition Schema Component (�3.6.1), modulo the impact of
- * Missing Sub-components (�5.3);"
+ * Group Definition Schema Component ($3.6.1), modulo the impact of
+ * Missing Sub-components ($5.3);"
*/
if ((attrGr->attrUses != NULL) &&
@@ -19491,8 +19506,8 @@
* SPEC a-props-correct (1)
* "The values of the properties of an attribute declaration must
* be as described in the property tableau in The Attribute
- * Declaration Schema Component (�3.2.1), modulo the impact of
- * Missing Sub-components (�5.3)."
+ * Declaration Schema Component ($3.2.1), modulo the impact of
+ * Missing Sub-components ($5.3)."
*/
if (WXS_ATTR_TYPEDEF(attr) == NULL)
@@ -19520,9 +19535,9 @@
/*
* SPEC a-props-correct (2)
* "if there is a {value constraint}, the canonical lexical
- * representation of its value must be �valid� with respect
- * to the {type definition} as defined in String Valid (�3.14.4)."
- * TODO: Don't care about the *cononical* stuff here, this requirement
+ * representation of its value must be `valid` with respect
+ * to the {type definition} as defined in String Valid ($3.14.4)."
+ * TODO: Don't care about the *canonical* stuff here, this requirement
* will be removed in WXS 1.1 anyway.
*/
ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
@@ -19589,15 +19604,15 @@
/*
* SPEC (1) "The values of the properties of an element declaration
* must be as described in the property tableau in The Element
- * Declaration Schema Component (�3.3.1), modulo the impact of Missing
- * Sub-components (�5.3)."
+ * Declaration Schema Component ($3.3.1), modulo the impact of Missing
+ * Sub-components ($5.3)."
*/
if (WXS_SUBST_HEAD(elemDecl) != NULL) {
xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
xmlSchemaCheckElementDeclComponent(head, pctxt);
/*
- * SPEC (3) "If there is a non-�absent� {substitution group
+ * SPEC (3) "If there is a non-`absent` {substitution group
* affiliation}, then {scope} must be global."
*/
if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
@@ -19641,9 +19656,9 @@
* of the element declaration must be validly derived from the {type
* definition} of the {substitution group affiliation}, given the value
* of the {substitution group exclusions} of the {substitution group
- * affiliation}, as defined in Type Derivation OK (Complex) (�3.4.6)
+ * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
* (if the {type definition} is complex) or as defined in
- * Type Derivation OK (Simple) (�3.14.6) (if the {type definition} is
+ * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
* simple)."
*
* NOTE: {substitution group exclusions} means the values of the
@@ -19707,9 +19722,9 @@
/*
* SPEC (2) "If there is a {value constraint}, the canonical lexical
- * representation of its value must be �valid� with respect to the
+ * representation of its value must be `valid` with respect to the
* {type definition} as defined in Element Default Valid (Immediate)
- * (�3.3.6)."
+ * ($3.3.6)."
*/
if (typeDef == NULL) {
xmlSchemaPErr(pctxt, elemDecl->node,
@@ -19777,7 +19792,7 @@
/*
* SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
* {disallowed substitutions} as the blocking constraint, as defined in
- * Substitution Group OK (Transitive) (�3.3.6)."
+ * Substitution Group OK (Transitive) ($3.3.6)."
*/
for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
head = WXS_SUBST_HEAD(head)) {
@@ -19910,7 +19925,7 @@
* SPEC Element Declarations Consistent:
* "If the {particles} contains, either directly,
* indirectly (that is, within the {particles} of a
- * contained model group, recursively) or �implicitly�
+ * contained model group, recursively) or `implicitly`
* two or more element declaration particles with
* the same {name} and {target namespace}, then
* all their type definitions must be the same
@@ -20108,12 +20123,12 @@
ptx = xmlSchemaGetPrimitiveType(tx);
pty = xmlSchemaGetPrimitiveType(ty);
/*
- * (1) if a datatype T' is �derived� by �restriction� from an
- * atomic datatype T then the �value space� of T' is a subset of
- * the �value space� of T. */
+ * (1) if a datatype T' is `derived` by `restriction` from an
+ * atomic datatype T then the `value space` of T' is a subset of
+ * the `value space` of T. */
/*
- * (2) if datatypes T' and T'' are �derived� by �restriction�
- * from a common atomic ancestor T then the �value space�s of T'
+ * (2) if datatypes T' and T'' are `derived` by `restriction`
+ * from a common atomic ancestor T then the `value space`s of T'
* and T'' may overlap.
*/
if (ptx != pty)
@@ -20214,8 +20229,8 @@
* SPEC au-props-correct (1)
* "The values of the properties of an attribute use must be as
* described in the property tableau in The Attribute Use Schema
- * Component (�3.5.1), modulo the impact of Missing
- * Sub-components (�5.3)."
+ * Component ($3.5.1), modulo the impact of Missing
+ * Sub-components ($5.3)."
*/
if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
@@ -20316,8 +20331,8 @@
/*
* The simple type definition corresponding to the <simpleType> element
* information item in the [children], if present, otherwise the simple
- * type definition �resolved� to by the �actual value� of the type
- * [attribute], if present, otherwise the �simple ur-type definition�.
+ * type definition `resolved` to by the `actual value` of the type
+ * [attribute], if present, otherwise the `simple ur-type definition`.
*/
if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
return(0);
@@ -20481,11 +20496,11 @@
/*
* SPEC src-redefine:
- * (6.2.1) "The �actual value� of its own name attribute plus
- * target namespace must successfully �resolve� to a model
+ * (6.2.1) "The `actual value` of its own name attribute plus
+ * target namespace must successfully `resolve` to a model
* group definition in I."
- * (7.2.1) "The �actual value� of its own name attribute plus
- * target namespace must successfully �resolve� to an attribute
+ * (7.2.1) "The `actual value` of its own name attribute plus
+ * target namespace must successfully `resolve` to an attribute
* group definition in I."
*
@@ -20658,10 +20673,10 @@
* SPEC src-redefine:
* (6.2.2) "The {model group} of the model group definition
* which corresponds to it per XML Representation of Model
- * Group Definition Schema Components (�3.7.2) must be a
- * �valid restriction� of the {model group} of that model
+ * Group Definition Schema Components ($3.7.2) must be a
+ * `valid restriction` of the {model group} of that model
* group definition in I, as defined in Particle Valid
- * (Restriction) (�3.9.6)."
+ * (Restriction) ($3.9.6)."
*/
break;
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
@@ -20670,11 +20685,11 @@
* (7.2.2) "The {attribute uses} and {attribute wildcard} of
* the attribute group definition which corresponds to it
* per XML Representation of Attribute Group Definition Schema
- * Components (�3.6.2) must be �valid restrictions� of the
+ * Components ($3.6.2) must be `valid restrictions` of the
* {attribute uses} and {attribute wildcard} of that attribute
* group definition in I, as defined in clause 2, clause 3 and
* clause 4 of Derivation Valid (Restriction, Complex)
- * (�3.4.6) (where references to the base type definition are
+ * ($3.4.6) (where references to the base type definition are
* understood as references to the attribute group definition
* in I)."
*/
@@ -20849,9 +20864,9 @@
* (6.2.2) The {model group} of the model group definition which
* corresponds to it per XML Representation of Model Group
- * Definition Schema Components (�3.7.2) must be a �valid
- * restriction� of the {model group} of that model group definition
- * in I, as defined in Particle Valid (Restriction) (�3.9.6)."
+ * Definition Schema Components ($3.7.2) must be a `valid
+ * restriction` of the {model group} of that model group definition
+ * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
*/
xmlSchemaCheckSRCRedefineFirst(pctxt);
@@ -21535,8 +21550,8 @@
return(XML_SCHEMA_WHITESPACE_REPLACE);
else {
/*
- * For all �atomic� datatypes other than string (and types �derived�
- * by �restriction� from it) the value of whiteSpace is fixed to
+ * For all `atomic` datatypes other than string (and types `derived`
+ * by `restriction` from it) the value of whiteSpace is fixed to
* collapse
* Note that this includes built-in list datatypes.
*/
@@ -22841,7 +22856,7 @@
xmlChar *str = NULL;
/*
* cvc-identity-constraint:
- * 3 For each node in the �target node set� all
+ * 3 For each node in the `target node set` all
* of the {fields}, with that node as the context
* node, evaluate to either an empty node-set or
* a node-set with exactly one member, which must
@@ -22971,8 +22986,8 @@
/*
* 4.1 If the {identity-constraint category} is unique(/key),
- * then no two members of the �qualified node set� have
- * �key-sequences� whose members are pairwise equal, as
+ * then no two members of the `qualified node set` have
+ * `key-sequences` whose members are pairwise equal, as
* defined by Equal in [XML Schemas: Datatypes].
*
* Get the IDC binding from the matcher and check for
@@ -23100,10 +23115,10 @@
{
xmlChar *str = NULL;
/*
- * 4.2.1 (KEY) The �target node set� and the
- * �qualified node set� are equal, that is, every
- * member of the �target node set� is also a member
- * of the �qualified node set� and vice versa.
+ * 4.2.1 (KEY) The `target node set` and the
+ * `qualified node set` are equal, that is, every
+ * member of the `target node set` is also a member
+ * of the `qualified node set` and vice versa.
*/
xmlSchemaCustomErr(ACTXT_CAST vctxt,
XML_SCHEMAV_CVC_IDC, NULL,
@@ -24184,6 +24199,7 @@
else
goto pattern_and_enum;
}
+
/*
* Whitespace handling is only of importance for string-based
* types.
@@ -24194,14 +24210,13 @@
ws = xmlSchemaGetWhiteSpaceFacetValue(type);
} else
ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
+
/*
* If the value was not computed (for string or
* anySimpleType based types), then use the provided
* type.
*/
- if (val == NULL)
- valType = valType;
- else
+ if (val != NULL)
valType = xmlSchemaGetValType(val);
ret = 0;
@@ -24499,14 +24514,14 @@
*/
/*
* 2.1 If The definition is ENTITY or is validly derived from ENTITY given
- * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6), then
- * the string must be a �declared entity name�.
+ * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
+ * the string must be a `declared entity name`.
*/
/*
* 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
- * given the empty set, as defined in Type Derivation OK (Simple) (�3.14.6),
- * then every whitespace-delimited substring of the string must be a �declared
- * entity name�.
+ * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
+ * then every whitespace-delimited substring of the string must be a `declared
+ * entity name`.
*/
/*
* 2.3 otherwise no further condition applies.
@@ -24518,8 +24533,8 @@
if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
xmlSchemaTypePtr biType; /* The built-in type. */
/*
- * SPEC (1.2.1) "if {variety} is �atomic� then the string must �match�
- * a literal in the �lexical space� of {base type definition}"
+ * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
+ * a literal in the `lexical space` of {base type definition}"
*/
/*
* Whitespace-normalize.
@@ -24630,9 +24645,9 @@
xmlChar *tmpValue = NULL;
unsigned long len = 0;
xmlSchemaValPtr prevVal = NULL, curVal = NULL;
- /* 1.2.2 if {variety} is �list� then the string must be a sequence
- * of white space separated tokens, each of which �match�es a literal
- * in the �lexical space� of {item type definition}
+ /* 1.2.2 if {variety} is `list` then the string must be a sequence
+ * of white space separated tokens, each of which `match`es a literal
+ * in the `lexical space` of {item type definition}
*/
/*
* Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
@@ -24713,10 +24728,10 @@
} else if (WXS_IS_UNION(type)) {
xmlSchemaTypeLinkPtr memberLink;
/*
- * TODO: For all datatypes �derived� by �union� whiteSpace does
- * not apply directly; however, the normalization behavior of �union�
+ * TODO: For all datatypes `derived` by `union` whiteSpace does
+ * not apply directly; however, the normalization behavior of `union`
* types is controlled by the value of whiteSpace on that one of the
- * �memberTypes� against which the �union� is successfully validated.
+ * `memberTypes` against which the `union` is successfully validated.
*
* This means that the value is normalized by the first validating
* member type, then the facets of the union type are applied. This
@@ -24724,8 +24739,8 @@
*/
/*
- * 1.2.3 if {variety} is �union� then the string must �match� a
- * literal in the �lexical space� of at least one member of
+ * 1.2.3 if {variety} is `union` then the string must `match` a
+ * literal in the `lexical space` of at least one member of
* {member type definitions}
*/
memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
@@ -24764,9 +24779,9 @@
*/
if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
/*
- * The normalization behavior of �union� types is controlled by
- * the value of whiteSpace on that one of the �memberTypes�
- * against which the �union� is successfully validated.
+ * The normalization behavior of `union` types is controlled by
+ * the value of whiteSpace on that one of the `memberTypes`
+ * against which the `union` is successfully validated.
*/
NORMALIZE(memberLink->type);
ret = xmlSchemaValidateFacets(actxt, node, type,
@@ -24926,14 +24941,14 @@
/*
* SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
- * "The �local type definition� must be validly
+ * "The `local type definition` must be validly
* derived from the {type definition} given the union of
* the {disallowed substitutions} and the {type definition}'s
* {prohibited substitutions}, as defined in
- * Type Derivation OK (Complex) (�3.4.6)
+ * Type Derivation OK (Complex) ($3.4.6)
* (if it is a complex type definition),
* or given {disallowed substitutions} as defined in Type
- * Derivation OK (Simple) (�3.14.6) (if it is a simple type
+ * Derivation OK (Simple) ($3.14.6) (if it is a simple type
* definition)."
*
* {disallowed substitutions}: the "block" on the element decl.
@@ -25204,8 +25219,8 @@
/*
* SPEC (cvc-attribute)
- * (1) "The declaration must not be �absent� (see Missing
- * Sub-components (�5.3) for how this can fail to be
+ * (1) "The declaration must not be `absent` (see Missing
+ * Sub-components ($5.3) for how this can fail to be
* the case)."
* (2) "Its {type definition} must not be absent."
*
@@ -25255,15 +25270,15 @@
* use with an {attribute declaration} whose {name} matches
* the attribute information item's [local name] and whose
* {target namespace} is identical to the attribute information
- * item's [namespace name] (where an �absent� {target namespace}
+ * item's [namespace name] (where an `absent` {target namespace}
* is taken to be identical to a [namespace name] with no value),
- * then the attribute information must be �valid� with respect
+ * then the attribute information must be `valid` with respect
* to that attribute use as per Attribute Locally Valid (Use)
- * (�3.5.4). In this case the {attribute declaration} of that
- * attribute use is the �context-determined declaration� for the
+ * ($3.5.4). In this case the {attribute declaration} of that
+ * attribute use is the `context-determined declaration` for the
* attribute information item with respect to Schema-Validity
- * Assessment (Attribute) (�3.2.4) and
- * Assessment Outcome (Attribute) (�3.2.5).
+ * Assessment (Attribute) ($3.2.4) and
+ * Assessment Outcome (Attribute) ($3.2.5).
*/
iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
iattr->use = attrUse;
@@ -25340,13 +25355,13 @@
continue;
/*
* SPEC (cvc-complex-type)
- * (3.2.2) "The attribute information item must be �valid� with
- * respect to it as defined in Item Valid (Wildcard) (�3.10.4)."
+ * (3.2.2) "The attribute information item must be `valid` with
+ * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
*
* SPEC Item Valid (Wildcard) (cvc-wildcard)
- * "... its [namespace name] must be �valid� with respect to
+ * "... its [namespace name] must be `valid` with respect to
* the wildcard constraint, as defined in Wildcard allows
- * Namespace Name (�3.10.4)."
+ * Namespace Name ($3.10.4)."
*/
if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
iattr->nsName) == 0) {
@@ -25382,11 +25397,11 @@
* SPEC (cvc-complex-type)
* (5) "Let [Definition:] the wild IDs be the set of
* all attribute information item to which clause 3.2
- * applied and whose �validation� resulted in a
- * �context-determined declaration� of mustFind or no
- * �context-determined declaration� at all, and whose
+ * applied and whose `validation` resulted in a
+ * `context-determined declaration` of mustFind or no
+ * `context-determined declaration` at all, and whose
* [local name] and [namespace name] resolve (as
- * defined by QName resolution (Instance) (�3.15.4)) to
+ * defined by QName resolution (Instance) ($3.15.4)) to
* an attribute declaration whose {type definition} is
* or is derived from ID. Then all of the following
* must be true:"
@@ -25396,7 +25411,7 @@
iattr->typeDef, XML_SCHEMAS_ID)) {
/*
* SPEC (5.1) "There must be no more than one
- * item in �wild IDs�."
+ * item in `wild IDs`."
*/
if (wildIDs != 0) {
/* VAL TODO */
@@ -25407,7 +25422,7 @@
wildIDs++;
/*
* SPEC (cvc-complex-type)
- * (5.2) "If �wild IDs� is non-empty, there must not
+ * (5.2) "If `wild IDs` is non-empty, there must not
* be any attribute uses among the {attribute uses}
* whose {attribute declaration}'s {type definition}
* is or is derived from ID."
@@ -25544,7 +25559,7 @@
if (xmlNewProp(defAttrOwnerElem,
iattr->localName, value) == NULL) {
VERROR_INT("xmlSchemaVAttributesComplex",
- "callling xmlNewProp()");
+ "calling xmlNewProp()");
if (normValue != NULL)
xmlFree(normValue);
goto internal_error;
@@ -25617,9 +25632,9 @@
fixed = 0;
/*
* SPEC (cvc-attribute)
- * (3) "The item's �normalized value� must be locally �valid�
+ * (3) "The item's `normalized value` must be locally `valid`
* with respect to that {type definition} as per
- * String Valid (�3.14.4)."
+ * String Valid ($3.14.4)."
*
* VAL TODO: Do we already have the
* "normalized attribute value" here?
@@ -25657,9 +25672,9 @@
if (fixed) {
/*
* SPEC Attribute Locally Valid (Use) (cvc-au)
- * "For an attribute information item to be�valid�
+ * "For an attribute information item to be `valid`
* with respect to an attribute use its *normalized*
- * value� must match the *canonical* lexical
+ * value must match the *canonical* lexical
* representation of the attribute use's {value
* constraint}value, if it is present and fixed."
*
@@ -25668,7 +25683,7 @@
*/
/*
* SPEC Attribute Locally Valid (cvc-attribute)
- * (4) "The item's *actual* value� must match the *value* of
+ * (4) "The item's *actual* value must match the *value* of
* the {value constraint}, if it is present and fixed."
*/
if (iattr->val == NULL) {
@@ -25898,8 +25913,8 @@
* SPEC (2.1) "its {content type} must be a simple type definition
* or mixed."
* SPEC (2.2.2) "If the {content type} is mixed, then the {content
- * type}'s particle must be �emptiable� as defined by
- * Particle Emptiable (�3.9.6)."
+ * type}'s particle must be `emptiable` as defined by
+ * Particle Emptiable ($3.9.6)."
*/
if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
@@ -25915,14 +25930,14 @@
}
/*
* 1 If the type definition is a simple type definition, then the string
- * must be �valid� with respect to that definition as defined by String
- * Valid (�3.14.4).
+ * must be `valid` with respect to that definition as defined by String
+ * Valid ($3.14.4).
*
* AND
*
* 2.2.1 If the {content type} is a simple type definition, then the
- * string must be �valid� with respect to that simple type definition
- * as defined by String Valid (�3.14.4).
+ * string must be `valid` with respect to that simple type definition
+ * as defined by String Valid ($3.14.4).
*/
if (WXS_IS_SIMPLE(inode->typeDef)) {
@@ -26163,10 +26178,10 @@
(! INODE_NILLED(inode))) {
/*
* cvc-elt (3.3.4) : 5.1.1
- * If the �actual type definition� is a �local type definition�
+ * If the `actual type definition` is a `local type definition`
* then the canonical lexical representation of the {value constraint}
- * value must be a valid default for the �actual type definition� as
- * defined in Element Default Valid (Immediate) (�3.3.6).
+ * value must be a valid default for the `actual type definition` as
+ * defined in Element Default Valid (Immediate) ($3.3.6).
*/
/*
* NOTE: 'local' above means types acquired by xsi:type.
@@ -26196,9 +26211,9 @@
* cvc-elt (3.3.4) : 5.1.2
* The element information item with the canonical lexical
* representation of the {value constraint} value used as its
- * �normalized value� must be �valid� with respect to the
- * �actual type definition� as defined by Element Locally Valid (Type)
- * (�3.3.4).
+ * `normalized value` must be `valid` with respect to the
+ * `actual type definition` as defined by Element Locally Valid (Type)
+ * ($3.3.4).
*/
if (WXS_IS_SIMPLE(inode->typeDef)) {
ret = xmlSchemaVCheckINodeDataType(vctxt,
@@ -26245,18 +26260,18 @@
} else if (! INODE_NILLED(inode)) {
/*
- * 5.2.1 The element information item must be �valid� with respect
- * to the �actual type definition� as defined by Element Locally
- * Valid (Type) (�3.3.4).
+ * 5.2.1 The element information item must be `valid` with respect
+ * to the `actual type definition` as defined by Element Locally
+ * Valid (Type) ($3.3.4).
*/
if (WXS_IS_SIMPLE(inode->typeDef)) {
/*
* SPEC (cvc-type) (3.1)
* "If the type definition is a simple type definition, ..."
* (3.1.3) "If clause 3.2 of Element Locally Valid
- * (Element) (�3.3.4) did not apply, then the �normalized value�
- * must be �valid� with respect to the type definition as defined
- * by String Valid (�3.14.4).
+ * (Element) ($3.3.4) did not apply, then the `normalized value`
+ * must be `valid` with respect to the type definition as defined
+ * by String Valid ($3.14.4).
*/
ret = xmlSchemaVCheckINodeDataType(vctxt,
inode, inode->typeDef, inode->value);
@@ -26264,14 +26279,14 @@
/*
* SPEC (cvc-type) (3.2) "If the type definition is a complex type
* definition, then the element information item must be
- * �valid� with respect to the type definition as per
- * Element Locally Valid (Complex Type) (�3.4.4);"
+ * `valid` with respect to the type definition as per
+ * Element Locally Valid (Complex Type) ($3.4.4);"
*
* SPEC (cvc-complex-type) (2.2)
* "If the {content type} is a simple type definition, ...
- * the �normalized value� of the element information item is
- * �valid� with respect to that simple type definition as
- * defined by String Valid (�3.14.4)."
+ * the `normalized value` of the element information item is
+ * `valid` with respect to that simple type definition as
+ * defined by String Valid ($3.14.4)."
*/
ret = xmlSchemaVCheckINodeDataType(vctxt,
inode, inode->typeDef->contentTypeDef, inode->value);
@@ -26313,8 +26328,8 @@
*/
if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
/*
- * 5.2.2.2.1 If the {content type} of the �actual type
- * definition� is mixed, then the *initial value* of the
+ * 5.2.2.2.1 If the {content type} of the `actual type
+ * definition` is mixed, then the *initial value* of the
* item must match the canonical lexical representation
* of the {value constraint} value.
*
@@ -26338,8 +26353,8 @@
}
} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
/*
- * 5.2.2.2.2 If the {content type} of the �actual type
- * definition� is a simple type definition, then the
+ * 5.2.2.2.2 If the {content type} of the `actual type
+ * definition` is a simple type definition, then the
* *actual value* of the item must match the canonical
* lexical representation of the {value constraint} value.
*/
@@ -26380,9 +26395,9 @@
goto internal_error;
/*
* MAYBE TODO:
- * SPEC (6) "The element information item must be �valid� with
+ * SPEC (6) "The element information item must be `valid` with
* respect to each of the {identity-constraint definitions} as per
- * Identity-constraint Satisfied (�3.11.4)."
+ * Identity-constraint Satisfied ($3.11.4)."
*/
/*
* PSVI TODO: If we expose IDC node-tables via PSVI then the tables
@@ -26460,8 +26475,8 @@
vctxt->depth--;
vctxt->inode = vctxt->elemInfos[vctxt->depth];
/*
- * VAL TODO: 7 If the element information item is the �validation root�, it must be
- * �valid� per Validation Root Valid (ID/IDREF) (�3.3.4).
+ * VAL TODO: 7 If the element information item is the `validation root`, it must be
+ * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
*/
return (ret);
@@ -26542,11 +26557,11 @@
* Fallback to "anyType".
*
* SPEC (cvc-assess-elt)
- * "If the item cannot be �strictly assessed�, [...]
+ * "If the item cannot be `strictly assessed`, [...]
* an element information item's schema validity may be laxly
- * assessed if its �context-determined declaration� is not
- * skip by �validating� with respect to the �ur-type
- * definition� as per Element Locally Valid (Type) (�3.3.4)."
+ * assessed if its `context-determined declaration` is not
+ * skip by `validating` with respect to the `ur-type
+ * definition` as per Element Locally Valid (Type) ($3.3.4)."
*/
vctxt->inode->typeDef =
xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
@@ -26618,9 +26633,9 @@
* SPEC (2.4) "If the {content type} is element-only or mixed,
* then the sequence of the element information item's
* element information item [children], if any, taken in
- * order, is �valid� with respect to the {content type}'s
+ * order, is `valid` with respect to the {content type}'s
* particle, as defined in Element Sequence Locally Valid
- * (Particle) (�3.9.4)."
+ * (Particle) ($3.9.4)."
*/
ret = xmlRegExecPushString2(regexCtxt,
vctxt->inode->localName,
@@ -27380,10 +27395,17 @@
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. There is no danger of accidentally
+ * decoding some entity other than & in this step because without
+ * unescaped ampersands there can be no other entities in the string.
*/
- value = xmlStrndup(attributes[j+3],
- attributes[j+4] - attributes[j+3]);
+ value = xmlStringLenDecodeEntities(vctxt->parserCtxt, attributes[j+3],
+ attributes[j+4] - attributes[j+3], XML_SUBSTITUTE_REF, 0, 0, 0);
/*
* TODO: Set the node line.
*/
diff --git a/xmlschemastypes.c b/xmlschemastypes.c
index a9edc03..5f38599 100644
--- a/xmlschemastypes.c
+++ b/xmlschemastypes.c
@@ -62,7 +62,7 @@
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? */
@@ -242,6 +242,10 @@
}
ret->type = XML_SCHEMA_FACET_MINLENGTH;
ret->val = xmlSchemaNewValue(XML_SCHEMAS_NNINTEGER);
+ if (ret->val == NULL) {
+ xmlFree(ret);
+ return(NULL);
+ }
ret->val->value.decimal.lo = value;
return (ret);
}
@@ -1135,9 +1139,13 @@
#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))
@@ -1351,7 +1359,7 @@
return ret;
if (*cur != ':')
return 1;
- if (!VALID_HOUR(value))
+ if (!VALID_HOUR(value) && value != 24 /* Allow end-of-day hour */)
return 2;
cur++;
@@ -1373,7 +1381,7 @@
if (ret != 0)
return ret;
- if ((!VALID_SEC(dt->sec)) || (!VALID_TZO(dt->tzo)))
+ if (!VALID_TIME(dt))
return 2;
*str = cur;
@@ -3844,13 +3852,14 @@
* Coverity detected an overrun in daysInMonth
* of size 12 at position 12 with index variable "((r)->mon - 1)"
*/
- if (tmon < 0)
- tmon = 0;
+ if (tmon < 1)
+ tmon = 1;
if (tmon > 12)
tmon = 12;
tempdays += MAX_DAYINMONTH(tyr, tmon);
carry = -1;
- } else if (tempdays > (long) MAX_DAYINMONTH(r->year, r->mon)) {
+ } else if (VALID_YEAR(r->year) && VALID_MONTH(r->mon) &&
+ tempdays > (long) MAX_DAYINMONTH(r->year, r->mon)) {
tempdays = tempdays - MAX_DAYINMONTH(r->year, r->mon);
carry = 1;
} else
@@ -4929,7 +4938,7 @@
if (y->type == XML_SCHEMAS_STRING)
yws = XML_SCHEMA_WHITESPACE_PRESERVE;
- else if (x->type == XML_SCHEMAS_NORMSTRING)
+ else if (y->type == XML_SCHEMAS_NORMSTRING)
yws = XML_SCHEMA_WHITESPACE_REPLACE;
else
yws = XML_SCHEMA_WHITESPACE_COLLAPSE;
@@ -5298,6 +5307,7 @@
xmlSchemaWhitespaceValueType ws)
{
int ret;
+ int stringType;
if (facet == NULL)
return(-1);
@@ -5310,7 +5320,15 @@
*/
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)
@@ -5644,7 +5662,7 @@
* @val: the precomputed value
* @retValue: the returned value
*
- * Get a the cononical lexical representation of the value.
+ * Get the canonical lexical representation of the value.
* The caller has to FREE the returned retValue.
*
* WARNING: Some value types are not supported yet, resulting
@@ -6066,7 +6084,7 @@
* @retValue: the returned value
* @ws: the whitespace type of the value
*
- * Get a the cononical representation of the value.
+ * Get the canonical representation of the value.
* The caller has to free the returned @retValue.
*
* Returns 0 if the value could be built, 1 if the value type is
diff --git a/xmlstring.c b/xmlstring.c
index a37220d..cc85777 100644
--- a/xmlstring.c
+++ b/xmlstring.c
@@ -457,6 +457,8 @@
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 @@
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);
@@ -538,7 +545,7 @@
* 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 +573,7 @@
* 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)) {
@@ -837,8 +844,8 @@
break;
if ( (ch = *ptr++) & 0x80)
while ((ch<<=1) & 0x80 ) {
- ptr++;
if (*ptr == 0) break;
+ ptr++;
}
}
return (ptr - utf);
@@ -980,5 +987,60 @@
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/xmlwriter.c b/xmlwriter.c
index d3f29f8..69541b8 100644
--- a/xmlwriter.c
+++ b/xmlwriter.c
@@ -31,9 +31,8 @@
/*
* The following VA_COPY was coded following an example in
* the Samba project. It may not be sufficient for some
- * esoteric implementations of va_list (i.e. it may need
- * something involving a memcpy) but (hopefully) will be
- * sufficient for libxml2.
+ * esoteric implementations of va_list but (hopefully) will
+ * be sufficient for libxml2.
*/
#ifndef VA_COPY
#ifdef HAVE_VA_COPY
@@ -42,7 +41,12 @@
#ifdef HAVE___VA_COPY
#define VA_COPY(dest,src) __va_copy(dest, src)
#else
- #define VA_COPY(dest,src) (dest) = (src)
+ #ifndef VA_LIST_IS_ARRAY
+ #define VA_COPY(dest,src) (dest) = (src)
+ #else
+ #include <string.h>
+ #define VA_COPY(dest,src) memcpy((char *)(dest),(char *)(src),sizeof(va_list))
+ #endif
#endif
#endif
#endif
@@ -109,7 +113,7 @@
const xmlChar * 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);
@@ -149,7 +153,7 @@
*
* Handle a writer error
*/
-static void
+static void LIBXML_ATTR_FORMAT(3,0)
xmlWriterErrMsgInt(xmlTextWriterPtr ctxt, xmlParserErrors error,
const char *msg, int val)
{
@@ -2238,10 +2242,12 @@
if (count == -1)
return -1;
sum += count;
- count = xmlTextWriterWriteString(writer, content);
- if (count == -1)
- return -1;
- sum += count;
+ if (content != NULL) {
+ count = xmlTextWriterWriteString(writer, content);
+ if (count == -1)
+ return -1;
+ sum += count;
+ }
count = xmlTextWriterEndElement(writer);
if (count == -1)
return -1;
diff --git a/xpath.c b/xpath.c
index 97410e7..06897c7 100644
--- a/xpath.c
+++ b/xpath.c
@@ -135,6 +135,298 @@
* any use of the macros IS_ASCII_CHARACTER and IS_ASCII_DIGIT)
*/
+#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
+/**
+ * xmlXPathCmpNodesExt:
+ * @node1: the first node
+ * @node2: the second node
+ *
+ * Compare two nodes w.r.t document order.
+ * This one is optimized for handling of non-element nodes.
+ *
+ * Returns -2 in case of error 1 if first point < second point, 0 if
+ * it's the same node, -1 otherwise
+ */
+static int
+xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) {
+ int depth1, depth2;
+ int misc = 0, precedence1 = 0, precedence2 = 0;
+ xmlNodePtr miscNode1 = NULL, miscNode2 = NULL;
+ xmlNodePtr cur, root;
+ long l1, l2;
+
+ if ((node1 == NULL) || (node2 == NULL))
+ return(-2);
+
+ if (node1 == node2)
+ return(0);
+
+ /*
+ * a couple of optimizations which will avoid computations in most cases
+ */
+ 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) &&
+ (node1->doc == node2->doc))
+ {
+ l1 = -((long) node1->content);
+ l2 = -((long) node2->content);
+ if (l1 < l2)
+ return(1);
+ if (l1 > l2)
+ return(-1);
+ } else
+ goto turtle_comparison;
+ }
+ break;
+ case XML_ATTRIBUTE_NODE:
+ precedence1 = 1; /* element is owner */
+ miscNode1 = node1;
+ node1 = node1->parent;
+ misc = 1;
+ break;
+ case XML_TEXT_NODE:
+ case XML_CDATA_SECTION_NODE:
+ case XML_COMMENT_NODE:
+ case XML_PI_NODE: {
+ miscNode1 = node1;
+ /*
+ * Find nearest element node.
+ */
+ if (node1->prev != NULL) {
+ do {
+ node1 = node1->prev;
+ if (node1->type == XML_ELEMENT_NODE) {
+ precedence1 = 3; /* element in prev-sibl axis */
+ break;
+ }
+ if (node1->prev == NULL) {
+ precedence1 = 2; /* element is parent */
+ /*
+ * URGENT TODO: Are there any cases, where the
+ * parent of such a node is not an element node?
+ */
+ node1 = node1->parent;
+ break;
+ }
+ } while (1);
+ } else {
+ precedence1 = 2; /* element is parent */
+ node1 = node1->parent;
+ }
+ if ((node1 == NULL) || (node1->type != XML_ELEMENT_NODE) ||
+ (0 <= (long) node1->content)) {
+ /*
+ * Fallback for whatever case.
+ */
+ node1 = miscNode1;
+ precedence1 = 0;
+ } else
+ misc = 1;
+ }
+ break;
+ case XML_NAMESPACE_DECL:
+ /*
+ * TODO: why do we return 1 for namespace nodes?
+ */
+ return(1);
+ default:
+ break;
+ }
+ switch (node2->type) {
+ case XML_ELEMENT_NODE:
+ break;
+ case XML_ATTRIBUTE_NODE:
+ precedence2 = 1; /* element is owner */
+ miscNode2 = node2;
+ node2 = node2->parent;
+ misc = 1;
+ break;
+ case XML_TEXT_NODE:
+ case XML_CDATA_SECTION_NODE:
+ case XML_COMMENT_NODE:
+ case XML_PI_NODE: {
+ miscNode2 = node2;
+ if (node2->prev != NULL) {
+ do {
+ node2 = node2->prev;
+ if (node2->type == XML_ELEMENT_NODE) {
+ precedence2 = 3; /* element in prev-sibl axis */
+ break;
+ }
+ if (node2->prev == NULL) {
+ precedence2 = 2; /* element is parent */
+ node2 = node2->parent;
+ break;
+ }
+ } while (1);
+ } else {
+ precedence2 = 2; /* element is parent */
+ node2 = node2->parent;
+ }
+ if ((node2 == NULL) || (node2->type != XML_ELEMENT_NODE) ||
+ (0 <= (long) node2->content))
+ {
+ node2 = miscNode2;
+ precedence2 = 0;
+ } else
+ misc = 1;
+ }
+ break;
+ case XML_NAMESPACE_DECL:
+ return(1);
+ default:
+ break;
+ }
+ if (misc) {
+ if (node1 == node2) {
+ if (precedence1 == precedence2) {
+ /*
+ * The ugly case; but normally there aren't many
+ * adjacent non-element nodes around.
+ */
+ cur = miscNode2->prev;
+ while (cur != NULL) {
+ if (cur == miscNode1)
+ return(1);
+ if (cur->type == XML_ELEMENT_NODE)
+ return(-1);
+ cur = cur->prev;
+ }
+ return (-1);
+ } else {
+ /*
+ * Evaluate based on higher precedence wrt to the element.
+ * TODO: This assumes attributes are sorted before content.
+ * Is this 100% correct?
+ */
+ if (precedence1 < precedence2)
+ return(1);
+ else
+ return(-1);
+ }
+ }
+ /*
+ * Special case: One of the helper-elements is contained by the other.
+ * <foo>
+ * <node2>
+ * <node1>Text-1(precedence1 == 2)</node1>
+ * </node2>
+ * Text-6(precedence2 == 3)
+ * </foo>
+ */
+ if ((precedence2 == 3) && (precedence1 > 1)) {
+ cur = node1->parent;
+ while (cur) {
+ if (cur == node2)
+ return(1);
+ cur = cur->parent;
+ }
+ }
+ if ((precedence1 == 3) && (precedence2 > 1)) {
+ cur = node2->parent;
+ while (cur) {
+ if (cur == node1)
+ return(-1);
+ cur = cur->parent;
+ }
+ }
+ }
+
+ /*
+ * Speedup using document order if availble.
+ */
+ if ((node1->type == XML_ELEMENT_NODE) &&
+ (node2->type == XML_ELEMENT_NODE) &&
+ (0 > (long) node1->content) &&
+ (0 > (long) node2->content) &&
+ (node1->doc == node2->doc)) {
+
+ l1 = -((long) node1->content);
+ l2 = -((long) node2->content);
+ if (l1 < l2)
+ return(1);
+ if (l1 > l2)
+ return(-1);
+ }
+
+turtle_comparison:
+
+ if (node1 == node2->prev)
+ return(1);
+ if (node1 == node2->next)
+ return(-1);
+ /*
+ * compute depth to root
+ */
+ for (depth2 = 0, cur = node2; cur->parent != NULL; cur = cur->parent) {
+ if (cur->parent == node1)
+ return(1);
+ depth2++;
+ }
+ root = cur;
+ for (depth1 = 0, cur = node1; cur->parent != NULL; cur = cur->parent) {
+ if (cur->parent == node2)
+ return(-1);
+ depth1++;
+ }
+ /*
+ * Distinct document (or distinct entities :-( ) case.
+ */
+ if (root != cur) {
+ return(-2);
+ }
+ /*
+ * get the nearest common ancestor.
+ */
+ while (depth1 > depth2) {
+ depth1--;
+ node1 = node1->parent;
+ }
+ while (depth2 > depth1) {
+ depth2--;
+ node2 = node2->parent;
+ }
+ while (node1->parent != node2->parent) {
+ node1 = node1->parent;
+ node2 = node2->parent;
+ /* should not happen but just in case ... */
+ if ((node1 == NULL) || (node2 == NULL))
+ return(-2);
+ }
+ /*
+ * Find who's first.
+ */
+ if (node1 == node2->prev)
+ return(1);
+ if (node1 == node2->next)
+ return(-1);
+ /*
+ * Speedup using document order if availble.
+ */
+ if ((node1->type == XML_ELEMENT_NODE) &&
+ (node2->type == XML_ELEMENT_NODE) &&
+ (0 > (long) node1->content) &&
+ (0 > (long) node2->content) &&
+ (node1->doc == node2->doc)) {
+
+ l1 = -((long) node1->content);
+ l2 = -((long) node2->content);
+ if (l1 < l2)
+ return(1);
+ if (l1 > l2)
+ return(-1);
+ }
+
+ for (cur = node1->next;cur != NULL;cur = cur->next)
+ if (cur == node2)
+ return(1);
+ return(-1); /* assume there is no sibling list corruption */
+}
+#endif /* XP_OPTIMIZED_NON_ELEM_COMPARISON */
+
/*
* Wrapper for the Timsort argorithm from timsort.h
*/
@@ -154,7 +446,6 @@
static
int wrap_cmp( xmlNodePtr x, xmlNodePtr y );
#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
- static int xmlXPathCmpNodesExt(xmlNodePtr, xmlNodePtr);
static int wrap_cmp( xmlNodePtr x, xmlNodePtr y )
{
int res = xmlXPathCmpNodesExt(x, y);
@@ -327,7 +618,7 @@
"Encoding error\n",
"Char out of XML range\n",
"Invalid or incomplete context\n",
- "Stack usage errror\n",
+ "Stack usage error\n",
"Forbidden variable\n",
"?? Unknown error ??\n" /* Must be last in the list! */
};
@@ -348,7 +639,7 @@
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 {
@@ -654,7 +945,7 @@
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;
@@ -2885,6 +3176,12 @@
fraction_place, number);
}
+ /* Remove leading spaces sometimes inserted by snprintf */
+ while (work[0] == ' ') {
+ for (ptr = &work[0];(ptr[0] = ptr[1]);ptr++);
+ size--;
+ }
+
/* Remove fractional trailing zeroes */
after_fraction = work + size;
ptr = after_fraction;
@@ -2896,7 +3193,7 @@
/* Finally copy result back to caller */
size = strlen(work) + 1;
- if (size > buffersize) {
+ if (size > buffersize && buffersize <= (int)sizeof(work)) {
work[buffersize - 1] = 0;
size = buffersize;
}
@@ -3110,298 +3407,6 @@
return(-1); /* assume there is no sibling list corruption */
}
-#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
-/**
- * xmlXPathCmpNodesExt:
- * @node1: the first node
- * @node2: the second node
- *
- * Compare two nodes w.r.t document order.
- * This one is optimized for handling of non-element nodes.
- *
- * Returns -2 in case of error 1 if first point < second point, 0 if
- * it's the same node, -1 otherwise
- */
-static int
-xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) {
- int depth1, depth2;
- int misc = 0, precedence1 = 0, precedence2 = 0;
- xmlNodePtr miscNode1 = NULL, miscNode2 = NULL;
- xmlNodePtr cur, root;
- long l1, l2;
-
- if ((node1 == NULL) || (node2 == NULL))
- return(-2);
-
- if (node1 == node2)
- return(0);
-
- /*
- * a couple of optimizations which will avoid computations in most cases
- */
- 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) &&
- (node1->doc == node2->doc))
- {
- l1 = -((long) node1->content);
- l2 = -((long) node2->content);
- if (l1 < l2)
- return(1);
- if (l1 > l2)
- return(-1);
- } else
- goto turtle_comparison;
- }
- break;
- case XML_ATTRIBUTE_NODE:
- precedence1 = 1; /* element is owner */
- miscNode1 = node1;
- node1 = node1->parent;
- misc = 1;
- break;
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_COMMENT_NODE:
- case XML_PI_NODE: {
- miscNode1 = node1;
- /*
- * Find nearest element node.
- */
- if (node1->prev != NULL) {
- do {
- node1 = node1->prev;
- if (node1->type == XML_ELEMENT_NODE) {
- precedence1 = 3; /* element in prev-sibl axis */
- break;
- }
- if (node1->prev == NULL) {
- precedence1 = 2; /* element is parent */
- /*
- * URGENT TODO: Are there any cases, where the
- * parent of such a node is not an element node?
- */
- node1 = node1->parent;
- break;
- }
- } while (1);
- } else {
- precedence1 = 2; /* element is parent */
- node1 = node1->parent;
- }
- if ((node1 == NULL) || (node1->type != XML_ELEMENT_NODE) ||
- (0 <= (long) node1->content)) {
- /*
- * Fallback for whatever case.
- */
- node1 = miscNode1;
- precedence1 = 0;
- } else
- misc = 1;
- }
- break;
- case XML_NAMESPACE_DECL:
- /*
- * TODO: why do we return 1 for namespace nodes?
- */
- return(1);
- default:
- break;
- }
- switch (node2->type) {
- case XML_ELEMENT_NODE:
- break;
- case XML_ATTRIBUTE_NODE:
- precedence2 = 1; /* element is owner */
- miscNode2 = node2;
- node2 = node2->parent;
- misc = 1;
- break;
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- case XML_COMMENT_NODE:
- case XML_PI_NODE: {
- miscNode2 = node2;
- if (node2->prev != NULL) {
- do {
- node2 = node2->prev;
- if (node2->type == XML_ELEMENT_NODE) {
- precedence2 = 3; /* element in prev-sibl axis */
- break;
- }
- if (node2->prev == NULL) {
- precedence2 = 2; /* element is parent */
- node2 = node2->parent;
- break;
- }
- } while (1);
- } else {
- precedence2 = 2; /* element is parent */
- node2 = node2->parent;
- }
- if ((node2 == NULL) || (node2->type != XML_ELEMENT_NODE) ||
- (0 <= (long) node1->content))
- {
- node2 = miscNode2;
- precedence2 = 0;
- } else
- misc = 1;
- }
- break;
- case XML_NAMESPACE_DECL:
- return(1);
- default:
- break;
- }
- if (misc) {
- if (node1 == node2) {
- if (precedence1 == precedence2) {
- /*
- * The ugly case; but normally there aren't many
- * adjacent non-element nodes around.
- */
- cur = miscNode2->prev;
- while (cur != NULL) {
- if (cur == miscNode1)
- return(1);
- if (cur->type == XML_ELEMENT_NODE)
- return(-1);
- cur = cur->prev;
- }
- return (-1);
- } else {
- /*
- * Evaluate based on higher precedence wrt to the element.
- * TODO: This assumes attributes are sorted before content.
- * Is this 100% correct?
- */
- if (precedence1 < precedence2)
- return(1);
- else
- return(-1);
- }
- }
- /*
- * Special case: One of the helper-elements is contained by the other.
- * <foo>
- * <node2>
- * <node1>Text-1(precedence1 == 2)</node1>
- * </node2>
- * Text-6(precedence2 == 3)
- * </foo>
- */
- if ((precedence2 == 3) && (precedence1 > 1)) {
- cur = node1->parent;
- while (cur) {
- if (cur == node2)
- return(1);
- cur = cur->parent;
- }
- }
- if ((precedence1 == 3) && (precedence2 > 1)) {
- cur = node2->parent;
- while (cur) {
- if (cur == node1)
- return(-1);
- cur = cur->parent;
- }
- }
- }
-
- /*
- * Speedup using document order if availble.
- */
- if ((node1->type == XML_ELEMENT_NODE) &&
- (node2->type == XML_ELEMENT_NODE) &&
- (0 > (long) node1->content) &&
- (0 > (long) node2->content) &&
- (node1->doc == node2->doc)) {
-
- l1 = -((long) node1->content);
- l2 = -((long) node2->content);
- if (l1 < l2)
- return(1);
- if (l1 > l2)
- return(-1);
- }
-
-turtle_comparison:
-
- if (node1 == node2->prev)
- return(1);
- if (node1 == node2->next)
- return(-1);
- /*
- * compute depth to root
- */
- for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {
- if (cur == node1)
- return(1);
- depth2++;
- }
- root = cur;
- for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {
- if (cur == node2)
- return(-1);
- depth1++;
- }
- /*
- * Distinct document (or distinct entities :-( ) case.
- */
- if (root != cur) {
- return(-2);
- }
- /*
- * get the nearest common ancestor.
- */
- while (depth1 > depth2) {
- depth1--;
- node1 = node1->parent;
- }
- while (depth2 > depth1) {
- depth2--;
- node2 = node2->parent;
- }
- while (node1->parent != node2->parent) {
- node1 = node1->parent;
- node2 = node2->parent;
- /* should not happen but just in case ... */
- if ((node1 == NULL) || (node2 == NULL))
- return(-2);
- }
- /*
- * Find who's first.
- */
- if (node1 == node2->prev)
- return(1);
- if (node1 == node2->next)
- return(-1);
- /*
- * Speedup using document order if availble.
- */
- if ((node1->type == XML_ELEMENT_NODE) &&
- (node2->type == XML_ELEMENT_NODE) &&
- (0 > (long) node1->content) &&
- (0 > (long) node2->content) &&
- (node1->doc == node2->doc)) {
-
- l1 = -((long) node1->content);
- l2 = -((long) node2->content);
- if (l1 < l2)
- return(1);
- if (l1 > l2)
- return(-1);
- }
-
- for (cur = node1->next;cur != NULL;cur = cur->next)
- if (cur == node2)
- return(1);
- return(-1); /* assume there is no sibling list corruption */
-}
-#endif /* XP_OPTIMIZED_NON_ELEM_COMPARISON */
-
/**
* xmlXPathNodeSetSort:
* @set: the node set
@@ -3701,7 +3706,7 @@
/* @@ 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);
@@ -7928,14 +7933,14 @@
xmlNodePtr
xmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
- if (cur == NULL) {
- if (ctxt->context->node == NULL)
- return(NULL);
- if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
- (ctxt->context->node->type == XML_NAMESPACE_DECL))
- return(NULL);
+ if (cur == NULL)
return(ctxt->context->node);
- }
+
+ if (ctxt->context->node == NULL)
+ return(NULL);
+ if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
+ (ctxt->context->node->type == XML_NAMESPACE_DECL))
+ return(NULL);
return(xmlXPathNextDescendant(ctxt, cur));
}
@@ -8385,7 +8390,7 @@
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 =
@@ -9991,7 +9996,7 @@
(c == '[') || (c == ']') || (c == '@') || /* accelerators */
(c == '*') || /* accelerators */
(!IS_LETTER(c) && (c != '_') &&
- ((qualified) && (c != ':')))) {
+ ((!qualified) || (c != ':')))) {
return(NULL);
}
@@ -12374,11 +12379,6 @@
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:
@@ -12392,9 +12392,17 @@
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;
}
@@ -12420,7 +12428,14 @@
if (axis == AXIS_ATTRIBUTE) {
if (cur->type == XML_ATTRIBUTE_NODE)
{
- XP_TEST_HIT
+ if (prefix == NULL)
+ {
+ XP_TEST_HIT
+ } else if ((cur->ns != NULL) &&
+ (xmlStrEqual(URI, cur->ns->href)))
+ {
+ XP_TEST_HIT
+ }
}
} else if (axis == AXIS_NAMESPACE) {
if (cur->type == XML_NAMESPACE_DECL)
@@ -12679,6 +12694,14 @@
* 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,
@@ -13512,10 +13535,15 @@
int frame;
frame = xmlXPathSetFrame(ctxt);
- if (op->ch1 != -1)
+ if (op->ch1 != -1) {
total +=
xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
- if (ctxt->valueNr < op->value) {
+ if (ctxt->error != XPATH_EXPRESSION_OK) {
+ xmlXPathPopFrame(ctxt, frame);
+ return (total);
+ }
+ }
+ if (ctxt->valueNr < ctxt->valueFrame + op->value) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathCompOpEval: parameter error\n");
ctxt->error = XPATH_INVALID_OPERAND;
@@ -13577,17 +13605,20 @@
bak = ctxt->context->node;
pp = ctxt->context->proximityPosition;
cs = ctxt->context->contextSize;
- if (op->ch1 != -1)
+ 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;
+ 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->doc = bakd;
- ctxt->context->node = bak;
+ ctxt->context->contextSize = cs;
+ ctxt->context->proximityPosition = pp;
+ ctxt->context->node = bak;
+ ctxt->context->doc = bakd;
CHECK_ERROR0;
}
return (total);
@@ -13974,9 +14005,14 @@
xmlNodeSetPtr oldset;
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);
@@ -14719,8 +14755,9 @@
* internal representation.
*/
- if ((op->ch1 != -1) &&
- (op->op == XPATH_OP_COLLECT /* 11 */))
+ if ((op->op == XPATH_OP_COLLECT /* 11 */) &&
+ (op->ch1 != -1) &&
+ (op->ch2 == -1 /* no predicate */))
{
xmlXPathStepOpPtr prevop = &comp->steps[op->ch1];
@@ -14763,6 +14800,10 @@
}
}
+ /* OP_VALUE has invalid ch1. */
+ if (op->op == XPATH_OP_VALUE)
+ return;
+
/* Recurse */
if (op->ch1 != -1)
xmlXPathOptimizeExpression(comp, &comp->steps[op->ch1]);
diff --git a/xpointer.c b/xpointer.c
index 46f11e8..676c510 100644
--- a/xpointer.c
+++ b/xpointer.c
@@ -85,7 +85,7 @@
*
* 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)
{
@@ -1375,6 +1375,8 @@
return(NULL);
ctxt = xmlXPathNewParserContext(str, ctx);
+ if (ctxt == NULL)
+ return(NULL);
ctxt->xptr = 1;
xmlXPtrEvalXPointer(ctxt);
@@ -1807,6 +1809,8 @@
*/
tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
xmlXPathFreeObject(obj);
+ if (tmp == NULL)
+ XP_ERROR(XPATH_MEMORY_ERROR)
obj = tmp;
}
@@ -1901,10 +1905,16 @@
*/
tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
xmlXPathFreeObject(obj);
+ if (tmp == NULL)
+ XP_ERROR(XPATH_MEMORY_ERROR)
obj = tmp;
}
newset = xmlXPtrLocationSetCreate(NULL);
+ if (newset == NULL) {
+ xmlXPathFreeObject(obj);
+ XP_ERROR(XPATH_MEMORY_ERROR);
+ }
oldset = (xmlLocationSetPtr) obj->user;
if (oldset != NULL) {
int i;
@@ -2049,6 +2059,8 @@
*/
tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
xmlXPathFreeObject(set);
+ if (tmp == NULL)
+ XP_ERROR(XPATH_MEMORY_ERROR)
set = tmp;
}
oldset = (xmlLocationSetPtr) set->user;
@@ -2057,6 +2069,10 @@
* The loop is to compute the covering range for each item and add it
*/
newset = xmlXPtrLocationSetCreate(NULL);
+ if (newset == NULL) {
+ xmlXPathFreeObject(set);
+ XP_ERROR(XPATH_MEMORY_ERROR);
+ }
for (i = 0;i < oldset->locNr;i++) {
xmlXPtrLocationSetAdd(newset,
xmlXPtrCoveringRange(ctxt, oldset->locTab[i]));
@@ -2195,6 +2211,8 @@
*/
tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
xmlXPathFreeObject(set);
+ if (tmp == NULL)
+ XP_ERROR(XPATH_MEMORY_ERROR)
set = tmp;
}
oldset = (xmlLocationSetPtr) set->user;
@@ -2203,6 +2221,10 @@
* The loop is to compute the covering range for each item and add it
*/
newset = xmlXPtrLocationSetCreate(NULL);
+ if (newset == NULL) {
+ xmlXPathFreeObject(set);
+ XP_ERROR(XPATH_MEMORY_ERROR);
+ }
for (i = 0;i < oldset->locNr;i++) {
xmlXPtrLocationSetAdd(newset,
xmlXPtrInsideRange(ctxt, oldset->locTab[i]));
@@ -2461,8 +2483,6 @@
((*end)->type == XML_NAMESPACE_DECL) || (endindex == NULL))
return(-1);
cur = start;
- if (cur == NULL)
- return(-1);
pos = startindex - 1;
stringlen = xmlStrlen(string);
@@ -2798,6 +2818,10 @@
set = valuePop(ctxt);
newset = xmlXPtrLocationSetCreate(NULL);
+ if (newset == NULL) {
+ xmlXPathFreeObject(set);
+ XP_ERROR(XPATH_MEMORY_ERROR);
+ }
if (set->nodesetval == NULL) {
goto error;
}
@@ -2809,6 +2833,8 @@
*/
tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
xmlXPathFreeObject(set);
+ if (tmp == NULL)
+ XP_ERROR(XPATH_MEMORY_ERROR)
set = tmp;
}
oldset = (xmlLocationSetPtr) set->user;