am 60fd9a36: (-s ours) DO NOT MERGE Fix for CVE-2011-3919
* commit '60fd9a3698956b22cb34a7553cf38cf679f473a6':
DO NOT MERGE Fix for CVE-2011-3919
diff --git a/Copyright b/Copyright
new file mode 100644
index 0000000..417e955
--- /dev/null
+++ b/Copyright
@@ -0,0 +1,27 @@
+Except where otherwise noted in the source code (e.g. the files hash.c,
+list.c and the trio files, which are covered by a similar licence but
+with different Copyright notices) all the files are:
+
+ Copyright (C) 1998-2003 Daniel Veillard. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is fur-
+nished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+DANIEL VEILLARD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Daniel Veillard shall not
+be used in advertising or otherwise to promote the sale, use or other deal-
+ings in this Software without prior written authorization from him.
+
diff --git a/HTMLparser.c b/HTMLparser.c
index 24b0fc0..1a4d80d 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -59,7 +59,7 @@
/************************************************************************
* *
- * Some factorized error routines *
+ * Some factorized error routines *
* *
************************************************************************/
@@ -147,7 +147,7 @@
/************************************************************************
* *
- * Parser stacks related functions and macros *
+ * Parser stacks related functions and macros *
* *
************************************************************************/
@@ -163,6 +163,10 @@
static int
htmlnamePush(htmlParserCtxtPtr ctxt, const xmlChar * value)
{
+ if ((ctxt->html < 3) && (xmlStrEqual(value, BAD_CAST "head")))
+ ctxt->html = 3;
+ if ((ctxt->html < 10) && (xmlStrEqual(value, BAD_CAST "body")))
+ ctxt->html = 10;
if (ctxt->nameNr >= ctxt->nameMax) {
ctxt->nameMax *= 2;
ctxt->nameTab = (const xmlChar * *)
@@ -205,6 +209,59 @@
return (ret);
}
+/**
+ * htmlNodeInfoPush:
+ * @ctxt: an HTML parser context
+ * @value: the node info
+ *
+ * Pushes a new element name on top of the node info stack
+ *
+ * Returns 0 in case of error, the index in the stack otherwise
+ */
+static int
+htmlNodeInfoPush(htmlParserCtxtPtr ctxt, htmlParserNodeInfo *value)
+{
+ if (ctxt->nodeInfoNr >= ctxt->nodeInfoMax) {
+ if (ctxt->nodeInfoMax == 0)
+ ctxt->nodeInfoMax = 5;
+ ctxt->nodeInfoMax *= 2;
+ ctxt->nodeInfoTab = (htmlParserNodeInfo *)
+ xmlRealloc((htmlParserNodeInfo *)ctxt->nodeInfoTab,
+ ctxt->nodeInfoMax *
+ sizeof(ctxt->nodeInfoTab[0]));
+ if (ctxt->nodeInfoTab == NULL) {
+ htmlErrMemory(ctxt, NULL);
+ return (0);
+ }
+ }
+ ctxt->nodeInfoTab[ctxt->nodeInfoNr] = *value;
+ ctxt->nodeInfo = &ctxt->nodeInfoTab[ctxt->nodeInfoNr];
+ return (ctxt->nodeInfoNr++);
+}
+
+/**
+ * htmlNodeInfoPop:
+ * @ctxt: an HTML parser context
+ *
+ * Pops the top element name from the node info stack
+ *
+ * Returns 0 in case of error, the pointer to NodeInfo otherwise
+ */
+static htmlParserNodeInfo *
+htmlNodeInfoPop(htmlParserCtxtPtr ctxt)
+{
+ if (ctxt->nodeInfoNr <= 0)
+ return (NULL);
+ ctxt->nodeInfoNr--;
+ if (ctxt->nodeInfoNr < 0)
+ return (NULL);
+ if (ctxt->nodeInfoNr > 0)
+ ctxt->nodeInfo = &ctxt->nodeInfoTab[ctxt->nodeInfoNr - 1];
+ else
+ ctxt->nodeInfo = NULL;
+ return &ctxt->nodeInfoTab[ctxt->nodeInfoNr];
+}
+
/*
* Macros for accessing the content. Those should be used only by the parser,
* and not exported.
@@ -263,8 +320,6 @@
#define NEXT xmlNextChar(ctxt)
#define RAW (ctxt->token ? -1 : (*ctxt->input->cur))
-#define NXT(val) ctxt->input->cur[(val)]
-#define CUR_PTR ctxt->input->cur
#define NEXTL(l) do { \
@@ -273,7 +328,7 @@
} else ctxt->input->col++; \
ctxt->token = 0; ctxt->input->cur += l; ctxt->nbChars++; \
} while (0)
-
+
/************
\
if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
@@ -288,6 +343,58 @@
else i += xmlCopyChar(l,&b[i],v)
/**
+ * htmlFindEncoding:
+ * @the HTML parser context
+ *
+ * Ty to find and encoding in the current data available in the input
+ * buffer this is needed to try to switch to the proper encoding when
+ * one face a character error.
+ * That's an heuristic, since it's operating outside of parsing it could
+ * try to use a meta which had been commented out, that's the reason it
+ * should only be used in case of error, not as a default.
+ *
+ * Returns an encoding string or NULL if not found, the string need to
+ * be freed
+ */
+static xmlChar *
+htmlFindEncoding(xmlParserCtxtPtr ctxt) {
+ const xmlChar *start, *cur, *end;
+
+ if ((ctxt == NULL) || (ctxt->input == NULL) ||
+ (ctxt->input->encoding != NULL) || (ctxt->input->buf == NULL) ||
+ (ctxt->input->buf->encoder != NULL))
+ return(NULL);
+ if ((ctxt->input->cur == NULL) || (ctxt->input->end == NULL))
+ return(NULL);
+
+ start = ctxt->input->cur;
+ end = ctxt->input->end;
+ /* we also expect the input buffer to be zero terminated */
+ if (*end != 0)
+ return(NULL);
+
+ cur = xmlStrcasestr(start, BAD_CAST "HTTP-EQUIV");
+ if (cur == NULL)
+ return(NULL);
+ cur = xmlStrcasestr(cur, BAD_CAST "CONTENT");
+ if (cur == NULL)
+ return(NULL);
+ cur = xmlStrcasestr(cur, BAD_CAST "CHARSET=");
+ if (cur == NULL)
+ return(NULL);
+ cur += 8;
+ start = cur;
+ while (((*cur >= 'A') && (*cur <= 'Z')) ||
+ ((*cur >= 'a') && (*cur <= 'z')) ||
+ ((*cur >= '0') && (*cur <= '9')) ||
+ (*cur == '-') || (*cur == '_') || (*cur == ':') || (*cur == '/'))
+ cur++;
+ if (cur == start)
+ return(NULL);
+ return(xmlStrndup(start, cur - start));
+}
+
+/**
* htmlCurrentChar:
* @ctxt: the HTML parser context
* @len: pointer to the length of the char read
@@ -309,7 +416,7 @@
if (ctxt->token != 0) {
*len = 0;
return(ctxt->token);
- }
+ }
if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
/*
* We are supposed to handle UTF8, check it's valid
@@ -318,7 +425,7 @@
* 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
+ * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
*
* Check for the 0x110000 limit too
*/
@@ -328,19 +435,25 @@
c = *cur;
if (c & 0x80) {
- if (cur[1] == 0)
+ 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) {
- if (cur[2] == 0)
+ if (cur[2] == 0) {
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+ cur = ctxt->input->cur;
+ }
if ((cur[2] & 0xc0) != 0x80)
goto encoding_error;
if ((c & 0xf0) == 0xf0) {
- if (cur[3] == 0)
+ if (cur[3] == 0) {
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+ cur = ctxt->input->cur;
+ }
if (((c & 0xf8) != 0xf0) ||
((cur[3] & 0xc0) != 0x80))
goto encoding_error;
@@ -366,9 +479,16 @@
if (!IS_CHAR(val)) {
htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
"Char 0x%X out of allowed range\n", val);
- }
+ }
return(val);
} else {
+ if ((*ctxt->input->cur == 0) &&
+ (ctxt->input->cur < ctxt->input->end)) {
+ htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
+ "Char 0x%X out of allowed range\n", 0);
+ *len = 1;
+ return(' ');
+ }
/* 1-byte code */
*len = 1;
return((int) *ctxt->input->cur);
@@ -386,8 +506,28 @@
/*
* Humm this is bad, do an automatic flow conversion
*/
- xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
- ctxt->charset = XML_CHAR_ENCODING_UTF8;
+ {
+ xmlChar * guess;
+ xmlCharEncodingHandlerPtr handler;
+
+ guess = htmlFindEncoding(ctxt);
+ if (guess == NULL) {
+ xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
+ } else {
+ if (ctxt->input->encoding != NULL)
+ xmlFree((xmlChar *) ctxt->input->encoding);
+ ctxt->input->encoding = guess;
+ handler = xmlFindCharEncodingHandler((const char *) guess);
+ if (handler != NULL) {
+ xmlSwitchToEncoding(ctxt, handler);
+ } else {
+ htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
+ "Unsupported encoding %s", guess, NULL);
+ }
+ }
+ ctxt->charset = XML_CHAR_ENCODING_UTF8;
+ }
+
return(xmlCurrentChar(ctxt, len));
encoding_error:
@@ -413,7 +553,7 @@
BAD_CAST buffer, NULL);
}
- ctxt->charset = XML_CHAR_ENCODING_8859_1;
+ ctxt->charset = XML_CHAR_ENCODING_8859_1;
*len = 1;
return((int) *ctxt->input->cur);
}
@@ -453,7 +593,7 @@
/************************************************************************
* *
- * The list of HTML elements and their properties *
+ * The list of HTML elements and their properties *
* *
************************************************************************/
@@ -478,9 +618,9 @@
#define NB_PHRASE 10
#define SPECIAL "a", "img", "applet", "embed", "object", "font", "basefont", "br", "script", "map", "q", "sub", "sup", "span", "bdo", "iframe"
#define NB_SPECIAL 16
-#define INLINE PCDATA FONTSTYLE PHRASE SPECIAL FORMCTRL
+#define INLINE FONTSTYLE, PHRASE, SPECIAL, FORMCTRL
#define NB_INLINE NB_PCDATA + NB_FONTSTYLE + NB_PHRASE + NB_SPECIAL + NB_FORMCTRL
-#define BLOCK HEADING, LIST "pre", "p", "dl", "div", "center", "noscript", "noframes", "blockquote", "form", "isindex", "hr", "table", "fieldset", "address"
+#define BLOCK HEADING, LIST, "pre", "p", "dl", "div", "center", "noscript", "noframes", "blockquote", "form", "isindex", "hr", "table", "fieldset", "address"
#define NB_BLOCK NB_HEADING + NB_LIST + 14
#define FORMCTRL "input", "select", "textarea", "label", "button"
#define NB_FORMCTRL 5
@@ -606,7 +746,7 @@
static const char* const select_content[] = { "optgroup", "option", NULL } ;
static const char* const select_attrs[] = { ATTRS, "name", "size", "multiple", "disabled", "tabindex", "onfocus", "onblur", "onchange", NULL } ;
static const char* const style_attrs[] = { I18N, "media", "title", NULL } ;
-static const char* const table_attrs[] = { ATTRS "summary", "width", "border", "frame", "rules", "cellspacing", "cellpadding", "datapagesize", NULL } ;
+static const char* const table_attrs[] = { ATTRS, "summary", "width", "border", "frame", "rules", "cellspacing", "cellpadding", "datapagesize", NULL } ;
static const char* const table_depr[] = { "align", "bgcolor", NULL } ;
static const char* const table_contents[] = { "caption", "col", "colgroup", "thead", "tfoot", "tbody", "tr", NULL} ;
static const char* const tr_elt[] = { "tr", NULL } ;
@@ -938,7 +1078,7 @@
"listing", "xmp", NULL,
"ol", "p", "head", "ul", NULL,
"menu", "p", "head", "ul", NULL,
-"p", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6", NULL,
+"p", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6", FONTSTYLE, NULL,
"div", "p", "head", NULL,
"noscript", "p", "head", NULL,
"center", "font", "b", "i", "p", "head", NULL,
@@ -949,7 +1089,7 @@
"table", "p", "head", "h1", "h2", "h3", "h4", "h5", "h6", "pre",
"listing", "xmp", "a", NULL,
"th", "th", "td", "p", "span", "font", "a", "b", "i", "u", NULL,
-"td", "th", "td", "p", "span", "font", "a", "b", "i", "u", NULL,
+"td", "th", "td", "p", "span", "font", "a", "b", "i", "u", NULL,
"tr", "th", "td", "tr", "caption", "col", "colgroup", "p", NULL,
"thead", "caption", "col", "colgroup", NULL,
"tfoot", "th", "td", "tr", "caption", "col", "colgroup", "thead",
@@ -1008,7 +1148,7 @@
* elements the parser can decide how to handle extra endtags.
* Endtags are only allowed to close elements with lower or equal
* priority.
- */
+ */
typedef struct {
const char *name;
@@ -1035,7 +1175,7 @@
/************************************************************************
* *
- * functions to handle HTML specific data *
+ * functions to handle HTML specific data *
* *
************************************************************************/
@@ -1085,7 +1225,7 @@
/**
* htmlGetEndPriority:
* @name: The name of the element to look up the priority for.
- *
+ *
* Return value: The "endtag" priority.
**/
static int
@@ -1164,7 +1304,7 @@
* A missplaced endtag can only close elements with lower
* or equal priority, so if we find an element with higher
* priority before we find an element with
- * matching name, we just ignore this endtag
+ * matching name, we just ignore this endtag
*/
if (htmlGetEndPriority(ctxt->nameTab[i]) > priority)
return;
@@ -1215,7 +1355,7 @@
* called when a new tag has been detected and generates the
* appropriates closes if possible/needed.
* If newtag is NULL this mean we are at the end of the resource
- * and we should check
+ * and we should check
*/
static void
htmlAutoClose(htmlParserCtxtPtr ctxt, const xmlChar * newtag)
@@ -1303,6 +1443,10 @@
*/
static void
htmlCheckImplied(htmlParserCtxtPtr ctxt, const xmlChar *newtag) {
+ int i;
+
+ if (ctxt->options & HTML_PARSE_NOIMPLIED)
+ return;
if (!htmlOmittedDefaultValue)
return;
if (xmlStrEqual(newtag, BAD_CAST"html"))
@@ -1314,24 +1458,31 @@
}
if ((xmlStrEqual(newtag, BAD_CAST"body")) || (xmlStrEqual(newtag, BAD_CAST"head")))
return;
- if ((ctxt->nameNr <= 1) &&
+ if ((ctxt->nameNr <= 1) &&
((xmlStrEqual(newtag, BAD_CAST"script")) ||
(xmlStrEqual(newtag, BAD_CAST"style")) ||
(xmlStrEqual(newtag, BAD_CAST"meta")) ||
(xmlStrEqual(newtag, BAD_CAST"link")) ||
(xmlStrEqual(newtag, BAD_CAST"title")) ||
(xmlStrEqual(newtag, BAD_CAST"base")))) {
- /*
- * dropped OBJECT ... i you put it first BODY will be
- * assumed !
- */
- htmlnamePush(ctxt, BAD_CAST"head");
- if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
- ctxt->sax->startElement(ctxt->userData, BAD_CAST"head", NULL);
+ if (ctxt->html >= 3) {
+ /* we already saw or generated an <head> before */
+ return;
+ }
+ /*
+ * dropped OBJECT ... i you put it first BODY will be
+ * assumed !
+ */
+ htmlnamePush(ctxt, BAD_CAST"head");
+ if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
+ ctxt->sax->startElement(ctxt->userData, BAD_CAST"head", NULL);
} else if ((!xmlStrEqual(newtag, BAD_CAST"noframes")) &&
(!xmlStrEqual(newtag, BAD_CAST"frame")) &&
(!xmlStrEqual(newtag, BAD_CAST"frameset"))) {
- int i;
+ if (ctxt->html >= 10) {
+ /* we already saw or generated a <body> before */
+ return;
+ }
for (i = 0;i < ctxt->nameNr;i++) {
if (xmlStrEqual(ctxt->nameTab[i], BAD_CAST"body")) {
return;
@@ -1340,7 +1491,7 @@
return;
}
}
-
+
htmlnamePush(ctxt, BAD_CAST"body");
if ((ctxt->sax != NULL) && (ctxt->sax->startElement != NULL))
ctxt->sax->startElement(ctxt->userData, BAD_CAST"body", NULL);
@@ -1402,12 +1553,12 @@
unsigned int i;
if (name == NULL)
- return(0);
+ return(0);
/*
* all script attributes start with 'on'
*/
if ((name[0] != 'o') || (name[1] != 'n'))
- return(0);
+ return(0);
for (i = 0;
i < sizeof(htmlScriptAttributes)/sizeof(htmlScriptAttributes[0]);
i++) {
@@ -1419,7 +1570,7 @@
/************************************************************************
* *
- * The list of HTML predefined entities *
+ * The list of HTML predefined entities *
* *
************************************************************************/
@@ -1833,7 +1984,7 @@
if (inend - in < trailing) {
break;
- }
+ }
for ( ; trailing; trailing--) {
if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
@@ -2023,7 +2174,7 @@
* *
************************************************************************/
/*
- * all tags allowing pc data from the html 4.01 loose dtd
+ * all tags allowing pc data from the html 4.01 loose dtd
* NOTE: it might be more apropriate to integrate this information
* into the html40ElementTable array but I don't want to risk any
* binary incomptibility
@@ -2083,7 +2234,7 @@
if (lastChild == NULL) {
if ((ctxt->node->type != XML_ELEMENT_NODE) &&
(ctxt->node->content != NULL)) return(0);
- /* keep ws in constructs like ...<b> </b>...
+ /* keep ws in constructs like ...<b> </b>...
for all tags "b" allowing PCDATA */
for ( i = 0; i < sizeof(allowPCData)/sizeof(allowPCData[0]); i++ ) {
if ( xmlStrEqual(ctxt->name, BAD_CAST allowPCData[i]) ) {
@@ -2093,7 +2244,7 @@
} else if (xmlNodeIsText(lastChild)) {
return(0);
} else {
- /* keep ws in constructs like <p><b>xy</b> <i>z</i><p>
+ /* keep ws in constructs like <p><b>xy</b> <i>z</i><p>
for all tags "p" allowing PCDATA */
for ( i = 0; i < sizeof(allowPCData)/sizeof(allowPCData[0]); i++ ) {
if ( xmlStrEqual(lastChild->name, BAD_CAST allowPCData[i]) ) {
@@ -2133,7 +2284,7 @@
cur->intSubset = NULL;
cur->doc = cur;
cur->name = NULL;
- cur->children = NULL;
+ cur->children = NULL;
cur->extSubset = NULL;
cur->oldNs = NULL;
cur->encoding = NULL;
@@ -2201,18 +2352,19 @@
xmlChar loc[HTML_PARSER_BUFFER_SIZE];
if (!IS_ASCII_LETTER(CUR) && (CUR != '_') &&
- (CUR != ':')) return(NULL);
+ (CUR != ':') && (CUR != '.')) return(NULL);
while ((i < HTML_PARSER_BUFFER_SIZE) &&
((IS_ASCII_LETTER(CUR)) || (IS_ASCII_DIGIT(CUR)) ||
- (CUR == ':') || (CUR == '-') || (CUR == '_'))) {
+ (CUR == ':') || (CUR == '-') || (CUR == '_') ||
+ (CUR == '.'))) {
if ((CUR >= 'A') && (CUR <= 'Z')) loc[i] = CUR + 0x20;
else loc[i] = CUR;
i++;
-
+
NEXT;
}
-
+
return(xmlDictLookup(ctxt->dict, loc, i));
}
@@ -2235,7 +2387,7 @@
if (!IS_ASCII_LETTER(NXT(1)) && (NXT(1) != '_') &&
(NXT(1) != ':')) return(NULL);
-
+
while ((i < HTML_PARSER_BUFFER_SIZE) &&
((IS_ASCII_LETTER(NXT(1+i))) || (IS_ASCII_DIGIT(NXT(1+i))) ||
(NXT(1+i) == ':') || (NXT(1+i) == '-') || (NXT(1+i) == '_'))) {
@@ -2243,7 +2395,7 @@
else loc[i] = NXT(1+i);
i++;
}
-
+
return(xmlDictLookup(ctxt->dict, loc, i));
}
@@ -2311,7 +2463,7 @@
while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
((IS_LETTER(c)) || (IS_DIGIT(c)) ||
(c == '.') || (c == '-') ||
- (c == '_') || (c == ':') ||
+ (c == '_') || (c == ':') ||
(IS_COMBINING(c)) ||
(IS_EXTENDER(c)))) {
if (count++ > 100) {
@@ -2330,7 +2482,7 @@
* htmlParseHTMLAttribute:
* @ctxt: an HTML parser context
* @stop: a char stop value
- *
+ *
* parse an HTML attribute value till the stop (quote), if
* stop is 0 then it stops at the first space
*
@@ -2375,13 +2527,13 @@
{ *out++ =((c >> 6) & 0x1F) | 0xC0; bits= 0; }
else if (c < 0x10000)
{ *out++ =((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else
+ else
{ *out++ =((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
+
for ( ; bits >= 0; bits-= 6) {
*out++ = ((c >> bits) & 0x3F) | 0x80;
}
-
+
if (out - buffer > buffer_size - 100) {
int indx = out - buffer;
@@ -2427,9 +2579,9 @@
{ *out++ =((c >> 6) & 0x1F) | 0xC0; bits= 0; }
else if (c < 0x10000)
{ *out++ =((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else
+ else
{ *out++ =((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
+
for ( ; bits >= 0; bits-= 6) {
*out++ = ((c >> bits) & 0x3F) | 0x80;
}
@@ -2452,16 +2604,16 @@
{ *out++ =((c >> 6) & 0x1F) | 0xC0; bits= 0; }
else if (c < 0x10000)
{ *out++ =((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else
+ else
{ *out++ =((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
+
for ( ; bits >= 0; bits-= 6) {
*out++ = ((c >> bits) & 0x3F) | 0x80;
}
NEXT;
}
}
- *out++ = 0;
+ *out = 0;
return(buffer);
}
@@ -2522,7 +2674,7 @@
* parse a value for an attribute
* Note: the parser won't do substitution of entities here, this
* will be handled later in xmlStringGetNodeList, unless it was
- * asked for ctxt->replaceEntities != 0
+ * asked for ctxt->replaceEntities != 0
*
* Returns the AttValue parsed or NULL.
*/
@@ -2563,7 +2715,7 @@
/**
* htmlParseSystemLiteral:
* @ctxt: an HTML parser context
- *
+ *
* parse an HTML Literal
*
* [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
@@ -2604,7 +2756,7 @@
htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_STARTED,
" or ' expected\n", NULL, NULL);
}
-
+
return(ret);
}
@@ -2653,7 +2805,7 @@
htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_STARTED,
"PubidLiteral \" or ' expected\n", NULL, NULL);
}
-
+
return(ret);
}
@@ -2700,8 +2852,8 @@
* CDATA.
*/
if (ctxt->recovery) {
- if (xmlStrncasecmp(ctxt->name, ctxt->input->cur+2,
- xmlStrlen(ctxt->name)) == 0)
+ if (xmlStrncasecmp(ctxt->name, ctxt->input->cur+2,
+ xmlStrlen(ctxt->name)) == 0)
{
break; /* while */
} else {
@@ -2711,7 +2863,7 @@
}
} else {
if (((NXT(2) >= 'A') && (NXT(2) <= 'Z')) ||
- ((NXT(2) >= 'a') && (NXT(2) <= 'z')))
+ ((NXT(2) >= 'a') && (NXT(2) <= 'z')))
{
break; /* while */
}
@@ -2735,9 +2887,11 @@
}
if ((!(IS_CHAR_CH(cur))) && (!((cur == 0) && (ctxt->progressive)))) {
- htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
- "Invalid char in CDATA 0x%X\n", cur);
- NEXT;
+ htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
+ "Invalid char in CDATA 0x%X\n", cur);
+ if (ctxt->input->cur < ctxt->input->end) {
+ NEXT;
+ }
}
if ((nbchar != 0) && (ctxt->sax != NULL) && (!ctxt->disableSAX)) {
@@ -2773,7 +2927,7 @@
SHRINK;
cur = CUR_CHAR(l);
while (((cur != '<') || (ctxt->token == '<')) &&
- ((cur != '&') || (ctxt->token == '&')) &&
+ ((cur != '&') || (ctxt->token == '&')) &&
(cur != 0)) {
if (!(IS_CHAR(cur))) {
htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
@@ -2999,7 +3153,7 @@
}
xmlFree(buf);
} else {
- htmlParseErr(ctxt, XML_ERR_PI_NOT_STARTED,
+ htmlParseErr(ctxt, XML_ERR_PI_NOT_STARTED,
"PI is not started correctly", NULL, NULL);
}
ctxt->instate = state;
@@ -3115,7 +3269,7 @@
((NXT(2) == 'x') || NXT(2) == 'X')) {
SKIP(3);
while (CUR != ';') {
- if ((CUR >= '0') && (CUR <= '9'))
+ if ((CUR >= '0') && (CUR <= '9'))
val = val * 16 + (CUR - '0');
else if ((CUR >= 'a') && (CUR <= 'f'))
val = val * 16 + (CUR - 'a') + 10;
@@ -3123,7 +3277,7 @@
val = val * 16 + (CUR - 'A') + 10;
else {
htmlParseErr(ctxt, XML_ERR_INVALID_HEX_CHARREF,
- "htmlParseCharRef: missing semicolumn\n",
+ "htmlParseCharRef: missing semicolon\n",
NULL, NULL);
break;
}
@@ -3134,11 +3288,11 @@
} else if ((CUR == '&') && (NXT(1) == '#')) {
SKIP(2);
while (CUR != ';') {
- if ((CUR >= '0') && (CUR <= '9'))
+ if ((CUR >= '0') && (CUR <= '9'))
val = val * 10 + (CUR - '0');
else {
htmlParseErr(ctxt, XML_ERR_INVALID_DEC_CHARREF,
- "htmlParseCharRef: missing semicolumn\n",
+ "htmlParseCharRef: missing semicolon\n",
NULL, NULL);
break;
}
@@ -3170,7 +3324,7 @@
*
* parse a DOCTYPE declaration
*
- * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
+ * [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
* ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
*/
@@ -3274,11 +3428,6 @@
NEXT;
SKIP_BLANKS;
val = htmlParseAttValue(ctxt);
- } else if (htmlIsBooleanAttr(name)) {
- /*
- * assume a minimized attribute
- */
- val = xmlStrdup(name);
}
*value = val;
@@ -3299,10 +3448,11 @@
htmlCheckEncoding(htmlParserCtxtPtr ctxt, const xmlChar *attvalue) {
const xmlChar *encoding;
- if ((ctxt == NULL) || (attvalue == NULL))
+ if ((ctxt == NULL) || (attvalue == NULL) ||
+ (ctxt->options & HTML_PARSE_IGNORE_ENC))
return;
- /* do not change encoding */
+ /* do not change encoding */
if (ctxt->input->encoding != NULL)
return;
@@ -3329,7 +3479,7 @@
* registered set of known encodings
*/
if (enc != XML_CHAR_ENCODING_ERROR) {
- if (((enc == XML_CHAR_ENCODING_UTF16LE) ||
+ if (((enc == XML_CHAR_ENCODING_UTF16LE) ||
(enc == XML_CHAR_ENCODING_UTF16BE) ||
(enc == XML_CHAR_ENCODING_UCS4LE) ||
(enc == XML_CHAR_ENCODING_UCS4BE)) &&
@@ -3351,7 +3501,9 @@
xmlSwitchToEncoding(ctxt, handler);
ctxt->charset = XML_CHAR_ENCODING_UTF8;
} else {
- ctxt->errNo = XML_ERR_UNSUPPORTED_ENCODING;
+ htmlParseErr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
+ "htmlCheckEncoding: unknown encoding %s\n",
+ encoding, NULL);
}
}
@@ -3377,6 +3529,8 @@
}
ctxt->input->base =
ctxt->input->cur = ctxt->input->buf->buffer->content;
+ ctxt->input->end =
+ &ctxt->input->base[ctxt->input->buf->buffer->use];
}
}
}
@@ -3417,7 +3571,7 @@
/**
* htmlParseStartTag:
* @ctxt: an HTML parser context
- *
+ *
* parse a start of tag either for rule element or
* EmptyElement. In both case we don't parse the tag closing chars.
*
@@ -3446,6 +3600,8 @@
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);
@@ -3464,7 +3620,8 @@
"htmlParseStartTag: invalid element name\n",
NULL, NULL);
/* Dump the bogus tag like browsers do */
- while ((IS_CHAR_CH(CUR)) && (CUR != '>'))
+ while ((IS_CHAR_CH(CUR)) && (CUR != '>') &&
+ (ctxt->instate != XML_PARSER_EOF))
NEXT;
return -1;
}
@@ -3492,7 +3649,7 @@
discardtag = 1;
ctxt->depth++;
}
- if ((ctxt->nameNr != 1) &&
+ if ((ctxt->nameNr != 1) &&
(xmlStrEqual(name, BAD_CAST"head"))) {
htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
"htmlParseStartTag: misplaced <head> tag\n",
@@ -3520,7 +3677,7 @@
*/
SKIP_BLANKS;
while ((IS_CHAR_CH(CUR)) &&
- (CUR != '>') &&
+ (CUR != '>') &&
((CUR != '/') || (NXT(1) != '>'))) {
long cons = ctxt->nbChars;
@@ -3744,7 +3901,7 @@
/**
* htmlParseReference:
* @ctxt: an HTML parser context
- *
+ *
* parse and handle entity references in content,
* this will end-up in a call to character() since this is either a
* CharRef, or a predefined entity.
@@ -3768,7 +3925,7 @@
else if (c < 0x800) { out[i++]=((c >> 6) & 0x1F) | 0xC0; bits= 0; }
else if (c < 0x10000) { out[i++]=((c >> 12) & 0x0F) | 0xE0; bits= 6; }
else { out[i++]=((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
+
for ( ; bits >= 0; bits-= 6) {
out[i++]= ((c >> bits) & 0x3F) | 0x80;
}
@@ -3803,9 +3960,9 @@
{ out[i++]=((c >> 6) & 0x1F) | 0xC0; bits= 0; }
else if (c < 0x10000)
{ out[i++]=((c >> 12) & 0x0F) | 0xE0; bits= 6; }
- else
+ else
{ out[i++]=((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
+
for ( ; bits >= 0; bits-= 6) {
out[i++]= ((c >> bits) & 0x3F) | 0x80;
}
@@ -3823,6 +3980,7 @@
* @ctxt: an HTML parser context
*
* Parse a content: comment, sub-element, reference or text.
+ * Kept for compatibility with old code
*/
static void
@@ -3837,6 +3995,10 @@
long cons = ctxt->nbChars;
GROW;
+
+ if (ctxt->instate == XML_PARSER_EOF)
+ break;
+
/*
* Our tag or one of it's parent or children is ending.
*/
@@ -3859,7 +4021,7 @@
"htmlParseStartTag: invalid element name\n",
NULL, NULL);
/* Dump the bogus tag like browsers do */
- while ((IS_CHAR_CH(CUR)) && (CUR != '>'))
+ while ((IS_CHAR_CH(CUR)) && (CUR != '>'))
NEXT;
if (currentNode != NULL)
@@ -3872,7 +4034,7 @@
htmlAutoClose(ctxt, name);
continue;
}
- }
+ }
}
/*
@@ -3931,7 +4093,7 @@
/*
* Fourth case : a reference. If if has not been resolved,
- * parsing returns it's Name, create the node
+ * parsing returns it's Name, create the node
*/
else if (CUR == '&') {
htmlParseReference(ctxt);
@@ -3967,23 +4129,11 @@
}
/**
- * htmlParseContent:
- * @ctxt: an HTML parser context
- *
- * Parse a content: comment, sub-element, reference or text.
- */
-
-void
-__htmlParseContent(void *ctxt) {
- if (ctxt != NULL)
- htmlParseContent((htmlParserCtxtPtr) ctxt);
-}
-
-/**
* htmlParseElement:
* @ctxt: an HTML parser context
*
* parse an HTML element, this is highly recursive
+ * this is kept for compatibility with previous code versions
*
* [39] element ::= EmptyElemTag | STag content ETag
*
@@ -4005,6 +4155,10 @@
"htmlParseElement: context error\n", NULL, NULL);
return;
}
+
+ if (ctxt->instate == XML_PARSER_EOF)
+ return;
+
/* Capture start position */
if (ctxt->record_info) {
node_info.begin_pos = ctxt->input->consumed +
@@ -4049,10 +4203,10 @@
/*
* end of parsing of this node.
*/
- if (xmlStrEqual(name, ctxt->name)) {
+ if (xmlStrEqual(name, ctxt->name)) {
nodePop(ctxt);
htmlnamePop(ctxt);
- }
+ }
/*
* Capture end position and add node
@@ -4086,8 +4240,8 @@
oldptr = ctxt->input->cur;
htmlParseContent(ctxt);
if (oldptr==ctxt->input->cur) break;
- if (ctxt->nameNr < depth) break;
- }
+ if (ctxt->nameNr < depth) break;
+ }
/*
* Capture end position and add node
@@ -4107,10 +4261,305 @@
xmlFree(currentNode);
}
+static void
+htmlParserFinishElementParsing(htmlParserCtxtPtr ctxt) {
+ /*
+ * Capture end position and add node
+ */
+ if ( ctxt->node != NULL && ctxt->record_info ) {
+ ctxt->nodeInfo->end_pos = ctxt->input->consumed +
+ (CUR_PTR - ctxt->input->base);
+ ctxt->nodeInfo->end_line = ctxt->input->line;
+ ctxt->nodeInfo->node = ctxt->node;
+ xmlParserAddNodeInfo(ctxt, ctxt->nodeInfo);
+ htmlNodeInfoPop(ctxt);
+ }
+ if (!IS_CHAR_CH(CUR)) {
+ htmlAutoCloseOnEnd(ctxt);
+ }
+}
+
+/**
+ * htmlParseElementInternal:
+ * @ctxt: an HTML parser context
+ *
+ * parse an HTML element, new version, non recursive
+ *
+ * [39] element ::= EmptyElemTag | STag content ETag
+ *
+ * [41] Attribute ::= Name Eq AttValue
+ */
+
+static void
+htmlParseElementInternal(htmlParserCtxtPtr ctxt) {
+ const xmlChar *name;
+ const htmlElemDesc * info;
+ htmlParserNodeInfo node_info;
+ int failed;
+
+ if ((ctxt == NULL) || (ctxt->input == NULL)) {
+ htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+ "htmlParseElementInternal: context error\n", NULL, NULL);
+ return;
+ }
+
+ if (ctxt->instate == XML_PARSER_EOF)
+ return;
+
+ /* Capture start position */
+ if (ctxt->record_info) {
+ node_info.begin_pos = ctxt->input->consumed +
+ (CUR_PTR - ctxt->input->base);
+ node_info.begin_line = ctxt->input->line;
+ }
+
+ failed = htmlParseStartTag(ctxt);
+ name = ctxt->name;
+ if ((failed == -1) || (name == NULL)) {
+ if (CUR == '>')
+ NEXT;
+ return;
+ }
+
+ /*
+ * Lookup the info for that element.
+ */
+ info = htmlTagLookup(name);
+ if (info == NULL) {
+ htmlParseErr(ctxt, XML_HTML_UNKNOWN_TAG,
+ "Tag %s invalid\n", name, NULL);
+ }
+
+ /*
+ * Check for an Empty Element labeled the XML/SGML way
+ */
+ if ((CUR == '/') && (NXT(1) == '>')) {
+ SKIP(2);
+ if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
+ ctxt->sax->endElement(ctxt->userData, name);
+ htmlnamePop(ctxt);
+ return;
+ }
+
+ if (CUR == '>') {
+ NEXT;
+ } else {
+ htmlParseErr(ctxt, XML_ERR_GT_REQUIRED,
+ "Couldn't find end of Start Tag %s\n", name, NULL);
+
+ /*
+ * end of parsing of this node.
+ */
+ if (xmlStrEqual(name, ctxt->name)) {
+ nodePop(ctxt);
+ htmlnamePop(ctxt);
+ }
+
+ if (ctxt->record_info)
+ htmlNodeInfoPush(ctxt, &node_info);
+ htmlParserFinishElementParsing(ctxt);
+ return;
+ }
+
+ /*
+ * Check for an Empty Element from DTD definition
+ */
+ if ((info != NULL) && (info->empty)) {
+ if ((ctxt->sax != NULL) && (ctxt->sax->endElement != NULL))
+ ctxt->sax->endElement(ctxt->userData, name);
+ htmlnamePop(ctxt);
+ return;
+ }
+
+ if (ctxt->record_info)
+ htmlNodeInfoPush(ctxt, &node_info);
+}
+
+/**
+ * htmlParseContentInternal:
+ * @ctxt: an HTML parser context
+ *
+ * Parse a content: comment, sub-element, reference or text.
+ * New version for non recursive htmlParseElementInternal
+ */
+
+static void
+htmlParseContentInternal(htmlParserCtxtPtr ctxt) {
+ xmlChar *currentNode;
+ int depth;
+ const xmlChar *name;
+
+ currentNode = xmlStrdup(ctxt->name);
+ depth = ctxt->nameNr;
+ while (1) {
+ long cons = ctxt->nbChars;
+
+ GROW;
+
+ if (ctxt->instate == XML_PARSER_EOF)
+ break;
+
+ /*
+ * Our tag or one of it's parent or children is ending.
+ */
+ if ((CUR == '<') && (NXT(1) == '/')) {
+ if (htmlParseEndTag(ctxt) &&
+ ((currentNode != NULL) || (ctxt->nameNr == 0))) {
+ if (currentNode != NULL)
+ xmlFree(currentNode);
+
+ currentNode = xmlStrdup(ctxt->name);
+ depth = ctxt->nameNr;
+ }
+ continue; /* while */
+ }
+
+ else if ((CUR == '<') &&
+ ((IS_ASCII_LETTER(NXT(1))) ||
+ (NXT(1) == '_') || (NXT(1) == ':'))) {
+ name = htmlParseHTMLName_nonInvasive(ctxt);
+ if (name == NULL) {
+ htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
+ "htmlParseStartTag: invalid element name\n",
+ NULL, NULL);
+ /* Dump the bogus tag like browsers do */
+ while ((IS_CHAR_CH(CUR)) && (CUR != '>'))
+ NEXT;
+
+ htmlParserFinishElementParsing(ctxt);
+ if (currentNode != NULL)
+ xmlFree(currentNode);
+
+ currentNode = xmlStrdup(ctxt->name);
+ depth = ctxt->nameNr;
+ continue;
+ }
+
+ if (ctxt->name != NULL) {
+ if (htmlCheckAutoClose(name, ctxt->name) == 1) {
+ htmlAutoClose(ctxt, name);
+ continue;
+ }
+ }
+ }
+
+ /*
+ * Has this node been popped out during parsing of
+ * the next element
+ */
+ if ((ctxt->nameNr > 0) && (depth >= ctxt->nameNr) &&
+ (!xmlStrEqual(currentNode, ctxt->name)))
+ {
+ htmlParserFinishElementParsing(ctxt);
+ if (currentNode != NULL) xmlFree(currentNode);
+
+ currentNode = xmlStrdup(ctxt->name);
+ depth = ctxt->nameNr;
+ continue;
+ }
+
+ if ((CUR != 0) && ((xmlStrEqual(currentNode, BAD_CAST"script")) ||
+ (xmlStrEqual(currentNode, BAD_CAST"style")))) {
+ /*
+ * Handle SCRIPT/STYLE separately
+ */
+ htmlParseScript(ctxt);
+ } else {
+ /*
+ * Sometimes DOCTYPE arrives in the middle of the document
+ */
+ if ((CUR == '<') && (NXT(1) == '!') &&
+ (UPP(2) == 'D') && (UPP(3) == 'O') &&
+ (UPP(4) == 'C') && (UPP(5) == 'T') &&
+ (UPP(6) == 'Y') && (UPP(7) == 'P') &&
+ (UPP(8) == 'E')) {
+ htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
+ "Misplaced DOCTYPE declaration\n",
+ BAD_CAST "DOCTYPE" , NULL);
+ htmlParseDocTypeDecl(ctxt);
+ }
+
+ /*
+ * First case : a comment
+ */
+ if ((CUR == '<') && (NXT(1) == '!') &&
+ (NXT(2) == '-') && (NXT(3) == '-')) {
+ htmlParseComment(ctxt);
+ }
+
+ /*
+ * Second case : a Processing Instruction.
+ */
+ else if ((CUR == '<') && (NXT(1) == '?')) {
+ htmlParsePI(ctxt);
+ }
+
+ /*
+ * Third case : a sub-element.
+ */
+ else if (CUR == '<') {
+ htmlParseElementInternal(ctxt);
+ if (currentNode != NULL) xmlFree(currentNode);
+
+ currentNode = xmlStrdup(ctxt->name);
+ depth = ctxt->nameNr;
+ }
+
+ /*
+ * Fourth case : a reference. If if has not been resolved,
+ * parsing returns it's Name, create the node
+ */
+ else if (CUR == '&') {
+ htmlParseReference(ctxt);
+ }
+
+ /*
+ * Fifth case : end of the resource
+ */
+ else if (CUR == 0) {
+ htmlAutoCloseOnEnd(ctxt);
+ break;
+ }
+
+ /*
+ * Last case, text. Note that References are handled directly.
+ */
+ else {
+ htmlParseCharData(ctxt);
+ }
+
+ if (cons == ctxt->nbChars) {
+ if (ctxt->node != NULL) {
+ htmlParseErr(ctxt, XML_ERR_INTERNAL_ERROR,
+ "detected an error in element content\n",
+ NULL, NULL);
+ }
+ break;
+ }
+ }
+ GROW;
+ }
+ if (currentNode != NULL) xmlFree(currentNode);
+}
+
+/**
+ * htmlParseContent:
+ * @ctxt: an HTML parser context
+ *
+ * Parse a content: comment, sub-element, reference or text.
+ * This is the entry point when called from parser.c
+ */
+
+void
+__htmlParseContent(void *ctxt) {
+ if (ctxt != NULL)
+ htmlParseContentInternal((htmlParserCtxtPtr) ctxt);
+}
+
/**
* htmlParseDocument:
* @ctxt: an HTML parser context
- *
+ *
* parse an HTML document (and build a tree if using the standard SAX
* interface).
*
@@ -4134,6 +4583,7 @@
return(XML_ERR_INTERNAL_ERROR);
}
ctxt->html = 1;
+ ctxt->linenumbers = 1;
GROW;
/*
* SAX: beginning of the document processing.
@@ -4163,7 +4613,7 @@
*/
SKIP_BLANKS;
if (CUR == 0) {
- htmlParseErr(ctxt, XML_ERR_DOCUMENT_EMPTY,
+ htmlParseErr(ctxt, XML_ERR_DOCUMENT_EMPTY,
"Document is empty\n", NULL, NULL);
}
@@ -4202,15 +4652,15 @@
while (((CUR == '<') && (NXT(1) == '!') &&
(NXT(2) == '-') && (NXT(3) == '-')) ||
((CUR == '<') && (NXT(1) == '?'))) {
- htmlParseComment(ctxt);
- htmlParsePI(ctxt);
+ htmlParseComment(ctxt);
+ htmlParsePI(ctxt);
SKIP_BLANKS;
- }
+ }
/*
* Time to start parsing the tree itself
*/
- htmlParseContent(ctxt);
+ htmlParseContentInternal(ctxt);
/*
* autoclose
@@ -4225,11 +4675,11 @@
if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
ctxt->sax->endDocument(ctxt->userData);
- if (ctxt->myDoc != NULL) {
+ if ((!(ctxt->options & HTML_PARSE_NODEFDTD)) && (ctxt->myDoc != NULL)) {
dtd = xmlGetIntSubset(ctxt->myDoc);
if (dtd == NULL)
- ctxt->myDoc->intSubset =
- xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "html",
+ ctxt->myDoc->intSubset =
+ xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "html",
BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
}
@@ -4275,7 +4725,7 @@
memset(sax, 0, sizeof(htmlSAXHandler));
/* Allocate the Input stack */
- ctxt->inputTab = (htmlParserInputPtr *)
+ ctxt->inputTab = (htmlParserInputPtr *)
xmlMalloc(5 * sizeof(htmlParserInputPtr));
if (ctxt->inputTab == NULL) {
htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
@@ -4313,7 +4763,7 @@
if (ctxt->nameTab == NULL) {
htmlErrMemory(NULL, "htmlInitParserCtxt: out of memory\n");
ctxt->nameNr = 0;
- ctxt->nameMax = 10;
+ ctxt->nameMax = 0;
ctxt->name = NULL;
ctxt->nodeNr = 0;
ctxt->nodeMax = 0;
@@ -4327,6 +4777,10 @@
ctxt->nameMax = 10;
ctxt->name = NULL;
+ ctxt->nodeInfoTab = NULL;
+ ctxt->nodeInfoNr = 0;
+ ctxt->nodeInfoMax = 0;
+
if (sax == NULL) ctxt->sax = (xmlSAXHandlerPtr) &htmlDefaultSAXHandler;
else {
ctxt->sax = sax;
@@ -4473,7 +4927,7 @@
xmlSwitchEncoding(ctxt, enc);
if (ctxt->errNo == XML_ERR_UNSUPPORTED_ENCODING) {
htmlParseErr(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
- "Unsupported encoding %s\n",
+ "Unsupported encoding %s\n",
(const xmlChar *) encoding, NULL);
}
} else {
@@ -4496,7 +4950,7 @@
#ifdef LIBXML_PUSH_ENABLED
/************************************************************************
* *
- * Progressive parsing interfaces *
+ * Progressive parsing interfaces *
* *
************************************************************************/
@@ -4520,85 +4974,190 @@
*/
static int
htmlParseLookupSequence(htmlParserCtxtPtr ctxt, xmlChar first,
- xmlChar next, xmlChar third, int iscomment) {
+ xmlChar next, xmlChar third, int iscomment,
+ int ignoreattrval)
+{
int base, len;
htmlParserInputPtr in;
const xmlChar *buf;
int incomment = 0;
+ int invalue = 0;
+ char valdellim = 0x0;
in = ctxt->input;
- if (in == NULL) return(-1);
+ if (in == NULL)
+ return (-1);
+
base = in->cur - in->base;
- if (base < 0) return(-1);
+ if (base < 0)
+ return (-1);
+
if (ctxt->checkIndex > base)
base = ctxt->checkIndex;
+
if (in->buf == NULL) {
- buf = in->base;
- len = in->length;
+ buf = in->base;
+ len = in->length;
} else {
- buf = in->buf->buffer->content;
- len = in->buf->buffer->use;
+ buf = in->buf->buffer->content;
+ len = in->buf->buffer->use;
}
+
/* take into account the sequence length */
- if (third) len -= 2;
- else if (next) len --;
- for (;base < len;base++) {
- if (!incomment && (base + 4 < len) && !iscomment) {
- if ((buf[base] == '<') && (buf[base + 1] == '!') &&
- (buf[base + 2] == '-') && (buf[base + 3] == '-')) {
- incomment = 1;
- /* do not increment past <! - some people use <!--> */
- base += 2;
- }
- }
- if (incomment) {
- if (base + 3 > len)
- return(-1);
- if ((buf[base] == '-') && (buf[base + 1] == '-') &&
- (buf[base + 2] == '>')) {
- incomment = 0;
- base += 2;
- }
- continue;
- }
+ if (third)
+ len -= 2;
+ else if (next)
+ len--;
+ for (; base < len; base++) {
+ if ((!incomment) && (base + 4 < len) && (!iscomment)) {
+ if ((buf[base] == '<') && (buf[base + 1] == '!') &&
+ (buf[base + 2] == '-') && (buf[base + 3] == '-')) {
+ incomment = 1;
+ /* do not increment past <! - some people use <!--> */
+ base += 2;
+ }
+ }
+ if (ignoreattrval) {
+ if (buf[base] == '"' || buf[base] == '\'') {
+ if (invalue) {
+ if (buf[base] == valdellim) {
+ invalue = 0;
+ continue;
+ }
+ } else {
+ valdellim = buf[base];
+ invalue = 1;
+ continue;
+ }
+ } else if (invalue) {
+ continue;
+ }
+ }
+ if (incomment) {
+ if (base + 3 > len)
+ return (-1);
+ if ((buf[base] == '-') && (buf[base + 1] == '-') &&
+ (buf[base + 2] == '>')) {
+ incomment = 0;
+ base += 2;
+ }
+ continue;
+ }
if (buf[base] == first) {
- if (third != 0) {
- if ((buf[base + 1] != next) ||
- (buf[base + 2] != third)) continue;
- } else if (next != 0) {
- if (buf[base + 1] != next) continue;
- }
- ctxt->checkIndex = 0;
+ if (third != 0) {
+ if ((buf[base + 1] != next) || (buf[base + 2] != third))
+ continue;
+ } else if (next != 0) {
+ if (buf[base + 1] != next)
+ continue;
+ }
+ ctxt->checkIndex = 0;
#ifdef DEBUG_PUSH
- if (next == 0)
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c' found at %d\n",
- first, base);
- else if (third == 0)
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c%c' found at %d\n",
- first, next, base);
- else
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c%c%c' found at %d\n",
- first, next, third, base);
+ if (next == 0)
+ xmlGenericError(xmlGenericErrorContext,
+ "HPP: lookup '%c' found at %d\n",
+ first, base);
+ else if (third == 0)
+ xmlGenericError(xmlGenericErrorContext,
+ "HPP: lookup '%c%c' found at %d\n",
+ first, next, base);
+ else
+ xmlGenericError(xmlGenericErrorContext,
+ "HPP: lookup '%c%c%c' found at %d\n",
+ first, next, third, base);
#endif
- return(base - (in->cur - in->base));
- }
+ return (base - (in->cur - in->base));
+ }
}
- ctxt->checkIndex = base;
+ if ((!incomment) && (!invalue))
+ ctxt->checkIndex = base;
#ifdef DEBUG_PUSH
if (next == 0)
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c' failed\n", first);
+ xmlGenericError(xmlGenericErrorContext,
+ "HPP: lookup '%c' failed\n", first);
else if (third == 0)
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c%c' failed\n", first, next);
- else
- xmlGenericError(xmlGenericErrorContext,
- "HPP: lookup '%c%c%c' failed\n", first, next, third);
+ xmlGenericError(xmlGenericErrorContext,
+ "HPP: lookup '%c%c' failed\n", first, next);
+ else
+ xmlGenericError(xmlGenericErrorContext,
+ "HPP: lookup '%c%c%c' failed\n", first, next,
+ third);
#endif
- return(-1);
+ return (-1);
+}
+
+/**
+ * htmlParseLookupChars:
+ * @ctxt: an HTML parser context
+ * @stop: Array of chars, which stop the lookup.
+ * @stopLen: Length of stop-Array
+ *
+ * Try to find if any char of the stop-Array is available in the input
+ * stream.
+ * This function has a side effect of (possibly) incrementing ctxt->checkIndex
+ * to avoid rescanning sequences of bytes, it DOES change the state of the
+ * parser, do not use liberally.
+ *
+ * Returns the index to the current parsing point if a stopChar
+ * is available, -1 otherwise.
+ */
+static int
+htmlParseLookupChars(htmlParserCtxtPtr ctxt, const xmlChar * stop,
+ int stopLen)
+{
+ int base, len;
+ htmlParserInputPtr in;
+ const xmlChar *buf;
+ int incomment = 0;
+ int i;
+
+ in = ctxt->input;
+ if (in == NULL)
+ return (-1);
+
+ base = in->cur - in->base;
+ if (base < 0)
+ return (-1);
+
+ if (ctxt->checkIndex > base)
+ base = ctxt->checkIndex;
+
+ if (in->buf == NULL) {
+ buf = in->base;
+ len = in->length;
+ } else {
+ buf = in->buf->buffer->content;
+ len = in->buf->buffer->use;
+ }
+
+ for (; base < len; base++) {
+ if (!incomment && (base + 4 < len)) {
+ if ((buf[base] == '<') && (buf[base + 1] == '!') &&
+ (buf[base + 2] == '-') && (buf[base + 3] == '-')) {
+ incomment = 1;
+ /* do not increment past <! - some people use <!--> */
+ base += 2;
+ }
+ }
+ if (incomment) {
+ if (base + 3 > len)
+ return (-1);
+ if ((buf[base] == '-') && (buf[base + 1] == '-') &&
+ (buf[base + 2] == '>')) {
+ incomment = 0;
+ base += 2;
+ }
+ continue;
+ }
+ for (i = 0; i < stopLen; ++i) {
+ if (buf[base] == stop[i]) {
+ ctxt->checkIndex = 0;
+ return (base - (in->cur - in->base));
+ }
+ }
+ }
+ ctxt->checkIndex = base;
+ return (-1);
}
/**
@@ -4680,7 +5239,7 @@
avail = in->buf->buffer->use - (in->cur - in->base);
if ((avail == 0) && (terminate)) {
htmlAutoCloseOnEnd(ctxt);
- if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
+ if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
/*
* SAX: end of the document processing.
*/
@@ -4730,7 +5289,7 @@
(UPP(6) == 'Y') && (UPP(7) == 'P') &&
(UPP(8) == 'E')) {
if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
goto done;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
@@ -4763,7 +5322,7 @@
if ((cur == '<') && (next == '!') &&
(in->cur[2] == '-') && (in->cur[3] == '-')) {
if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '-', '-', '>', 1) < 0))
+ (htmlParseLookupSequence(ctxt, '-', '-', '>', 1, 1) < 0))
goto done;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
@@ -4773,7 +5332,7 @@
ctxt->instate = XML_PARSER_MISC;
} else if ((cur == '<') && (next == '?')) {
if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
goto done;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
@@ -4787,7 +5346,7 @@
(UPP(6) == 'Y') && (UPP(7) == 'P') &&
(UPP(8) == 'E')) {
if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
goto done;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
@@ -4816,14 +5375,14 @@
avail = in->length - (in->cur - in->base);
else
avail = in->buf->buffer->use - (in->cur - in->base);
- if (avail < 2)
+ if (avail < 2)
goto done;
cur = in->cur[0];
next = in->cur[1];
if ((cur == '<') && (next == '!') &&
(in->cur[2] == '-') && (in->cur[3] == '-')) {
if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '-', '-', '>', 1) < 0))
+ (htmlParseLookupSequence(ctxt, '-', '-', '>', 1, 1) < 0))
goto done;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
@@ -4833,7 +5392,7 @@
ctxt->instate = XML_PARSER_PROLOG;
} else if ((cur == '<') && (next == '?')) {
if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
goto done;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
@@ -4870,7 +5429,7 @@
if ((cur == '<') && (next == '!') &&
(in->cur[2] == '-') && (in->cur[3] == '-')) {
if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '-', '-', '>', 1) < 0))
+ (htmlParseLookupSequence(ctxt, '-', '-', '>', 1, 1) < 0))
goto done;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
@@ -4880,7 +5439,7 @@
ctxt->instate = XML_PARSER_EPILOG;
} else if ((cur == '<') && (next == '?')) {
if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
goto done;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
@@ -4930,7 +5489,7 @@
break;
}
if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
goto done;
failed = htmlParseStartTag(ctxt);
@@ -4977,10 +5536,10 @@
/*
* end of parsing of this node.
*/
- if (xmlStrEqual(name, ctxt->name)) {
+ if (xmlStrEqual(name, ctxt->name)) {
nodePop(ctxt);
htmlnamePop(ctxt);
- }
+ }
ctxt->instate = XML_PARSER_CONTENT;
#ifdef DEBUG_PUSH
@@ -5055,7 +5614,7 @@
int idx;
xmlChar val;
- idx = htmlParseLookupSequence(ctxt, '<', '/', 0, 0);
+ idx = htmlParseLookupSequence(ctxt, '<', '/', 0, 0, 0);
if (idx < 0)
goto done;
val = in->cur[idx + 2];
@@ -5082,7 +5641,7 @@
(UPP(6) == 'Y') && (UPP(7) == 'P') &&
(UPP(8) == 'E')) {
if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
goto done;
htmlParseErr(ctxt, XML_HTML_STRUCURE_ERROR,
"Misplaced DOCTYPE declaration\n",
@@ -5092,7 +5651,7 @@
(in->cur[2] == '-') && (in->cur[3] == '-')) {
if ((!terminate) &&
(htmlParseLookupSequence(
- ctxt, '-', '-', '>', 1) < 0))
+ ctxt, '-', '-', '>', 1, 1) < 0))
goto done;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
@@ -5102,7 +5661,7 @@
ctxt->instate = XML_PARSER_CONTENT;
} else if ((cur == '<') && (next == '?')) {
if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
goto done;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
@@ -5130,7 +5689,8 @@
break;
} else if (cur == '&') {
if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, ';', 0, 0, 0) < 0))
+ (htmlParseLookupChars(ctxt,
+ BAD_CAST "; >/", 4) < 0))
goto done;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
@@ -5146,7 +5706,7 @@
* data detection.
*/
if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '<', 0, 0, 0) < 0))
+ (htmlParseLookupChars(ctxt, BAD_CAST "<&", 2) < 0))
goto done;
ctxt->checkIndex = 0;
#ifdef DEBUG_PUSH
@@ -5172,7 +5732,7 @@
if (avail < 2)
goto done;
if ((!terminate) &&
- (htmlParseLookupSequence(ctxt, '>', 0, 0, 0) < 0))
+ (htmlParseLookupSequence(ctxt, '>', 0, 0, 0, 1) < 0))
goto done;
htmlParseEndTag(ctxt);
if (ctxt->nameNr == 0) {
@@ -5299,10 +5859,10 @@
}
}
-done:
+done:
if ((avail == 0) && (terminate)) {
htmlAutoCloseOnEnd(ctxt);
- if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
+ if ((ctxt->nameNr == 0) && (ctxt->instate != XML_PARSER_EOF)) {
/*
* SAX: end of the document processing.
*/
@@ -5317,8 +5877,8 @@
xmlDtdPtr dtd;
dtd = xmlGetIntSubset(ctxt->myDoc);
if (dtd == NULL)
- ctxt->myDoc->intSubset =
- xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "html",
+ ctxt->myDoc->intSubset =
+ xmlCreateIntSubset(ctxt->myDoc, BAD_CAST "html",
BAD_CAST "-//W3C//DTD HTML 4.0 Transitional//EN",
BAD_CAST "http://www.w3.org/TR/REC-html40/loose.dtd");
}
@@ -5352,8 +5912,8 @@
int base = ctxt->input->base - ctxt->input->buf->buffer->content;
int cur = ctxt->input->cur - ctxt->input->base;
int res;
-
- res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
+
+ res = xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
if (res < 0) {
ctxt->errNo = XML_PARSER_EOF;
ctxt->disableSAX = 1;
@@ -5377,7 +5937,7 @@
if ((in->encoder != NULL) && (in->buffer != NULL) &&
(in->raw != NULL)) {
int nbchars;
-
+
nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
if (nbchars < 0) {
htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING,
@@ -5394,14 +5954,14 @@
(ctxt->instate != XML_PARSER_MISC)) {
ctxt->errNo = XML_ERR_DOCUMENT_END;
ctxt->wellFormed = 0;
- }
+ }
if (ctxt->instate != XML_PARSER_EOF) {
if ((ctxt->sax) && (ctxt->sax->endDocument != NULL))
ctxt->sax->endDocument(ctxt->userData);
}
ctxt->instate = XML_PARSER_EOF;
}
- return((xmlParserErrors) ctxt->errNo);
+ return((xmlParserErrors) ctxt->errNo);
}
/************************************************************************
@@ -5426,7 +5986,7 @@
* Returns the new parser context or NULL
*/
htmlParserCtxtPtr
-htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data,
+htmlCreatePushParserCtxt(htmlSAXHandlerPtr sax, void *user_data,
const char *chunk, int size, const char *filename,
xmlCharEncoding enc) {
htmlParserCtxtPtr ctxt;
@@ -5457,7 +6017,7 @@
memcpy(ctxt->sax, sax, sizeof(htmlSAXHandler));
if (user_data != NULL)
ctxt->userData = user_data;
- }
+ }
if (filename == NULL) {
ctxt->directory = NULL;
} else {
@@ -5479,17 +6039,17 @@
inputStream->buf = buf;
inputStream->base = inputStream->buf->buffer->content;
inputStream->cur = inputStream->buf->buffer->content;
- inputStream->end =
+ inputStream->end =
&inputStream->buf->buffer->content[inputStream->buf->buffer->use];
inputPush(ctxt, inputStream);
if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
- (ctxt->input->buf != NULL)) {
+ (ctxt->input->buf != NULL)) {
int base = ctxt->input->base - ctxt->input->buf->buffer->content;
int cur = ctxt->input->cur - ctxt->input->base;
- xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
+ xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
ctxt->input->base = ctxt->input->buf->buffer->content + base;
ctxt->input->cur = ctxt->input->base + cur;
@@ -5510,12 +6070,12 @@
* @cur: a pointer to an array of xmlChar
* @encoding: a free form C string describing the HTML document encoding, or NULL
* @sax: the SAX handler block
- * @userData: if using SAX, this pointer will be provided on callbacks.
+ * @userData: if using SAX, this pointer will be provided on callbacks.
*
* Parse an HTML in-memory document. If sax is not NULL, use the SAX callbacks
* to handle parse events. If sax is NULL, fallback to the default DOM
* behavior and return a tree.
- *
+ *
* Returns the resulting document tree unless SAX is NULL or the document is
* not well formed.
*/
@@ -5532,7 +6092,7 @@
ctxt = htmlCreateDocParserCtxt(cur, encoding);
if (ctxt == NULL) return(NULL);
- if (sax != NULL) {
+ if (sax != NULL) {
if (ctxt->sax != NULL) xmlFree (ctxt->sax);
ctxt->sax = sax;
ctxt->userData = userData;
@@ -5545,7 +6105,7 @@
ctxt->userData = NULL;
}
htmlFreeParserCtxt(ctxt);
-
+
return(ret);
}
@@ -5555,7 +6115,7 @@
* @encoding: a free form C string describing the HTML document encoding, or NULL
*
* parse an HTML in-memory document and build a tree.
- *
+ *
* Returns the resulting document tree
*/
@@ -5570,7 +6130,7 @@
* @filename: the filename
* @encoding: a free form C string describing the HTML document encoding, or NULL
*
- * Create a parser context for a file content.
+ * Create a parser context for a file content.
* Automatic support for ZLIB/Compress compressed document is provided
* by default if found at compile-time.
*
@@ -5602,7 +6162,7 @@
xmlFreeParserCtxt(ctxt);
return(NULL);
}
-
+
inputStream = xmlLoadExternalEntity(canonicFilename, NULL, ctxt);
xmlFree(canonicFilename);
if (inputStream == NULL) {
@@ -5615,14 +6175,14 @@
/* set encoding */
if (encoding) {
content = xmlMallocAtomic (xmlStrlen(content_line) + strlen(encoding) + 1);
- if (content) {
+ if (content) {
strcpy ((char *)content, (char *)content_line);
strcat ((char *)content, (char *)encoding);
htmlCheckEncoding (ctxt, content);
xmlFree (content);
}
}
-
+
return(ctxt);
}
@@ -5631,7 +6191,7 @@
* @filename: the filename
* @encoding: a free form C string describing the HTML document encoding, or NULL
* @sax: the SAX handler block
- * @userData: if using SAX, this pointer will be provided on callbacks.
+ * @userData: if using SAX, this pointer will be provided on callbacks.
*
* parse an HTML file and build a tree. Automatic support for ZLIB/Compress
* compressed document is provided by default if found at compile-time.
@@ -5643,7 +6203,7 @@
*/
htmlDocPtr
-htmlSAXParseFile(const char *filename, const char *encoding, htmlSAXHandlerPtr sax,
+htmlSAXParseFile(const char *filename, const char *encoding, htmlSAXHandlerPtr sax,
void *userData) {
htmlDocPtr ret;
htmlParserCtxtPtr ctxt;
@@ -5667,7 +6227,7 @@
ctxt->userData = NULL;
}
htmlFreeParserCtxt(ctxt);
-
+
return(ret);
}
@@ -5689,7 +6249,7 @@
/**
* htmlHandleOmittedElem:
- * @val: int 0 or 1
+ * @val: int 0 or 1
*
* Set and return the previous value for handling HTML omitted tags.
*
@@ -5829,7 +6389,7 @@
* current scope
*/
#define DICT_FREE(str) \
- if ((str) && ((!dict) || \
+ if ((str) && ((!dict) || \
(xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
xmlFree((char *)(str));
@@ -5844,7 +6404,7 @@
{
xmlParserInputPtr input;
xmlDictPtr dict;
-
+
if (ctxt == NULL)
return;
@@ -5896,6 +6456,7 @@
ctxt->wellFormed = 1;
ctxt->nsWellFormed = 1;
+ ctxt->disableSAX = 0;
ctxt->valid = 1;
ctxt->vctxt.userData = ctxt;
ctxt->vctxt.error = xmlParserValidityError;
@@ -5971,6 +6532,18 @@
ctxt->options |= HTML_PARSE_COMPACT;
options -= HTML_PARSE_COMPACT;
}
+ if (options & XML_PARSE_HUGE) {
+ ctxt->options |= XML_PARSE_HUGE;
+ options -= XML_PARSE_HUGE;
+ }
+ if (options & HTML_PARSE_NODEFDTD) {
+ ctxt->options |= HTML_PARSE_NODEFDTD;
+ options -= HTML_PARSE_NODEFDTD;
+ }
+ if (options & HTML_PARSE_IGNORE_ENC) {
+ ctxt->options |= HTML_PARSE_IGNORE_ENC;
+ options -= HTML_PARSE_IGNORE_ENC;
+ }
ctxt->dictNames = 0;
return (options);
}
@@ -5984,7 +6557,7 @@
* @reuse: keep the context for reuse
*
* Common front-end for the htmlRead functions
- *
+ *
* Returns the resulting document tree or NULL
*/
static htmlDocPtr
@@ -5992,7 +6565,7 @@
int options, int reuse)
{
htmlDocPtr ret;
-
+
htmlCtxtUseOptions(ctxt, options);
ctxt->html = 1;
if (encoding != NULL) {
@@ -6030,7 +6603,7 @@
* @options: a combination of htmlParserOption(s)
*
* parse an XML in-memory document and build a tree.
- *
+ *
* Returns the resulting document tree
*/
htmlDocPtr
@@ -6055,7 +6628,7 @@
* @options: a combination of htmlParserOption(s)
*
* parse an XML file from the filesystem or the network.
- *
+ *
* Returns the resulting document tree
*/
htmlDocPtr
@@ -6079,7 +6652,7 @@
* @options: a combination of htmlParserOption(s)
*
* parse an XML in-memory document and build a tree.
- *
+ *
* Returns the resulting document tree
*/
htmlDocPtr
@@ -6105,7 +6678,7 @@
* @options: a combination of htmlParserOption(s)
*
* parse an XML from a file descriptor and build a tree.
- *
+ *
* Returns the resulting document tree
*/
htmlDocPtr
@@ -6147,7 +6720,7 @@
* @options: a combination of htmlParserOption(s)
*
* parse an HTML document from I/O functions and source and build a tree.
- *
+ *
* Returns the resulting document tree
*/
htmlDocPtr
@@ -6191,7 +6764,7 @@
*
* parse an XML in-memory document and build a tree.
* This reuses the existing @ctxt parser context
- *
+ *
* Returns the resulting document tree
*/
htmlDocPtr
@@ -6224,7 +6797,7 @@
*
* parse an XML file from the filesystem or the network.
* This reuses the existing @ctxt parser context
- *
+ *
* Returns the resulting document tree
*/
htmlDocPtr
@@ -6259,7 +6832,7 @@
*
* parse an XML in-memory document and build a tree.
* This reuses the existing @ctxt parser context
- *
+ *
* Returns the resulting document tree
*/
htmlDocPtr
@@ -6301,7 +6874,7 @@
*
* parse an XML from a file descriptor and build a tree.
* This reuses the existing @ctxt parser context
- *
+ *
* Returns the resulting document tree
*/
htmlDocPtr
@@ -6343,7 +6916,7 @@
*
* parse an HTML document from I/O functions and source and build a tree.
* This reuses the existing @ctxt parser context
- *
+ *
* Returns the resulting document tree
*/
htmlDocPtr
diff --git a/HTMLtree.c b/HTMLtree.c
index 37999f7..f23ae02 100644
--- a/HTMLtree.c
+++ b/HTMLtree.c
@@ -160,14 +160,18 @@
*/
int
htmlSetMetaEncoding(htmlDocPtr doc, const xmlChar *encoding) {
- htmlNodePtr cur, meta;
- const xmlChar *content;
+ htmlNodePtr cur, meta = NULL, head = NULL;
+ const xmlChar *content = NULL;
char newcontent[100];
if (doc == NULL)
return(-1);
+ /* html isn't a real encoding it's just libxml2 way to get entities */
+ if (!xmlStrcasecmp(encoding, BAD_CAST "html"))
+ return(-1);
+
if (encoding != NULL) {
snprintf(newcontent, sizeof(newcontent), "text/html; charset=%s",
(char *)encoding);
@@ -201,39 +205,24 @@
if ((cur->type == XML_ELEMENT_NODE) && (cur->name != NULL)) {
if (xmlStrcasecmp(cur->name, BAD_CAST"head") == 0)
break;
- if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0)
+ if (xmlStrcasecmp(cur->name, BAD_CAST"meta") == 0) {
+ head = cur->parent;
goto found_meta;
+ }
}
cur = cur->next;
}
if (cur == NULL)
return(-1);
found_head:
- if (cur->children == NULL) {
- if (encoding == NULL)
- return(0);
- meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
- xmlAddChild(cur, meta);
- xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
- xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
- return(0);
- }
+ head = cur;
+ if (cur->children == NULL)
+ goto create;
cur = cur->children;
found_meta:
- if (encoding != NULL) {
- /*
- * Create a new Meta element with the right attributes
- */
-
- meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
- xmlAddPrevSibling(cur, meta);
- xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
- xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
- }
-
/*
- * Search and destroy all the remaining the meta elements carrying
+ * Search and update all the remaining the meta elements carrying
* encoding informations
*/
while (cur != NULL) {
@@ -253,11 +242,11 @@
if ((!xmlStrcasecmp(attr->name, BAD_CAST"http-equiv"))
&& (!xmlStrcasecmp(value, BAD_CAST"Content-Type")))
http = 1;
- else
+ else
{
if ((value != NULL) &&
- (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
- content = value;
+ (!xmlStrcasecmp(attr->name, BAD_CAST"content")))
+ content = value;
}
if ((http != 0) && (content != NULL))
break;
@@ -266,16 +255,36 @@
}
if ((http != 0) && (content != NULL)) {
meta = cur;
- cur = cur->next;
- xmlUnlinkNode(meta);
- xmlFreeNode(meta);
- continue;
+ break;
}
}
}
cur = cur->next;
}
+create:
+ if (meta == NULL) {
+ if ((encoding != NULL) && (head != NULL)) {
+ /*
+ * Create a new Meta element with the right attributes
+ */
+
+ meta = xmlNewDocNode(doc, NULL, BAD_CAST"meta", NULL);
+ if (head->children == NULL)
+ xmlAddChild(head, meta);
+ else
+ xmlAddPrevSibling(head->children, meta);
+ xmlNewProp(meta, BAD_CAST"http-equiv", BAD_CAST"Content-Type");
+ xmlNewProp(meta, BAD_CAST"content", BAD_CAST newcontent);
+ }
+ } else {
+ /* change the document only if there is a real encoding change */
+ if (xmlStrcasestr(content, encoding) == NULL) {
+ xmlSetProp(meta, BAD_CAST"content", BAD_CAST newcontent);
+ }
+ }
+
+
return(0);
}
@@ -472,7 +481,7 @@
if (enc != XML_CHAR_ENCODING_UTF8) {
handler = xmlFindCharEncodingHandler(encoding);
if (handler == NULL)
- return(-1);
+ htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
}
}
@@ -553,11 +562,9 @@
}
handler = xmlFindCharEncodingHandler(encoding);
- if (handler == NULL) {
- *mem = NULL;
- *size = 0;
- return;
- }
+ if (handler == NULL)
+ htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
+
} else {
handler = xmlFindCharEncodingHandler(encoding);
}
@@ -578,7 +585,7 @@
return;
}
- htmlDocContentDumpFormatOutput(buf, cur, NULL, format);
+ htmlDocContentDumpFormatOutput(buf, cur, NULL, format);
xmlOutputBufferFlush(buf);
if (buf->conv != NULL) {
@@ -1052,7 +1059,7 @@
handler = xmlFindCharEncodingHandler(encoding);
if (handler == NULL)
- return(-1);
+ htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
} else {
handler = xmlFindCharEncodingHandler(encoding);
}
@@ -1111,7 +1118,7 @@
handler = xmlFindCharEncodingHandler(encoding);
if (handler == NULL)
- return(-1);
+ htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
}
}
@@ -1155,7 +1162,7 @@
if ((cur == NULL) || (filename == NULL))
return(-1);
-
+
xmlInitParser();
if (encoding != NULL) {
@@ -1172,9 +1179,9 @@
handler = xmlFindCharEncodingHandler(encoding);
if (handler == NULL)
- return(-1);
- htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
+ htmlSaveErr(XML_SAVE_UNKNOWN_ENCODING, NULL, encoding);
}
+ htmlSetMetaEncoding(cur, (const xmlChar *) encoding);
} else {
htmlSetMetaEncoding(cur, (const xmlChar *) "UTF-8");
}
diff --git a/SAX2.c b/SAX2.c
index 164409c..e230cea 100644
--- a/SAX2.c
+++ b/SAX2.c
@@ -1105,24 +1105,33 @@
return;
}
+#ifdef LIBXML_HTML_ENABLED
+ if ((ctxt->html) &&
+ (value == NULL) && (htmlIsBooleanAttr(fullname))) {
+ nval = xmlStrdup(fullname);
+ value = (const xmlChar *) nval;
+ } else
+#endif
+ {
#ifdef LIBXML_VALID_ENABLED
- /*
- * Do the last stage of the attribute normalization
- * Needed for HTML too:
- * http://www.w3.org/TR/html4/types.html#h-6.2
- */
- ctxt->vctxt.valid = 1;
- nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt,
- ctxt->myDoc, ctxt->node,
- fullname, value);
- if (ctxt->vctxt.valid != 1) {
- ctxt->valid = 0;
- }
- if (nval != NULL)
- value = nval;
+ /*
+ * Do the last stage of the attribute normalization
+ * Needed for HTML too:
+ * http://www.w3.org/TR/html4/types.html#h-6.2
+ */
+ ctxt->vctxt.valid = 1;
+ nval = xmlValidCtxtNormalizeAttributeValue(&ctxt->vctxt,
+ ctxt->myDoc, ctxt->node,
+ fullname, value);
+ if (ctxt->vctxt.valid != 1) {
+ ctxt->valid = 0;
+ }
+ if (nval != NULL)
+ value = nval;
#else
- nval = NULL;
+ nval = NULL;
#endif /* LIBXML_VALID_ENABLED */
+ }
/*
* Check whether it's a namespace definition
@@ -1246,30 +1255,32 @@
}
if (ns != NULL) {
- xmlAttrPtr prop;
namespace = xmlSearchNs(ctxt->myDoc, ctxt->node, ns);
+
if (namespace == NULL) {
xmlNsErrMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
"Namespace prefix %s of attribute %s is not defined\n",
ns, name);
- }
+ } else {
+ xmlAttrPtr prop;
- prop = ctxt->node->properties;
- while (prop != NULL) {
- if (prop->ns != NULL) {
- if ((xmlStrEqual(name, prop->name)) &&
- ((namespace == prop->ns) ||
- (xmlStrEqual(namespace->href, prop->ns->href)))) {
- xmlNsErrMsg(ctxt, XML_ERR_ATTRIBUTE_REDEFINED,
- "Attribute %s in %s redefined\n",
- name, namespace->href);
- ctxt->wellFormed = 0;
- if (ctxt->recovery == 0) ctxt->disableSAX = 1;
- goto error;
- }
- }
- prop = prop->next;
- }
+ prop = ctxt->node->properties;
+ while (prop != NULL) {
+ if (prop->ns != NULL) {
+ if ((xmlStrEqual(name, prop->name)) &&
+ ((namespace == prop->ns) ||
+ (xmlStrEqual(namespace->href, prop->ns->href)))) {
+ xmlNsErrMsg(ctxt, XML_ERR_ATTRIBUTE_REDEFINED,
+ "Attribute %s in %s redefined\n",
+ name, namespace->href);
+ ctxt->wellFormed = 0;
+ if (ctxt->recovery == 0) ctxt->disableSAX = 1;
+ goto error;
+ }
+ }
+ prop = prop->next;
+ }
+ }
} else {
namespace = NULL;
}
@@ -1420,6 +1431,10 @@
} else {
fulln = xmlStrdup(attr->name);
}
+ if (fulln == NULL) {
+ xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElement");
+ break;
+ }
/*
* Check that the attribute is not declared in the
@@ -1442,6 +1457,7 @@
(const char *)fulln,
(const char *)attr->elem);
}
+ xmlFree(fulln);
}
attr = attr->nexth;
}
@@ -2147,6 +2163,7 @@
xmlNodePtr parent;
xmlNsPtr last = NULL, ns;
const xmlChar *uri, *pref;
+ xmlChar *lname = NULL;
int i, j;
if (ctx == NULL) return;
@@ -2166,6 +2183,20 @@
}
/*
+ * Take care of the rare case of an undefined namespace prefix
+ */
+ if ((prefix != NULL) && (URI == NULL)) {
+ if (ctxt->dictNames) {
+ const xmlChar *fullname;
+
+ fullname = xmlDictQLookup(ctxt->dict, prefix, localname);
+ if (fullname != NULL)
+ localname = fullname;
+ } else {
+ lname = xmlBuildQName(localname, prefix, NULL, 0);
+ }
+ }
+ /*
* allocate the node
*/
if (ctxt->freeElems != NULL) {
@@ -2178,7 +2209,10 @@
if (ctxt->dictNames)
ret->name = localname;
else {
- ret->name = xmlStrdup(localname);
+ if (lname == NULL)
+ ret->name = xmlStrdup(localname);
+ else
+ ret->name = lname;
if (ret->name == NULL) {
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
return;
@@ -2190,8 +2224,11 @@
if (ctxt->dictNames)
ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
(xmlChar *) localname, NULL);
- else
+ else if (lname == NULL)
ret = xmlNewDocNode(ctxt->myDoc, NULL, localname, NULL);
+ else
+ ret = xmlNewDocNodeEatName(ctxt->myDoc, NULL,
+ (xmlChar *) lname, NULL);
if (ret == NULL) {
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
return;
@@ -2226,8 +2263,12 @@
if ((URI != NULL) && (prefix == pref))
ret->ns = ns;
} else {
- xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
- return;
+ /*
+ * any out of memory error would already have been raised
+ * but we can't be garanteed it's the actual error due to the
+ * API, best is to skip in this case
+ */
+ continue;
}
#ifdef LIBXML_VALID_ENABLED
if ((!ctxt->html) && ctxt->validate && ctxt->wellFormed &&
@@ -2278,9 +2319,14 @@
xmlSAX2ErrMemory(ctxt, "xmlSAX2StartElementNs");
return;
}
- xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
- "Namespace prefix %s was not found\n",
- prefix, NULL);
+ if (prefix != NULL)
+ xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
+ "Namespace prefix %s was not found\n",
+ prefix, NULL);
+ else
+ xmlNsWarnMsg(ctxt, XML_NS_ERR_UNDEFINED_NAMESPACE,
+ "Namespace default prefix was not found\n",
+ NULL, NULL);
}
}
@@ -2289,8 +2335,33 @@
*/
if (nb_attributes > 0) {
for (j = 0,i = 0;i < nb_attributes;i++,j+=5) {
+ /*
+ * Handle the rare case of an undefined atribute prefix
+ */
+ if ((attributes[j+1] != NULL) && (attributes[j+2] == NULL)) {
+ if (ctxt->dictNames) {
+ const xmlChar *fullname;
+
+ fullname = xmlDictQLookup(ctxt->dict, attributes[j+1],
+ attributes[j]);
+ if (fullname != NULL) {
+ xmlSAX2AttributeNs(ctxt, fullname, NULL,
+ attributes[j+3], attributes[j+4]);
+ continue;
+ }
+ } else {
+ lname = xmlBuildQName(attributes[j], attributes[j+1],
+ NULL, 0);
+ if (lname != NULL) {
+ xmlSAX2AttributeNs(ctxt, lname, NULL,
+ attributes[j+3], attributes[j+4]);
+ xmlFree(lname);
+ continue;
+ }
+ }
+ }
xmlSAX2AttributeNs(ctxt, attributes[j], attributes[j+1],
- attributes[j+3], attributes[j+4]);
+ attributes[j+3], attributes[j+4]);
}
}
@@ -2554,7 +2625,6 @@
ret = xmlNewDocPI(ctxt->myDoc, target, data);
if (ret == NULL) return;
- parent = ctxt->node;
if (ctxt->linenumbers) {
if (ctxt->input != NULL) {
diff --git a/ThirdPartyProject.prop b/ThirdPartyProject.prop
index 9ddc179..4467c98 100644
--- a/ThirdPartyProject.prop
+++ b/ThirdPartyProject.prop
@@ -1,7 +1,7 @@
# Copyright 2010 Google Inc. All Rights Reserved.
#Fri Jul 16 10:03:09 PDT 2010
-currentVersion=2.7.6
-version=2.7.3
+currentVersion=2.7.8
+version=2.7.8
isNative=true
name=libxml2
keywords=libxml2
diff --git a/c14n.c b/c14n.c
index f333297..9c3cad2 100644
--- a/c14n.c
+++ b/c14n.c
@@ -60,9 +60,11 @@
xmlC14NPosition pos;
int parent_is_doc;
xmlC14NVisibleNsStackPtr ns_rendered;
+
+ /* C14N mode */
+ xmlC14NMode mode;
/* exclusive canonicalization */
- int exclusive;
xmlChar **inclusive_ns_prefixes;
/* error number */
@@ -117,6 +119,9 @@
(ctx)->is_visible_callback((ctx)->user_data, \
(xmlNodePtr)(node), (xmlNodePtr)(parent)) : 1)
+#define xmlC14NIsExclusive( ctx ) \
+ ( (ctx)->mode == XML_C14N_EXCLUSIVE_1_0 )
+
/************************************************************************
* *
* Some factorized error routines *
@@ -492,9 +497,7 @@
{
return ((ns != NULL) &&
(xmlStrEqual(ns->prefix, BAD_CAST "xml")) &&
- (xmlStrEqual(ns->href,
- BAD_CAST
- "http://www.w3.org/XML/1998/namespace")));
+ (xmlStrEqual(ns->href, XML_XML_NAMESPACE)));
}
@@ -713,7 +716,7 @@
return (-1);
}
- if(!ctx->exclusive) {
+ if(!xmlC14NIsExclusive(ctx)) {
xmlC14NErrParam("processing namespaces axis (exc c14n)");
return (-1);
@@ -845,6 +848,25 @@
/**
+ * xmlC14NIsXmlAttr:
+ * @attr: the attr to check
+ *
+ * Checks whether the given attribute is a default "xml:" namespace
+ * with href="http://www.w3.org/XML/1998/namespace"
+ *
+ * Returns 1 if the node is default or 0 otherwise
+ */
+
+/* todo: make it a define? */
+static int
+xmlC14NIsXmlAttr(xmlAttrPtr attr)
+{
+ return ((attr->ns != NULL) &&
+ (xmlC14NIsXmlNs(attr->ns) != 0));
+}
+
+
+/**
* xmlC14NAttrsCompare:
* @attr1: the pointer tls o first attr
* @attr2: the pointer to second attr
@@ -925,7 +947,7 @@
xmlOutputBufferWriteString(ctx->buf, (const char *) attr->name);
xmlOutputBufferWriteString(ctx->buf, "=\"");
- value = xmlNodeListGetString(attr->doc, attr->children, 1);
+ value = xmlNodeListGetString(ctx->doc, attr->children, 1);
/* todo: should we log an error if value==NULL ? */
if (value != NULL) {
buffer = xmlC11NNormalizeAttr(value);
@@ -943,10 +965,133 @@
}
/**
+ * xmlC14NFindHiddenParentAttr:
+ *
+ * Finds an attribute in a hidden parent node.
+ *
+ * Returns a pointer to the attribute node (if found) or NULL otherwise.
+ */
+static xmlAttrPtr
+xmlC14NFindHiddenParentAttr(xmlC14NCtxPtr ctx, xmlNodePtr cur, const xmlChar * name, const xmlChar * ns)
+{
+ xmlAttrPtr res;
+ while((cur != NULL) && (!xmlC14NIsVisible(ctx, cur, cur->parent))) {
+ res = xmlHasNsProp(cur, name, ns);
+ if(res != NULL) {
+ return res;
+ }
+
+ cur = cur->parent;
+ }
+
+ return NULL;
+}
+
+/**
+ * xmlC14NFixupBaseAttr:
+ *
+ * Fixes up the xml:base attribute
+ *
+ * Returns the newly created attribute or NULL
+ */
+static xmlAttrPtr
+xmlC14NFixupBaseAttr(xmlC14NCtxPtr ctx, xmlAttrPtr xml_base_attr)
+{
+ xmlChar * res = NULL;
+ xmlNodePtr cur;
+ xmlAttrPtr attr;
+ xmlChar * tmp_str;
+ xmlChar * tmp_str2;
+ int tmp_str_len;
+
+ if ((ctx == NULL) || (xml_base_attr == NULL) || (xml_base_attr->parent == NULL)) {
+ xmlC14NErrParam("processing xml:base attribute");
+ return (NULL);
+ }
+
+ /* start from current value */
+ res = xmlNodeListGetString(ctx->doc, xml_base_attr->children, 1);
+ if(res == NULL) {
+ xmlC14NErrInternal("processing xml:base attribute - can't get attr value");
+ return (NULL);
+ }
+
+ /* go up the stack until we find a node that we rendered already */
+ cur = xml_base_attr->parent->parent;
+ while((cur != NULL) && (!xmlC14NIsVisible(ctx, cur, cur->parent))) {
+ attr = xmlHasNsProp(cur, BAD_CAST "base", XML_XML_NAMESPACE);
+ if(attr != NULL) {
+ /* get attr value */
+ tmp_str = xmlNodeListGetString(ctx->doc, attr->children, 1);
+ if(tmp_str == NULL) {
+ xmlFree(res);
+
+ xmlC14NErrInternal("processing xml:base attribute - can't get attr value");
+ return (NULL);
+ }
+
+ /* we need to add '/' if our current base uri ends with '..' or '.'
+ to ensure that we are forced to go "up" all the time */
+ tmp_str_len = xmlStrlen(tmp_str);
+ if(tmp_str_len > 1 && tmp_str[tmp_str_len - 2] == '.') {
+ tmp_str2 = xmlStrcat(tmp_str, BAD_CAST "/");
+ if(tmp_str2 == NULL) {
+ xmlFree(tmp_str);
+ xmlFree(res);
+
+ xmlC14NErrInternal("processing xml:base attribute - can't modify uri");
+ return (NULL);
+ }
+
+ tmp_str = tmp_str2;
+ }
+
+ /* build uri */
+ tmp_str2 = xmlBuildURI(res, tmp_str);
+ if(tmp_str2 == NULL) {
+ xmlFree(tmp_str);
+ xmlFree(res);
+
+ xmlC14NErrInternal("processing xml:base attribute - can't construct uri");
+ return (NULL);
+ }
+
+ /* cleanup and set the new res */
+ xmlFree(tmp_str);
+ xmlFree(res);
+ res = tmp_str2;
+ }
+
+ /* next */
+ cur = cur->parent;
+ }
+
+ /* check if result uri is empty or not */
+ if((res == NULL) || xmlStrEqual(res, BAD_CAST "")) {
+ xmlFree(res);
+ return (NULL);
+ }
+
+ /* create and return the new attribute node */
+ attr = xmlNewNsProp(NULL, xml_base_attr->ns, BAD_CAST "base", res);
+ if(attr == NULL) {
+ xmlFree(res);
+
+ xmlC14NErrInternal("processing xml:base attribute - can't construct attribute");
+ return (NULL);
+ }
+
+ /* done */
+ xmlFree(res);
+ return (attr);
+}
+
+/**
* xmlC14NProcessAttrsAxis:
* @ctx: the C14N context
* @cur: the current node
* @parent_visible: the visibility of parent node
+ * @all_parents_visible: the visibility of all parent nodes
*
* Prints out canonical attribute axis of the current node to the
* buffer from C14N context as follows
@@ -978,7 +1123,13 @@
xmlC14NProcessAttrsAxis(xmlC14NCtxPtr ctx, xmlNodePtr cur, int parent_visible)
{
xmlAttrPtr attr;
- xmlListPtr list;
+ xmlListPtr list;
+ xmlAttrPtr attrs_to_delete = NULL;
+
+ /* special processing for 1.1 spec */
+ xmlAttrPtr xml_base_attr = NULL;
+ xmlAttrPtr xml_lang_attr = NULL;
+ xmlAttrPtr xml_space_attr = NULL;
if ((ctx == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE)) {
xmlC14NErrParam("processing attributes axis");
@@ -994,42 +1145,184 @@
return (-1);
}
- /*
- * Add all visible attributes from current node.
- */
- attr = cur->properties;
- while (attr != NULL) {
- /* check that attribute is visible */
- if (xmlC14NIsVisible(ctx, attr, cur)) {
- xmlListInsert(list, attr);
- }
- attr = attr->next;
- }
-
- /*
- * include attributes in "xml" namespace defined in ancestors
- * (only for non-exclusive XML Canonicalization)
- */
- if (parent_visible && (!ctx->exclusive) && (cur->parent != NULL)
- && (!xmlC14NIsVisible(ctx, cur->parent, cur->parent->parent))) {
- /*
- * If XPath node-set is not specified then the parent is always
- * visible!
+ switch(ctx->mode) {
+ case XML_C14N_1_0:
+ /* The processing of an element node E MUST be modified slightly when an XPath node-set is
+ * given as input and the element's parent is omitted from the node-set. The method for processing
+ * the attribute axis of an element E in the node-set is enhanced. All element nodes along E's
+ * ancestor axis are examined for nearest occurrences of attributes in the xml namespace, such
+ * as xml:lang and xml:space (whether or not they are in the node-set). From this list of attributes,
+ * remove any that are in E's attribute axis (whether or not they are in the node-set). Then,
+ * lexicographically merge this attribute list with the nodes of E's attribute axis that are in
+ * the node-set. The result of visiting the attribute axis is computed by processing the attribute
+ * nodes in this merged attribute list.
*/
- cur = cur->parent;
- while (cur != NULL) {
- attr = cur->properties;
- while (attr != NULL) {
- if ((attr->ns != NULL)
- && (xmlStrEqual(attr->ns->prefix, BAD_CAST "xml"))) {
- if (xmlListSearch(list, attr) == NULL) {
- xmlListInsert(list, attr);
- }
- }
- attr = attr->next;
+
+ /*
+ * Add all visible attributes from current node.
+ */
+ attr = cur->properties;
+ while (attr != NULL) {
+ /* check that attribute is visible */
+ if (xmlC14NIsVisible(ctx, attr, cur)) {
+ xmlListInsert(list, attr);
}
- cur = cur->parent;
+ attr = attr->next;
}
+
+ /*
+ * Handle xml attributes
+ */
+ if (parent_visible && (cur->parent != NULL) &&
+ (!xmlC14NIsVisible(ctx, cur->parent, cur->parent->parent)))
+ {
+ xmlNodePtr tmp;
+
+ /*
+ * If XPath node-set is not specified then the parent is always
+ * visible!
+ */
+ tmp = cur->parent;
+ while (tmp != NULL) {
+ attr = tmp->properties;
+ while (attr != NULL) {
+ if (xmlC14NIsXmlAttr(attr) != 0) {
+ if (xmlListSearch(list, attr) == NULL) {
+ xmlListInsert(list, attr);
+ }
+ }
+ attr = attr->next;
+ }
+ tmp = tmp->parent;
+ }
+ }
+
+ /* done */
+ break;
+ case XML_C14N_EXCLUSIVE_1_0:
+ /* attributes in the XML namespace, such as xml:lang and xml:space
+ * are not imported into orphan nodes of the document subset
+ */
+
+ /*
+ * Add all visible attributes from current node.
+ */
+ attr = cur->properties;
+ while (attr != NULL) {
+ /* check that attribute is visible */
+ if (xmlC14NIsVisible(ctx, attr, cur)) {
+ xmlListInsert(list, attr);
+ }
+ attr = attr->next;
+ }
+
+ /* do nothing special for xml attributes */
+ break;
+ case XML_C14N_1_1:
+ /* The processing of an element node E MUST be modified slightly when an XPath node-set is
+ * given as input and some of the element's ancestors are omitted from the node-set.
+ *
+ * Simple inheritable attributes are attributes that have a value that requires at most a simple
+ * redeclaration. This redeclaration is done by supplying a new value in the child axis. The
+ * redeclaration of a simple inheritable attribute A contained in one of E's ancestors is done
+ * by supplying a value to an attribute Ae inside E with the same name. Simple inheritable attributes
+ * are xml:lang and xml:space.
+ *
+ * The method for processing the attribute axis of an element E in the node-set is hence enhanced.
+ * All element nodes along E's ancestor axis are examined for the nearest occurrences of simple
+ * inheritable attributes in the xml namespace, such as xml:lang and xml:space (whether or not they
+ * are in the node-set). From this list of attributes, any simple inheritable attributes that are
+ * already in E's attribute axis (whether or not they are in the node-set) are removed. Then,
+ * lexicographically merge this attribute list with the nodes of E's attribute axis that are in
+ * the node-set. The result of visiting the attribute axis is computed by processing the attribute
+ * nodes in this merged attribute list.
+ *
+ * The xml:id attribute is not a simple inheritable attribute and no processing of these attributes is
+ * performed.
+ *
+ * The xml:base attribute is not a simple inheritable attribute and requires special processing beyond
+ * a simple redeclaration.
+ *
+ * Attributes in the XML namespace other than xml:base, xml:id, xml:lang, and xml:space MUST be processed
+ * as ordinary attributes.
+ */
+
+ /*
+ * Add all visible attributes from current node.
+ */
+ attr = cur->properties;
+ while (attr != NULL) {
+ /* special processing for XML attribute kiks in only when we have invisible parents */
+ if ((!parent_visible) || (xmlC14NIsXmlAttr(attr) == 0)) {
+ /* check that attribute is visible */
+ if (xmlC14NIsVisible(ctx, attr, cur)) {
+ xmlListInsert(list, attr);
+ }
+ } else {
+ int matched = 0;
+
+ /* check for simple inheritance attributes */
+ if((!matched) && (xml_lang_attr == NULL) && xmlStrEqual(attr->name, BAD_CAST "lang")) {
+ xml_lang_attr = attr;
+ matched = 1;
+ }
+ if((!matched) && (xml_space_attr == NULL) && xmlStrEqual(attr->name, BAD_CAST "space")) {
+ xml_space_attr = attr;
+ matched = 1;
+ }
+
+ /* check for base attr */
+ if((!matched) && (xml_base_attr == NULL) && xmlStrEqual(attr->name, BAD_CAST "base")) {
+ xml_base_attr = attr;
+ matched = 1;
+ }
+
+ /* otherwise, it is a normal attribute, so just check if it is visible */
+ if((!matched) && xmlC14NIsVisible(ctx, attr, cur)) {
+ xmlListInsert(list, attr);
+ }
+ }
+
+ /* move to the next one */
+ attr = attr->next;
+ }
+
+ /* special processing for XML attribute kiks in only when we have invisible parents */
+ if ((parent_visible)) {
+
+ /* simple inheritance attributes - copy */
+ if(xml_lang_attr == NULL) {
+ xml_lang_attr = xmlC14NFindHiddenParentAttr(ctx, cur->parent, BAD_CAST "lang", XML_XML_NAMESPACE);
+ }
+ if(xml_lang_attr != NULL) {
+ xmlListInsert(list, xml_lang_attr);
+ }
+ if(xml_space_attr == NULL) {
+ xml_space_attr = xmlC14NFindHiddenParentAttr(ctx, cur->parent, BAD_CAST "space", XML_XML_NAMESPACE);
+ }
+ if(xml_space_attr != NULL) {
+ xmlListInsert(list, xml_space_attr);
+ }
+
+ /* base uri attribute - fix up */
+ if(xml_base_attr == NULL) {
+ /* if we don't have base uri attribute, check if we have a "hidden" one above */
+ xml_base_attr = xmlC14NFindHiddenParentAttr(ctx, cur->parent, BAD_CAST "base", XML_XML_NAMESPACE);
+ }
+ if(xml_base_attr != NULL) {
+ xml_base_attr = xmlC14NFixupBaseAttr(ctx, xml_base_attr);
+ if(xml_base_attr != NULL) {
+ xmlListInsert(list, xml_base_attr);
+
+ /* note that we MUST delete returned attr node ourselves! */
+ xml_base_attr->next = attrs_to_delete;
+ attrs_to_delete = xml_base_attr;
+ }
+ }
+ }
+
+ /* done */
+ break;
}
/*
@@ -1040,6 +1333,7 @@
/*
* Cleanup
*/
+ xmlFreePropList(attrs_to_delete);
xmlListDelete(list);
return (0);
}
@@ -1096,6 +1390,8 @@
* xmlC14NProcessElementNode:
* @ctx: the pointer to C14N context object
* @cur: the node to process
+ * @visible: this node is visible
+ * @all_parents_visible: whether all the parents of this node are visible
*
* Canonical XML v 1.0 (http://www.w3.org/TR/xml-c14n)
*
@@ -1159,7 +1455,7 @@
xmlOutputBufferWriteString(ctx->buf, (const char *) cur->name);
}
- if (!ctx->exclusive) {
+ if (!xmlC14NIsExclusive(ctx)) {
ret = xmlC14NProcessNamespacesAxis(ctx, cur, visible);
} else {
ret = xmlExcC14NProcessNamespacesAxis(ctx, cur, visible);
@@ -1457,9 +1753,10 @@
* or not
* @user_data: the first parameter for @is_visible_callback function
* (in most cases, it is nodes set)
+ * @mode: the c14n mode (see @xmlC14NMode)
* @inclusive_ns_prefixe the list of inclusive namespace prefixes
* ended with a NULL or NULL if there is no
- * inclusive namespaces (only for exclusive
+ * inclusive namespaces (only for `
* canonicalization)
* @with_comments: include comments in the result (!=0) or not (==0)
* @buf: the output buffer to store canonical XML; this
@@ -1473,7 +1770,7 @@
static xmlC14NCtxPtr
xmlC14NNewCtx(xmlDocPtr doc,
xmlC14NIsVisibleCallback is_visible_callback, void* user_data,
- int exclusive, xmlChar ** inclusive_ns_prefixes,
+ xmlC14NMode mode, xmlChar ** inclusive_ns_prefixes,
int with_comments, xmlOutputBufferPtr buf)
{
xmlC14NCtxPtr ctx = NULL;
@@ -1531,11 +1828,11 @@
}
/*
- * Set "exclusive" flag, create a nodes set for namespaces
- * stack and remember list of incluseve prefixes
+ * Set "mode" flag and remember list of incluseve prefixes
+ * for exclusive c14n
*/
- if (exclusive) {
- ctx->exclusive = 1;
+ ctx->mode = mode;
+ if(xmlC14NIsExclusive(ctx)) {
ctx->inclusive_ns_prefixes = inclusive_ns_prefixes;
}
return (ctx);
@@ -1548,8 +1845,7 @@
* or not
* @user_data: the first parameter for @is_visible_callback function
* (in most cases, it is nodes set)
- * @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
- * otherwise - exclusive canonicalization)
+ * @mode: the c14n mode (see @xmlC14NMode)
* @inclusive_ns_prefixes: the list of inclusive namespace prefixes
* ended with a NULL or NULL if there is no
* inclusive namespaces (only for exclusive
@@ -1567,10 +1863,11 @@
*/
int
xmlC14NExecute(xmlDocPtr doc, xmlC14NIsVisibleCallback is_visible_callback,
- void* user_data, int exclusive, xmlChar **inclusive_ns_prefixes,
+ void* user_data, int mode, xmlChar **inclusive_ns_prefixes,
int with_comments, xmlOutputBufferPtr buf) {
xmlC14NCtxPtr ctx;
+ xmlC14NMode c14n_mode = XML_C14N_1_0;
int ret;
if ((buf == NULL) || (doc == NULL)) {
@@ -1578,6 +1875,19 @@
return (-1);
}
+ /* for backward compatibility, we have to have "mode" as "int"
+ and here we check that user gives valid value */
+ switch(mode) {
+ case XML_C14N_1_0:
+ case XML_C14N_EXCLUSIVE_1_0:
+ case XML_C14N_1_1:
+ c14n_mode = (xmlC14NMode)mode;
+ break;
+ default:
+ xmlC14NErrParam("invalid mode for executing c14n");
+ return (-1);
+ }
+
/*
* Validate the encoding output buffer encoding
*/
@@ -1588,8 +1898,8 @@
}
ctx = xmlC14NNewCtx(doc, is_visible_callback, user_data,
- exclusive, inclusive_ns_prefixes,
- with_comments, buf);
+ c14n_mode, inclusive_ns_prefixes,
+ with_comments, buf);
if (ctx == NULL) {
xmlC14NErr(NULL, (xmlNodePtr) doc, XML_C14N_CREATE_CTXT,
"xmlC14NExecute: unable to create C14N context\n");
@@ -1637,8 +1947,7 @@
* @doc: the XML document for canonization
* @nodes: the nodes set to be included in the canonized image
* or NULL if all document nodes should be included
- * @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
- * otherwise - exclusive canonicalization)
+ * @mode: the c14n mode (see @xmlC14NMode)
* @inclusive_ns_prefixes: the list of inclusive namespace prefixes
* ended with a NULL or NULL if there is no
* inclusive namespaces (only for exclusive
@@ -1656,12 +1965,12 @@
*/
int
xmlC14NDocSaveTo(xmlDocPtr doc, xmlNodeSetPtr nodes,
- int exclusive, xmlChar ** inclusive_ns_prefixes,
+ int mode, xmlChar ** inclusive_ns_prefixes,
int with_comments, xmlOutputBufferPtr buf) {
return(xmlC14NExecute(doc,
(xmlC14NIsVisibleCallback)xmlC14NIsNodeInNodeset,
nodes,
- exclusive,
+ mode,
inclusive_ns_prefixes,
with_comments,
buf));
@@ -1673,8 +1982,7 @@
* @doc: the XML document for canonization
* @nodes: the nodes set to be included in the canonized image
* or NULL if all document nodes should be included
- * @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
- * otherwise - exclusive canonicalization)
+ * @mode: the c14n mode (see @xmlC14NMode)
* @inclusive_ns_prefixes: the list of inclusive namespace prefixes
* ended with a NULL or NULL if there is no
* inclusive namespaces (only for exclusive
@@ -1692,7 +2000,7 @@
*/
int
xmlC14NDocDumpMemory(xmlDocPtr doc, xmlNodeSetPtr nodes,
- int exclusive, xmlChar ** inclusive_ns_prefixes,
+ int mode, xmlChar ** inclusive_ns_prefixes,
int with_comments, xmlChar ** doc_txt_ptr)
{
int ret;
@@ -1717,7 +2025,7 @@
/*
* canonize document and write to buffer
*/
- ret = xmlC14NDocSaveTo(doc, nodes, exclusive, inclusive_ns_prefixes,
+ ret = xmlC14NDocSaveTo(doc, nodes, mode, inclusive_ns_prefixes,
with_comments, buf);
if (ret < 0) {
xmlC14NErrInternal("saving doc to output buffer");
@@ -1743,8 +2051,7 @@
* @doc: the XML document for canonization
* @nodes: the nodes set to be included in the canonized image
* or NULL if all document nodes should be included
- * @exclusive: the exclusive flag (0 - non-exclusive canonicalization;
- * otherwise - exclusive canonicalization)
+ * @mode: the c14n mode (see @xmlC14NMode)
* @inclusive_ns_prefixes: the list of inclusive namespace prefixes
* ended with a NULL or NULL if there is no
* inclusive namespaces (only for exclusive
@@ -1764,7 +2071,7 @@
*/
int
xmlC14NDocSave(xmlDocPtr doc, xmlNodeSetPtr nodes,
- int exclusive, xmlChar ** inclusive_ns_prefixes,
+ int mode, xmlChar ** inclusive_ns_prefixes,
int with_comments, const char *filename, int compression)
{
xmlOutputBufferPtr buf;
@@ -1791,7 +2098,7 @@
/*
* canonize document and write to buffer
*/
- ret = xmlC14NDocSaveTo(doc, nodes, exclusive, inclusive_ns_prefixes,
+ ret = xmlC14NDocSaveTo(doc, nodes, mode, inclusive_ns_prefixes,
with_comments, buf);
if (ret < 0) {
xmlC14NErrInternal("cannicanize document to buffer");
@@ -1919,7 +2226,7 @@
}
cur++;
}
- *out++ = 0;
+ *out = 0;
return (buffer);
}
#endif /* LIBXML_OUTPUT_ENABLED */
diff --git a/catalog.c b/catalog.c
index af84b7c..f33a0aa 100644
--- a/catalog.c
+++ b/catalog.c
@@ -997,18 +997,15 @@
}
#ifdef HAVE_STAT
len = read(fd, content, size);
+ close(fd);
#else
len = fread(content, 1, size, fd);
+ fclose(fd);
#endif
if (len < 0) {
xmlFree(content);
return (NULL);
}
-#ifdef HAVE_STAT
- close(fd);
-#else
- fclose(fd);
-#endif
content[len] = 0;
return(content);
diff --git a/config.h b/config.h
index d980955..c70d020 100644
--- a/config.h
+++ b/config.h
@@ -1,21 +1,5 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.in by autoheader. */
-#define PACKAGE "libxml2"
-#define VERSION "2.7.3"
-/* #undef HAVE_LIBZ */
-/* #undef HAVE_LIBM */
-#define HAVE_ISINF
-#define HAVE_ISNAN
-/* #undef HAVE_LIBHISTORY */
-/* #undef HAVE_LIBREADLINE */
-/* #undef HAVE_LIBPTHREAD */
-/* #undef HAVE_PTHREAD_H */
-
-/* Define if IPV6 support is there */
-/* #undef SUPPORT_IP6 */
-
-/* Define if getaddrinfo is there */
-/* #undef HAVE_GETADDRINFO */
/* Define to 1 if you have the <ansidecl.h> header file. */
/* #undef HAVE_ANSIDECL_H */
@@ -42,7 +26,7 @@
#define HAVE_DLFCN_H 1
/* Have dlopen based dso */
-#define HAVE_DLOPEN 1
+#define HAVE_DLOPEN /**/
/* Define to 1 if you have the <dl.h> header file. */
/* #undef HAVE_DL_H */
@@ -75,7 +59,7 @@
#define HAVE_FTIME 1
/* Define if getaddrinfo is there */
-/* #undef HAVE_GETADDRINFO */
+/* #undef HAVE_GETADDRINFO */
/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
@@ -90,10 +74,10 @@
/* #undef HAVE_INTTYPES_H_H */
/* Define if isinf is there */
-#define HAVE_ISINF
+#define HAVE_ISINF /**/
/* Define if isnan is there */
-#define HAVE_ISNAN
+#define HAVE_ISNAN /**/
/* Define to 1 if you have the `isnand' function. */
/* #undef HAVE_ISNAND */
@@ -101,6 +85,9 @@
/* Define if history library is there (-lhistory) */
/* #undef HAVE_LIBHISTORY */
+/* Have compression library */
+/* #undef HAVE_LIBLZMA */
+
/* Define if pthread library is there (-lpthread) */
/* #undef HAVE_LIBPTHREAD */
@@ -116,6 +103,9 @@
/* Define to 1 if you have the `localtime' function. */
#define HAVE_LOCALTIME 1
+/* Define to 1 if you have the <lzma.h> header file. */
+/* #undef HAVE_LZMA_H */
+
/* Define to 1 if you have the <malloc.h> header file. */
/* #undef HAVE_MALLOC_H 1 Already defined in AndroidConfig.h */
@@ -137,12 +127,18 @@
/* Define to 1 if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
+/* Define to 1 if you have the <poll.h> header file. */
+#define HAVE_POLL_H 1
+
/* Define to 1 if you have the `printf' function. */
#define HAVE_PRINTF 1
/* Define if <pthread.h> is there */
/* #undef HAVE_PTHREAD_H */
+/* Define to 1 if you have the `rand' function. */
+#define HAVE_RAND 1
+
/* Define to 1 if you have the <resolv.h> header file. */
#define HAVE_RESOLV_H 1
@@ -161,6 +157,9 @@
/* Define to 1 if you have the `sprintf' function. */
#define HAVE_SPRINTF 1
+/* Define to 1 if you have the `srand' function. */
+#define HAVE_SRAND 1
+
/* Define to 1 if you have the `sscanf' function. */
#define HAVE_SSCANF 1
@@ -223,6 +222,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
+/* Define to 1 if you have the `time' function. */
+#define HAVE_TIME 1
+
/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1
@@ -253,6 +255,10 @@
/* Define as const if the declaration of iconv() needs const. */
/* #undef ICONV_CONST */
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#define LT_OBJDIR ".libs/"
+
/* Name of package */
#define PACKAGE "libxml2"
@@ -268,6 +274,9 @@
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
@@ -281,7 +290,7 @@
/* #undef SUPPORT_IP6 */
/* Version number of package */
-#define VERSION "2.7.3"
+#define VERSION "2.7.8"
/* Determine what socket length (socklen_t) data type is */
#define XML_SOCKLEN_T socklen_t
diff --git a/debugXML.c b/debugXML.c
index b56651b..c26217a 100644
--- a/debugXML.c
+++ b/debugXML.c
@@ -259,7 +259,9 @@
"Name is not an NCName '%s'", (const char *) name);
}
if ((ctxt->dict != NULL) &&
- (!xmlDictOwns(ctxt->dict, name))) {
+ (!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'",
(const char *) name);
@@ -2801,7 +2803,6 @@
{
char prompt[500] = "/ > ";
char *cmdline = NULL, *cur;
- int nbargs;
char command[100];
char arg[400];
int i;
@@ -2853,7 +2854,6 @@
* Parse the command itself
*/
cur = cmdline;
- nbargs = 0;
while ((*cur == ' ') || (*cur == '\t'))
cur++;
i = 0;
@@ -2866,7 +2866,6 @@
command[i] = 0;
if (i == 0)
continue;
- nbargs++;
/*
* Parse the argument
@@ -2880,8 +2879,6 @@
arg[i++] = *cur++;
}
arg[i] = 0;
- if (i != 0)
- nbargs++;
/*
* start interpreting the command
@@ -2944,7 +2941,7 @@
xmlGenericError(xmlGenericErrorContext,
"Write command requires a filename argument\n");
else
- xmlShellWrite(ctxt, arg, NULL, NULL);
+ xmlShellWrite(ctxt, arg, ctxt->node, NULL);
#endif /* LIBXML_OUTPUT_ENABLED */
} else if (!strcmp(command, "grep")) {
xmlShellGrep(ctxt, arg, ctxt->node, NULL);
diff --git a/dict.c b/dict.c
index 0e07e8d..ae4966b 100644
--- a/dict.c
+++ b/dict.c
@@ -2,7 +2,7 @@
* dict.c: dictionary of reusable strings, just used to avoid allocation
* and freeing operations.
*
- * Copyright (C) 2003 Daniel Veillard.
+ * Copyright (C) 2003-2012 Daniel Veillard.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -19,6 +19,28 @@
#define IN_LIBXML
#include "libxml.h"
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+/*
+ * Following http://www.ocert.org/advisories/ocert-2011-003.html
+ * it seems that having hash randomization might be a good idea
+ * when using XML with untrusted data
+ * Note1: that it works correctly only if compiled with WITH_BIG_KEY
+ * which is the default.
+ * Note2: the fast function used for a small dict won't protect very
+ * well but since the attack is based on growing a very big hash
+ * list we will use the BigKey algo as soon as the hash size grows
+ * over MIN_DICT_SIZE so this actually works
+ */
+#if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME)
+#define DICT_RANDOMIZATION
+#endif
+
#include <string.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
@@ -44,23 +66,23 @@
#define WITH_BIG_KEY
#ifdef WITH_BIG_KEY
-#define xmlDictComputeKey(dict, name, len) \
- (((dict)->size == MIN_DICT_SIZE) ? \
- xmlDictComputeFastKey(name, len) : \
- xmlDictComputeBigKey(name, len))
+#define xmlDictComputeKey(dict, name, len) \
+ (((dict)->size == MIN_DICT_SIZE) ? \
+ xmlDictComputeFastKey(name, len, (dict)->seed) : \
+ xmlDictComputeBigKey(name, len, (dict)->seed))
-#define xmlDictComputeQKey(dict, prefix, plen, name, len) \
- (((prefix) == NULL) ? \
- (xmlDictComputeKey(dict, name, len)) : \
- (((dict)->size == MIN_DICT_SIZE) ? \
- xmlDictComputeFastQKey(prefix, plen, name, len) : \
- xmlDictComputeBigQKey(prefix, plen, name, len)))
+#define xmlDictComputeQKey(dict, prefix, plen, name, len) \
+ (((prefix) == NULL) ? \
+ (xmlDictComputeKey(dict, name, len)) : \
+ (((dict)->size == MIN_DICT_SIZE) ? \
+ xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed) : \
+ xmlDictComputeBigQKey(prefix, plen, name, len, (dict)->seed)))
#else /* !WITH_BIG_KEY */
-#define xmlDictComputeKey(dict, name, len) \
- xmlDictComputeFastKey(name, len)
-#define xmlDictComputeQKey(dict, prefix, plen, name, len) \
- xmlDictComputeFastQKey(prefix, plen, name, len)
+#define xmlDictComputeKey(dict, name, len) \
+ xmlDictComputeFastKey(name, len, (dict)->seed)
+#define xmlDictComputeQKey(dict, prefix, plen, name, len) \
+ xmlDictComputeFastQKey(prefix, plen, name, len, (dict)->seed)
#endif /* WITH_BIG_KEY */
/*
@@ -98,6 +120,8 @@
xmlDictStringsPtr strings;
struct _xmlDict *subdict;
+ /* used for randomization */
+ int seed;
};
/*
@@ -125,6 +149,9 @@
if ((xmlDictMutex = xmlNewRMutex()) == NULL)
return(0);
+#ifdef DICT_RANDOMIZATION
+ srand(time(NULL));
+#endif
xmlDictInitialized = 1;
return(1);
}
@@ -277,13 +304,13 @@
*/
static uint32_t
-xmlDictComputeBigKey(const xmlChar* data, int namelen) {
+xmlDictComputeBigKey(const xmlChar* data, int namelen, int seed) {
uint32_t hash;
int i;
if (namelen <= 0 || data == NULL) return(0);
- hash = 0;
+ hash = seed;
for (i = 0;i < namelen; i++) {
hash += data[i];
@@ -310,12 +337,12 @@
*/
static unsigned long
xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
- const xmlChar *name, int len)
+ const xmlChar *name, int len, int seed)
{
uint32_t hash;
int i;
- hash = 0;
+ hash = seed;
for (i = 0;i < plen; i++) {
hash += prefix[i];
@@ -346,8 +373,8 @@
* for low hash table fill.
*/
static unsigned long
-xmlDictComputeFastKey(const xmlChar *name, int namelen) {
- unsigned long value = 0L;
+xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
+ unsigned long value = seed;
if (name == NULL) return(0);
value = *name;
@@ -381,9 +408,9 @@
*/
static unsigned long
xmlDictComputeFastQKey(const xmlChar *prefix, int plen,
- const xmlChar *name, int len)
+ const xmlChar *name, int len, int seed)
{
- unsigned long value = 0L;
+ unsigned long value = (unsigned long) seed;
if (plen == 0)
value += 30 * (unsigned long) ':';
@@ -460,6 +487,11 @@
dict->subdict = NULL;
if (dict->dict) {
memset(dict->dict, 0, MIN_DICT_SIZE * sizeof(xmlDictEntry));
+#ifdef DICT_RANDOMIZATION
+ dict->seed = rand();
+#else
+ dict->seed = 0;
+#endif
return(dict);
}
xmlFree(dict);
@@ -486,6 +518,7 @@
#ifdef DICT_DEBUG_PATTERNS
fprintf(stderr, "R");
#endif
+ dict->seed = sub->seed;
dict->subdict = sub;
xmlDictReference(dict->subdict);
}
@@ -698,7 +731,6 @@
inside_dict = 0;
iter = next;
}
- inside_dict = 0;
}
xmlFree(dict->dict);
}
diff --git a/elfgcchack.h b/elfgcchack.h
index 14cad6d..84e8151 100644
--- a/elfgcchack.h
+++ b/elfgcchack.h
@@ -15491,6 +15491,18 @@
#if defined(LIBXML_XINCLUDE_ENABLED)
#ifdef bottom_xinclude
+#undef xmlXIncludeProcessTreeFlagsData
+extern __typeof (xmlXIncludeProcessTreeFlagsData) xmlXIncludeProcessTreeFlagsData __attribute((alias("xmlXIncludeProcessTreeFlagsData__internal_alias")));
+#else
+#ifndef xmlXIncludeProcessTreeFlagsData
+extern __typeof (xmlXIncludeProcessTreeFlagsData) xmlXIncludeProcessTreeFlagsData__internal_alias __attribute((visibility("hidden")));
+#define xmlXIncludeProcessTreeFlagsData xmlXIncludeProcessTreeFlagsData__internal_alias
+#endif
+#endif
+#endif
+
+#if defined(LIBXML_XINCLUDE_ENABLED)
+#ifdef bottom_xinclude
#undef xmlXIncludeSetFlags
extern __typeof (xmlXIncludeSetFlags) xmlXIncludeSetFlags __attribute((alias("xmlXIncludeSetFlags__internal_alias")));
#else
diff --git a/encoding.c b/encoding.c
index 2abc32e..fb0c38a 100644
--- a/encoding.c
+++ b/encoding.c
@@ -1,7 +1,7 @@
/*
* encoding.c : implements the encoding conversion functions needed for XML
*
- * Related specs:
+ * Related specs:
* rfc2044 (UTF-8 and UTF-16) F. Yergeau Alis Technologies
* rfc2781 UTF-16, an encoding of ISO 10646, P. Hoffman, F. Yergeau
* [ISO-10646] UTF-8 and UTF-16 in Annexes
@@ -98,7 +98,7 @@
}
#ifdef LIBXML_ICU_ENABLED
-static uconv_t*
+static uconv_t*
openIcuConverter(const char* name, int toUnicode)
{
UErrorCode status = U_ZERO_ERROR;
@@ -112,11 +112,11 @@
status = U_ZERO_ERROR;
if (toUnicode) {
- ucnv_setToUCallBack(conv->uconv, UCNV_TO_U_CALLBACK_STOP,
+ ucnv_setToUCallBack(conv->uconv, UCNV_TO_U_CALLBACK_STOP,
NULL, NULL, NULL, &status);
}
else {
- ucnv_setFromUCallBack(conv->uconv, UCNV_FROM_U_CALLBACK_STOP,
+ ucnv_setFromUCallBack(conv->uconv, UCNV_FROM_U_CALLBACK_STOP,
NULL, NULL, NULL, &status);
}
if (U_FAILURE(status))
@@ -128,7 +128,7 @@
return conv;
error:
- if (conv->uconv)
+ if (conv->uconv)
ucnv_close(conv->uconv);
xmlFree(conv);
return NULL;
@@ -183,12 +183,12 @@
break;
if (c < 0x80) {
*out++ = c;
- } else {
+ } else {
*outlen = out - outstart;
*inlen = processed - base;
return(-1);
}
-
+
processed = (const unsigned char*) in;
}
*outlen = out - outstart;
@@ -254,7 +254,7 @@
if (inend - in < trailing) {
break;
- }
+ }
for ( ; trailing; trailing--) {
if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
@@ -311,19 +311,19 @@
outend = out + *outlen;
inend = in + (*inlen);
instop = inend;
-
- while (in < inend && out < outend - 1) {
- if (*in >= 0x80) {
+
+ while ((in < inend) && (out < outend - 1)) {
+ if (*in >= 0x80) {
*out++ = (((*in) >> 6) & 0x1F) | 0xC0;
- *out++ = ((*in) & 0x3F) | 0x80;
+ *out++ = ((*in) & 0x3F) | 0x80;
++in;
}
- if (instop - in > outend - out) instop = in + (outend - out);
- while (in < instop && *in < 0x80) {
+ if ((instop - in) > (outend - out)) instop = in + (outend - out);
+ while ((in < instop) && (*in < 0x80)) {
*out++ = *in++;
}
- }
- if (in < inend && out < outend && *in < 0x80) {
+ }
+ if ((in < inend) && (out < outend) && (*in < 0x80)) {
*out++ = *in++;
}
*outlen = out - outstart;
@@ -427,7 +427,7 @@
if (inend - in < trailing) {
break;
- }
+ }
for ( ; trailing; trailing--) {
if (in >= inend)
@@ -535,7 +535,7 @@
else if (c < 0x800) { *out++= ((c >> 6) & 0x1F) | 0xC0; bits= 0; }
else if (c < 0x10000) { *out++= ((c >> 12) & 0x0F) | 0xE0; bits= 6; }
else { *out++= ((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
+
for ( ; bits >= 0; bits-= 6) {
if (out >= outend)
break;
@@ -560,7 +560,7 @@
* block of chars out.
*
* Returns the number of bytes written, or -1 if lack of space, or -2
- * if the transcoding failed.
+ * if the transcoding failed.
*/
static int
UTF8ToUTF16LE(unsigned char* outb, int *outlen,
@@ -606,7 +606,7 @@
if (inend - in < trailing) {
break;
- }
+ }
for ( ; trailing; trailing--) {
if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80))
@@ -669,7 +669,7 @@
* block of chars out.
*
* Returns the number of bytes written, or -1 if lack of space, or -2
- * if the transcoding failed.
+ * if the transcoding failed.
*/
static int
UTF8ToUTF16(unsigned char* outb, int *outlen,
@@ -741,7 +741,7 @@
in++;
} else {
c= *in++;
- }
+ }
if ((c & 0xFC00) == 0xD800) { /* surrogates */
if (in >= inend) { /* (in > inend) shouldn't happens */
*outlen = out - outstart;
@@ -771,15 +771,15 @@
}
/* assertion: c is a single UTF-4 value */
- if (out >= outend)
+ if (out >= outend)
break;
if (c < 0x80) { *out++= c; bits= -6; }
else if (c < 0x800) { *out++= ((c >> 6) & 0x1F) | 0xC0; bits= 0; }
else if (c < 0x10000) { *out++= ((c >> 12) & 0x0F) | 0xE0; bits= 6; }
else { *out++= ((c >> 18) & 0x07) | 0xF0; bits= 12; }
-
+
for ( ; bits >= 0; bits-= 6) {
- if (out >= outend)
+ if (out >= outend)
break;
*out++= ((c >> bits) & 0x3F) | 0x80;
}
@@ -802,7 +802,7 @@
* block of chars out.
*
* Returns the number of byte written, or -1 by lack of space, or -2
- * if the transcoding failed.
+ * if the transcoding failed.
*/
static int
UTF8ToUTF16BE(unsigned char* outb, int *outlen,
@@ -848,7 +848,7 @@
if (inend - in < trailing) {
break;
- }
+ }
for ( ; trailing; trailing--) {
if ((in >= inend) || (((d= *in++) & 0xC0) != 0x80)) break;
@@ -912,13 +912,13 @@
*
* Guess the encoding of the entity using the first bytes of the entity content
* according to the non-normative appendix F of the XML-1.0 recommendation.
- *
+ *
* Returns one of the XML_CHAR_ENCODING_... values.
*/
xmlCharEncoding
xmlDetectCharEncoding(const unsigned char* in, int len)
{
- if (in == NULL)
+ if (in == NULL)
return(XML_CHAR_ENCODING_NONE);
if (len >= 4) {
if ((in[0] == 0x00) && (in[1] == 0x00) &&
@@ -999,7 +999,7 @@
* @alias: the alias name as parsed, in UTF-8 format (ASCII actually)
*
* Lookup an encoding name for the given alias.
- *
+ *
* Returns NULL if not found, otherwise the original name
*/
const char *
@@ -1037,7 +1037,7 @@
*
* Registers an alias @alias for an encoding named @name. Existing alias
* will be overwritten.
- *
+ *
* Returns 0 in case of success, -1 in case of error
*/
int
@@ -1057,13 +1057,13 @@
if (xmlCharEncodingAliases == NULL) {
xmlCharEncodingAliasesNb = 0;
xmlCharEncodingAliasesMax = 20;
- xmlCharEncodingAliases = (xmlCharEncodingAliasPtr)
+ xmlCharEncodingAliases = (xmlCharEncodingAliasPtr)
xmlMalloc(xmlCharEncodingAliasesMax * sizeof(xmlCharEncodingAlias));
if (xmlCharEncodingAliases == NULL)
return(-1);
} else if (xmlCharEncodingAliasesNb >= xmlCharEncodingAliasesMax) {
xmlCharEncodingAliasesMax *= 2;
- xmlCharEncodingAliases = (xmlCharEncodingAliasPtr)
+ xmlCharEncodingAliases = (xmlCharEncodingAliasPtr)
xmlRealloc(xmlCharEncodingAliases,
xmlCharEncodingAliasesMax * sizeof(xmlCharEncodingAlias));
}
@@ -1094,7 +1094,7 @@
* @alias: the alias name as parsed, in UTF-8 format (ASCII actually)
*
* Unregisters an encoding alias @alias
- *
+ *
* Returns 0 in case of success, -1 in case of error
*/
int
@@ -1129,7 +1129,7 @@
* Compare the string to the encoding schemes already known. Note
* that the comparison is case insensitive accordingly to the section
* [XML] 4.3.3 Character Encoding in Entities.
- *
+ *
* Returns one of the XML_CHAR_ENCODING_... values or XML_CHAR_ENCODING_NONE
* if not recognized.
*/
@@ -1166,7 +1166,7 @@
*/
if (!strcmp(upper, "UTF-16")) return(XML_CHAR_ENCODING_UTF16LE);
if (!strcmp(upper, "UTF16")) return(XML_CHAR_ENCODING_UTF16LE);
-
+
if (!strcmp(upper, "ISO-10646-UCS-2")) return(XML_CHAR_ENCODING_UCS2);
if (!strcmp(upper, "UCS-2")) return(XML_CHAR_ENCODING_UCS2);
if (!strcmp(upper, "UCS2")) return(XML_CHAR_ENCODING_UCS2);
@@ -1179,7 +1179,7 @@
if (!strcmp(upper, "UCS-4")) return(XML_CHAR_ENCODING_UCS4LE);
if (!strcmp(upper, "UCS4")) return(XML_CHAR_ENCODING_UCS4LE);
-
+
if (!strcmp(upper, "ISO-8859-1")) return(XML_CHAR_ENCODING_8859_1);
if (!strcmp(upper, "ISO-LATIN-1")) return(XML_CHAR_ENCODING_8859_1);
if (!strcmp(upper, "ISO LATIN 1")) return(XML_CHAR_ENCODING_8859_1);
@@ -1302,7 +1302,7 @@
* Returns the xmlCharEncodingHandlerPtr created (or NULL in case of error).
*/
xmlCharEncodingHandlerPtr
-xmlNewCharEncodingHandler(const char *name,
+xmlNewCharEncodingHandler(const char *name,
xmlCharEncodingInputFunc input,
xmlCharEncodingOutputFunc output) {
xmlCharEncodingHandlerPtr handler;
@@ -1347,6 +1347,7 @@
xmlEncodingErrMemory("xmlNewCharEncodingHandler : out of memory !\n");
return(NULL);
}
+ memset(handler, 0, sizeof(xmlCharEncodingHandler));
handler->input = input;
handler->output = output;
handler->name = up;
@@ -1382,7 +1383,7 @@
void
xmlInitCharEncodingHandlers(void) {
unsigned short int tst = 0x1234;
- unsigned char *ptr = (unsigned char *) &tst;
+ unsigned char *ptr = (unsigned char *) &tst;
if (handlers != NULL) return;
@@ -1402,9 +1403,9 @@
}
xmlNewCharEncodingHandler("UTF-8", UTF8ToUTF8, UTF8ToUTF8);
#ifdef LIBXML_OUTPUT_ENABLED
- xmlUTF16LEHandler =
+ xmlUTF16LEHandler =
xmlNewCharEncodingHandler("UTF-16LE", UTF16LEToUTF8, UTF8ToUTF16LE);
- xmlUTF16BEHandler =
+ xmlUTF16BEHandler =
xmlNewCharEncodingHandler("UTF-16BE", UTF16BEToUTF8, UTF8ToUTF16BE);
xmlNewCharEncodingHandler("UTF-16", UTF16LEToUTF8, UTF8ToUTF16);
xmlNewCharEncodingHandler("ISO-8859-1", isolat1ToUTF8, UTF8Toisolat1);
@@ -1414,9 +1415,9 @@
xmlNewCharEncodingHandler("HTML", NULL, UTF8ToHtml);
#endif
#else
- xmlUTF16LEHandler =
+ xmlUTF16LEHandler =
xmlNewCharEncodingHandler("UTF-16LE", UTF16LEToUTF8, NULL);
- xmlUTF16BEHandler =
+ xmlUTF16BEHandler =
xmlNewCharEncodingHandler("UTF-16BE", UTF16BEToUTF8, NULL);
xmlNewCharEncodingHandler("UTF-16", UTF16LEToUTF8, NULL);
xmlNewCharEncodingHandler("ISO-8859-1", isolat1ToUTF8, NULL);
@@ -1466,7 +1467,7 @@
void
xmlRegisterCharEncodingHandler(xmlCharEncodingHandlerPtr handler) {
if (handlers == NULL) xmlInitCharEncodingHandlers();
- if (handler == NULL) {
+ if ((handler == NULL) || (handlers == NULL)) {
xmlEncodingErr(XML_I18N_NO_HANDLER,
"xmlRegisterCharEncodingHandler: NULL handler !\n", NULL);
return;
@@ -1510,6 +1511,8 @@
if (handler != NULL) return(handler);
handler = xmlFindCharEncodingHandler("ebcdic");
if (handler != NULL) return(handler);
+ handler = xmlFindCharEncodingHandler("EBCDIC-US");
+ if (handler != NULL) return(handler);
break;
case XML_CHAR_ENCODING_UCS4BE:
handler = xmlFindCharEncodingHandler("ISO-10646-UCS-4");
@@ -1600,10 +1603,10 @@
handler = xmlFindCharEncodingHandler("EUC-JP");
if (handler != NULL) return(handler);
break;
- default:
+ default:
break;
}
-
+
#ifdef DEBUG_ENCODING
xmlGenericError(xmlGenericErrorContext,
"No handler found for encoding %d\n", enc);
@@ -1629,7 +1632,7 @@
iconv_t icv_in, icv_out;
#endif /* LIBXML_ICONV_ENABLED */
#ifdef LIBXML_ICU_ENABLED
- xmlCharEncodingHandlerPtr enc;
+ xmlCharEncodingHandlerPtr encu;
uconv_t *ucv_in, *ucv_out;
#endif /* LIBXML_ICU_ENABLED */
char upper[100];
@@ -1656,14 +1659,17 @@
}
upper[i] = 0;
- for (i = 0;i < nbCharEncodingHandler; i++)
- if (!strcmp(upper, handlers[i]->name)) {
+ if (handlers != NULL) {
+ for (i = 0;i < nbCharEncodingHandler; i++) {
+ if (!strcmp(upper, handlers[i]->name)) {
#ifdef DEBUG_ENCODING
- xmlGenericError(xmlGenericErrorContext,
- "Found registered handler for encoding %s\n", name);
+ xmlGenericError(xmlGenericErrorContext,
+ "Found registered handler for encoding %s\n", name);
#endif
- return(handlers[i]);
- }
+ return(handlers[i]);
+ }
+ }
+ }
#ifdef LIBXML_ICONV_ENABLED
/* check whether iconv can handle this */
@@ -1683,6 +1689,7 @@
iconv_close(icv_out);
return(NULL);
}
+ memset(enc, 0, sizeof(xmlCharEncodingHandler));
enc->name = xmlMemStrdup(name);
enc->input = NULL;
enc->output = NULL;
@@ -1703,23 +1710,24 @@
ucv_in = openIcuConverter(name, 1);
ucv_out = openIcuConverter(name, 0);
if (ucv_in != NULL && ucv_out != NULL) {
- enc = (xmlCharEncodingHandlerPtr)
- xmlMalloc(sizeof(xmlCharEncodingHandler));
- if (enc == NULL) {
+ encu = (xmlCharEncodingHandlerPtr)
+ xmlMalloc(sizeof(xmlCharEncodingHandler));
+ if (encu == NULL) {
closeIcuConverter(ucv_in);
closeIcuConverter(ucv_out);
return(NULL);
}
- enc->name = xmlMemStrdup(name);
- enc->input = NULL;
- enc->output = NULL;
- enc->uconv_in = ucv_in;
- enc->uconv_out = ucv_out;
+ memset(encu, 0, sizeof(xmlCharEncodingHandler));
+ encu->name = xmlMemStrdup(name);
+ encu->input = NULL;
+ encu->output = NULL;
+ encu->uconv_in = ucv_in;
+ encu->uconv_out = ucv_out;
#ifdef DEBUG_ENCODING
xmlGenericError(xmlGenericErrorContext,
"Found ICU converter handler for encoding %s\n", name);
#endif
- return enc;
+ return encu;
} else if (ucv_in != NULL || ucv_out != NULL) {
closeIcuConverter(ucv_in);
closeIcuConverter(ucv_out);
@@ -1764,12 +1772,12 @@
* @in: a pointer to an array of ISO Latin 1 chars
* @inlen: the length of @in
*
- * Returns 0 if success, or
+ * Returns 0 if success, or
* -1 by lack of space, or
* -2 if the transcoding fails (for *in is not valid utf8 string or
* the result of transformation can't fit into the encoding we want), or
* -3 if there the last byte can't form a single output char.
- *
+ *
* The value of @inlen after return is the number of octets consumed
* as the return value is positive, else unpredictable.
* The value of @outlen after return is the number of ocetes consumed.
@@ -1831,12 +1839,12 @@
* @in: a pointer to an array of ISO Latin 1 chars
* @inlen: the length of @in
*
- * Returns 0 if success, or
+ * Returns 0 if success, or
* -1 by lack of space, or
* -2 if the transcoding fails (for *in is not valid utf8 string or
* the result of transformation can't fit into the encoding we want), or
* -3 if there the last byte can't form a single output char.
- *
+ *
* The value of @inlen after return is the number of octets consumed
* as the return value is positive, else unpredictable.
* The value of @outlen after return is the number of ocetes consumed.
@@ -1853,7 +1861,7 @@
return(-1);
}
- /*
+ /*
* TODO(jungshik)
* 1. is ucnv_convert(To|From)Algorithmic better?
* 2. had we better use an explicit pivot buffer?
@@ -1871,7 +1879,7 @@
&ucv_in, ucv_in + *inlen, NULL, NULL, NULL, NULL,
0, TRUE, &err);
}
- *inlen = ucv_in - (const char*) in;
+ *inlen = ucv_in - (const char*) in;
*outlen = ucv_out - (char *) out;
if (U_SUCCESS(err))
return 0;
@@ -1889,24 +1897,28 @@
* The real API used by libxml for on-the-fly conversion *
* *
************************************************************************/
+int
+xmlCharEncFirstLineInt(xmlCharEncodingHandler *handler, xmlBufferPtr out,
+ xmlBufferPtr in, int len);
/**
- * xmlCharEncFirstLine:
+ * xmlCharEncFirstLineInt:
* @handler: char enconding transformation data structure
* @out: an xmlBuffer for the output.
* @in: an xmlBuffer for the input
- *
+ * @len: number of bytes to convert for the first line, or -1
+ *
* Front-end for the encoding handler input function, but handle only
* the very first line, i.e. limit itself to 45 chars.
- *
- * Returns the number of byte written if success, or
+ *
+ * Returns the number of byte written if success, or
* -1 general error
* -2 if the transcoding fails (for *in is not valid utf8 string or
* the result of transformation can't fit into the encoding we want), or
*/
int
-xmlCharEncFirstLine(xmlCharEncodingHandler *handler, xmlBufferPtr out,
- xmlBufferPtr in) {
+xmlCharEncFirstLineInt(xmlCharEncodingHandler *handler, xmlBufferPtr out,
+ xmlBufferPtr in, int len) {
int ret = -2;
int written;
int toconv;
@@ -1916,16 +1928,23 @@
if (in == NULL) return(-1);
/* calculate space available */
- written = out->size - out->use;
+ written = out->size - out->use - 1; /* count '\0' */
toconv = in->use;
/*
* echo '<?xml version="1.0" encoding="UCS4"?>' | wc -c => 38
* 45 chars should be sufficient to reach the end of the encoding
* declaration without going too far inside the document content.
* on UTF-16 this means 90bytes, on UCS4 this means 180
+ * The actual value depending on guessed encoding is passed as @len
+ * if provided
*/
- if (toconv > 180)
- toconv = 180;
+ if (len >= 0) {
+ if (toconv > len)
+ toconv = len;
+ } else {
+ if (toconv > 180)
+ toconv = 180;
+ }
if (toconv * 2 >= written) {
xmlBufferGrow(out, toconv);
written = out->size - out->use - 1;
@@ -1990,14 +2009,34 @@
}
/**
+ * xmlCharEncFirstLine:
+ * @handler: char enconding transformation data structure
+ * @out: an xmlBuffer for the output.
+ * @in: an xmlBuffer for the input
+ *
+ * Front-end for the encoding handler input function, but handle only
+ * the very first line, i.e. limit itself to 45 chars.
+ *
+ * Returns the number of byte written if success, or
+ * -1 general error
+ * -2 if the transcoding fails (for *in is not valid utf8 string or
+ * the result of transformation can't fit into the encoding we want), or
+ */
+int
+xmlCharEncFirstLine(xmlCharEncodingHandler *handler, xmlBufferPtr out,
+ xmlBufferPtr in) {
+ return(xmlCharEncFirstLineInt(handler, out, in, -1));
+}
+
+/**
* xmlCharEncInFunc:
* @handler: char encoding transformation data structure
* @out: an xmlBuffer for the output.
* @in: an xmlBuffer for the input
- *
+ *
* Generic front-end for the encoding handler input function
- *
- * Returns the number of byte written if success, or
+ *
+ * Returns the number of byte written if success, or
* -1 general error
* -2 if the transcoding fails (for *in is not valid utf8 string or
* the result of transformation can't fit into the encoding we want), or
@@ -2020,7 +2059,7 @@
toconv = in->use;
if (toconv == 0)
return (0);
- written = out->size - out->use;
+ written = out->size - out->use -1; /* count '\0' */
if (toconv * 2 >= written) {
xmlBufferGrow(out, out->size + toconv * 2);
written = out->size - out->use - 1;
@@ -2079,7 +2118,7 @@
case -2: {
char buf[50];
- snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X",
+ snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X",
in->content[0], in->content[1],
in->content[2], in->content[3]);
buf[49] = 0;
@@ -2101,15 +2140,15 @@
* @handler: char enconding transformation data structure
* @out: an xmlBuffer for the output.
* @in: an xmlBuffer for the input
- *
+ *
* Generic front-end for the encoding handler output function
- * a first call with @in == NULL has to be made firs to initiate the
+ * a first call with @in == NULL has to be made firs to initiate the
* output in case of non-stateless encoding needing to initiate their
* state or the output (like the BOM in UTF16).
* In case of UTF8 sequence conversion errors for the given encoder,
* the content will be automatically remapped to a CharRef sequence.
- *
- * Returns the number of byte written if success, or
+ *
+ * Returns the number of byte written if success, or
* -1 general error
* -2 if the transcoding fails (for *in is not valid utf8 string or
* the result of transformation can't fit into the encoding we want), or
@@ -2127,7 +2166,7 @@
if (out == NULL) return(-1);
retry:
-
+
written = out->size - out->use;
if (written > 0)
@@ -2290,7 +2329,7 @@
} else {
char buf[50];
- snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X",
+ snprintf(&buf[0], 49, "0x%02X 0x%02X 0x%02X 0x%02X",
in->content[0], in->content[1],
in->content[2], in->content[3]);
buf[49] = 0;
@@ -2309,7 +2348,7 @@
/**
* xmlCharEncCloseFunc:
* @handler: char enconding transformation data structure
- *
+ *
* Generic front-end for encoding handler close function
*
* Returns 0 if success, or -1 in case of error
@@ -2317,6 +2356,7 @@
int
xmlCharEncCloseFunc(xmlCharEncodingHandler *handler) {
int ret = 0;
+ int tofree = 0;
if (handler == NULL) return(-1);
if (handler->name == NULL) return(-1);
#ifdef LIBXML_ICONV_ENABLED
@@ -2325,9 +2365,7 @@
* and the associated icon resources.
*/
if ((handler->iconv_out != NULL) || (handler->iconv_in != NULL)) {
- if (handler->name != NULL)
- xmlFree(handler->name);
- handler->name = NULL;
+ tofree = 1;
if (handler->iconv_out != NULL) {
if (iconv_close(handler->iconv_out))
ret = -1;
@@ -2338,14 +2376,11 @@
ret = -1;
handler->iconv_in = NULL;
}
- xmlFree(handler);
}
#endif /* LIBXML_ICONV_ENABLED */
#ifdef LIBXML_ICU_ENABLED
if ((handler->uconv_out != NULL) || (handler->uconv_in != NULL)) {
- if (handler->name != NULL)
- xmlFree(handler->name);
- handler->name = NULL;
+ tofree = 1;
if (handler->uconv_out != NULL) {
closeIcuConverter(handler->uconv_out);
handler->uconv_out = NULL;
@@ -2354,9 +2389,15 @@
closeIcuConverter(handler->uconv_in);
handler->uconv_in = NULL;
}
- xmlFree(handler);
}
#endif
+ if (tofree) {
+ /* free up only dynamic handlers iconv/uconv */
+ if (handler->name != NULL)
+ xmlFree(handler->name);
+ handler->name = NULL;
+ xmlFree(handler);
+ }
#ifdef DEBUG_ENCODING
if (ret)
xmlGenericError(xmlGenericErrorContext,
@@ -2386,7 +2427,7 @@
long
xmlByteConsumed(xmlParserCtxtPtr ctxt) {
xmlParserInputPtr in;
-
+
if (ctxt == NULL) return(-1);
in = ctxt->input;
if (in == NULL) return(-1);
@@ -2448,6 +2489,7 @@
unused += written;
cur += toconv;
} while (ret == -2);
+#endif
} else {
/* could not find a converter */
return(-1);
@@ -2459,7 +2501,6 @@
}
return(in->consumed + (in->cur - in->base));
}
-#endif
#if !defined(LIBXML_ICONV_ENABLED) && !defined(LIBXML_ICU_ENABLED)
#ifdef LIBXML_ISO8859X_ENABLED
@@ -2487,6 +2528,7 @@
const unsigned char* outstart = out;
const unsigned char* inend;
const unsigned char* instart = in;
+ const unsigned char* processed = in;
if ((out == NULL) || (outlen == NULL) || (inlen == NULL) ||
(xlattable == NULL))
@@ -2503,81 +2545,82 @@
while (in < inend) {
unsigned char d = *in++;
if (d < 0x80) {
- *out++ = d;
+ *out++ = d;
} else if (d < 0xC0) {
/* trailing byte in leading position */
*outlen = out - outstart;
- *inlen = in - instart - 1;
+ *inlen = processed - instart;
return(-2);
} else if (d < 0xE0) {
unsigned char c;
if (!(in < inend)) {
/* trailing byte not in input buffer */
*outlen = out - outstart;
- *inlen = in - instart - 1;
- return(-2);
+ *inlen = processed - instart;
+ return(-3);
}
c = *in++;
if ((c & 0xC0) != 0x80) {
/* not a trailing byte */
*outlen = out - outstart;
- *inlen = in - instart - 2;
+ *inlen = processed - instart;
return(-2);
}
- c = c & 0x3F;
+ c = c & 0x3F;
d = d & 0x1F;
d = xlattable [48 + c + xlattable [d] * 64];
if (d == 0) {
/* not in character set */
*outlen = out - outstart;
- *inlen = in - instart - 2;
+ *inlen = processed - instart;
return(-2);
}
- *out++ = d;
+ *out++ = d;
} else if (d < 0xF0) {
unsigned char c1;
unsigned char c2;
if (!(in < inend - 1)) {
/* trailing bytes not in input buffer */
*outlen = out - outstart;
- *inlen = in - instart - 1;
- return(-2);
+ *inlen = processed - instart;
+ return(-3);
}
c1 = *in++;
if ((c1 & 0xC0) != 0x80) {
/* not a trailing byte (c1) */
*outlen = out - outstart;
- *inlen = in - instart - 2;
+ *inlen = processed - instart;
return(-2);
}
c2 = *in++;
if ((c2 & 0xC0) != 0x80) {
/* not a trailing byte (c2) */
*outlen = out - outstart;
- *inlen = in - instart - 2;
+ *inlen = processed - instart;
return(-2);
}
- c1 = c1 & 0x3F;
- c2 = c2 & 0x3F;
+ c1 = c1 & 0x3F;
+ c2 = c2 & 0x3F;
d = d & 0x0F;
- d = xlattable [48 + c2 + xlattable [48 + c1 +
+ d = xlattable [48 + c2 + xlattable [48 + c1 +
xlattable [32 + d] * 64] * 64];
if (d == 0) {
/* not in character set */
*outlen = out - outstart;
- *inlen = in - instart - 3;
+ *inlen = processed - instart;
return(-2);
}
- *out++ = d;
+ *out++ = d;
} else {
/* cannot transcode >= U+010000 */
*outlen = out - outstart;
- *inlen = in - instart - 1;
+ *inlen = processed - instart;
return(-2);
}
+ processed = in;
}
*outlen = out - outstart;
- *inlen = in - instart;
+ *inlen = processed - instart;
return(*outlen);
}
@@ -2611,16 +2654,16 @@
outend = out + *outlen;
inend = in + *inlen;
instop = inend;
- c = *in;
- while (in < inend && out < outend - 1) {
- if (c >= 0x80) {
- c = unicodetable [c - 0x80];
+
+ while ((in < inend) && (out < outend - 2)) {
+ if (*in >= 0x80) {
+ c = unicodetable [*in - 0x80];
if (c == 0) {
/* undefined code point */
*outlen = out - outstart;
*inlen = in - instart;
return (-1);
- }
+ }
if (c < 0x800) {
*out++ = ((c >> 6) & 0x1F) | 0xC0;
*out++ = (c & 0x3F) | 0x80;
@@ -2628,48 +2671,47 @@
*out++ = ((c >> 12) & 0x0F) | 0xE0;
*out++ = ((c >> 6) & 0x3F) | 0x80;
*out++ = (c & 0x3F) | 0x80;
- }
+ }
++in;
- c = *in;
}
- if (instop - in > outend - out) instop = in + (outend - out);
- while (c < 0x80 && in < instop) {
- *out++ = c;
- ++in;
- c = *in;
+ if (instop - in > outend - out) instop = in + (outend - out);
+ while ((*in < 0x80) && (in < instop)) {
+ *out++ = *in++;
}
- }
- if (in < inend && out < outend && c < 0x80) {
- *out++ = c;
- ++in;
+ }
+ if ((in < inend) && (out < outend) && (*in < 0x80)) {
+ *out++ = *in++;
+ }
+ if ((in < inend) && (out < outend) && (*in < 0x80)) {
+ *out++ = *in++;
}
*outlen = out - outstart;
*inlen = in - instart;
return (*outlen);
}
-
+
/************************************************************************
* Lookup tables for ISO-8859-2..ISO-8859-16 transcoding *
************************************************************************/
static unsigned short const xmlunicodetable_ISO8859_2 [128] = {
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
- 0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7,
- 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b,
- 0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7,
- 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c,
- 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7,
- 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
- 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7,
- 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
- 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7,
- 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
- 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7,
- 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7,
+ 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b,
+ 0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7,
+ 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c,
+ 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7,
+ 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
+ 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7,
+ 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
+ 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7,
+ 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
+ 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7,
+ 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9,
};
static unsigned char const xmltranscodetable_ISO8859_2 [48 + 6 * 64] = {
@@ -2703,22 +2745,22 @@
};
static unsigned short const xmlunicodetable_ISO8859_3 [128] = {
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
- 0x00a0, 0x0126, 0x02d8, 0x00a3, 0x00a4, 0x0000, 0x0124, 0x00a7,
- 0x00a8, 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, 0x0000, 0x017b,
- 0x00b0, 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7,
- 0x00b8, 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, 0x0000, 0x017c,
- 0x00c0, 0x00c1, 0x00c2, 0x0000, 0x00c4, 0x010a, 0x0108, 0x00c7,
- 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
- 0x0000, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7,
- 0x011c, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df,
- 0x00e0, 0x00e1, 0x00e2, 0x0000, 0x00e4, 0x010b, 0x0109, 0x00e7,
- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
- 0x0000, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7,
- 0x011d, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x0126, 0x02d8, 0x00a3, 0x00a4, 0x0000, 0x0124, 0x00a7,
+ 0x00a8, 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, 0x0000, 0x017b,
+ 0x00b0, 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7,
+ 0x00b8, 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, 0x0000, 0x017c,
+ 0x00c0, 0x00c1, 0x00c2, 0x0000, 0x00c4, 0x010a, 0x0108, 0x00c7,
+ 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+ 0x0000, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7,
+ 0x011c, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df,
+ 0x00e0, 0x00e1, 0x00e2, 0x0000, 0x00e4, 0x010b, 0x0109, 0x00e7,
+ 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x0000, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7,
+ 0x011d, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9,
};
static unsigned char const xmltranscodetable_ISO8859_3 [48 + 7 * 64] = {
@@ -2756,22 +2798,22 @@
};
static unsigned short const xmlunicodetable_ISO8859_4 [128] = {
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
- 0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x0128, 0x013b, 0x00a7,
- 0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af,
- 0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7,
- 0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b,
- 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e,
- 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a,
- 0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
- 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df,
- 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f,
- 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b,
- 0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
- 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x0128, 0x013b, 0x00a7,
+ 0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af,
+ 0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7,
+ 0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b,
+ 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e,
+ 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a,
+ 0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+ 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df,
+ 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f,
+ 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b,
+ 0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
+ 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9,
};
static unsigned char const xmltranscodetable_ISO8859_4 [48 + 6 * 64] = {
@@ -2805,22 +2847,22 @@
};
static unsigned short const xmlunicodetable_ISO8859_5 [128] = {
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
- 0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
- 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f,
- 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
- 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
- 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
- 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
- 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
- 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
- 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
- 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f,
- 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
- 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
+ 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f,
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+ 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+ 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+ 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f,
+ 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
+ 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f,
};
static unsigned char const xmltranscodetable_ISO8859_5 [48 + 6 * 64] = {
@@ -2854,22 +2896,22 @@
};
static unsigned short const xmlunicodetable_ISO8859_6 [128] = {
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
- 0x00a0, 0x0000, 0x0000, 0x0000, 0x00a4, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x060c, 0x00ad, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f,
- 0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
- 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f,
- 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637,
- 0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647,
- 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f,
- 0x0650, 0x0651, 0x0652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x0000, 0x0000, 0x0000, 0x00a4, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x060c, 0x00ad, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f,
+ 0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
+ 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f,
+ 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637,
+ 0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647,
+ 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f,
+ 0x0650, 0x0651, 0x0652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
};
static unsigned char const xmltranscodetable_ISO8859_6 [48 + 5 * 64] = {
@@ -2899,22 +2941,22 @@
};
static unsigned short const xmlunicodetable_ISO8859_7 [128] = {
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
- 0x00a0, 0x2018, 0x2019, 0x00a3, 0x0000, 0x0000, 0x00a6, 0x00a7,
- 0x00a8, 0x00a9, 0x0000, 0x00ab, 0x00ac, 0x00ad, 0x0000, 0x2015,
- 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x0385, 0x0386, 0x00b7,
- 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f,
- 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
- 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
- 0x03a0, 0x03a1, 0x0000, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
- 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af,
- 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
- 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
- 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7,
- 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0000,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x2018, 0x2019, 0x00a3, 0x0000, 0x0000, 0x00a6, 0x00a7,
+ 0x00a8, 0x00a9, 0x0000, 0x00ab, 0x00ac, 0x00ad, 0x0000, 0x2015,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x0385, 0x0386, 0x00b7,
+ 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f,
+ 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
+ 0x03a0, 0x03a1, 0x0000, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
+ 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af,
+ 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
+ 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
+ 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7,
+ 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0000,
};
static unsigned char const xmltranscodetable_ISO8859_7 [48 + 7 * 64] = {
@@ -2952,22 +2994,22 @@
};
static unsigned short const xmlunicodetable_ISO8859_8 [128] = {
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
- 0x00a0, 0x0000, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
- 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
- 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
- 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2017,
- 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7,
- 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df,
- 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7,
- 0x05e8, 0x05e9, 0x05ea, 0x0000, 0x0000, 0x200e, 0x200f, 0x0000,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x0000, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
+ 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
+ 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2017,
+ 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7,
+ 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df,
+ 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7,
+ 0x05e8, 0x05e9, 0x05ea, 0x0000, 0x0000, 0x200e, 0x200f, 0x0000,
};
static unsigned char const xmltranscodetable_ISO8859_8 [48 + 7 * 64] = {
@@ -3005,22 +3047,22 @@
};
static unsigned short const xmlunicodetable_ISO8859_9 [128] = {
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
- 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
- 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
- 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
- 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
- 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
- 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
- 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
- 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df,
- 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
- 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
- 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
+ 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
+ 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
+ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
+ 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+ 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+ 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df,
+ 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
+ 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
+ 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff,
};
static unsigned char const xmltranscodetable_ISO8859_9 [48 + 5 * 64] = {
@@ -3050,22 +3092,22 @@
};
static unsigned short const xmlunicodetable_ISO8859_10 [128] = {
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
- 0x00a0, 0x0104, 0x0112, 0x0122, 0x012a, 0x0128, 0x0136, 0x00a7,
- 0x013b, 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a,
- 0x00b0, 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7,
- 0x013c, 0x0111, 0x0161, 0x0167, 0x017e, 0x2015, 0x016b, 0x014b,
- 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e,
- 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf,
- 0x00d0, 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168,
- 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
- 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f,
- 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef,
- 0x00f0, 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169,
- 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x0104, 0x0112, 0x0122, 0x012a, 0x0128, 0x0136, 0x00a7,
+ 0x013b, 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a,
+ 0x00b0, 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7,
+ 0x013c, 0x0111, 0x0161, 0x0167, 0x017e, 0x2015, 0x016b, 0x014b,
+ 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e,
+ 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf,
+ 0x00d0, 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168,
+ 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+ 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f,
+ 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef,
+ 0x00f0, 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169,
+ 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138,
};
static unsigned char const xmltranscodetable_ISO8859_10 [48 + 7 * 64] = {
@@ -3103,22 +3145,22 @@
};
static unsigned short const xmlunicodetable_ISO8859_11 [128] = {
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
- 0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07,
- 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f,
- 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17,
- 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f,
- 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27,
- 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f,
- 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37,
- 0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e3f,
- 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47,
- 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f,
- 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57,
- 0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07,
+ 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f,
+ 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17,
+ 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f,
+ 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27,
+ 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f,
+ 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37,
+ 0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e3f,
+ 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47,
+ 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f,
+ 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57,
+ 0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0x0000, 0x0000, 0x0000, 0x0000,
};
static unsigned char const xmltranscodetable_ISO8859_11 [48 + 6 * 64] = {
@@ -3152,22 +3194,22 @@
};
static unsigned short const xmlunicodetable_ISO8859_13 [128] = {
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
- 0x00a0, 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x201e, 0x00a6, 0x00a7,
- 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6,
- 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, 0x00b5, 0x00b6, 0x00b7,
- 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6,
- 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112,
- 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b,
- 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7,
- 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df,
- 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113,
- 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c,
- 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7,
- 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x2019,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x201e, 0x00a6, 0x00a7,
+ 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, 0x00b5, 0x00b6, 0x00b7,
+ 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6,
+ 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112,
+ 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b,
+ 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7,
+ 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df,
+ 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113,
+ 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c,
+ 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7,
+ 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x2019,
};
static unsigned char const xmltranscodetable_ISO8859_13 [48 + 7 * 64] = {
@@ -3205,22 +3247,22 @@
};
static unsigned short const xmlunicodetable_ISO8859_14 [128] = {
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
- 0x00a0, 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7,
- 0x1e80, 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x0178,
- 0x1e1e, 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56,
- 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61,
- 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
- 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
- 0x0174, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a,
- 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df,
- 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
- 0x0175, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b,
- 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7,
+ 0x1e80, 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x0178,
+ 0x1e1e, 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56,
+ 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61,
+ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
+ 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+ 0x0174, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a,
+ 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df,
+ 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
+ 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x0175, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b,
+ 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff,
};
static unsigned char const xmltranscodetable_ISO8859_14 [48 + 10 * 64] = {
@@ -3270,22 +3312,22 @@
};
static unsigned short const xmlunicodetable_ISO8859_15 [128] = {
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
- 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7,
- 0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
- 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7,
- 0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf,
- 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
- 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
- 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
- 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
- 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
- 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
- 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7,
+ 0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7,
+ 0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf,
+ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
+ 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+ 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
+ 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+ 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
+ 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
+ 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff,
};
static unsigned char const xmltranscodetable_ISO8859_15 [48 + 6 * 64] = {
@@ -3319,22 +3361,22 @@
};
static unsigned short const xmlunicodetable_ISO8859_16 [128] = {
- 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
- 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
- 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
- 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
- 0x00a0, 0x0104, 0x0105, 0x0141, 0x20ac, 0x201e, 0x0160, 0x00a7,
- 0x0161, 0x00a9, 0x0218, 0x00ab, 0x0179, 0x00ad, 0x017a, 0x017b,
- 0x00b0, 0x00b1, 0x010c, 0x0142, 0x017d, 0x201d, 0x00b6, 0x00b7,
- 0x017e, 0x010d, 0x0219, 0x00bb, 0x0152, 0x0153, 0x0178, 0x017c,
- 0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0106, 0x00c6, 0x00c7,
- 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
- 0x0110, 0x0143, 0x00d2, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x015a,
- 0x0170, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0118, 0x021a, 0x00df,
- 0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x0107, 0x00e6, 0x00e7,
- 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
- 0x0111, 0x0144, 0x00f2, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x015b,
- 0x0171, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0119, 0x021b, 0x00ff,
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x00a0, 0x0104, 0x0105, 0x0141, 0x20ac, 0x201e, 0x0160, 0x00a7,
+ 0x0161, 0x00a9, 0x0218, 0x00ab, 0x0179, 0x00ad, 0x017a, 0x017b,
+ 0x00b0, 0x00b1, 0x010c, 0x0142, 0x017d, 0x201d, 0x00b6, 0x00b7,
+ 0x017e, 0x010d, 0x0219, 0x00bb, 0x0152, 0x0153, 0x0178, 0x017c,
+ 0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0106, 0x00c6, 0x00c7,
+ 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+ 0x0110, 0x0143, 0x00d2, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x015a,
+ 0x0170, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0118, 0x021a, 0x00df,
+ 0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x0107, 0x00e6, 0x00e7,
+ 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x0111, 0x0144, 0x00f2, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x015b,
+ 0x0171, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0119, 0x021b, 0x00ff,
};
static unsigned char const xmltranscodetable_ISO8859_16 [48 + 9 * 64] = {
diff --git a/entities.c b/entities.c
index c171e97..6aef49f 100644
--- a/entities.c
+++ b/entities.c
@@ -690,7 +690,7 @@
}
cur++;
}
- *out++ = 0;
+ *out = 0;
return(buffer);
}
@@ -772,7 +772,7 @@
}
cur++;
}
- *out++ = 0;
+ *out = 0;
return(buffer);
}
diff --git a/error.c b/error.c
index 5f03d94..a891faa 100644
--- a/error.c
+++ b/error.c
@@ -132,7 +132,7 @@
*/
void
xmlSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) {
- xmlGenericErrorContext = ctx;
+ xmlStructuredErrorContext = ctx;
xmlStructuredError = handler;
}
@@ -452,6 +452,8 @@
xmlErrorPtr to = &xmlLastError;
xmlNodePtr baseptr = NULL;
+ if (code == XML_ERR_OK)
+ return;
if ((xmlGetWarningsDefaultValue == 0) && (level == XML_ERR_WARNING))
return;
if ((domain == XML_FROM_PARSER) || (domain == XML_FROM_HTML) ||
@@ -459,8 +461,11 @@
(domain == XML_FROM_IO) || (domain == XML_FROM_VALID)) {
ctxt = (xmlParserCtxtPtr) ctx;
if ((schannel == NULL) && (ctxt != NULL) && (ctxt->sax != NULL) &&
- (ctxt->sax->initialized == XML_SAX2_MAGIC))
+ (ctxt->sax->initialized == XML_SAX2_MAGIC) &&
+ (ctxt->sax->serror != NULL)) {
schannel = ctxt->sax->serror;
+ data = ctxt->userData;
+ }
}
/*
* Check if structured error handler set
@@ -471,18 +476,8 @@
* if user has defined handler, change data ptr to user's choice
*/
if (schannel != NULL)
- data = xmlGenericErrorContext;
+ data = xmlStructuredErrorContext;
}
- if ((domain == XML_FROM_VALID) &&
- ((channel == xmlParserValidityError) ||
- (channel == xmlParserValidityWarning))) {
- ctxt = (xmlParserCtxtPtr) ctx;
- if ((schannel == NULL) && (ctxt != NULL) && (ctxt->sax != NULL) &&
- (ctxt->sax->initialized == XML_SAX2_MAGIC))
- schannel = ctxt->sax->serror;
- }
- if (code == XML_ERR_OK)
- return;
/*
* Formatting the message
*/
@@ -573,7 +568,6 @@
if ((to->file == NULL) && (node != NULL) && (node->doc != NULL)) {
to->file = (char *) xmlStrdup(node->doc->URL);
}
- file = to->file;
}
to->line = line;
if (str1 != NULL)
@@ -590,27 +584,25 @@
if (to != &xmlLastError)
xmlCopyError(to,&xmlLastError);
+ if (schannel != NULL) {
+ schannel(data, to);
+ return;
+ }
+
/*
* Find the callback channel if channel param is NULL
*/
- if ((ctxt != NULL) && (channel == NULL) && (xmlStructuredError == NULL) && (ctxt->sax != NULL)) {
+ if ((ctxt != NULL) && (channel == NULL) &&
+ (xmlStructuredError == NULL) && (ctxt->sax != NULL)) {
if (level == XML_ERR_WARNING)
channel = ctxt->sax->warning;
else
channel = ctxt->sax->error;
data = ctxt->userData;
} else if (channel == NULL) {
- if (xmlStructuredError != NULL)
- schannel = xmlStructuredError;
- else
- channel = xmlGenericError;
- if (!data) {
- data = xmlGenericErrorContext;
- }
- }
- if (schannel != NULL) {
- schannel(data, to);
- return;
+ channel = xmlGenericError;
+ if (!data)
+ data = xmlGenericErrorContext;
}
if (channel == NULL)
return;
@@ -927,6 +919,7 @@
if (ctxt == NULL)
return;
+ ctxt->errNo = XML_ERR_OK;
if (ctxt->lastError.code == XML_ERR_OK)
return;
xmlResetError(&ctxt->lastError);
diff --git a/globals.c b/globals.c
index cbc6625..69002f0 100644
--- a/globals.c
+++ b/globals.c
@@ -46,7 +46,8 @@
*/
void xmlInitGlobals(void)
{
- xmlThrDefMutex = xmlNewMutex();
+ if (xmlThrDefMutex == NULL)
+ xmlThrDefMutex = xmlNewMutex();
}
/**
@@ -148,6 +149,7 @@
#undef xmlGenericError
#undef xmlStructuredError
#undef xmlGenericErrorContext
+#undef xmlStructuredErrorContext
#undef xmlGetWarningsDefaultValue
#undef xmlIndentTreeOutput
#undef xmlTreeIndentString
@@ -314,6 +316,13 @@
*/
void *xmlGenericErrorContext = NULL;
static void *xmlGenericErrorContextThrDef = NULL;
+/**
+ * xmlStructuredErrorContext:
+ *
+ * Global setting passed to structured error callbacks
+ */
+void *xmlStructuredErrorContext = NULL;
+static void *xmlStructuredErrorContextThrDef = NULL;
xmlError xmlLastError;
/*
@@ -545,6 +554,7 @@
gs->xmlGenericError = xmlGenericErrorThrDef;
gs->xmlStructuredError = xmlStructuredErrorThrDef;
gs->xmlGenericErrorContext = xmlGenericErrorContextThrDef;
+ gs->xmlStructuredErrorContext = xmlStructuredErrorContextThrDef;
gs->xmlRegisterNodeDefaultValue = xmlRegisterNodeDefaultValueThrDef;
gs->xmlDeregisterNodeDefaultValue = xmlDeregisterNodeDefaultValueThrDef;
@@ -573,7 +583,7 @@
void
xmlThrDefSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) {
xmlMutexLock(xmlThrDefMutex);
- xmlGenericErrorContextThrDef = ctx;
+ xmlStructuredErrorContextThrDef = ctx;
xmlStructuredErrorThrDef = handler;
xmlMutexUnlock(xmlThrDefMutex);
}
@@ -876,6 +886,15 @@
return (&xmlGetGlobalState()->xmlGenericErrorContext);
}
+#undef xmlStructuredErrorContext
+void * *
+__xmlStructuredErrorContext(void) {
+ if (IS_MAIN_THREAD)
+ return (&xmlStructuredErrorContext);
+ else
+ return (&xmlGetGlobalState()->xmlStructuredErrorContext);
+}
+
#undef xmlGetWarningsDefaultValue
int *
__xmlGetWarningsDefaultValue(void) {
@@ -910,7 +929,7 @@
return ret;
}
-#undef xmlTreeIndentString
+#undef xmlTreeIndentString
const char * *
__xmlTreeIndentString(void) {
if (IS_MAIN_THREAD)
diff --git a/hash.c b/hash.c
index 22f9bb4..fe1424f 100644
--- a/hash.c
+++ b/hash.c
@@ -3,7 +3,7 @@
*
* Reference: Your favorite introductory book on algorithms
*
- * Copyright (C) 2000 Bjorn Reese and Daniel Veillard.
+ * Copyright (C) 2000,2012 Bjorn Reese and Daniel Veillard.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -21,6 +21,22 @@
#include "libxml.h"
#include <string.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+/*
+ * Following http://www.ocert.org/advisories/ocert-2011-003.html
+ * it seems that having hash randomization might be a good idea
+ * when using XML with untrusted data
+ */
+#if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME)
+#define HASH_RANDOMIZATION
+#endif
+
#include <libxml/parser.h>
#include <libxml/hash.h>
#include <libxml/xmlmemory.h>
@@ -31,6 +47,10 @@
/* #define DEBUG_GROW */
+#ifdef HASH_RANDOMIZATION
+static int hash_initialized = 0;
+#endif
+
/*
* A single entry in the hash table
*/
@@ -53,6 +73,9 @@
int size;
int nbElems;
xmlDictPtr dict;
+#ifdef HASH_RANDOMIZATION
+ int random_seed;
+#endif
};
/*
@@ -65,6 +88,9 @@
unsigned long value = 0L;
char ch;
+#ifdef HASH_RANDOMIZATION
+ value = table->random_seed;
+#endif
if (name != NULL) {
value += 30 * (*name);
while ((ch = *name++) != 0) {
@@ -92,6 +118,9 @@
unsigned long value = 0L;
char ch;
+#ifdef HASH_RANDOMIZATION
+ value = table->random_seed;
+#endif
if (prefix != NULL)
value += 30 * (*prefix);
else
@@ -156,6 +185,13 @@
table->table = xmlMalloc(size * sizeof(xmlHashEntry));
if (table->table) {
memset(table->table, 0, size * sizeof(xmlHashEntry));
+#ifdef HASH_RANDOMIZATION
+ if (!hash_initialized) {
+ srand(time(NULL));
+ hash_initialized = 1;
+ }
+ table->random_seed = rand();
+#endif
return(table);
}
xmlFree(table);
@@ -320,7 +356,6 @@
inside_table = 0;
iter = next;
}
- inside_table = 0;
}
xmlFree(table->table);
}
diff --git a/include/libxml/HTMLparser.h b/include/libxml/HTMLparser.h
index 05905e4..10a3d65 100644
--- a/include/libxml/HTMLparser.h
+++ b/include/libxml/HTMLparser.h
@@ -177,12 +177,15 @@
*/
typedef enum {
HTML_PARSE_RECOVER = 1<<0, /* Relaxed parsing */
+ HTML_PARSE_NODEFDTD = 1<<2, /* do not default a doctype if not found */
HTML_PARSE_NOERROR = 1<<5, /* suppress error reports */
HTML_PARSE_NOWARNING= 1<<6, /* suppress warning reports */
HTML_PARSE_PEDANTIC = 1<<7, /* pedantic error reporting */
HTML_PARSE_NOBLANKS = 1<<8, /* remove blank nodes */
HTML_PARSE_NONET = 1<<11,/* Forbid network access */
- HTML_PARSE_COMPACT = 1<<16 /* compact small text nodes */
+ HTML_PARSE_NOIMPLIED= 1<<13,/* Do not add implied html/body... elements */
+ HTML_PARSE_COMPACT = 1<<16,/* compact small text nodes */
+ HTML_PARSE_IGNORE_ENC=1<<21 /* ignore internal document encoding hint */
} htmlParserOption;
XMLPUBFUN void XMLCALL
diff --git a/include/libxml/c14n.h b/include/libxml/c14n.h
index a8aa737..3011af7 100644
--- a/include/libxml/c14n.h
+++ b/include/libxml/c14n.h
@@ -52,11 +52,22 @@
* ...
*/
+/*
+ * xmlC14NMode:
+ *
+ * Predefined values for C14N modes
+ *
+ */
+typedef enum {
+ XML_C14N_1_0 = 0, /* Origianal C14N 1.0 spec */
+ XML_C14N_EXCLUSIVE_1_0 = 1, /* Exclusive C14N 1.0 spec */
+ XML_C14N_1_1 = 2 /* C14N 1.1 spec */
+} xmlC14NMode;
XMLPUBFUN int XMLCALL
xmlC14NDocSaveTo (xmlDocPtr doc,
xmlNodeSetPtr nodes,
- int exclusive,
+ int mode, /* a xmlC14NMode */
xmlChar **inclusive_ns_prefixes,
int with_comments,
xmlOutputBufferPtr buf);
@@ -64,7 +75,7 @@
XMLPUBFUN int XMLCALL
xmlC14NDocDumpMemory (xmlDocPtr doc,
xmlNodeSetPtr nodes,
- int exclusive,
+ int mode, /* a xmlC14NMode */
xmlChar **inclusive_ns_prefixes,
int with_comments,
xmlChar **doc_txt_ptr);
@@ -72,7 +83,7 @@
XMLPUBFUN int XMLCALL
xmlC14NDocSave (xmlDocPtr doc,
xmlNodeSetPtr nodes,
- int exclusive,
+ int mode, /* a xmlC14NMode */
xmlChar **inclusive_ns_prefixes,
int with_comments,
const char* filename,
@@ -100,7 +111,7 @@
xmlC14NExecute (xmlDocPtr doc,
xmlC14NIsVisibleCallback is_visible_callback,
void* user_data,
- int exclusive,
+ int mode, /* a xmlC14NMode */
xmlChar **inclusive_ns_prefixes,
int with_comments,
xmlOutputBufferPtr buf);
diff --git a/include/libxml/encoding.h b/include/libxml/encoding.h
index c68ec10..3a3b9b2 100644
--- a/include/libxml/encoding.h
+++ b/include/libxml/encoding.h
@@ -26,24 +26,9 @@
#ifdef LIBXML_ICONV_ENABLED
#include <iconv.h>
-#else
+#endif
#ifdef LIBXML_ICU_ENABLED
#include <unicode/ucnv.h>
-#if 0
-/* Forward-declare UConverter here rather than pulling in <unicode/ucnv.h>
- * to prevent unwanted ICU symbols being exposed to users of libxml2.
- * One particular case is Qt4 conflicting on UChar32.
- */
-#include <stdint.h>
-struct UConverter;
-typedef struct UConverter UConverter;
-#ifdef _MSC_VER
-typedef wchar_t UChar;
-#else
-typedef uint16_t UChar;
-#endif
-#endif
-#endif
#endif
#ifdef __cplusplus
extern "C" {
diff --git a/include/libxml/globals.h b/include/libxml/globals.h
index 57e25fa..9d688e0 100644
--- a/include/libxml/globals.h
+++ b/include/libxml/globals.h
@@ -76,6 +76,7 @@
#undef xmlGenericError
#undef xmlStructuredError
#undef xmlGenericErrorContext
+#undef xmlStructuredErrorContext
#undef xmlGetWarningsDefaultValue
#undef xmlIndentTreeOutput
#undef xmlTreeIndentString
@@ -158,6 +159,8 @@
xmlParserInputBufferCreateFilenameFunc xmlParserInputBufferCreateFilenameValue;
xmlOutputBufferCreateFilenameFunc xmlOutputBufferCreateFilenameValue;
+
+ void *xmlStructuredErrorContext;
};
#ifdef __cplusplus
@@ -354,6 +357,14 @@
XMLPUBVAR void * xmlGenericErrorContext;
#endif
+XMLPUBFUN void * * XMLCALL __xmlStructuredErrorContext(void);
+#ifdef LIBXML_THREAD_ENABLED
+#define xmlStructuredErrorContext \
+(*(__xmlStructuredErrorContext()))
+#else
+XMLPUBVAR void * xmlStructuredErrorContext;
+#endif
+
XMLPUBFUN int * XMLCALL __xmlGetWarningsDefaultValue(void);
#ifdef LIBXML_THREAD_ENABLED
#define xmlGetWarningsDefaultValue \
diff --git a/include/libxml/nanoftp.h b/include/libxml/nanoftp.h
index e3c28a0..397bbba 100644
--- a/include/libxml/nanoftp.h
+++ b/include/libxml/nanoftp.h
@@ -7,7 +7,7 @@
*
* Author: Daniel Veillard
*/
-
+
#ifndef __NANO_FTP_H__
#define __NANO_FTP_H__
@@ -15,12 +15,31 @@
#ifdef LIBXML_FTP_ENABLED
+/* Needed for portability to Windows 64 bits */
+#if defined(__MINGW32__) || defined(_WIN32_WCE)
+#include <winsock2.h>
+#else
+/**
+ * SOCKET:
+ *
+ * macro used to provide portability of code to windows sockets
+ */
+#define SOCKET int
+/**
+ * INVALID_SOCKET:
+ *
+ * macro used to provide portability of code to windows sockets
+ * the value to be used when the socket is not valid
+ */
+#define INVALID_SOCKET (-1)
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
/**
- * ftpListCallback:
+ * ftpListCallback:
* @userData: user provided data for the callback
* @filename: the file name (including "->" when links are shown)
* @attrib: the attribute string
@@ -44,7 +63,7 @@
const char *month, int day, int hour,
int minute);
/**
- * ftpDataCallback:
+ * ftpDataCallback:
* @userData: the user provided context
* @data: the data received
* @len: its size in bytes
@@ -60,78 +79,78 @@
*/
XMLPUBFUN void XMLCALL
xmlNanoFTPInit (void);
-XMLPUBFUN void XMLCALL
+XMLPUBFUN void XMLCALL
xmlNanoFTPCleanup (void);
/*
* Creating/freeing contexts.
*/
-XMLPUBFUN void * XMLCALL
+XMLPUBFUN void * XMLCALL
xmlNanoFTPNewCtxt (const char *URL);
-XMLPUBFUN void XMLCALL
+XMLPUBFUN void XMLCALL
xmlNanoFTPFreeCtxt (void * ctx);
-XMLPUBFUN void * XMLCALL
+XMLPUBFUN void * XMLCALL
xmlNanoFTPConnectTo (const char *server,
int port);
/*
* Opening/closing session connections.
*/
-XMLPUBFUN void * XMLCALL
+XMLPUBFUN void * XMLCALL
xmlNanoFTPOpen (const char *URL);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlNanoFTPConnect (void *ctx);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlNanoFTPClose (void *ctx);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlNanoFTPQuit (void *ctx);
-XMLPUBFUN void XMLCALL
+XMLPUBFUN void XMLCALL
xmlNanoFTPScanProxy (const char *URL);
-XMLPUBFUN void XMLCALL
+XMLPUBFUN void XMLCALL
xmlNanoFTPProxy (const char *host,
int port,
const char *user,
const char *passwd,
int type);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlNanoFTPUpdateURL (void *ctx,
const char *URL);
/*
* Rather internal commands.
*/
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlNanoFTPGetResponse (void *ctx);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlNanoFTPCheckResponse (void *ctx);
/*
* CD/DIR/GET handlers.
*/
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlNanoFTPCwd (void *ctx,
const char *directory);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlNanoFTPDele (void *ctx,
const char *file);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN SOCKET XMLCALL
xmlNanoFTPGetConnection (void *ctx);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlNanoFTPCloseConnection(void *ctx);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlNanoFTPList (void *ctx,
ftpListCallback callback,
void *userData,
const char *filename);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN SOCKET XMLCALL
xmlNanoFTPGetSocket (void *ctx,
const char *filename);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlNanoFTPGet (void *ctx,
ftpDataCallback callback,
void *userData,
const char *filename);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlNanoFTPRead (void *ctx,
void *dest,
int len);
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index bd9de24..54f1660 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -190,7 +190,10 @@
const xmlChar *version; /* the XML version string */
const xmlChar *encoding; /* the declared encoding, if any */
int standalone; /* standalone document */
- int html; /* an HTML(1)/Docbook(2) document */
+ int html; /* an HTML(1)/Docbook(2) document
+ * 3 is HTML after <head>
+ * 10 is HTML after <body>
+ */
/* Input stream stack */
xmlParserInputPtr input; /* Current input stream */
@@ -276,7 +279,6 @@
int nsNr; /* the number of inherited namespaces */
int nsMax; /* the size of the arrays */
const xmlChar * *nsTab; /* the array of prefix/namespace name */
- struct _xmlParserCtxt *nsParent; /* parent context to inherit namespaces from * */
int *attallocs; /* which attribute were allocated */
void * *pushTab; /* array of data for push */
xmlHashTablePtr attsDefault; /* defaulted attributes if any */
@@ -300,6 +302,12 @@
xmlParserMode parseMode; /* the parser mode */
unsigned long nbentities; /* number of entities references */
unsigned long sizeentities; /* size of parsed entities */
+
+ /* for use by HTML non-recursive parser */
+ xmlParserNodeInfo *nodeInfo; /* Current NodeInfo */
+ int nodeInfoNr; /* Depth of the parsing stack */
+ int nodeInfoMax; /* Max depth of the parsing stack */
+ xmlParserNodeInfo *nodeInfoTab; /* array of nodeInfos */
};
/**
@@ -595,7 +603,7 @@
* Display and format a warning messages, callback.
*/
typedef void (XMLCDECL *warningSAXFunc) (void *ctx,
- const char *msg, ...) ATTRIBUTE_PRINTF(2,3);
+ const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
/**
* errorSAXFunc:
* @ctx: an XML parser context
@@ -605,7 +613,7 @@
* Display and format an error messages, callback.
*/
typedef void (XMLCDECL *errorSAXFunc) (void *ctx,
- const char *msg, ...) ATTRIBUTE_PRINTF(2,3);
+ const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
/**
* fatalErrorSAXFunc:
* @ctx: an XML parser context
@@ -617,7 +625,7 @@
* get all the callbacks for errors.
*/
typedef void (XMLCDECL *fatalErrorSAXFunc) (void *ctx,
- const char *msg, ...) ATTRIBUTE_PRINTF(2,3);
+ const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
/**
* isStandaloneSAXFunc:
* @ctx: the user data (XML parser context)
@@ -851,7 +859,7 @@
* Recovery mode
*/
XMLPUBFUN xmlDocPtr XMLCALL
- xmlRecoverDoc (xmlChar *cur);
+ xmlRecoverDoc (const xmlChar *cur);
XMLPUBFUN xmlDocPtr XMLCALL
xmlRecoverMemory (const char *buffer,
int size);
@@ -1097,8 +1105,9 @@
crash if you try to modify the tree) */
XML_PARSE_OLD10 = 1<<17,/* parse using XML-1.0 before update 5 */
XML_PARSE_NOBASEFIX = 1<<18,/* do not fixup XINCLUDE xml:base uris */
- XML_PARSE_HUGE = 1<<19, /* relax any hardcoded limit from the parser */
- XML_PARSE_OLDSAX = 1<<20 /* parse using SAX2 interface from before 2.7.0 */
+ XML_PARSE_HUGE = 1<<19,/* relax any hardcoded limit from the parser */
+ XML_PARSE_OLDSAX = 1<<20,/* parse using SAX2 interface before 2.7.0 */
+ XML_PARSE_IGNORE_ENC= 1<<21 /* ignore internal document encoding hint */
} xmlParserOption;
XMLPUBFUN void XMLCALL
@@ -1215,6 +1224,7 @@
XML_WITH_DEBUG_RUN = 30,
XML_WITH_ZLIB = 31,
XML_WITH_ICU = 32,
+ XML_WITH_LZMA = 33,
XML_WITH_NONE = 99999 /* just to be sure of allocation size */
} xmlFeature;
diff --git a/include/libxml/relaxng.h b/include/libxml/relaxng.h
index d3e39e0..bdb0a7d 100644
--- a/include/libxml/relaxng.h
+++ b/include/libxml/relaxng.h
@@ -32,7 +32,7 @@
*
* Signature of an error callback from a Relax-NG validation
*/
-typedef void (XMLCDECL *xmlRelaxNGValidityErrorFunc) (void *ctx, const char *msg, ...) ATTRIBUTE_PRINTF(2,3);
+typedef void (XMLCDECL *xmlRelaxNGValidityErrorFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
/**
* xmlRelaxNGValidityWarningFunc:
@@ -42,7 +42,7 @@
*
* Signature of a warning callback from a Relax-NG validation
*/
-typedef void (XMLCDECL *xmlRelaxNGValidityWarningFunc) (void *ctx, const char *msg, ...) ATTRIBUTE_PRINTF(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/valid.h b/include/libxml/valid.h
index f1892b0..a2307f1 100644
--- a/include/libxml/valid.h
+++ b/include/libxml/valid.h
@@ -41,7 +41,7 @@
*/
typedef void (XMLCDECL *xmlValidityErrorFunc) (void *ctx,
const char *msg,
- ...) ATTRIBUTE_PRINTF(2,3);
+ ...) LIBXML_ATTR_FORMAT(2,3);
/**
* xmlValidityWarningFunc:
@@ -56,7 +56,7 @@
*/
typedef void (XMLCDECL *xmlValidityWarningFunc) (void *ctx,
const char *msg,
- ...) ATTRIBUTE_PRINTF(2,3);
+ ...) LIBXML_ATTR_FORMAT(2,3);
#ifdef IN_LIBXML
/**
diff --git a/include/libxml/xinclude.h b/include/libxml/xinclude.h
index ba9c9b5..863ab25 100644
--- a/include/libxml/xinclude.h
+++ b/include/libxml/xinclude.h
@@ -89,18 +89,22 @@
/*
* standalone processing
*/
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlXIncludeProcess (xmlDocPtr doc);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlXIncludeProcessFlags (xmlDocPtr doc,
int flags);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlXIncludeProcessFlagsData(xmlDocPtr doc,
int flags,
void *data);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
+ xmlXIncludeProcessTreeFlagsData(xmlNodePtr tree,
+ int flags,
+ void *data);
+XMLPUBFUN int XMLCALL
xmlXIncludeProcessTree (xmlNodePtr tree);
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlXIncludeProcessTreeFlags(xmlNodePtr tree,
int flags);
/*
diff --git a/include/libxml/xmlerror.h b/include/libxml/xmlerror.h
index 7cce9c3..e924211 100644
--- a/include/libxml/xmlerror.h
+++ b/include/libxml/xmlerror.h
@@ -843,7 +843,7 @@
*/
typedef void (XMLCDECL *xmlGenericErrorFunc) (void *ctx,
const char *msg,
- ...) ATTRIBUTE_PRINTF(2,3);
+ ...) LIBXML_ATTR_FORMAT(2,3);
/**
* xmlStructuredErrorFunc:
* @userData: user provided data for the error callback
@@ -874,19 +874,19 @@
XMLPUBFUN void XMLCDECL
xmlParserError (void *ctx,
const char *msg,
- ...) ATTRIBUTE_PRINTF(2,3);
+ ...) LIBXML_ATTR_FORMAT(2,3);
XMLPUBFUN void XMLCDECL
xmlParserWarning (void *ctx,
const char *msg,
- ...) ATTRIBUTE_PRINTF(2,3);
+ ...) LIBXML_ATTR_FORMAT(2,3);
XMLPUBFUN void XMLCDECL
xmlParserValidityError (void *ctx,
const char *msg,
- ...) ATTRIBUTE_PRINTF(2,3);
+ ...) LIBXML_ATTR_FORMAT(2,3);
XMLPUBFUN void XMLCDECL
xmlParserValidityWarning (void *ctx,
const char *msg,
- ...) ATTRIBUTE_PRINTF(2,3);
+ ...) LIBXML_ATTR_FORMAT(2,3);
XMLPUBFUN void XMLCALL
xmlParserPrintFileInfo (xmlParserInputPtr input);
XMLPUBFUN void XMLCALL
@@ -930,7 +930,7 @@
int int1,
int col,
const char *msg,
- ...) ATTRIBUTE_PRINTF(16,17);
+ ...) LIBXML_ATTR_FORMAT(16,17);
XMLPUBFUN void XMLCALL
__xmlSimpleError (int domain,
int code,
diff --git a/include/libxml/xmlexports.h b/include/libxml/xmlexports.h
index 29a6f54..9c6790c 100644
--- a/include/libxml/xmlexports.h
+++ b/include/libxml/xmlexports.h
@@ -108,6 +108,11 @@
#undef XMLPUBVAR
#undef XMLCALL
#undef XMLCDECL
+ /*
+ * if defined(IN_LIBXML) this raises problems on mingw with msys
+ * _imp__xmlFree listed as missing. Try to workaround the problem
+ * by also making that declaration when compiling client code.
+ */
#if defined(IN_LIBXML) && !defined(LIBXML_STATIC)
#define XMLPUBFUN __declspec(dllexport)
#define XMLPUBVAR __declspec(dllexport)
diff --git a/include/libxml/xmlmemory.h b/include/libxml/xmlmemory.h
index 8f3b109..17e375a 100644
--- a/include/libxml/xmlmemory.h
+++ b/include/libxml/xmlmemory.h
@@ -63,7 +63,7 @@
*
* Returns a pointer to the newly allocated block or NULL in case of error.
*/
-typedef void *(ATTRIBUTE_ALLOC_SIZE(1) XMLCALL *xmlMallocFunc)(size_t size);
+typedef void *(LIBXML_ATTR_ALLOC_SIZE(1) XMLCALL *xmlMallocFunc)(size_t size);
/**
* xmlReallocFunc:
@@ -88,11 +88,11 @@
/*
* The 4 interfaces used for all memory handling within libxml.
-LIBXML_DLL_IMPORT extern xmlFreeFunc xmlFree;
-LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMalloc;
-LIBXML_DLL_IMPORT extern xmlMallocFunc xmlMallocAtomic;
-LIBXML_DLL_IMPORT extern xmlReallocFunc xmlRealloc;
-LIBXML_DLL_IMPORT extern xmlStrdupFunc xmlMemStrdup;
+LIBXML_DLL_IMPORT xmlFreeFunc xmlFree;
+LIBXML_DLL_IMPORT xmlMallocFunc xmlMalloc;
+LIBXML_DLL_IMPORT xmlMallocFunc xmlMallocAtomic;
+LIBXML_DLL_IMPORT xmlReallocFunc xmlRealloc;
+LIBXML_DLL_IMPORT xmlStrdupFunc xmlMemStrdup;
*/
/*
@@ -150,7 +150,7 @@
XMLPUBFUN void XMLCALL
xmlMemoryDump (void);
XMLPUBFUN void * XMLCALL
- xmlMemMalloc (size_t size) ATTRIBUTE_ALLOC_SIZE(1);
+ xmlMemMalloc (size_t size) LIBXML_ATTR_ALLOC_SIZE(1);
XMLPUBFUN void * XMLCALL
xmlMemRealloc (void *ptr,size_t size);
XMLPUBFUN void XMLCALL
@@ -158,11 +158,11 @@
XMLPUBFUN char * XMLCALL
xmlMemoryStrdup (const char *str);
XMLPUBFUN void * XMLCALL
- xmlMallocLoc (size_t size, const char *file, int line) ATTRIBUTE_ALLOC_SIZE(1);
+ xmlMallocLoc (size_t size, const char *file, int line) LIBXML_ATTR_ALLOC_SIZE(1);
XMLPUBFUN void * XMLCALL
xmlReallocLoc (void *ptr, size_t size, const char *file, int line);
XMLPUBFUN void * XMLCALL
- xmlMallocAtomicLoc (size_t size, const char *file, int line) ATTRIBUTE_ALLOC_SIZE(1);
+ xmlMallocAtomicLoc (size_t size, const char *file, int line) LIBXML_ATTR_ALLOC_SIZE(1);
XMLPUBFUN char * XMLCALL
xmlMemStrdupLoc (const char *str, const char *file, int line);
diff --git a/include/libxml/xmlsave.h b/include/libxml/xmlsave.h
index 4201b4d..fb329b2 100644
--- a/include/libxml/xmlsave.h
+++ b/include/libxml/xmlsave.h
@@ -33,7 +33,8 @@
XML_SAVE_NO_XHTML = 1<<3, /* disable XHTML1 specific rules */
XML_SAVE_XHTML = 1<<4, /* force XHTML1 specific rules */
XML_SAVE_AS_XML = 1<<5, /* force XML serialization on HTML doc */
- XML_SAVE_AS_HTML = 1<<6 /* force HTML serialization on XML doc */
+ XML_SAVE_AS_HTML = 1<<6, /* force HTML serialization on XML doc */
+ XML_SAVE_WSNONSIG = 1<<7 /* format with non-significant whitespace */
} xmlSaveOption;
diff --git a/include/libxml/xmlschemas.h b/include/libxml/xmlschemas.h
index ebef3a7..752bc3a 100644
--- a/include/libxml/xmlschemas.h
+++ b/include/libxml/xmlschemas.h
@@ -92,7 +92,7 @@
*
* Signature of an error callback from an XSD validation
*/
-typedef void (XMLCDECL *xmlSchemaValidityErrorFunc) (void *ctx, const char *msg, ...) ATTRIBUTE_PRINTF(2,3);
+typedef void (XMLCDECL *xmlSchemaValidityErrorFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
/**
* xmlSchemaValidityWarningFunc:
@@ -102,7 +102,7 @@
*
* Signature of a warning callback from an XSD validation
*/
-typedef void (XMLCDECL *xmlSchemaValidityWarningFunc) (void *ctx, const char *msg, ...) ATTRIBUTE_PRINTF(2,3);
+typedef void (XMLCDECL *xmlSchemaValidityWarningFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
/**
* A schemas validation context
diff --git a/include/libxml/xmlstring.h b/include/libxml/xmlstring.h
index 1dfc5ea..0bc6888 100644
--- a/include/libxml/xmlstring.h
+++ b/include/libxml/xmlstring.h
@@ -59,7 +59,7 @@
const xmlChar *val);
XMLPUBFUN const xmlChar * XMLCALL
xmlStrcasestr (const xmlChar *str,
- xmlChar *val);
+ const xmlChar *val);
XMLPUBFUN int XMLCALL
xmlStrcmp (const xmlChar *str1,
const xmlChar *str2);
diff --git a/include/libxml/xmlversion.h b/include/libxml/xmlversion.h
index d98f5b0..9e6f66b 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.7.3"
+#define LIBXML_DOTTED_VERSION "2.7.8"
/**
* LIBXML_VERSION:
*
* the version number: 1.2.3 value is 10203
*/
-#define LIBXML_VERSION 20703
+#define LIBXML_VERSION 20708
/**
* LIBXML_VERSION_STRING:
*
* the version number string, 1.2.3 value is "10203"
*/
-#define LIBXML_VERSION_STRING "20703"
+#define LIBXML_VERSION_STRING "20708"
/**
* LIBXML_VERSION_EXTRA:
*
* extra version information, used to show a CVS compilation
*/
-#define LIBXML_VERSION_EXTRA ""
+#define LIBXML_VERSION_EXTRA "-GITv2.7.8-56-g8973d58"
/**
* 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(20703);
+#define LIBXML_TEST_VERSION xmlCheckVersion(20708);
#ifndef VMS
#if 0
@@ -391,6 +391,15 @@
#define LIBXML_ZLIB_ENABLED
#endif
+/**
+ * LIBXML_LZMA_ENABLED:
+ *
+ * Whether the Lzma support is compiled in
+ */
+#if 0
+#define LIBXML_LZMA_ENABLED
+#endif
+
#ifdef __GNUC__
#ifdef HAVE_ANSIDECL_H
#include <ansidecl.h>
@@ -407,35 +416,35 @@
#endif
/**
- * ATTRIBUTE_ALLOC_SIZE:
+ * LIBXML_ATTR_ALLOC_SIZE:
*
* Macro used to indicate to GCC this is an allocator function
*/
-#ifndef ATTRIBUTE_ALLOC_SIZE
+#ifndef LIBXML_ATTR_ALLOC_SIZE
# if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
-# define ATTRIBUTE_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
+# define LIBXML_ATTR_ALLOC_SIZE(x) __attribute__((alloc_size(x)))
# else
-# define ATTRIBUTE_ALLOC_SIZE(x)
+# define LIBXML_ATTR_ALLOC_SIZE(x)
# endif
#else
-# define ATTRIBUTE_ALLOC_SIZE(x)
+# define LIBXML_ATTR_ALLOC_SIZE(x)
#endif
/**
- * ATTRIBUTE_PRINTF:
+ * LIBXML_ATTR_FORMAT:
*
* Macro used to indicate to GCC the parameter are printf like
*/
-#ifndef ATTRIBUTE_PRINTF
+#ifndef LIBXML_ATTR_FORMAT
# if ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))
-# define ATTRIBUTE_PRINTF(fmt,args) __attribute__((__format__(__printf__,fmt,args)))
+# define LIBXML_ATTR_FORMAT(fmt,args) __attribute__((__format__(__printf__,fmt,args)))
# else
-# define ATTRIBUTE_PRINTF(fmt,args)
+# define LIBXML_ATTR_FORMAT(fmt,args)
# endif
#else
-# define ATTRIBUTE_PRINTF(fmt,args)
+# define LIBXML_ATTR_FORMAT(fmt,args)
#endif
#else /* ! __GNUC__ */
@@ -446,20 +455,22 @@
*/
#define ATTRIBUTE_UNUSED
/**
- * ATTRIBUTE_ALLOC_SIZE:
+ * LIBXML_ATTR_ALLOC_SIZE:
*
* Macro used to indicate to GCC this is an allocator function
*/
-#define ATTRIBUTE_ALLOC_SIZE(x)
+#define LIBXML_ATTR_ALLOC_SIZE(x)
/**
- * ATTRIBUTE_PRINTF:
+ * LIBXML_ATTR_FORMAT:
*
* Macro used to indicate to GCC the parameter are printf like
*/
-#define ATTRIBUTE_PRINTF(fmt,args)
+#define LIBXML_ATTR_FORMAT(fmt,args)
#endif /* __GNUC__ */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+
+
diff --git a/include/libxml/xmlwriter.h b/include/libxml/xmlwriter.h
index df4509d..91e683c 100644
--- a/include/libxml/xmlwriter.h
+++ b/include/libxml/xmlwriter.h
@@ -70,12 +70,12 @@
XMLPUBFUN int XMLCALL
xmlTextWriterWriteFormatComment(xmlTextWriterPtr writer,
const char *format, ...)
- ATTRIBUTE_PRINTF(2,3);
+ LIBXML_ATTR_FORMAT(2,3);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteVFormatComment(xmlTextWriterPtr writer,
const char *format,
va_list argptr)
- ATTRIBUTE_PRINTF(2,0);
+ LIBXML_ATTR_FORMAT(2,0);
XMLPUBFUN int XMLCALL xmlTextWriterWriteComment(xmlTextWriterPtr
writer,
const xmlChar *
@@ -105,13 +105,13 @@
xmlTextWriterWriteFormatElement(xmlTextWriterPtr writer,
const xmlChar * name,
const char *format, ...)
- ATTRIBUTE_PRINTF(3,4);
+ LIBXML_ATTR_FORMAT(3,4);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteVFormatElement(xmlTextWriterPtr writer,
const xmlChar * name,
const char *format,
va_list argptr)
- ATTRIBUTE_PRINTF(3,0);
+ LIBXML_ATTR_FORMAT(3,0);
XMLPUBFUN int XMLCALL xmlTextWriterWriteElement(xmlTextWriterPtr
writer,
const xmlChar * name,
@@ -123,7 +123,7 @@
const xmlChar * name,
const xmlChar * namespaceURI,
const char *format, ...)
- ATTRIBUTE_PRINTF(5,6);
+ LIBXML_ATTR_FORMAT(5,6);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteVFormatElementNS(xmlTextWriterPtr writer,
const xmlChar * prefix,
@@ -131,7 +131,7 @@
const xmlChar * namespaceURI,
const char *format,
va_list argptr)
- ATTRIBUTE_PRINTF(5,0);
+ LIBXML_ATTR_FORMAT(5,0);
XMLPUBFUN int XMLCALL xmlTextWriterWriteElementNS(xmlTextWriterPtr
writer,
const xmlChar *
@@ -148,11 +148,11 @@
XMLPUBFUN int XMLCALL
xmlTextWriterWriteFormatRaw(xmlTextWriterPtr writer,
const char *format, ...)
- ATTRIBUTE_PRINTF(2,3);
+ LIBXML_ATTR_FORMAT(2,3);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteVFormatRaw(xmlTextWriterPtr writer,
const char *format, va_list argptr)
- ATTRIBUTE_PRINTF(2,0);
+ LIBXML_ATTR_FORMAT(2,0);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteRawLen(xmlTextWriterPtr writer,
const xmlChar * content, int len);
@@ -163,13 +163,13 @@
writer,
const char
*format, ...)
- ATTRIBUTE_PRINTF(2,3);
+ LIBXML_ATTR_FORMAT(2,3);
XMLPUBFUN int XMLCALL xmlTextWriterWriteVFormatString(xmlTextWriterPtr
writer,
const char
*format,
va_list argptr)
- ATTRIBUTE_PRINTF(2,0);
+ LIBXML_ATTR_FORMAT(2,0);
XMLPUBFUN int XMLCALL xmlTextWriterWriteString(xmlTextWriterPtr writer,
const xmlChar *
content);
@@ -204,13 +204,13 @@
xmlTextWriterWriteFormatAttribute(xmlTextWriterPtr writer,
const xmlChar * name,
const char *format, ...)
- ATTRIBUTE_PRINTF(3,4);
+ LIBXML_ATTR_FORMAT(3,4);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteVFormatAttribute(xmlTextWriterPtr writer,
const xmlChar * name,
const char *format,
va_list argptr)
- ATTRIBUTE_PRINTF(3,0);
+ LIBXML_ATTR_FORMAT(3,0);
XMLPUBFUN int XMLCALL xmlTextWriterWriteAttribute(xmlTextWriterPtr
writer,
const xmlChar * name,
@@ -222,7 +222,7 @@
const xmlChar * name,
const xmlChar * namespaceURI,
const char *format, ...)
- ATTRIBUTE_PRINTF(5,6);
+ LIBXML_ATTR_FORMAT(5,6);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteVFormatAttributeNS(xmlTextWriterPtr writer,
const xmlChar * prefix,
@@ -230,7 +230,7 @@
const xmlChar * namespaceURI,
const char *format,
va_list argptr)
- ATTRIBUTE_PRINTF(5,0);
+ LIBXML_ATTR_FORMAT(5,0);
XMLPUBFUN int XMLCALL xmlTextWriterWriteAttributeNS(xmlTextWriterPtr
writer,
const xmlChar *
@@ -257,12 +257,12 @@
xmlTextWriterWriteFormatPI(xmlTextWriterPtr writer,
const xmlChar * target,
const char *format, ...)
- ATTRIBUTE_PRINTF(3,4);
+ LIBXML_ATTR_FORMAT(3,4);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteVFormatPI(xmlTextWriterPtr writer,
const xmlChar * target,
const char *format, va_list argptr)
- ATTRIBUTE_PRINTF(3,0);
+ LIBXML_ATTR_FORMAT(3,0);
XMLPUBFUN int XMLCALL
xmlTextWriterWritePI(xmlTextWriterPtr writer,
const xmlChar * target,
@@ -287,11 +287,11 @@
XMLPUBFUN int XMLCALL
xmlTextWriterWriteFormatCDATA(xmlTextWriterPtr writer,
const char *format, ...)
- ATTRIBUTE_PRINTF(2,3);
+ LIBXML_ATTR_FORMAT(2,3);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteVFormatCDATA(xmlTextWriterPtr writer,
const char *format, va_list argptr)
- ATTRIBUTE_PRINTF(2,0);
+ LIBXML_ATTR_FORMAT(2,0);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteCDATA(xmlTextWriterPtr writer,
const xmlChar * content);
@@ -315,14 +315,14 @@
const xmlChar * pubid,
const xmlChar * sysid,
const char *format, ...)
- ATTRIBUTE_PRINTF(5,6);
+ LIBXML_ATTR_FORMAT(5,6);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteVFormatDTD(xmlTextWriterPtr writer,
const xmlChar * name,
const xmlChar * pubid,
const xmlChar * sysid,
const char *format, va_list argptr)
- ATTRIBUTE_PRINTF(5,0);
+ LIBXML_ATTR_FORMAT(5,0);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteDTD(xmlTextWriterPtr writer,
const xmlChar * name,
@@ -353,13 +353,13 @@
xmlTextWriterWriteFormatDTDElement(xmlTextWriterPtr writer,
const xmlChar * name,
const char *format, ...)
- ATTRIBUTE_PRINTF(3,4);
+ LIBXML_ATTR_FORMAT(3,4);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteVFormatDTDElement(xmlTextWriterPtr writer,
const xmlChar * name,
const char *format,
va_list argptr)
- ATTRIBUTE_PRINTF(3,0);
+ LIBXML_ATTR_FORMAT(3,0);
XMLPUBFUN int XMLCALL xmlTextWriterWriteDTDElement(xmlTextWriterPtr
writer,
const xmlChar *
@@ -383,13 +383,13 @@
xmlTextWriterWriteFormatDTDAttlist(xmlTextWriterPtr writer,
const xmlChar * name,
const char *format, ...)
- ATTRIBUTE_PRINTF(3,4);
+ LIBXML_ATTR_FORMAT(3,4);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteVFormatDTDAttlist(xmlTextWriterPtr writer,
const xmlChar * name,
const char *format,
va_list argptr)
- ATTRIBUTE_PRINTF(3,0);
+ LIBXML_ATTR_FORMAT(3,0);
XMLPUBFUN int XMLCALL xmlTextWriterWriteDTDAttlist(xmlTextWriterPtr
writer,
const xmlChar *
@@ -414,14 +414,14 @@
int pe,
const xmlChar * name,
const char *format, ...)
- ATTRIBUTE_PRINTF(4,5);
+ LIBXML_ATTR_FORMAT(4,5);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteVFormatDTDInternalEntity(xmlTextWriterPtr writer,
int pe,
const xmlChar * name,
const char *format,
va_list argptr)
- ATTRIBUTE_PRINTF(4,0);
+ LIBXML_ATTR_FORMAT(4,0);
XMLPUBFUN int XMLCALL
xmlTextWriterWriteDTDInternalEntity(xmlTextWriterPtr writer,
int pe,
diff --git a/include/libxml/xpath.h b/include/libxml/xpath.h
index 1a9e30e..ddd9dd8 100644
--- a/include/libxml/xpath.h
+++ b/include/libxml/xpath.h
@@ -68,7 +68,8 @@
XPATH_UNDEF_PREFIX_ERROR,
XPATH_ENCODING_ERROR,
XPATH_INVALID_CHAR_ERROR,
- XPATH_INVALID_CTXT
+ XPATH_INVALID_CTXT,
+ XPATH_STACK_ERROR
} xmlXPathError;
/*
@@ -380,6 +381,8 @@
xmlXPathCompExprPtr comp; /* the precompiled expression */
int xptr; /* it this an XPointer expression */
xmlNodePtr ancestor; /* used for walking preceding axis */
+
+ int valueFrame; /* used to limit Pop on the stack */
};
/************************************************************************
diff --git a/libxml.h b/libxml.h
index 3c44c83..dfc6c64 100644
--- a/libxml.h
+++ b/libxml.h
@@ -90,4 +90,7 @@
#endif
#endif
#endif
+#if !defined(PIC) && !defined(NOLIBTOOL)
+# define LIBXML_STATIC
+#endif
#endif /* ! __XML_LIBXML_H__ */
diff --git a/nanoftp.c b/nanoftp.c
index a54b85b..a7ca5b6 100644
--- a/nanoftp.c
+++ b/nanoftp.c
@@ -78,7 +78,9 @@
#if defined(__MINGW32__) || defined(_WIN32_WCE)
+#ifndef _WINSOCKAPI_
#define _WINSOCKAPI_
+#endif
#include <wsockcompat.h>
#include <winsock2.h>
#undef XML_SOCKLEN_T
@@ -92,7 +94,6 @@
#if !defined(__BEOS__) || defined(__HAIKU__)
#define closesocket(s) close(s)
#endif
-#define SOCKET int
#endif
#ifdef __BEOS__
@@ -484,7 +485,7 @@
ret->returnValue = 0;
ret->controlBufIndex = 0;
ret->controlBufUsed = 0;
- ret->controlFd = -1;
+ ret->controlFd = INVALID_SOCKET;
unescaped = xmlURIUnescapeString(URL, 0, NULL);
if (unescaped != NULL) {
@@ -511,8 +512,8 @@
if (ctxt->protocol != NULL) xmlFree(ctxt->protocol);
if (ctxt->path != NULL) xmlFree(ctxt->path);
ctxt->passive = 1;
- if (ctxt->controlFd >= 0) closesocket(ctxt->controlFd);
- ctxt->controlFd = -1;
+ if (ctxt->controlFd != INVALID_SOCKET) closesocket(ctxt->controlFd);
+ ctxt->controlFd = INVALID_SOCKET;
ctxt->controlBufIndex = -1;
ctxt->controlBufUsed = -1;
xmlFree(ctxt);
@@ -567,7 +568,7 @@
int len;
int size;
- if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);
+ if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
if ((ctxt->controlBufIndex < 0) || (ctxt->controlBufIndex > FTP_BUF_SIZE)) {
#ifdef DEBUG_FTP
@@ -619,8 +620,8 @@
if ((len = recv(ctxt->controlFd, &ctxt->controlBuf[ctxt->controlBufIndex],
size, 0)) < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "recv failed");
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+ ctxt->controlFd = INVALID_SOCKET;
return(-1);
}
#ifdef DEBUG_FTP
@@ -648,7 +649,7 @@
int len;
int res = -1, cur = -1;
- if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);
+ if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
get_more:
/*
@@ -737,7 +738,7 @@
fd_set rfd;
struct timeval tv;
- if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);
+ if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&rfd);
@@ -826,7 +827,7 @@
char buf[200];
int len, res;
- if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);
+ if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
snprintf(buf, sizeof(buf), "QUIT\r\n");
len = strlen(buf);
@@ -951,7 +952,7 @@
addrlen = sizeof (struct sockaddr_in);
}
- if (ctxt->controlFd < 0) {
+ if (ctxt->controlFd == INVALID_SOCKET) {
__xmlIOErr(XML_FROM_FTP, 0, "socket failed");
return(-1);
}
@@ -962,8 +963,8 @@
if (connect(ctxt->controlFd, (struct sockaddr *) &ctxt->ftpAddr,
addrlen) < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "Failed to create a connection");
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+ ctxt->controlFd = INVALID_SOCKET;
return(-1);
}
@@ -972,8 +973,8 @@
*/
res = xmlNanoFTPGetResponse(ctxt);
if (res != 2) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+ ctxt->controlFd = INVALID_SOCKET;
return(-1);
}
@@ -1030,7 +1031,7 @@
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
closesocket(ctxt->controlFd);
- ctxt->controlFd = -1;
+ ctxt->controlFd = INVALID_SOCKET;
return(res);
}
res = xmlNanoFTPGetResponse(ctxt);
@@ -1052,13 +1053,13 @@
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
closesocket(ctxt->controlFd);
- ctxt->controlFd = -1;
+ ctxt->controlFd = INVALID_SOCKET;
return(res);
}
res = xmlNanoFTPGetResponse(ctxt);
if (res > 3) {
closesocket(ctxt->controlFd);
- ctxt->controlFd = -1;
+ ctxt->controlFd = INVALID_SOCKET;
return(-1);
}
break;
@@ -1069,7 +1070,7 @@
case -1:
default:
closesocket(ctxt->controlFd);
- ctxt->controlFd = -1;
+ ctxt->controlFd = INVALID_SOCKET;
return(-1);
}
}
@@ -1092,8 +1093,8 @@
res = send(ctxt->controlFd, buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+ ctxt->controlFd = INVALID_SOCKET;
return(res);
}
res = xmlNanoFTPGetResponse(ctxt);
@@ -1103,8 +1104,8 @@
break;
}
if (proxyType == 1) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+ ctxt->controlFd = INVALID_SOCKET;
return(-1);
}
case 2:
@@ -1123,8 +1124,8 @@
res = send(ctxt->controlFd, buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+ ctxt->controlFd = INVALID_SOCKET;
return(res);
}
res = xmlNanoFTPGetResponse(ctxt);
@@ -1145,8 +1146,8 @@
res = send(ctxt->controlFd, buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+ ctxt->controlFd = INVALID_SOCKET;
return(res);
}
res = xmlNanoFTPGetResponse(ctxt);
@@ -1156,8 +1157,8 @@
return(0);
}
if (proxyType == 2) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+ ctxt->controlFd = INVALID_SOCKET;
return(-1);
}
case 3:
@@ -1166,8 +1167,8 @@
* send the code or at least the sequence in use.
*/
default:
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+ ctxt->controlFd = INVALID_SOCKET;
return(-1);
}
}
@@ -1176,8 +1177,8 @@
*/
res = xmlNanoFTPSendUser(ctxt);
if (res < 0) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+ ctxt->controlFd = INVALID_SOCKET;
return(-1);
}
res = xmlNanoFTPGetResponse(ctxt);
@@ -1191,14 +1192,14 @@
case 5:
case -1:
default:
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+ ctxt->controlFd = INVALID_SOCKET;
return(-1);
}
res = xmlNanoFTPSendPasswd(ctxt);
if (res < 0) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+ ctxt->controlFd = INVALID_SOCKET;
return(-1);
}
res = xmlNanoFTPGetResponse(ctxt);
@@ -1213,8 +1214,8 @@
case 5:
case -1:
default:
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
- ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
+ ctxt->controlFd = INVALID_SOCKET;
return(-1);
}
@@ -1270,7 +1271,7 @@
int len;
int res;
- if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);
+ if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
if (directory == NULL) return 0;
/*
@@ -1319,7 +1320,7 @@
int len;
int res;
- if ((ctxt == NULL) || (ctxt->controlFd < 0) || (file == NULL)) return(-1);
+ if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET) || (file == NULL)) return(-1);
if (file == NULL) return (0);
/*
@@ -1362,7 +1363,7 @@
* Returns -1 incase of error, 0 otherwise
*/
-int
+SOCKET
xmlNanoFTPGetConnection(void *ctx) {
xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
char buf[200], *cur;
@@ -1377,7 +1378,7 @@
#endif
XML_SOCKLEN_T dataAddrLen;
- if (ctxt == NULL) return(-1);
+ if (ctxt == NULL) return INVALID_SOCKET;
memset (&dataAddr, 0, sizeof(dataAddr));
#ifdef SUPPORT_IP6
@@ -1393,9 +1394,9 @@
dataAddrLen = sizeof (struct sockaddr_in);
}
- if (ctxt->dataFd < 0) {
+ if (ctxt->dataFd == INVALID_SOCKET) {
__xmlIOErr(XML_FROM_FTP, 0, "socket failed");
- return (-1);
+ return INVALID_SOCKET;
}
if (ctxt->passive) {
@@ -1412,19 +1413,19 @@
res = send(ctxt->controlFd, buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(res);
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+ return INVALID_SOCKET;
}
res = xmlNanoFTPReadResponse(ctx);
if (res != 2) {
if (res == 5) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(-1);
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+ return INVALID_SOCKET;
} else {
/*
* retry with an active connection
*/
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
ctxt->passive = 0;
}
}
@@ -1435,10 +1436,10 @@
if (sscanf (cur, "%u", &temp[0]) != 1) {
__xmlIOErr(XML_FROM_FTP, XML_FTP_EPSV_ANSWER,
"Invalid answer to EPSV\n");
- if (ctxt->dataFd != -1) {
- closesocket (ctxt->dataFd); ctxt->dataFd = -1;
+ if (ctxt->dataFd != INVALID_SOCKET) {
+ closesocket (ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
}
- return (-1);
+ return INVALID_SOCKET;
}
memcpy (&((struct sockaddr_in6 *)&dataAddr)->sin6_addr, &((struct sockaddr_in6 *)&ctxt->ftpAddr)->sin6_addr, sizeof(struct in6_addr));
((struct sockaddr_in6 *)&dataAddr)->sin6_port = htons (temp[0]);
@@ -1450,10 +1451,10 @@
&temp[3], &temp[4], &temp[5]) != 6) {
__xmlIOErr(XML_FROM_FTP, XML_FTP_PASV_ANSWER,
"Invalid answer to PASV\n");
- if (ctxt->dataFd != -1) {
- closesocket (ctxt->dataFd); ctxt->dataFd = -1;
+ if (ctxt->dataFd != INVALID_SOCKET) {
+ closesocket (ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
}
- return (-1);
+ return INVALID_SOCKET;
}
for (i=0; i<6; i++) ad[i] = (unsigned char) (temp[i] & 0xff);
memcpy (&((struct sockaddr_in *)&dataAddr)->sin_addr, &ad[0], 4);
@@ -1462,8 +1463,8 @@
if (connect(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "Failed to create a data connection");
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return (-1);
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+ return INVALID_SOCKET;
}
} else {
getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
@@ -1476,15 +1477,15 @@
if (bind(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "bind failed");
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return (-1);
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+ return INVALID_SOCKET;
}
getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
if (listen(ctxt->dataFd, 1) < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "listen failed");
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return (-1);
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+ return INVALID_SOCKET;
}
#ifdef SUPPORT_IP6
if ((ctxt->ftpAddr).ss_family == AF_INET6) {
@@ -1513,13 +1514,13 @@
res = send(ctxt->controlFd, buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(res);
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+ return INVALID_SOCKET;
}
res = xmlNanoFTPGetResponse(ctxt);
if (res != 2) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(-1);
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+ return INVALID_SOCKET;
}
}
return(ctxt->dataFd);
@@ -1542,9 +1543,9 @@
fd_set rfd, efd;
struct timeval tv;
- if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);
+ if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
tv.tv_sec = 15;
tv.tv_usec = 0;
FD_ZERO(&rfd);
@@ -1556,7 +1557,7 @@
#ifdef DEBUG_FTP
perror("select");
#endif
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
return(-1);
}
if (res == 0) {
@@ -1564,11 +1565,11 @@
xmlGenericError(xmlGenericErrorContext,
"xmlNanoFTPCloseConnection: timeout\n");
#endif
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
} else {
res = xmlNanoFTPGetResponse(ctxt);
if (res != 2) {
- closesocket(ctxt->controlFd); ctxt->controlFd = -1;
+ closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
return(-1);
}
}
@@ -1729,7 +1730,7 @@
if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)
return(-1);
ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
- if (ctxt->dataFd == -1)
+ if (ctxt->dataFd == INVALID_SOCKET)
return(-1);
snprintf(buf, sizeof(buf), "LIST -L\r\n");
} else {
@@ -1738,7 +1739,7 @@
return(-1);
}
ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
- if (ctxt->dataFd == -1)
+ if (ctxt->dataFd == INVALID_SOCKET)
return(-1);
snprintf(buf, sizeof(buf), "LIST -L %s\r\n", filename);
}
@@ -1750,12 +1751,12 @@
res = send(ctxt->controlFd, buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
return(res);
}
res = xmlNanoFTPReadResponse(ctxt);
if (res != 1) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
return(-res);
}
@@ -1771,18 +1772,18 @@
#ifdef DEBUG_FTP
perror("select");
#endif
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
return(-1);
}
if (res == 0) {
res = xmlNanoFTPCheckResponse(ctxt);
if (res < 0) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- ctxt->dataFd = -1;
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+ ctxt->dataFd = INVALID_SOCKET;
return(-1);
}
if (res == 2) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
return(0);
}
@@ -1791,8 +1792,8 @@
if ((len = recv(ctxt->dataFd, &buf[indx], sizeof(buf) - (indx + 1), 0)) < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "recv");
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- ctxt->dataFd = -1;
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+ ctxt->dataFd = INVALID_SOCKET;
return(-1);
}
#ifdef DEBUG_FTP
@@ -1824,18 +1825,18 @@
*/
-int
+SOCKET
xmlNanoFTPGetSocket(void *ctx, const char *filename) {
xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
char buf[300];
int res, len;
if (ctx == NULL)
- return(-1);
+ return INVALID_SOCKET;
if ((filename == NULL) && (ctxt->path == NULL))
- return(-1);
+ return INVALID_SOCKET;
ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
- if (ctxt->dataFd == -1)
- return(-1);
+ if (ctxt->dataFd == INVALID_SOCKET)
+ return INVALID_SOCKET;
snprintf(buf, sizeof(buf), "TYPE I\r\n");
len = strlen(buf);
@@ -1845,13 +1846,13 @@
res = send(ctxt->controlFd, buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(res);
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+ return INVALID_SOCKET;
}
res = xmlNanoFTPReadResponse(ctxt);
if (res != 2) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(-res);
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+ return INVALID_SOCKET;
}
if (filename == NULL)
snprintf(buf, sizeof(buf), "RETR %s\r\n", ctxt->path);
@@ -1865,13 +1866,13 @@
res = send(ctxt->controlFd, buf, len, 0);
if (res < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "send failed");
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(res);
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+ return INVALID_SOCKET;
}
res = xmlNanoFTPReadResponse(ctxt);
if (res != 1) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- return(-res);
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+ return INVALID_SOCKET;
}
return(ctxt->dataFd);
}
@@ -1903,7 +1904,7 @@
return(-1);
if (callback == NULL)
return(-1);
- if (xmlNanoFTPGetSocket(ctxt, filename) < 0)
+ if (xmlNanoFTPGetSocket(ctxt, filename) == INVALID_SOCKET)
return(-1);
do {
@@ -1916,18 +1917,18 @@
#ifdef DEBUG_FTP
perror("select");
#endif
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
return(-1);
}
if (res == 0) {
res = xmlNanoFTPCheckResponse(ctxt);
if (res < 0) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
- ctxt->dataFd = -1;
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
+ ctxt->dataFd = INVALID_SOCKET;
return(-1);
}
if (res == 2) {
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
return(0);
}
@@ -1936,7 +1937,7 @@
if ((len = recv(ctxt->dataFd, buf, sizeof(buf), 0)) < 0) {
__xmlIOErr(XML_FROM_FTP, 0, "recv failed");
callback(userData, buf, len);
- closesocket(ctxt->dataFd); ctxt->dataFd = -1;
+ closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
return(-1);
}
callback(userData, buf, len);
@@ -1962,7 +1963,7 @@
xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
if (ctx == NULL) return(-1);
- if (ctxt->dataFd < 0) return(0);
+ if (ctxt->dataFd == INVALID_SOCKET) return(0);
if (dest == NULL) return(-1);
if (len <= 0) return(0);
@@ -1990,7 +1991,7 @@
void*
xmlNanoFTPOpen(const char *URL) {
xmlNanoFTPCtxtPtr ctxt;
- int sock;
+ SOCKET sock;
xmlNanoFTPInit();
if (URL == NULL) return(NULL);
@@ -2003,7 +2004,7 @@
return(NULL);
}
sock = xmlNanoFTPGetSocket(ctxt, ctxt->path);
- if (sock < 0) {
+ if (sock == INVALID_SOCKET) {
xmlNanoFTPFreeCtxt(ctxt);
return(NULL);
}
@@ -2026,14 +2027,14 @@
if (ctxt == NULL)
return(-1);
- if (ctxt->dataFd >= 0) {
+ if (ctxt->dataFd != INVALID_SOCKET) {
closesocket(ctxt->dataFd);
- ctxt->dataFd = -1;
+ ctxt->dataFd = INVALID_SOCKET;
}
- if (ctxt->controlFd >= 0) {
+ if (ctxt->controlFd != INVALID_SOCKET) {
xmlNanoFTPQuit(ctxt);
closesocket(ctxt->controlFd);
- ctxt->controlFd = -1;
+ ctxt->controlFd = INVALID_SOCKET;
}
xmlNanoFTPFreeCtxt(ctxt);
return(0);
diff --git a/nanohttp.c b/nanohttp.c
index 9001ae5..a8af0e1 100644
--- a/nanohttp.c
+++ b/nanohttp.c
@@ -54,9 +54,13 @@
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
+#ifndef HAVE_POLL_H
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
+#else
+#include <poll.h>
+#endif
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
@@ -71,18 +75,18 @@
#ifdef VMS
#include <stropts>
#define XML_SOCKLEN_T unsigned int
-#define SOCKET int
#endif
#if defined(__MINGW32__) || defined(_WIN32_WCE)
+#ifndef _WINSOCKAPI_
#define _WINSOCKAPI_
+#endif
#include <wsockcompat.h>
#include <winsock2.h>
#undef XML_SOCKLEN_T
#define XML_SOCKLEN_T unsigned int
#endif
-
#include <libxml/globals.h>
#include <libxml/xmlerror.h>
#include <libxml/xmlmemory.h>
@@ -99,6 +103,7 @@
#define closesocket(s) close(s)
#endif
#define SOCKET int
+#define INVALID_SOCKET (-1)
#endif
#ifdef __BEOS__
@@ -110,9 +115,6 @@
#ifndef XML_SOCKLEN_T
#define XML_SOCKLEN_T unsigned int
#endif
-#ifndef SOCKET
-#define SOCKET int
-#endif
#ifdef STANDALONE
#define DEBUG_HTTP
@@ -146,6 +148,7 @@
int inlen; /* len of the input buffer */
int last; /* return code for last operation */
int returnValue; /* the protocol return value */
+ int version; /* the protocol version */
int ContentLength; /* specified content length from HTTP header */
char *contentType; /* the MIME type for the input */
char *location; /* the new URL in case of redirect */
@@ -191,10 +194,10 @@
#ifdef SUPPORT_IP6
static
int have_ipv6(void) {
- int s;
+ SOCKET s;
s = socket (AF_INET6, SOCK_STREAM, 0);
- if (s != -1) {
+ if (s != INVALID_SOCKET) {
close (s);
return (1);
}
@@ -388,7 +391,7 @@
memset(ret, 0, sizeof(xmlNanoHTTPCtxt));
ret->port = 80;
ret->returnValue = 0;
- ret->fd = -1;
+ ret->fd = INVALID_SOCKET;
ret->ContentLength = -1;
xmlNanoHTTPScanURL(ret, URL);
@@ -425,8 +428,8 @@
#endif
ctxt->state = XML_NANO_HTTP_NONE;
- if (ctxt->fd >= 0) closesocket(ctxt->fd);
- ctxt->fd = -1;
+ if (ctxt->fd != INVALID_SOCKET) closesocket(ctxt->fd);
+ ctxt->fd = INVALID_SOCKET;
xmlFree(ctxt);
}
@@ -439,51 +442,64 @@
*/
static int
-xmlNanoHTTPSend(xmlNanoHTTPCtxtPtr ctxt, const char * xmt_ptr, int outlen) {
+xmlNanoHTTPSend(xmlNanoHTTPCtxtPtr ctxt, const char *xmt_ptr, int outlen)
+{
+ int total_sent = 0;
+#ifdef HAVE_POLL_H
+ struct pollfd p;
+#else
+ struct timeval tv;
+ fd_set wfd;
+#endif
- int total_sent = 0;
-
- if ( (ctxt->state & XML_NANO_HTTP_WRITE) && (xmt_ptr != NULL ) ) {
+ if ((ctxt->state & XML_NANO_HTTP_WRITE) && (xmt_ptr != NULL)) {
while (total_sent < outlen) {
int nsent = send(ctxt->fd, xmt_ptr + total_sent,
- outlen - total_sent, 0);
- if (nsent>0)
+ outlen - total_sent, 0);
+
+ if (nsent > 0)
total_sent += nsent;
- else if ( ( nsent == -1 ) &&
+ else if ((nsent == -1) &&
#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
- ( socket_errno( ) != EAGAIN ) &&
+ (socket_errno() != EAGAIN) &&
#endif
- ( socket_errno( ) != EWOULDBLOCK ) ) {
- __xmlIOErr(XML_FROM_HTTP, 0, "send failed\n");
- if ( total_sent == 0 )
- total_sent = -1;
- break;
- }
- else {
- /*
- ** No data sent
- ** Since non-blocking sockets are used, wait for
- ** socket to be writable or default timeout prior
- ** to retrying.
- */
+ (socket_errno() != EWOULDBLOCK)) {
+ __xmlIOErr(XML_FROM_HTTP, 0, "send failed\n");
+ if (total_sent == 0)
+ total_sent = -1;
+ break;
+ } else {
+ /*
+ * No data sent
+ * Since non-blocking sockets are used, wait for
+ * socket to be writable or default timeout prior
+ * to retrying.
+ */
+#ifndef HAVE_POLL_H
+#ifndef _WINSOCKAPI_
+ if (ctxt->fd > FD_SETSIZE)
+ return -1;
+#endif
- struct timeval tv;
- fd_set wfd;
-
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
- FD_ZERO( &wfd );
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+ FD_ZERO(&wfd);
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4018)
#endif
- FD_SET( ctxt->fd, &wfd );
+ FD_SET(ctxt->fd, &wfd);
#ifdef _MSC_VER
#pragma warning(pop)
#endif
- (void)select( ctxt->fd + 1, NULL, &wfd, NULL, &tv );
- }
- }
+ (void) select(ctxt->fd + 1, NULL, &wfd, NULL, &tv);
+#else
+ p.fd = ctxt->fd;
+ p.events = POLLOUT;
+ (void) poll(&p, 1, timeout * 1000);
+#endif /* !HAVE_POLL_H */
+ }
+ }
}
return total_sent;
@@ -500,96 +516,119 @@
*/
static int
-xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt) {
+xmlNanoHTTPRecv(xmlNanoHTTPCtxtPtr ctxt)
+{
+#ifdef HAVE_POLL_H
+ struct pollfd p;
+#else
fd_set rfd;
struct timeval tv;
+#endif
while (ctxt->state & XML_NANO_HTTP_READ) {
- if (ctxt->in == NULL) {
- ctxt->in = (char *) xmlMallocAtomic(65000 * sizeof(char));
- if (ctxt->in == NULL) {
- xmlHTTPErrMemory("allocating input");
- ctxt->last = -1;
- return(-1);
- }
- ctxt->inlen = 65000;
- ctxt->inptr = ctxt->content = ctxt->inrptr = ctxt->in;
- }
- if (ctxt->inrptr > ctxt->in + XML_NANO_HTTP_CHUNK) {
- int delta = ctxt->inrptr - ctxt->in;
- int len = ctxt->inptr - ctxt->inrptr;
-
- memmove(ctxt->in, ctxt->inrptr, len);
- ctxt->inrptr -= delta;
- ctxt->content -= delta;
- ctxt->inptr -= delta;
- }
- if ((ctxt->in + ctxt->inlen) < (ctxt->inptr + XML_NANO_HTTP_CHUNK)) {
- int d_inptr = ctxt->inptr - ctxt->in;
- int d_content = ctxt->content - ctxt->in;
- int d_inrptr = ctxt->inrptr - ctxt->in;
- char * tmp_ptr = ctxt->in;
+ if (ctxt->in == NULL) {
+ ctxt->in = (char *) xmlMallocAtomic(65000 * sizeof(char));
+ if (ctxt->in == NULL) {
+ xmlHTTPErrMemory("allocating input");
+ ctxt->last = -1;
+ return (-1);
+ }
+ ctxt->inlen = 65000;
+ ctxt->inptr = ctxt->content = ctxt->inrptr = ctxt->in;
+ }
+ if (ctxt->inrptr > ctxt->in + XML_NANO_HTTP_CHUNK) {
+ int delta = ctxt->inrptr - ctxt->in;
+ int len = ctxt->inptr - ctxt->inrptr;
- ctxt->inlen *= 2;
+ memmove(ctxt->in, ctxt->inrptr, len);
+ ctxt->inrptr -= delta;
+ ctxt->content -= delta;
+ ctxt->inptr -= delta;
+ }
+ if ((ctxt->in + ctxt->inlen) < (ctxt->inptr + XML_NANO_HTTP_CHUNK)) {
+ int d_inptr = ctxt->inptr - ctxt->in;
+ int d_content = ctxt->content - ctxt->in;
+ int d_inrptr = ctxt->inrptr - ctxt->in;
+ char *tmp_ptr = ctxt->in;
+
+ ctxt->inlen *= 2;
ctxt->in = (char *) xmlRealloc(tmp_ptr, ctxt->inlen);
- if (ctxt->in == NULL) {
- xmlHTTPErrMemory("allocating input buffer");
- xmlFree( tmp_ptr );
- ctxt->last = -1;
- return(-1);
- }
+ if (ctxt->in == NULL) {
+ xmlHTTPErrMemory("allocating input buffer");
+ xmlFree(tmp_ptr);
+ ctxt->last = -1;
+ return (-1);
+ }
ctxt->inptr = ctxt->in + d_inptr;
ctxt->content = ctxt->in + d_content;
ctxt->inrptr = ctxt->in + d_inrptr;
- }
- ctxt->last = recv(ctxt->fd, ctxt->inptr, XML_NANO_HTTP_CHUNK, 0);
- if (ctxt->last > 0) {
- ctxt->inptr += ctxt->last;
- return(ctxt->last);
- }
- if (ctxt->last == 0) {
- return(0);
- }
- if (ctxt->last == -1) {
- switch (socket_errno()) {
- case EINPROGRESS:
- case EWOULDBLOCK:
+ }
+ ctxt->last = recv(ctxt->fd, ctxt->inptr, XML_NANO_HTTP_CHUNK, 0);
+ if (ctxt->last > 0) {
+ ctxt->inptr += ctxt->last;
+ return (ctxt->last);
+ }
+ if (ctxt->last == 0) {
+ return (0);
+ }
+ if (ctxt->last == -1) {
+ switch (socket_errno()) {
+ case EINPROGRESS:
+ case EWOULDBLOCK:
#if defined(EAGAIN) && EAGAIN != EWOULDBLOCK
- case EAGAIN:
+ case EAGAIN:
#endif
- break;
+ break;
- case ECONNRESET:
- case ESHUTDOWN:
- return ( 0 );
+ case ECONNRESET:
+ case ESHUTDOWN:
+ return (0);
- default:
- __xmlIOErr(XML_FROM_HTTP, 0, "recv failed\n");
- return(-1);
- }
- }
+ default:
+ __xmlIOErr(XML_FROM_HTTP, 0, "recv failed\n");
+ return (-1);
+ }
+ }
+#ifdef HAVE_POLL_H
+ p.fd = ctxt->fd;
+ p.events = POLLIN;
+ if ((poll(&p, 1, timeout * 1000) < 1)
+#if defined(EINTR)
+ && (errno != EINTR)
+#endif
+ )
+ return (0);
+#else /* !HAVE_POLL_H */
+#ifndef _WINSOCKAPI_
+ if (ctxt->fd > FD_SETSIZE)
+ return 0;
+#endif
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
- FD_ZERO(&rfd);
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+ FD_ZERO(&rfd);
+
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4018)
#endif
- FD_SET(ctxt->fd, &rfd);
+
+ FD_SET(ctxt->fd, &rfd);
+
#ifdef _MSC_VER
#pragma warning(pop)
#endif
-
- if ( (select(ctxt->fd+1, &rfd, NULL, NULL, &tv)<1)
+
+ if ((select(ctxt->fd + 1, &rfd, NULL, NULL, &tv) < 1)
#if defined(EINTR)
- && (errno != EINTR)
+ && (errno != EINTR)
#endif
- )
- return(0);
+ )
+ return (0);
+#endif /* !HAVE_POLL_H */
}
- return(0);
+ return (0);
}
/**
@@ -686,6 +725,7 @@
}
if ((*cur != 0) && (*cur != ' ') && (*cur != '\t')) return;
ctxt->returnValue = ret;
+ ctxt->version = version;
} else if (!xmlStrncasecmp(BAD_CAST line, BAD_CAST"Content-Type:", 13)) {
const xmlChar *charset, *last, *mime;
cur += 13;
@@ -800,90 +840,99 @@
* Returns -1 in case of failure, the file descriptor number otherwise
*/
-static int
+static SOCKET
xmlNanoHTTPConnectAttempt(struct sockaddr *addr)
{
+#ifndef HAVE_POLL_H
fd_set wfd;
#ifdef _WINSOCKAPI_
fd_set xfd;
#endif
struct timeval tv;
+#else /* !HAVE_POLL_H */
+ struct pollfd p;
+#endif /* !HAVE_POLL_H */
int status;
+
int addrlen;
+
SOCKET s;
-
+
#ifdef SUPPORT_IP6
if (addr->sa_family == AF_INET6) {
- s = socket (PF_INET6, SOCK_STREAM, IPPROTO_TCP);
- addrlen = sizeof (struct sockaddr_in6);
- }
- else
+ s = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
+ addrlen = sizeof(struct sockaddr_in6);
+ } else
#endif
{
- s = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);
- addrlen = sizeof (struct sockaddr_in);
+ s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+ addrlen = sizeof(struct sockaddr_in);
}
- if (s==-1) {
+ if (s == INVALID_SOCKET) {
#ifdef DEBUG_HTTP
- perror("socket");
+ perror("socket");
#endif
- __xmlIOErr(XML_FROM_HTTP, 0, "socket failed\n");
- return(-1);
+ __xmlIOErr(XML_FROM_HTTP, 0, "socket failed\n");
+ return INVALID_SOCKET;
}
-
#ifdef _WINSOCKAPI_
{
- u_long one = 1;
+ u_long one = 1;
- status = ioctlsocket(s, FIONBIO, &one) == SOCKET_ERROR ? -1 : 0;
+ status = ioctlsocket(s, FIONBIO, &one) == SOCKET_ERROR ? -1 : 0;
}
#else /* _WINSOCKAPI_ */
#if defined(VMS)
{
- int enable = 1;
- status = ioctl(s, FIONBIO, &enable);
+ int enable = 1;
+
+ status = ioctl(s, FIONBIO, &enable);
}
#else /* VMS */
#if defined(__BEOS__) && !defined(__HAIKU__)
- {
- bool noblock = true;
- status = setsockopt(s, SOL_SOCKET, SO_NONBLOCK, &noblock, sizeof(noblock));
- }
+ {
+ bool noblock = true;
+
+ status =
+ setsockopt(s, SOL_SOCKET, SO_NONBLOCK, &noblock,
+ sizeof(noblock));
+ }
#else /* __BEOS__ */
if ((status = fcntl(s, F_GETFL, 0)) != -1) {
#ifdef O_NONBLOCK
- status |= O_NONBLOCK;
+ status |= O_NONBLOCK;
#else /* O_NONBLOCK */
#ifdef F_NDELAY
- status |= F_NDELAY;
+ status |= F_NDELAY;
#endif /* F_NDELAY */
#endif /* !O_NONBLOCK */
- status = fcntl(s, F_SETFL, status);
+ status = fcntl(s, F_SETFL, status);
}
if (status < 0) {
#ifdef DEBUG_HTTP
- perror("nonblocking");
+ perror("nonblocking");
#endif
- __xmlIOErr(XML_FROM_HTTP, 0, "error setting non-blocking IO\n");
- closesocket(s);
- return(-1);
+ __xmlIOErr(XML_FROM_HTTP, 0, "error setting non-blocking IO\n");
+ closesocket(s);
+ return INVALID_SOCKET;
}
#endif /* !__BEOS__ */
#endif /* !VMS */
#endif /* !_WINSOCKAPI_ */
- if (connect (s, addr, addrlen) == -1) {
- switch (socket_errno()) {
- case EINPROGRESS:
- case EWOULDBLOCK:
- break;
- default:
- __xmlIOErr(XML_FROM_HTTP, 0, "error connecting to HTTP server");
- closesocket(s);
- return(-1);
- }
- }
-
+ if (connect(s, addr, addrlen) == -1) {
+ switch (socket_errno()) {
+ case EINPROGRESS:
+ case EWOULDBLOCK:
+ break;
+ default:
+ __xmlIOErr(XML_FROM_HTTP, 0,
+ "error connecting to HTTP server");
+ closesocket(s);
+ return INVALID_SOCKET;
+ }
+ }
+#ifndef HAVE_POLL_H
tv.tv_sec = timeout;
tv.tv_usec = 0;
@@ -891,63 +940,82 @@
#pragma warning(push)
#pragma warning(disable: 4018)
#endif
+#ifndef _WINSOCKAPI_
+ if (s > FD_SETSIZE)
+ return INVALID_SOCKET;
+#endif
FD_ZERO(&wfd);
FD_SET(s, &wfd);
-#ifdef _WINSOCKAPI_
+#ifdef _WINSOCKAPI_
FD_ZERO(&xfd);
FD_SET(s, &xfd);
-
- switch(select(s+1, NULL, &wfd, &xfd, &tv))
+
+ switch (select(s + 1, NULL, &wfd, &xfd, &tv))
#else
- switch(select(s+1, NULL, &wfd, NULL, &tv))
+ switch (select(s + 1, NULL, &wfd, NULL, &tv))
#endif
#ifdef _MSC_VER
#pragma warning(pop)
#endif
+
+#else /* !HAVE_POLL_H */
+ p.fd = s;
+ p.events = POLLOUT;
+ switch (poll(&p, 1, timeout * 1000))
+#endif /* !HAVE_POLL_H */
+
{
- case 0:
- /* Time out */
- __xmlIOErr(XML_FROM_HTTP, 0, "Connect attempt timed out");
- closesocket(s);
- return(-1);
- case -1:
- /* Ermm.. ?? */
- __xmlIOErr(XML_FROM_HTTP, 0, "Connect failed");
- closesocket(s);
- return(-1);
+ case 0:
+ /* Time out */
+ __xmlIOErr(XML_FROM_HTTP, 0, "Connect attempt timed out");
+ closesocket(s);
+ return INVALID_SOCKET;
+ case -1:
+ /* Ermm.. ?? */
+ __xmlIOErr(XML_FROM_HTTP, 0, "Connect failed");
+ closesocket(s);
+ return INVALID_SOCKET;
}
- if ( FD_ISSET(s, &wfd)
+#ifndef HAVE_POLL_H
+ if (FD_ISSET(s, &wfd)
#ifdef _WINSOCKAPI_
- || FD_ISSET(s, &xfd)
+ || FD_ISSET(s, &xfd)
#endif
- ) {
- XML_SOCKLEN_T len;
- len = sizeof(status);
+ )
+#else /* !HAVE_POLL_H */
+ if (p.revents == POLLOUT)
+#endif /* !HAVE_POLL_H */
+ {
+ XML_SOCKLEN_T len;
+
+ len = sizeof(status);
#ifdef SO_ERROR
- if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&status, &len) < 0 ) {
- /* Solaris error code */
- __xmlIOErr(XML_FROM_HTTP, 0, "getsockopt failed\n");
- return (-1);
- }
+ if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char *) &status, &len) <
+ 0) {
+ /* Solaris error code */
+ __xmlIOErr(XML_FROM_HTTP, 0, "getsockopt failed\n");
+ return INVALID_SOCKET;
+ }
#endif
- if ( status ) {
- __xmlIOErr(XML_FROM_HTTP, 0, "Error connecting to remote host");
- closesocket(s);
- errno = status;
- return (-1);
- }
+ if (status) {
+ __xmlIOErr(XML_FROM_HTTP, 0,
+ "Error connecting to remote host");
+ closesocket(s);
+ errno = status;
+ return INVALID_SOCKET;
+ }
} else {
- /* pbm */
- __xmlIOErr(XML_FROM_HTTP, 0, "select failed\n");
- closesocket(s);
- return (-1);
+ /* pbm */
+ __xmlIOErr(XML_FROM_HTTP, 0, "select failed\n");
+ closesocket(s);
+ return INVALID_SOCKET;
}
-
- return(s);
+
+ return (s);
}
-
+
/**
* xmlNanoHTTPConnectHost:
* @host: the host name
@@ -959,7 +1027,7 @@
* Returns -1 in case of failure, the file descriptor number otherwise
*/
-static int
+static SOCKET
xmlNanoHTTPConnectHost(const char *host, int port)
{
struct hostent *h;
@@ -972,7 +1040,7 @@
struct sockaddr_in6 sockin6;
#endif
int i;
- int s;
+ SOCKET s;
memset (&sockin, 0, sizeof(sockin));
#ifdef SUPPORT_IP6
@@ -1003,7 +1071,7 @@
status = getaddrinfo (host, NULL, &hints, &result);
if (status) {
__xmlIOErr(XML_FROM_HTTP, 0, "getaddrinfo failed\n");
- return (-1);
+ return INVALID_SOCKET;
}
for (res = result; res; res = res->ai_next) {
@@ -1011,7 +1079,7 @@
if (res->ai_addrlen > sizeof(sockin)) {
__xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
freeaddrinfo (result);
- return (-1);
+ return INVALID_SOCKET;
}
memcpy (&sockin, res->ai_addr, res->ai_addrlen);
sockin.sin_port = htons (port);
@@ -1021,7 +1089,7 @@
if (res->ai_addrlen > sizeof(sockin6)) {
__xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
freeaddrinfo (result);
- return (-1);
+ return INVALID_SOCKET;
}
memcpy (&sockin6, res->ai_addr, res->ai_addrlen);
sockin6.sin6_port = htons (port);
@@ -1031,7 +1099,7 @@
continue; /* for */
s = xmlNanoHTTPConnectAttempt (addr);
- if (s != -1) {
+ if (s != INVALID_SOCKET) {
freeaddrinfo (result);
return (s);
}
@@ -1085,7 +1153,7 @@
#else
__xmlIOErr(XML_FROM_HTTP, 0, "Failed to resolve host");
#endif
- return (-1);
+ return INVALID_SOCKET;
}
for (i = 0; h->h_addr_list[i]; i++) {
@@ -1093,7 +1161,7 @@
/* A records (IPv4) */
if ((unsigned int) h->h_length > sizeof(ia)) {
__xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
- return (-1);
+ return INVALID_SOCKET;
}
memcpy (&ia, h->h_addr_list[i], h->h_length);
sockin.sin_family = h->h_addrtype;
@@ -1105,7 +1173,7 @@
/* AAAA records (IPv6) */
if ((unsigned int) h->h_length > sizeof(ia6)) {
__xmlIOErr(XML_FROM_HTTP, 0, "address size mismatch\n");
- return (-1);
+ return INVALID_SOCKET;
}
memcpy (&ia6, h->h_addr_list[i], h->h_length);
sockin6.sin6_family = h->h_addrtype;
@@ -1117,7 +1185,7 @@
break; /* for */
s = xmlNanoHTTPConnectAttempt (addr);
- if (s != -1)
+ if (s != INVALID_SOCKET)
return (s);
}
}
@@ -1128,7 +1196,7 @@
"xmlNanoHTTPConnectHost: unable to connect to '%s'.\n",
host);
#endif
- return (-1);
+ return INVALID_SOCKET;
}
@@ -1272,8 +1340,8 @@
const char *headers, int ilen ) {
xmlNanoHTTPCtxtPtr ctxt;
char *bp, *p;
- int blen, ret;
- int head;
+ int blen;
+ SOCKET ret;
int nbRedirects = 0;
char *redirURL = NULL;
#ifdef DEBUG_HTTP
@@ -1317,7 +1385,7 @@
blen = strlen(ctxt->hostname);
ret = xmlNanoHTTPConnectHost(ctxt->hostname, ctxt->port);
}
- if (ret < 0) {
+ if (ret == INVALID_SOCKET) {
xmlNanoHTTPFreeCtxt(ctxt);
if (redirURL != NULL) xmlFree(redirURL);
return(NULL);
@@ -1435,11 +1503,9 @@
}
ctxt->state = XML_NANO_HTTP_READ;
- head = 1;
while ((p = xmlNanoHTTPReadLine(ctxt)) != NULL) {
- if (head && (*p == 0)) {
- head = 0;
+ if (*p == 0) {
ctxt->content = ctxt->inrptr;
xmlFree(p);
break;
@@ -1549,7 +1615,8 @@
char *buf = NULL;
int fd;
int len;
-
+ int ret = 0;
+
if (filename == NULL) return(-1);
ctxt = xmlNanoHTTPOpen(URL, contentType);
if (ctxt == NULL) return(-1);
@@ -1570,12 +1637,14 @@
xmlNanoHTTPFetchContent( ctxt, &buf, &len );
if ( len > 0 ) {
- write(fd, buf, len);
+ if (write(fd, buf, len) == -1) {
+ ret = -1;
+ }
}
xmlNanoHTTPClose(ctxt);
close(fd);
- return(0);
+ return(ret);
}
#ifdef LIBXML_OUTPUT_ENABLED
@@ -1594,7 +1663,8 @@
char *buf = NULL;
int fd;
int len;
-
+ int ret = 0;
+
if ((ctxt == NULL) || (filename == NULL)) return(-1);
if (!strcmp(filename, "-"))
@@ -1609,12 +1679,14 @@
xmlNanoHTTPFetchContent( ctxt, &buf, &len );
if ( len > 0 ) {
- write(fd, buf, len);
+ if (write(fd, buf, len) == -1) {
+ ret = -1;
+ }
}
xmlNanoHTTPClose(ctxt);
close(fd);
- return(0);
+ return(ret);
}
#endif /* LIBXML_OUTPUT_ENABLED */
diff --git a/parser.c b/parser.c
index 6de2ef4..72a467c 100644
--- a/parser.c
+++ b/parser.c
@@ -79,10 +79,17 @@
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif
+#ifdef HAVE_LZMA_H
+#include <lzma.h>
+#endif
static void
xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info);
+static xmlParserCtxtPtr
+xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
+ const xmlChar *base, xmlParserCtxtPtr pctx);
+
/************************************************************************
* *
* Arbitrary limits set in the parser. See XML_PARSE_HUGE *
@@ -193,13 +200,14 @@
static const char *xmlW3CPIs[] = {
"xml-stylesheet",
+ "xml-model",
NULL
};
/* DEPR void xmlParserHandleReference(xmlParserCtxtPtr ctxt); */
-xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
- const xmlChar **str);
+static xmlEntityPtr xmlParseStringPEReference(xmlParserCtxtPtr ctxt,
+ const xmlChar **str);
static xmlParserErrors
xmlParseExternalEntityPrivate(xmlDocPtr doc, xmlParserCtxtPtr oldctxt,
@@ -246,14 +254,15 @@
return;
if (ctxt != NULL)
ctxt->errNo = XML_ERR_ATTRIBUTE_REDEFINED;
+
if (prefix == NULL)
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
- ctxt->errNo, XML_ERR_FATAL, NULL, 0,
+ XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
(const char *) localname, NULL, NULL, 0, 0,
"Attribute %s redefined\n", localname);
else
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
- ctxt->errNo, XML_ERR_FATAL, NULL, 0,
+ XML_ERR_ATTRIBUTE_REDEFINED, XML_ERR_FATAL, NULL, 0,
(const char *) prefix, (const char *) localname,
NULL, 0, 0, "Attribute %s:%s redefined\n", prefix,
localname);
@@ -519,13 +528,21 @@
if ((ctxt != NULL) && (ctxt->sax != NULL) &&
(ctxt->sax->initialized == XML_SAX2_MAGIC))
schannel = ctxt->sax->serror;
- __xmlRaiseError(schannel,
+ if (ctxt != NULL) {
+ __xmlRaiseError(schannel,
(ctxt->sax) ? ctxt->sax->warning : NULL,
ctxt->userData,
ctxt, NULL, XML_FROM_PARSER, error,
XML_ERR_WARNING, NULL, 0,
(const char *) str1, (const char *) str2, NULL, 0, 0,
msg, (const char *) str1, (const char *) str2);
+ } else {
+ __xmlRaiseError(schannel, NULL, NULL,
+ ctxt, NULL, XML_FROM_PARSER, error,
+ XML_ERR_WARNING, NULL, 0,
+ (const char *) str1, (const char *) str2, NULL, 0, 0,
+ msg, (const char *) str1, (const char *) str2);
+ }
}
/**
@@ -551,14 +568,20 @@
if ((ctxt->sax != NULL) && (ctxt->sax->initialized == XML_SAX2_MAGIC))
schannel = ctxt->sax->serror;
}
- __xmlRaiseError(schannel,
+ if (ctxt != NULL) {
+ __xmlRaiseError(schannel,
ctxt->vctxt.error, ctxt->vctxt.userData,
ctxt, NULL, XML_FROM_DTD, error,
XML_ERR_ERROR, NULL, 0, (const char *) str1,
(const char *) str2, NULL, 0, 0,
msg, (const char *) str1, (const char *) str2);
- if (ctxt != NULL) {
ctxt->valid = 0;
+ } else {
+ __xmlRaiseError(schannel, NULL, NULL,
+ ctxt, NULL, XML_FROM_DTD, error,
+ XML_ERR_ERROR, NULL, 0, (const char *) str1,
+ (const char *) str2, NULL, 0, 0,
+ msg, (const char *) str1, (const char *) str2);
}
}
@@ -723,8 +746,6 @@
if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
(ctxt->instate == XML_PARSER_EOF))
return;
- if (ctxt != NULL)
- ctxt->errNo = error;
__xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
XML_ERR_WARNING, NULL, 0, (const char *) info1,
(const char *) info2, (const char *) info3, 0, 0, msg,
@@ -937,6 +958,12 @@
#else
return(0);
#endif
+ case XML_WITH_LZMA:
+#ifdef LIBXML_LZMA_ENABLED
+ return(1);
+#else
+ return(0);
+#endif
case XML_WITH_ICU:
#ifdef LIBXML_ICU_ENABLED
return(1);
@@ -1286,60 +1313,182 @@
* [37] UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+
* [38] Subcode ::= ([a-z] | [A-Z])+
*
+ * The current REC reference the sucessors of RFC 1766, currently 5646
+ *
+ * http://www.rfc-editor.org/rfc/rfc5646.txt
+ * langtag = language
+ * ["-" script]
+ * ["-" region]
+ * *("-" variant)
+ * *("-" extension)
+ * ["-" privateuse]
+ * language = 2*3ALPHA ; shortest ISO 639 code
+ * ["-" extlang] ; sometimes followed by
+ * ; extended language subtags
+ * / 4ALPHA ; or reserved for future use
+ * / 5*8ALPHA ; or registered language subtag
+ *
+ * extlang = 3ALPHA ; selected ISO 639 codes
+ * *2("-" 3ALPHA) ; permanently reserved
+ *
+ * script = 4ALPHA ; ISO 15924 code
+ *
+ * region = 2ALPHA ; ISO 3166-1 code
+ * / 3DIGIT ; UN M.49 code
+ *
+ * variant = 5*8alphanum ; registered variants
+ * / (DIGIT 3alphanum)
+ *
+ * extension = singleton 1*("-" (2*8alphanum))
+ *
+ * ; Single alphanumerics
+ * ; "x" reserved for private use
+ * singleton = DIGIT ; 0 - 9
+ * / %x41-57 ; A - W
+ * / %x59-5A ; Y - Z
+ * / %x61-77 ; a - w
+ * / %x79-7A ; y - z
+ *
+ * it sounds right to still allow Irregular i-xxx IANA and user codes too
+ * The parser below doesn't try to cope with extension or privateuse
+ * that could be added but that's not interoperable anyway
+ *
* Returns 1 if correct 0 otherwise
**/
int
xmlCheckLanguageID(const xmlChar * lang)
{
- const xmlChar *cur = lang;
+ const xmlChar *cur = lang, *nxt;
if (cur == NULL)
return (0);
if (((cur[0] == 'i') && (cur[1] == '-')) ||
- ((cur[0] == 'I') && (cur[1] == '-'))) {
+ ((cur[0] == 'I') && (cur[1] == '-')) ||
+ ((cur[0] == 'x') && (cur[1] == '-')) ||
+ ((cur[0] == 'X') && (cur[1] == '-'))) {
/*
- * IANA code
+ * Still allow IANA code and user code which were coming
+ * from the previous version of the XML-1.0 specification
+ * it's deprecated but we should not fail
*/
cur += 2;
- while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming */
+ while (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
((cur[0] >= 'a') && (cur[0] <= 'z')))
cur++;
- } else if (((cur[0] == 'x') && (cur[1] == '-')) ||
- ((cur[0] == 'X') && (cur[1] == '-'))) {
- /*
- * User code
- */
- cur += 2;
- while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming */
- ((cur[0] >= 'a') && (cur[0] <= 'z')))
- cur++;
- } else if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
- ((cur[0] >= 'a') && (cur[0] <= 'z'))) {
- /*
- * ISO639
- */
- cur++;
- if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
- ((cur[0] >= 'a') && (cur[0] <= 'z')))
- cur++;
- else
- return (0);
- } else
- return (0);
- while (cur[0] != 0) { /* non input consuming */
- if (cur[0] != '-')
- return (0);
- cur++;
- if (((cur[0] >= 'A') && (cur[0] <= 'Z')) ||
- ((cur[0] >= 'a') && (cur[0] <= 'z')))
- cur++;
- else
- return (0);
- while (((cur[0] >= 'A') && (cur[0] <= 'Z')) || /* non input consuming */
- ((cur[0] >= 'a') && (cur[0] <= 'z')))
- cur++;
+ return(cur[0] == 0);
}
+ nxt = cur;
+ while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
+ ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
+ nxt++;
+ if (nxt - cur >= 4) {
+ /*
+ * Reserved
+ */
+ if ((nxt - cur > 8) || (nxt[0] != 0))
+ return(0);
+ return(1);
+ }
+ if (nxt - cur < 2)
+ return(0);
+ /* we got an ISO 639 code */
+ if (nxt[0] == 0)
+ return(1);
+ if (nxt[0] != '-')
+ return(0);
+
+ nxt++;
+ cur = nxt;
+ /* now we can have extlang or script or region or variant */
+ if ((nxt[0] >= '0') && (nxt[0] <= '9'))
+ goto region_m49;
+
+ while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
+ ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
+ nxt++;
+ if (nxt - cur == 4)
+ goto script;
+ if (nxt - cur == 2)
+ goto region;
+ if ((nxt - cur >= 5) && (nxt - cur <= 8))
+ goto variant;
+ if (nxt - cur != 3)
+ return(0);
+ /* we parsed an extlang */
+ if (nxt[0] == 0)
+ return(1);
+ if (nxt[0] != '-')
+ return(0);
+
+ nxt++;
+ cur = nxt;
+ /* now we can have script or region or variant */
+ if ((nxt[0] >= '0') && (nxt[0] <= '9'))
+ goto region_m49;
+
+ while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
+ ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
+ nxt++;
+ if (nxt - cur == 2)
+ goto region;
+ if ((nxt - cur >= 5) && (nxt - cur <= 8))
+ goto variant;
+ if (nxt - cur != 4)
+ return(0);
+ /* we parsed a script */
+script:
+ if (nxt[0] == 0)
+ return(1);
+ if (nxt[0] != '-')
+ return(0);
+
+ nxt++;
+ cur = nxt;
+ /* now we can have region or variant */
+ if ((nxt[0] >= '0') && (nxt[0] <= '9'))
+ goto region_m49;
+
+ while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
+ ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
+ nxt++;
+
+ if ((nxt - cur >= 5) && (nxt - cur <= 8))
+ goto variant;
+ if (nxt - cur != 2)
+ return(0);
+ /* we parsed a region */
+region:
+ if (nxt[0] == 0)
+ return(1);
+ if (nxt[0] != '-')
+ return(0);
+
+ nxt++;
+ cur = nxt;
+ /* now we can just have a variant */
+ while (((nxt[0] >= 'A') && (nxt[0] <= 'Z')) ||
+ ((nxt[0] >= 'a') && (nxt[0] <= 'z')))
+ nxt++;
+
+ if ((nxt - cur < 5) || (nxt - cur > 8))
+ return(0);
+
+ /* we parsed a variant */
+variant:
+ if (nxt[0] == 0)
+ return(1);
+ if (nxt[0] != '-')
+ return(0);
+ /* extensions and private use subtags not checked */
return (1);
+
+region_m49:
+ if (((nxt[1] >= '0') && (nxt[1] <= '9')) &&
+ ((nxt[2] >= '0') && (nxt[2] <= '9'))) {
+ nxt += 3;
+ goto region;
+ }
+ return(0);
}
/************************************************************************
@@ -1348,8 +1497,8 @@
* *
************************************************************************/
-xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
- const xmlChar ** str);
+static xmlEntityPtr xmlParseStringEntityRef(xmlParserCtxtPtr ctxt,
+ const xmlChar ** str);
#ifdef SAX2
/**
@@ -1680,15 +1829,14 @@
if (ctxt->nameNr >= ctxt->nameMax) {
const xmlChar * *tmp;
- ctxt->nameMax *= 2;
tmp = (const xmlChar * *) xmlRealloc((xmlChar * *)ctxt->nameTab,
- ctxt->nameMax *
+ ctxt->nameMax * 2 *
sizeof(ctxt->nameTab[0]));
if (tmp == NULL) {
- ctxt->nameMax /= 2;
goto mem_error;
}
ctxt->nameTab = tmp;
+ ctxt->nameMax *= 2;
}
ctxt->nameTab[ctxt->nameNr] = value;
ctxt->name = value;
@@ -1853,7 +2001,7 @@
static void xmlGROW (xmlParserCtxtPtr ctxt) {
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
- if ((*ctxt->input->cur == 0) &&
+ if ((ctxt->input->cur != NULL) && (*ctxt->input->cur == 0) &&
(xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0))
xmlPopInput(ctxt);
}
@@ -2620,7 +2768,7 @@
else
c = 0;
}
- buffer[nbchars++] = 0;
+ buffer[nbchars] = 0;
return(buffer);
mem_error:
@@ -2923,12 +3071,15 @@
* Routines to parse Name, NCName and NmToken *
* *
************************************************************************/
-unsigned long nbParseName = 0;
-unsigned long nbParseNmToken = 0;
-unsigned long nbParseNCName = 0;
-unsigned long nbParseNCNameComplex = 0;
-unsigned long nbParseNameComplex = 0;
-unsigned long nbParseStringName = 0;
+#ifdef DEBUG
+static unsigned long nbParseName = 0;
+static unsigned long nbParseNmToken = 0;
+static unsigned long nbParseNCName = 0;
+static unsigned long nbParseNCNameComplex = 0;
+static unsigned long nbParseNameComplex = 0;
+static unsigned long nbParseStringName = 0;
+#endif
+
/*
* The two following functions are related to the change of accepted
* characters for Name and NmToken in the Revision 5 of XML-1.0
@@ -3018,7 +3169,9 @@
int c;
int count = 0;
+#ifdef DEBUG
nbParseNameComplex++;
+#endif
/*
* Handler for more complex cases
@@ -3134,7 +3287,9 @@
GROW;
+#ifdef DEBUG
nbParseName++;
+#endif
/*
* Accelerator for simple ASCII names
@@ -3171,7 +3326,9 @@
int c;
int count = 0;
+#ifdef DEBUG
nbParseNCNameComplex++;
+#endif
/*
* Handler for more complex cases
@@ -3217,7 +3374,9 @@
const xmlChar *ret;
int count = 0;
+#ifdef DEBUG
nbParseNCName++;
+#endif
/*
* Accelerator for simple ASCII names
@@ -3312,7 +3471,9 @@
int len = 0, l;
int c;
+#ifdef DEBUG
nbParseStringName++;
+#endif
c = CUR_SCHAR(cur, l);
if (!xmlIsNameStartChar(ctxt, c)) {
@@ -3386,7 +3547,9 @@
int c;
int count = 0;
+#ifdef DEBUG
nbParseNmToken++;
+#endif
GROW;
c = CUR_CHAR(l);
@@ -3694,7 +3857,12 @@
if (rep != NULL) {
current = rep;
while (*current != 0) { /* non input consuming */
- buf[len++] = *current++;
+ if ((*current == 0xD) || (*current == 0xA) ||
+ (*current == 0x9)) {
+ buf[len++] = 0x20;
+ current++;
+ } else
+ buf[len++] = *current++;
if (len > buf_size - 10) {
growBuffer(buf, 10);
}
@@ -3984,7 +4152,7 @@
return(buf);
}
-void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
+static void xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata);
/*
* used for the test in the inner loop of the char data testing
@@ -4189,7 +4357,7 @@
* of xmlParseCharData() when the parsing requires handling
* of non-ASCII characters.
*/
-void
+static void
xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
xmlChar buf[XML_PARSER_BIG_BUFFER_SIZE + 5];
int nbchar = 0;
@@ -4790,7 +4958,8 @@
(ctxt->sax->processingInstruction != NULL))
ctxt->sax->processingInstruction(ctxt->userData,
target, NULL);
- ctxt->instate = state;
+ if (ctxt->instate != XML_PARSER_EOF)
+ ctxt->instate = state;
return;
}
buf = (xmlChar *) xmlMallocAtomic(size * sizeof(xmlChar));
@@ -4870,7 +5039,8 @@
} else {
xmlFatalErr(ctxt, XML_ERR_PI_NOT_STARTED, NULL);
}
- ctxt->instate = state;
+ if (ctxt->instate != XML_PARSER_EOF)
+ ctxt->instate = state;
}
}
@@ -5312,7 +5482,8 @@
if (name == NULL) {
xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
"Name expected in NOTATION declaration\n");
- return(ret);
+ xmlFreeEnumeration(ret);
+ return(NULL);
}
tmp = ret;
while (tmp != NULL) {
@@ -5328,7 +5499,10 @@
}
if (tmp == NULL) {
cur = xmlCreateEnumeration(name);
- if (cur == NULL) return(ret);
+ if (cur == NULL) {
+ xmlFreeEnumeration(ret);
+ return(NULL);
+ }
if (last == NULL) ret = last = cur;
else {
last->next = cur;
@@ -5339,9 +5513,8 @@
} while (RAW == '|');
if (RAW != ')') {
xmlFatalErr(ctxt, XML_ERR_NOTATION_NOT_FINISHED, NULL);
- if ((last != NULL) && (last != ret))
- xmlFreeEnumeration(last);
- return(ret);
+ xmlFreeEnumeration(ret);
+ return(NULL);
}
NEXT;
return(ret);
@@ -5396,7 +5569,10 @@
cur = xmlCreateEnumeration(name);
if (!xmlDictOwns(ctxt->dict, name))
xmlFree(name);
- if (cur == NULL) return(ret);
+ if (cur == NULL) {
+ xmlFreeEnumeration(ret);
+ return(NULL);
+ }
if (last == NULL) ret = last = cur;
else {
last->next = cur;
@@ -5744,7 +5920,8 @@
if (cur->c2 != NULL)
cur->c2->parent = cur;
}
- ret->ocur = XML_ELEMENT_CONTENT_MULT;
+ if (ret != NULL)
+ ret->ocur = XML_ELEMENT_CONTENT_MULT;
if ((ctxt->validate) && (ctxt->input->id != inputchk)) {
xmlValidityError(ctxt, XML_ERR_ENTITY_BOUNDARY,
"Element content declaration doesn't start and stop in the same entity\n",
@@ -5764,9 +5941,10 @@
}
/**
- * xmlParseElementChildrenContentDecl:
+ * xmlParseElementChildrenContentDeclPriv:
* @ctxt: an XML parser context
* @inputchk: the input used for the current entity, needed for boundary checks
+ * @depth: the level of recursion
*
* parse the declaration for a Mixed Element content
* The leading '(' and spaces have been skipped in xmlParseElementContentDecl
@@ -5794,12 +5972,20 @@
* Returns the tree of xmlElementContentPtr describing the element
* hierarchy.
*/
-xmlElementContentPtr
-xmlParseElementChildrenContentDecl (xmlParserCtxtPtr ctxt, int inputchk) {
+static xmlElementContentPtr
+xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
+ int depth) {
xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
const xmlChar *elem;
xmlChar type = 0;
+ if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0)) ||
+ (depth > 2048)) {
+ xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
+"xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
+ depth);
+ return(NULL);
+ }
SKIP_BLANKS;
GROW;
if (RAW == '(') {
@@ -5808,7 +5994,8 @@
/* Recurse on first child */
NEXT;
SKIP_BLANKS;
- cur = ret = xmlParseElementChildrenContentDecl(ctxt, inputid);
+ cur = ret = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
+ depth + 1);
SKIP_BLANKS;
GROW;
} else {
@@ -5940,7 +6127,8 @@
/* Recurse on second child */
NEXT;
SKIP_BLANKS;
- last = xmlParseElementChildrenContentDecl(ctxt, inputid);
+ last = xmlParseElementChildrenContentDeclPriv(ctxt, inputid,
+ depth + 1);
SKIP_BLANKS;
} else {
elem = xmlParseName(ctxt);
@@ -6051,6 +6239,42 @@
}
/**
+ * xmlParseElementChildrenContentDecl:
+ * @ctxt: an XML parser context
+ * @inputchk: the input used for the current entity, needed for boundary checks
+ *
+ * parse the declaration for a Mixed Element content
+ * The leading '(' and spaces have been skipped in xmlParseElementContentDecl
+ *
+ * [47] children ::= (choice | seq) ('?' | '*' | '+')?
+ *
+ * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
+ *
+ * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
+ *
+ * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
+ *
+ * [ VC: Proper Group/PE Nesting ] applies to [49] and [50]
+ * TODO Parameter-entity replacement text must be properly nested
+ * with parenthesized groups. That is to say, if either of the
+ * opening or closing parentheses in a choice, seq, or Mixed
+ * construct is contained in the replacement text for a parameter
+ * entity, both must be contained in the same replacement text. For
+ * interoperability, if a parameter-entity reference appears in a
+ * choice, seq, or Mixed construct, its replacement text should not
+ * be empty, and neither the first nor last non-blank character of
+ * the replacement text should be a connector (| or ,).
+ *
+ * Returns the tree of xmlElementContentPtr describing the element
+ * hierarchy.
+ */
+xmlElementContentPtr
+xmlParseElementChildrenContentDecl(xmlParserCtxtPtr ctxt, int inputchk) {
+ /* stub left for API/ABI compat */
+ return(xmlParseElementChildrenContentDeclPriv(ctxt, inputchk, 1));
+}
+
+/**
* xmlParseElementContentDecl:
* @ctxt: an XML parser context
* @name: the name of the element being defined.
@@ -6086,7 +6310,7 @@
tree = xmlParseElementMixedContentDecl(ctxt, inputid);
res = XML_ELEMENT_TYPE_MIXED;
} else {
- tree = xmlParseElementChildrenContentDecl(ctxt, inputid);
+ tree = xmlParseElementChildrenContentDeclPriv(ctxt, inputid, 1);
res = XML_ELEMENT_TYPE_ELEMENT;
}
SKIP_BLANKS;
@@ -6524,7 +6748,7 @@
xmlDetectSAX2(ctxt);
GROW;
- if ((ctxt->encoding == (const xmlChar *)XML_CHAR_ENCODING_NONE) &&
+ if ((ctxt->encoding == NULL) &&
(ctxt->input->end - ctxt->input->cur >= 4)) {
xmlChar start[4];
xmlCharEncoding enc;
@@ -6779,6 +7003,7 @@
ent->owner = 1;
while (list != NULL) {
list->parent = (xmlNodePtr) ent;
+ xmlSetTreeDoc(list, ent->doc);
if (list->next == NULL)
ent->last = list;
list = list->next;
@@ -7208,7 +7433,7 @@
* Returns the xmlEntityPtr if found, or NULL otherwise. The str pointer
* is updated to the current location in the string.
*/
-xmlEntityPtr
+static xmlEntityPtr
xmlParseStringEntityRef(xmlParserCtxtPtr ctxt, const xmlChar ** str) {
xmlChar *name;
const xmlChar *ptr;
@@ -7223,7 +7448,6 @@
return(NULL);
ptr++;
- cur = *ptr;
name = xmlParseStringName(ctxt, &ptr);
if (name == NULL) {
xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
@@ -7617,7 +7841,7 @@
* Returns the string of the entity content.
* str is updated to the current value of the index
*/
-xmlEntityPtr
+static xmlEntityPtr
xmlParseStringPEReference(xmlParserCtxtPtr ctxt, const xmlChar **str) {
const xmlChar *ptr;
xmlChar cur;
@@ -7630,7 +7854,6 @@
if (cur != '%')
return(NULL);
ptr++;
- cur = *ptr;
name = xmlParseStringName(ctxt, &ptr);
if (name == NULL) {
xmlFatalErrMsg(ctxt, XML_ERR_NAME_REQUIRED,
@@ -8195,7 +8418,6 @@
return(NULL);
return(ctxt->nsTab[i + 1]);
}
- if (ctxt->nsParent) return xmlGetNamespace(ctxt->nsParent, prefix);
return(NULL);
}
@@ -8295,7 +8517,7 @@
static const xmlChar *
xmlParseQNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *name,
xmlChar const *prefix) {
- const xmlChar *cmp = name;
+ const xmlChar *cmp;
const xmlChar *in;
const xmlChar *ret;
const xmlChar *prefix2;
@@ -8304,7 +8526,7 @@
GROW;
in = ctxt->input->cur;
-
+
cmp = prefix;
while (*in != 0 && *in == *cmp) {
++in;
@@ -9118,6 +9340,8 @@
*/
if (name != (xmlChar*)1) {
if (name == NULL) name = BAD_CAST "unparseable";
+ if ((line == 0) && (ctxt->node != NULL))
+ line = ctxt->node->line;
xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
"Opening and ending tag mismatch: %s line %d and %s\n",
ctxt->name, line, name);
@@ -9337,8 +9561,8 @@
void
xmlParseElement(xmlParserCtxtPtr ctxt) {
const xmlChar *name;
- const xmlChar *prefix;
- const xmlChar *URI;
+ const xmlChar *prefix = NULL;
+ const xmlChar *URI = NULL;
xmlParserNodeInfo node_info;
int line, tlen;
xmlNodePtr ret;
@@ -9376,6 +9600,8 @@
else
name = xmlParseStartTag(ctxt);
#endif /* LIBXML_SAX1_ENABLED */
+ if (ctxt->instate == XML_PARSER_EOF)
+ return;
if (name == NULL) {
spacePop(ctxt);
return;
@@ -9709,6 +9935,13 @@
} else {
xmlFatalErr(ctxt, XML_ERR_STRING_NOT_STARTED, NULL);
}
+
+ /*
+ * Non standard parsing, allowing the user to ignore encoding
+ */
+ if (ctxt->options & XML_PARSE_IGNORE_ENC)
+ return(encoding);
+
/*
* UTF-16 encoding stwich has already taken place at this stage,
* more over the little-endian/big-endian selection is already done
@@ -9937,6 +10170,12 @@
}
xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, "Blank needed here\n");
}
+
+ /*
+ * We can grow the input buffer freely at that point
+ */
+ GROW;
+
SKIP_BLANKS;
ctxt->input->standalone = xmlParseSDDecl(ctxt);
@@ -10015,7 +10254,7 @@
if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
- if ((ctxt->encoding == (const xmlChar *)XML_CHAR_ENCODING_NONE) &&
+ if ((ctxt->encoding == NULL) &&
((ctxt->input->end - ctxt->input->cur) >= 4)) {
/*
* Get the 4 first bytes and decode the charset
@@ -10039,8 +10278,13 @@
/*
* Check for the XMLDecl in the Prolog.
+ * do not GROW here to avoid the detected encoder to decode more
+ * than just the first line, unless the amount of data is really
+ * too small to hold "<?xml version="1.0" encoding="foo"
*/
- GROW;
+ if ((ctxt->input->end - ctxt->input->cur) < 35) {
+ GROW;
+ }
if ((CMP5(CUR_PTR, '<', '?', 'x', 'm', 'l')) && (IS_BLANK_CH(NXT(5)))) {
/*
@@ -10707,8 +10951,8 @@
break;
case XML_PARSER_START_TAG: {
const xmlChar *name;
- const xmlChar *prefix;
- const xmlChar *URI;
+ const xmlChar *prefix = NULL;
+ const xmlChar *URI = NULL;
int nsNr = ctxt->nsNr;
if ((avail < 2) && (ctxt->inputNr == 1))
@@ -10744,6 +10988,8 @@
else
name = xmlParseStartTag(ctxt);
#endif /* LIBXML_SAX1_ENABLED */
+ if (ctxt->instate == XML_PARSER_EOF)
+ goto done;
if (name == NULL) {
spacePop(ctxt);
ctxt->instate = XML_PARSER_EOF;
@@ -10930,7 +11176,9 @@
else
xmlParseEndTag1(ctxt, 0);
#endif /* LIBXML_SAX1_ENABLED */
- if (ctxt->nameNr == 0) {
+ if (ctxt->instate == XML_PARSER_EOF) {
+ /* Nothing */
+ } else if (ctxt->nameNr == 0) {
ctxt->instate = XML_PARSER_EPILOG;
} else {
ctxt->instate = XML_PARSER_CONTENT;
@@ -11422,6 +11670,7 @@
xmlParseChunk(xmlParserCtxtPtr ctxt, const char *chunk, int size,
int terminate) {
int end_in_lf = 0;
+ int remain = 0;
if (ctxt == NULL)
return(XML_ERR_INTERNAL_ERROR);
@@ -11434,12 +11683,50 @@
end_in_lf = 1;
size--;
}
+
+xmldecl_done:
+
if ((size > 0) && (chunk != NULL) && (ctxt->input != NULL) &&
(ctxt->input->buf != NULL) && (ctxt->instate != XML_PARSER_EOF)) {
int base = ctxt->input->base - ctxt->input->buf->buffer->content;
int cur = ctxt->input->cur - ctxt->input->base;
int res;
-
+
+ /*
+ * Specific handling if we autodetected an encoding, we should not
+ * push more than the first line ... which depend on the encoding
+ * And only push the rest once the final encoding was detected
+ */
+ if ((ctxt->instate == XML_PARSER_START) && (ctxt->input != NULL) &&
+ (ctxt->input->buf != NULL) && (ctxt->input->buf->encoder != NULL)) {
+ unsigned int len = 45;
+
+ if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
+ BAD_CAST "UTF-16")) ||
+ (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
+ BAD_CAST "UTF16")))
+ len = 90;
+ else if ((xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
+ BAD_CAST "UCS-4")) ||
+ (xmlStrcasestr(BAD_CAST ctxt->input->buf->encoder->name,
+ BAD_CAST "UCS4")))
+ len = 180;
+
+ if (ctxt->input->buf->rawconsumed < len)
+ len -= ctxt->input->buf->rawconsumed;
+
+ /*
+ * Change size for reading the initial declaration only
+ * if size is greater than len. Otherwise, memmove in xmlBufferAdd
+ * will blindly copy extra bytes from memory.
+ */
+ if ((unsigned int) size > len) {
+ remain = size - len;
+ size = len;
+ } else {
+ remain = 0;
+ }
+ }
res =xmlParserInputBufferPush(ctxt->input->buf, size, chunk);
if (res < 0) {
ctxt->errNo = XML_PARSER_EOF;
@@ -11460,7 +11747,7 @@
if ((in->encoder != NULL) && (in->buffer != NULL) &&
(in->raw != NULL)) {
int nbchars;
-
+
nbchars = xmlCharEncInFunc(in->encoder, in->buffer, in->raw);
if (nbchars < 0) {
/* TODO 2.6.0 */
@@ -11471,13 +11758,23 @@
}
}
}
- xmlParseTryOrFinish(ctxt, terminate);
+ if (remain != 0)
+ xmlParseTryOrFinish(ctxt, 0);
+ else
+ xmlParseTryOrFinish(ctxt, terminate);
+ if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
+ return(ctxt->errNo);
+
+ if (remain != 0) {
+ chunk += size;
+ size = remain;
+ remain = 0;
+ goto xmldecl_done;
+ }
if ((end_in_lf == 1) && (ctxt->input != NULL) &&
(ctxt->input->buf != NULL)) {
xmlParserInputBufferPush(ctxt->input->buf, 1, "\r");
}
- if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
- return(ctxt->errNo);
if (terminate) {
/*
* Check for termination
@@ -12041,8 +12338,6 @@
int ret = 0;
xmlChar start[4];
xmlCharEncoding enc;
- xmlParserInputPtr inputStream;
- char *directory = NULL;
if (ctx == NULL) return(-1);
@@ -12058,27 +12353,11 @@
if (ctx->myDoc == NULL) /* @@ relax but check for dereferences */
return(-1);
- ctxt = xmlNewParserCtxt();
+ ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, ctx);
if (ctxt == NULL) {
return(-1);
}
- ctxt->userData = ctxt;
- ctxt->_private = ctx->_private;
-
- inputStream = xmlLoadExternalEntity((char *)URL, (char *)ID, ctxt);
- if (inputStream == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(-1);
- }
-
- inputPush(ctxt, inputStream);
-
- if ((ctxt->directory == NULL) && (directory == NULL))
- directory = xmlParserGetDirectory((char *)URL);
- if ((ctxt->directory == NULL) && (directory != NULL))
- ctxt->directory = directory;
-
oldsax = ctxt->sax;
ctxt->sax = ctx->sax;
xmlDetectSAX2(ctxt);
@@ -12271,7 +12550,7 @@
return(XML_ERR_INTERNAL_ERROR);
- ctxt = xmlCreateEntityParserCtxt(URL, ID, NULL);
+ ctxt = xmlCreateEntityParserCtxtInternal(URL, ID, NULL, oldctxt);
if (ctxt == NULL) return(XML_WAR_UNDECLARED_ENTITY);
ctxt->userData = ctxt;
if (oldctxt != NULL) {
@@ -12401,7 +12680,9 @@
* Record in the parent context the number of entities replacement
* done when parsing that reference.
*/
- oldctxt->nbentities += ctxt->nbentities;
+ if (oldctxt != NULL)
+ oldctxt->nbentities += ctxt->nbentities;
+
/*
* Also record the size of the entity parsed
*/
@@ -12519,6 +12800,9 @@
xmlNodePtr last = NULL;
int size;
xmlParserErrors ret = XML_ERR_OK;
+#ifdef SAX2
+ int i;
+#endif
if (((oldctxt->depth > 40) && ((oldctxt->options & XML_PARSE_HUGE) == 0)) ||
(oldctxt->depth > 1024)) {
@@ -12545,7 +12829,12 @@
ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5);
ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36);
- ctxt->nsParent = oldctxt;
+#ifdef SAX2
+ /* propagate namespaces down the entity */
+ for (i = 0;i < oldctxt->nsNr;i += 2) {
+ nsPush(ctxt, oldctxt->nsTab[i], oldctxt->nsTab[i+1]);
+ }
+#endif
oldsax = ctxt->sax;
ctxt->sax = oldctxt->sax;
@@ -12652,7 +12941,9 @@
* Record in the parent context the number of entities replacement
* done when parsing that reference.
*/
- oldctxt->nbentities += ctxt->nbentities;
+ if (oldctxt != NULL)
+ oldctxt->nbentities += ctxt->nbentities;
+
/*
* Also record the last error if any
*/
@@ -12741,22 +13032,22 @@
if (doc->type == XML_DOCUMENT_NODE)
ctxt = xmlCreateMemoryParserCtxt((char *) data, datalen);
#ifdef LIBXML_HTML_ENABLED
- else if (doc->type == XML_HTML_DOCUMENT_NODE)
+ else if (doc->type == XML_HTML_DOCUMENT_NODE) {
ctxt = htmlCreateMemoryParserCtxt((char *) data, datalen);
+ /*
+ * When parsing in context, it makes no sense to add implied
+ * elements like html/body/etc...
+ */
+ options |= HTML_PARSE_NOIMPLIED;
+ }
#endif
else
return(XML_ERR_INTERNAL_ERROR);
if (ctxt == NULL)
return(XML_ERR_NO_MEMORY);
- fake = xmlNewComment(NULL);
- if (fake == NULL) {
- xmlFreeParserCtxt(ctxt);
- return(XML_ERR_NO_MEMORY);
- }
- xmlAddChild(node, fake);
- /*
+ /*
* Use input doc's dict if present, else assure XML_PARSE_NODICT is set.
* We need a dictionary for xmlDetectSAX2, so if there's no doc dict
* we must wait until the last moment to free the original one.
@@ -12768,10 +13059,32 @@
} else
options |= XML_PARSE_NODICT;
+ if (doc->encoding != NULL) {
+ xmlCharEncodingHandlerPtr hdlr;
+
+ if (ctxt->encoding != NULL)
+ xmlFree((xmlChar *) ctxt->encoding);
+ ctxt->encoding = xmlStrdup((const xmlChar *) doc->encoding);
+
+ hdlr = xmlFindCharEncodingHandler(doc->encoding);
+ if (hdlr != NULL) {
+ xmlSwitchToEncoding(ctxt, hdlr);
+ } else {
+ return(XML_ERR_UNSUPPORTED_ENCODING);
+ }
+ }
+
xmlCtxtUseOptionsInternal(ctxt, options, NULL);
xmlDetectSAX2(ctxt);
ctxt->myDoc = doc;
+ fake = xmlNewComment(NULL);
+ if (fake == NULL) {
+ xmlFreeParserCtxt(ctxt);
+ return(XML_ERR_NO_MEMORY);
+ }
+ xmlAddChild(node, fake);
+
if (node->type == XML_ELEMENT_NODE) {
nodePush(ctxt, node);
/*
@@ -13108,10 +13421,11 @@
#endif /* LIBXML_SAX1_ENABLED */
/**
- * xmlCreateEntityParserCtxt:
+ * xmlCreateEntityParserCtxtInternal:
* @URL: the entity URL
* @ID: the entity PUBLIC ID
* @base: a possible base for the target URI
+ * @pctx: parser context used to set options on new context
*
* Create a parser context for an external entity
* Automatic support for ZLIB/Compress compressed document is provided
@@ -13119,9 +13433,9 @@
*
* Returns the new parser context or NULL
*/
-xmlParserCtxtPtr
-xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
- const xmlChar *base) {
+static xmlParserCtxtPtr
+xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID,
+ const xmlChar *base, xmlParserCtxtPtr pctx) {
xmlParserCtxtPtr ctxt;
xmlParserInputPtr inputStream;
char *directory = NULL;
@@ -13132,6 +13446,11 @@
return(NULL);
}
+ if (pctx != NULL) {
+ ctxt->options = pctx->options;
+ ctxt->_private = pctx->_private;
+ }
+
uri = xmlBuildURI(URL, base);
if (uri == NULL) {
@@ -13166,6 +13485,25 @@
return(ctxt);
}
+/**
+ * xmlCreateEntityParserCtxt:
+ * @URL: the entity URL
+ * @ID: the entity PUBLIC ID
+ * @base: a possible base for the target URI
+ *
+ * Create a parser context for an external entity
+ * Automatic support for ZLIB/Compress compressed document is provided
+ * by default if found at compile-time.
+ *
+ * Returns the new parser context or NULL
+ */
+xmlParserCtxtPtr
+xmlCreateEntityParserCtxt(const xmlChar *URL, const xmlChar *ID,
+ const xmlChar *base) {
+ return xmlCreateEntityParserCtxtInternal(URL, ID, base, NULL);
+
+}
+
/************************************************************************
* *
* Front ends when parsing from a file *
@@ -13334,7 +13672,7 @@
*/
xmlDocPtr
-xmlRecoverDoc(xmlChar *cur) {
+xmlRecoverDoc(const xmlChar *cur) {
return(xmlSAXParseDoc(NULL, cur, 1));
}
@@ -13536,6 +13874,8 @@
xmlDocPtr ret;
xmlParserCtxtPtr ctxt;
+ xmlInitParser();
+
ctxt = xmlCreateMemoryParserCtxt(buffer, size);
if (ctxt == NULL) return(NULL);
if (sax != NULL) {
@@ -13561,7 +13901,7 @@
if (sax != NULL)
ctxt->sax = NULL;
xmlFreeParserCtxt(ctxt);
-
+
return(ret);
}
@@ -13624,14 +13964,16 @@
*
* A better SAX parsing routine.
* parse an XML in-memory buffer and call the given SAX handler routines.
- *
+ *
* Returns 0 in case of success or a error number otherwise
*/
int xmlSAXUserParseMemory(xmlSAXHandlerPtr sax, void *user_data,
const char *buffer, int size) {
int ret = 0;
xmlParserCtxtPtr ctxt;
-
+
+ xmlInitParser();
+
ctxt = xmlCreateMemoryParserCtxt(buffer, size);
if (ctxt == NULL) return -1;
if (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler)
@@ -13641,7 +13983,7 @@
if (user_data != NULL)
ctxt->userData = user_data;
-
+
xmlParseDocument(ctxt);
if (ctxt->wellFormed)
@@ -13815,11 +14157,11 @@
__xmlGlobalInitMutexLock();
if (xmlParserInitialized == 0) {
#endif
+ xmlInitThreads();
+ xmlInitGlobals();
if ((xmlGenericError == xmlGenericErrorDefaultFunc) ||
(xmlGenericError == NULL))
initGenericErrorDefaultFunc(NULL);
- xmlInitGlobals();
- xmlInitThreads();
xmlInitMemory();
xmlInitCharEncodingHandlers();
xmlDefaultSAXHandlerInit();
@@ -13853,6 +14195,14 @@
* the library and all XML/HTML documents built with it.
* See also xmlInitParser() which has the opposite function of preparing
* the library for operations.
+ *
+ * WARNING: if your application is multithreaded or has plugin support
+ * calling this may crash the application if another thread or
+ * a plugin is still using libxml2. It's sometimes very hard to
+ * guess if libxml2 is in use in the application, some libraries
+ * or plugins may use it without notice. In case of doubt abstain
+ * from calling this function or do it just before calling exit()
+ * to avoid leak reports from valgrind !
*/
void
@@ -14235,6 +14585,10 @@
ctxt->options |= XML_PARSE_OLDSAX;
options -= XML_PARSE_OLDSAX;
}
+ if (options & XML_PARSE_IGNORE_ENC) {
+ ctxt->options |= XML_PARSE_IGNORE_ENC;
+ options -= XML_PARSE_IGNORE_ENC;
+ }
ctxt->linenumbers = 1;
return (options);
}
diff --git a/parserInternals.c b/parserInternals.c
index 758c6b3..2404ddf 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -494,20 +494,26 @@
if (c & 0x80) {
if (c == 0xC0)
goto encoding_error;
- if (cur[1] == 0)
+ 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)
+ if (cur[2] == 0) {
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+ cur = ctxt->input->cur;
+ }
if ((cur[2] & 0xc0) != 0x80)
goto encoding_error;
if ((c & 0xf0) == 0xf0) {
- if (cur[3] == 0)
+ if (cur[3] == 0) {
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+ cur = ctxt->input->cur;
+ }
if (((c & 0xf8) != 0xf0) ||
((cur[3] & 0xc0) != 0x80))
goto encoding_error;
@@ -640,18 +646,24 @@
if (c & 0x80) {
if (((c & 0x40) == 0) || (c == 0xC0))
goto encoding_error;
- if (cur[1] == 0)
+ 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) {
- if (cur[2] == 0)
+ if (cur[2] == 0) {
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+ cur = ctxt->input->cur;
+ }
if ((cur[2] & 0xc0) != 0x80)
goto encoding_error;
if ((c & 0xf0) == 0xf0) {
- if (cur[3] == 0)
+ if (cur[3] == 0) {
xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+ cur = ctxt->input->cur;
+ }
if (((c & 0xf8) != 0xf0) ||
((cur[3] & 0xc0) != 0x80))
goto encoding_error;
@@ -933,6 +945,17 @@
* *
************************************************************************/
+/* defined in encoding.c, not public */
+int
+xmlCharEncFirstLineInt(xmlCharEncodingHandler *handler, xmlBufferPtr out,
+ xmlBufferPtr in, int len);
+
+static int
+xmlSwitchToEncodingInt(xmlParserCtxtPtr ctxt,
+ xmlCharEncodingHandlerPtr handler, int len);
+static int
+xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
+ xmlCharEncodingHandlerPtr handler, int len);
/**
* xmlSwitchEncoding:
* @ctxt: the parser context
@@ -947,6 +970,7 @@
xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
{
xmlCharEncodingHandlerPtr handler;
+ int len = -1;
if (ctxt == NULL) return(-1);
switch (enc) {
@@ -990,9 +1014,33 @@
(ctxt->input->cur[2] == 0xBF)) {
ctxt->input->cur += 3;
}
- break ;
- default:
- break;
+ len = 90;
+ break;
+ case XML_CHAR_ENCODING_UCS2:
+ len = 90;
+ break;
+ case XML_CHAR_ENCODING_UCS4BE:
+ case XML_CHAR_ENCODING_UCS4LE:
+ case XML_CHAR_ENCODING_UCS4_2143:
+ case XML_CHAR_ENCODING_UCS4_3412:
+ len = 180;
+ break;
+ case XML_CHAR_ENCODING_EBCDIC:
+ case XML_CHAR_ENCODING_8859_1:
+ case XML_CHAR_ENCODING_8859_2:
+ case XML_CHAR_ENCODING_8859_3:
+ case XML_CHAR_ENCODING_8859_4:
+ case XML_CHAR_ENCODING_8859_5:
+ case XML_CHAR_ENCODING_8859_6:
+ case XML_CHAR_ENCODING_8859_7:
+ case XML_CHAR_ENCODING_8859_8:
+ case XML_CHAR_ENCODING_8859_9:
+ case XML_CHAR_ENCODING_ASCII:
+ case XML_CHAR_ENCODING_2022_JP:
+ case XML_CHAR_ENCODING_SHIFT_JIS:
+ case XML_CHAR_ENCODING_EUC_JP:
+ len = 45;
+ break;
}
handler = xmlGetCharEncodingHandler(enc);
if (handler == NULL) {
@@ -1083,7 +1131,7 @@
if (handler == NULL)
return(-1);
ctxt->charset = XML_CHAR_ENCODING_UTF8;
- return(xmlSwitchToEncoding(ctxt, handler));
+ return(xmlSwitchToEncodingInt(ctxt, handler, len));
}
/**
@@ -1091,15 +1139,16 @@
* @ctxt: the parser context
* @input: the input stream
* @handler: the encoding handler
+ * @len: the number of bytes to convert for the first line or -1
*
* change the input functions when discovering the character encoding
* of a given entity.
*
* Returns 0 in case of success, -1 otherwise
*/
-int
-xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
- xmlCharEncodingHandlerPtr handler)
+static int
+xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
+ xmlCharEncodingHandlerPtr handler, int len)
{
int nbchars;
@@ -1196,9 +1245,10 @@
* parsed with the autodetected encoding
* into the parser reading buffer.
*/
- nbchars = xmlCharEncFirstLine(input->buf->encoder,
- input->buf->buffer,
- input->buf->raw);
+ nbchars = xmlCharEncFirstLineInt(input->buf->encoder,
+ input->buf->buffer,
+ input->buf->raw,
+ len);
}
if (nbchars < 0) {
xmlErrInternal(ctxt,
@@ -1224,6 +1274,58 @@
}
/**
+ * xmlSwitchInputEncoding:
+ * @ctxt: the parser context
+ * @input: the input stream
+ * @handler: the encoding handler
+ *
+ * change the input functions when discovering the character encoding
+ * of a given entity.
+ *
+ * Returns 0 in case of success, -1 otherwise
+ */
+int
+xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
+ xmlCharEncodingHandlerPtr handler) {
+ return(xmlSwitchInputEncodingInt(ctxt, input, handler, -1));
+}
+
+/**
+ * xmlSwitchToEncodingInt:
+ * @ctxt: the parser context
+ * @handler: the encoding handler
+ * @len: the lenght to convert or -1
+ *
+ * change the input functions when discovering the character encoding
+ * of a given entity, and convert only @len bytes of the output, this
+ * is needed on auto detect to allows any declared encoding later to
+ * convert the actual content after the xmlDecl
+ *
+ * Returns 0 in case of success, -1 otherwise
+ */
+static int
+xmlSwitchToEncodingInt(xmlParserCtxtPtr ctxt,
+ xmlCharEncodingHandlerPtr handler, int len) {
+ int ret = 0;
+
+ if (handler != NULL) {
+ if (ctxt->input != NULL) {
+ ret = xmlSwitchInputEncodingInt(ctxt, ctxt->input, handler, len);
+ } else {
+ xmlErrInternal(ctxt, "xmlSwitchToEncoding : no input\n",
+ NULL);
+ return(-1);
+ }
+ /*
+ * The parsing is now done in UTF8 natively
+ */
+ ctxt->charset = XML_CHAR_ENCODING_UTF8;
+ } else
+ return(-1);
+ return(ret);
+}
+
+/**
* xmlSwitchToEncoding:
* @ctxt: the parser context
* @handler: the encoding handler
@@ -1236,23 +1338,7 @@
int
xmlSwitchToEncoding(xmlParserCtxtPtr ctxt, xmlCharEncodingHandlerPtr handler)
{
- int ret = 0;
-
- if (handler != NULL) {
- if (ctxt->input != NULL) {
- ret = xmlSwitchInputEncoding(ctxt, ctxt->input, handler);
- } else {
- xmlErrInternal(ctxt, "xmlSwitchToEncoding : no input\n",
- NULL);
- return(-1);
- }
- /*
- * The parsing is now done in UTF8 natively
- */
- ctxt->charset = XML_CHAR_ENCODING_UTF8;
- } else
- return(-1);
- return(ret);
+ return (xmlSwitchToEncodingInt(ctxt, handler, -1));
}
/************************************************************************
@@ -1696,6 +1782,7 @@
if (ctxt->spaceTab != NULL) xmlFree(ctxt->spaceTab);
if (ctxt->nameTab != NULL) xmlFree((xmlChar * *)ctxt->nameTab);
if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab);
+ if (ctxt->nodeInfoTab != NULL) xmlFree(ctxt->nodeInfoTab);
if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab);
if (ctxt->version != NULL) xmlFree((char *) ctxt->version);
if (ctxt->encoding != NULL) xmlFree((char *) ctxt->encoding);
@@ -2067,7 +2154,7 @@
int old = xmlKeepBlanksDefaultValue;
xmlKeepBlanksDefaultValue = val;
- xmlIndentTreeOutput = !val;
+ if (!val) xmlIndentTreeOutput = 1;
return(old);
}
diff --git a/relaxng.c b/relaxng.c
index 6459769..f575287 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -149,6 +149,7 @@
#define IS_PROCESSED (1 << 5)
#define IS_COMPILABLE (1 << 6)
#define IS_NOT_COMPILABLE (1 << 7)
+#define IS_EXTERNAL_REF (1 << 8)
struct _xmlRelaxNGDefine {
xmlRelaxNGType type; /* the type of definition */
@@ -414,6 +415,7 @@
xmlDocPtr doc; /* the associated XML document */
xmlRelaxNGDefinePtr content; /* the definitions */
xmlRelaxNGPtr schema; /* the schema */
+ int externalRef; /* 1 if an external ref */
};
@@ -1006,7 +1008,7 @@
xmlRelaxNGStatesPtr ret;
if ((ctxt != NULL) &&
- (ctxt->freeState != NULL) && (ctxt->freeStatesNr > 0)) {
+ (ctxt->freeStates != NULL) && (ctxt->freeStatesNr > 0)) {
ctxt->freeStatesNr--;
ret = ctxt->freeStates[ctxt->freeStatesNr];
ret->nbState = 0;
@@ -1559,8 +1561,8 @@
href = xmlGetProp(tmp, BAD_CAST "href");
#endif
if (xmlRelaxNGRemoveRedefine(ctxt, href,
- inc->doc->children->
- children, name) == 1) {
+ xmlDocGetRootElement(inc->doc)->children,
+ name) == 1) {
found = 1;
}
#ifdef DEBUG_INCLUDE
@@ -1970,6 +1972,7 @@
ret->doc = doc;
ret->href = xmlStrdup(URL);
ret->next = ctxt->documents;
+ ret->externalRef = 1;
ctxt->documents = ret;
/*
@@ -2372,6 +2375,9 @@
} else {
node = seq = NULL;
}
+ if ((node == NULL) && (seq == NULL)) {
+ node = ctxt->pnode;
+ }
xmlRelaxNGShowValidError(ctxt, err, node, seq, arg1, arg2);
}
/*
@@ -2849,6 +2855,10 @@
* *
************************************************************************/
+/* from automata.c but not exported */
+void xmlAutomataSetFlags(xmlAutomataPtr am, int flags);
+
+
static int xmlRelaxNGTryCompile(xmlRelaxNGParserCtxtPtr ctxt,
xmlRelaxNGDefinePtr def);
@@ -3032,6 +3042,17 @@
ctxt->am = xmlNewAutomata();
if (ctxt->am == NULL)
return (-1);
+
+ /*
+ * assume identical strings but not same pointer are different
+ * atoms, needed for non-determinism detection
+ * That way if 2 elements with the same name are in a choice
+ * branch the automata is found non-deterministic and
+ * we fallback to the normal validation which does the right
+ * thing of exploring both choices.
+ */
+ xmlAutomataSetFlags(ctxt->am, 1);
+
ctxt->state = xmlAutomataGetInitState(ctxt->am);
while (list != NULL) {
xmlRelaxNGCompile(ctxt, list);
@@ -3063,6 +3084,7 @@
ctxt->am = xmlNewAutomata();
if (ctxt->am == NULL)
return (-1);
+ xmlAutomataSetFlags(ctxt->am, 1);
ctxt->state = xmlAutomataGetInitState(ctxt->am);
while (list != NULL) {
xmlRelaxNGCompile(ctxt, list);
@@ -3071,6 +3093,11 @@
xmlAutomataSetFinalState(ctxt->am, ctxt->state);
def->contModel = xmlAutomataCompile(ctxt->am);
if (!xmlRegexpIsDeterminist(def->contModel)) {
+#ifdef DEBUG_COMPILE
+ xmlGenericError(xmlGenericErrorContext,
+ "Content model not determinist %s\n",
+ def->name);
+#endif
/*
* we can only use the automata if it is determinist
*/
@@ -3098,7 +3125,11 @@
case XML_RELAXNG_OPTIONAL:{
xmlAutomataStatePtr oldstate = ctxt->state;
- xmlRelaxNGCompile(ctxt, def->content);
+ list = def->content;
+ while (list != NULL) {
+ xmlRelaxNGCompile(ctxt, list);
+ list = list->next;
+ }
xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
break;
}
@@ -3440,6 +3471,9 @@
{
xmlChar *ret, *escape;
+ if (node == NULL)
+ return(NULL);
+
if ((IS_RELAXNG(node, "data")) || (IS_RELAXNG(node, "value"))) {
ret = xmlGetProp(node, BAD_CAST "datatypeLibrary");
if (ret != NULL) {
@@ -4616,6 +4650,72 @@
}
/**
+ * xmlRelaxNGParseImportRef:
+ * @payload: the parser context
+ * @data: the current grammar
+ * @name: the reference name
+ *
+ * Import import one references into the current grammar
+ */
+static void
+xmlRelaxNGParseImportRef(void *payload, void *data, xmlChar *name) {
+ xmlRelaxNGParserCtxtPtr ctxt = (xmlRelaxNGParserCtxtPtr) data;
+ xmlRelaxNGDefinePtr def = (xmlRelaxNGDefinePtr) payload;
+ int tmp;
+
+ def->dflags |= IS_EXTERNAL_REF;
+
+ tmp = xmlHashAddEntry(ctxt->grammar->refs, name, def);
+ if (tmp < 0) {
+ xmlRelaxNGDefinePtr prev;
+
+ prev = (xmlRelaxNGDefinePtr)
+ xmlHashLookup(ctxt->grammar->refs, def->name);
+ if (prev == NULL) {
+ if (def->name != NULL) {
+ xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
+ "Error refs definitions '%s'\n",
+ def->name, NULL);
+ } else {
+ xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
+ "Error refs definitions\n",
+ NULL, NULL);
+ }
+ } else {
+ def->nextHash = prev->nextHash;
+ prev->nextHash = def;
+ }
+ }
+}
+
+/**
+ * xmlRelaxNGParseImportRefs:
+ * @ctxt: the parser context
+ * @grammar: the sub grammar
+ *
+ * Import references from the subgrammar into the current grammar
+ *
+ * Returns 0 in case of success, -1 in case of failure
+ */
+static int
+xmlRelaxNGParseImportRefs(xmlRelaxNGParserCtxtPtr ctxt,
+ xmlRelaxNGGrammarPtr grammar) {
+ if ((ctxt == NULL) || (grammar == NULL) || (ctxt->grammar == NULL))
+ return(-1);
+ if (grammar->refs == NULL)
+ return(0);
+ if (ctxt->grammar->refs == NULL)
+ ctxt->grammar->refs = xmlHashCreate(10);
+ if (ctxt->grammar->refs == NULL) {
+ xmlRngPErr(ctxt, NULL, XML_RNGP_REF_CREATE_FAILED,
+ "Could not create references hash\n", NULL, NULL);
+ return(-1);
+ }
+ xmlHashScan(grammar->refs, xmlRelaxNGParseImportRef, ctxt);
+ return(0);
+}
+
+/**
* xmlRelaxNGProcessExternalRef:
* @ctxt: the parser context
* @node: the externlRef node
@@ -4683,6 +4783,8 @@
if ((docu->schema != NULL) &&
(docu->schema->topgrammar != NULL)) {
docu->content = docu->schema->topgrammar->start;
+ if (docu->schema->topgrammar->refs)
+ xmlRelaxNGParseImportRefs(ctxt, docu->schema->topgrammar);
}
/*
@@ -5267,7 +5369,8 @@
} else {
xmlRngPErr(ctxt, node, XML_RNGP_CHOICE_CONTENT,
"expecting name, anyName, nsName or choice : got %s\n",
- node->name, NULL);
+ (node == NULL ? (const xmlChar *) "nothing" : node->name),
+ NULL);
return (NULL);
}
if (ret != def) {
@@ -5569,6 +5672,12 @@
xmlRelaxNGGrammarPtr grammar;
xmlRelaxNGDefinePtr def, cur;
+ /*
+ * Those rules don't apply to imported ref from xmlRelaxNGParseImportRef
+ */
+ if (ref->dflags & IS_EXTERNAL_REF)
+ return;
+
grammar = ctxt->grammar;
if (grammar == NULL) {
xmlRngPErr(ctxt, ref->node, XML_ERR_INTERNAL_ERROR,
@@ -6133,7 +6242,7 @@
xmlRelaxNGDefinePtr cur, int flags,
xmlRelaxNGType ptype)
{
- int nflags = flags;
+ int nflags;
xmlRelaxNGContentType ret, tmp, val = XML_RELAXNG_CONTENT_EMPTY;
while (cur != NULL) {
@@ -6157,6 +6266,16 @@
"Found forbidden pattern data/except//ref\n",
NULL, NULL);
}
+ if (cur->content == NULL) {
+ if (cur->type == XML_RELAXNG_PARENTREF)
+ xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
+ "Internal found no define for parent refs\n",
+ NULL, NULL);
+ else
+ xmlRngPErr(ctxt, cur->node, XML_RNGP_REF_NO_DEF,
+ "Internal found no define for ref %s\n",
+ (cur->name ? cur->name: BAD_CAST "null"), NULL);
+ }
if (cur->depth > -4) {
cur->depth = -4;
ret = xmlRelaxNGCheckRules(ctxt, cur->content,
@@ -6408,6 +6527,10 @@
if (ptype == XML_RELAXNG_GROUP) {
val = xmlRelaxNGGroupContentType(val, ret);
} else if (ptype == XML_RELAXNG_INTERLEAVE) {
+ /*
+ * TODO: scan complain that tmp is never used, seems on purpose
+ * need double-checking
+ */
tmp = xmlRelaxNGGroupContentType(val, ret);
if (tmp != XML_RELAXNG_CONTENT_ERROR)
tmp = xmlRelaxNGMaxContentType(val, ret);
@@ -6495,6 +6618,7 @@
ctxt);
}
+
/* @@@@ */
ctxt->grammar = old;
@@ -8345,7 +8469,7 @@
ret = -1;
else
ret = 1;
- xmlRelaxNGFreeValidState(ctxt, state);
+ xmlRelaxNGFreeValidState(ctxt, ctxt->state);
ctxt->state = NULL;
#ifdef DEBUG_PROGRESSIVE
if (ret < 0)
@@ -8760,6 +8884,11 @@
case XML_RELAXNG_ZEROORMORE:{
xmlChar *cur, *temp;
+ if ((ctxt->state->value == NULL) ||
+ (*ctxt->state->value == 0)) {
+ ret = 0;
+ break;
+ }
oldflags = ctxt->flags;
ctxt->flags |= FLAGS_IGNORABLE;
cur = ctxt->state->value;
@@ -8781,6 +8910,30 @@
xmlRelaxNGPopErrors(ctxt, 0);
break;
}
+ case XML_RELAXNG_OPTIONAL:{
+ xmlChar *temp;
+
+ if ((ctxt->state->value == NULL) ||
+ (*ctxt->state->value == 0)) {
+ ret = 0;
+ break;
+ }
+ oldflags = ctxt->flags;
+ ctxt->flags |= FLAGS_IGNORABLE;
+ temp = ctxt->state->value;
+ ret = xmlRelaxNGValidateValue(ctxt, define->content);
+ ctxt->flags = oldflags;
+ if (ret != 0) {
+ ctxt->state->value = temp;
+ if (ctxt->errNr > 0)
+ xmlRelaxNGPopErrors(ctxt, 0);
+ ret = 0;
+ break;
+ }
+ if (ctxt->errNr > 0)
+ xmlRelaxNGPopErrors(ctxt, 0);
+ break;
+ }
case XML_RELAXNG_EXCEPT:{
xmlRelaxNGDefinePtr list;
@@ -8815,8 +8968,11 @@
case XML_RELAXNG_REF:
case XML_RELAXNG_PARENTREF:
if (define->content == NULL) {
- }
- ret = xmlRelaxNGValidateValue(ctxt, define->content);
+ VALID_ERR(XML_RELAXNG_ERR_NODEFINE);
+ ret = -1;
+ } else {
+ ret = xmlRelaxNGValidateValue(ctxt, define->content);
+ }
break;
default:
TODO ret = -1;
@@ -9323,6 +9479,7 @@
oldstate =
ctxt->states->tabState[ctxt->states->nbState - 1];
ctxt->states->tabState[ctxt->states->nbState - 1] = NULL;
+ ctxt->states->nbState--;
}
}
for (j = 0; j < ctxt->states->nbState ; j++) {
@@ -9331,7 +9488,12 @@
xmlRelaxNGFreeStates(ctxt, ctxt->states);
ctxt->states = NULL;
if (found == 0) {
- VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
+ if (cur == NULL) {
+ VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA,
+ (const xmlChar *) "noname");
+ } else {
+ VALID_ERR2(XML_RELAXNG_ERR_INTEREXTRA, cur->name);
+ }
ret = -1;
ctxt->state = oldstate;
goto done;
@@ -9878,8 +10040,8 @@
}
for (i = 0; i < ctxt->states->nbState; i++) {
xmlRelaxNGFreeValidState(ctxt,
- ctxt->states->
- tabState[i]);
+ ctxt->states->tabState[i]);
+ ctxt->states->tabState[i] = NULL;
}
xmlRelaxNGFreeStates(ctxt, ctxt->states);
ctxt->flags = oldflags;
@@ -10001,11 +10163,8 @@
} else {
for (j = 0; j < ctxt->states->nbState; j++) {
xmlRelaxNGAddStates(ctxt, res,
- xmlRelaxNGCopyValidState(ctxt,
- ctxt->
- states->
- tabState
- [j]));
+ xmlRelaxNGCopyValidState(ctxt,
+ ctxt->states->tabState[j]));
}
}
oldflags = ctxt->flags;
@@ -10034,10 +10193,7 @@
j++) {
tmp =
xmlRelaxNGAddStates(ctxt, res,
- ctxt->
- states->
- tabState
- [j]);
+ ctxt->states->tabState[j]);
if (tmp == 1)
progress = 1;
}
@@ -10071,9 +10227,7 @@
} else if (ctxt->states != NULL) {
for (j = 0; j < ctxt->states->nbState; j++) {
tmp = xmlRelaxNGAddStates(ctxt, res,
- ctxt->
- states->
- tabState[j]);
+ ctxt->states->tabState[j]);
if (tmp == 1)
progress = 1;
}
@@ -10111,8 +10265,7 @@
for (i = base; i < res->nbState; i++)
xmlRelaxNGAddStates(ctxt, states,
xmlRelaxNGCopyValidState
- (ctxt,
- res->tabState[i]));
+ (ctxt, res->tabState[i]));
ctxt->states = states;
}
}
@@ -10634,6 +10787,60 @@
return (ret);
}
+/**
+ * xmlRelaxNGCleanPSVI:
+ * @node: an input element or document
+ *
+ * Call this routine to speed up XPath computation on static documents.
+ * This stamps all the element nodes with the document order
+ * Like for line information, the order is kept in the element->content
+ * field, the value stored is actually - the node number (starting at -1)
+ * to be able to differentiate from line numbers.
+ *
+ * Returns the number of elements found in the document or -1 in case
+ * of error.
+ */
+static void
+xmlRelaxNGCleanPSVI(xmlNodePtr node) {
+ xmlNodePtr cur;
+
+ if ((node == NULL) ||
+ ((node->type != XML_ELEMENT_NODE) &&
+ (node->type != XML_DOCUMENT_NODE) &&
+ (node->type != XML_HTML_DOCUMENT_NODE)))
+ return;
+ if (node->type == XML_ELEMENT_NODE)
+ node->psvi = NULL;
+
+ cur = node->children;
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE) {
+ cur->psvi = NULL;
+ if (cur->children != NULL) {
+ cur = cur->children;
+ continue;
+ }
+ }
+ if (cur->next != NULL) {
+ cur = cur->next;
+ continue;
+ }
+ do {
+ cur = cur->parent;
+ if (cur == NULL)
+ break;
+ if (cur == node) {
+ cur = NULL;
+ break;
+ }
+ if (cur->next != NULL) {
+ cur = cur->next;
+ break;
+ }
+ } while (cur != NULL);
+ }
+ return;
+}
/************************************************************************
* *
* Validation interfaces *
@@ -10808,6 +11015,11 @@
ret = xmlRelaxNGValidateDocument(ctxt, doc);
/*
+ * Remove all left PSVI
+ */
+ xmlRelaxNGCleanPSVI((xmlNodePtr) doc);
+
+ /*
* TODO: build error codes
*/
if (ret == -1)
diff --git a/threads.c b/threads.c
index 2223e8a..1eeac0e 100644
--- a/threads.c
+++ b/threads.c
@@ -26,9 +26,7 @@
#endif
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
-#endif
-
-#ifdef HAVE_WIN32_THREADS
+#elif defined HAVE_WIN32_THREADS
#include <windows.h>
#ifndef HAVE_COMPILER_TLS
#include <process.h>
@@ -412,7 +410,7 @@
if (tok->held == 0) {
if (tok->waiters)
pthread_cond_signal(&tok->cv);
- tok->tid = 0;
+ memset(&tok->tid, 0, sizeof(tok->tid));
}
pthread_mutex_unlock(&tok->lock);
#elif defined HAVE_WIN32_THREADS
@@ -441,7 +439,8 @@
/* Make sure the global init lock is initialized and then lock it. */
#ifdef HAVE_PTHREAD_H
/* The mutex is statically initialized, so we just lock it. */
- pthread_mutex_lock(&global_init_lock);
+ if (pthread_mutex_lock)
+ pthread_mutex_lock(&global_init_lock);
#elif defined HAVE_WIN32_THREADS
LPCRITICAL_SECTION cs;
@@ -510,7 +509,8 @@
__xmlGlobalInitMutexUnlock(void)
{
#ifdef HAVE_PTHREAD_H
- pthread_mutex_unlock(&global_init_lock);
+ if (pthread_mutex_unlock)
+ pthread_mutex_unlock(&global_init_lock);
#elif defined HAVE_WIN32_THREADS
if (global_init_lock != NULL) {
LeaveCriticalSection(global_init_lock);
@@ -529,7 +529,8 @@
void
__xmlGlobalInitMutexDestroy(void)
{
-#if defined HAVE_WIN32_THREADS
+#ifdef HAVE_PTHREAD_H
+#elif defined HAVE_WIN32_THREADS
if (global_init_lock != NULL) {
DeleteCriticalSection(global_init_lock);
free(global_init_lock);
@@ -593,8 +594,8 @@
}
#endif /* LIBXML_THREAD_ENABLED */
-
-#ifdef HAVE_WIN32_THREADS
+#ifdef HAVE_PTHREAD_H
+#elif defined HAVE_WIN32_THREADS
#if !defined(HAVE_COMPILER_TLS)
#if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
typedef struct _xmlGlobalStateCleanupHelperParams {
@@ -758,6 +759,8 @@
* xmlGetThreadId:
*
* xmlGetThreadId() find the current thread ID number
+ * Note that this is likely to be broken on some platforms using pthreads
+ * as the specification doesn't mandate pthread_t to be an integer type
*
* Returns the current thread ID number
*/
@@ -765,9 +768,15 @@
xmlGetThreadId(void)
{
#ifdef HAVE_PTHREAD_H
+ pthread_t id;
+ int ret;
+
if (libxml_is_threaded == 0)
return (0);
- return ((int) pthread_self());
+ id = pthread_self();
+ /* horrible but preserves compat, see warning above */
+ memcpy(&ret, &id, sizeof(ret));
+ return (ret);
#elif defined HAVE_WIN32_THREADS
return GetCurrentThreadId();
#elif defined HAVE_BEOS_THREADS
@@ -803,7 +812,7 @@
xmlGenericError(xmlGenericErrorContext, "xmlIsMainThread()\n");
#endif
#ifdef HAVE_PTHREAD_H
- return (mainthread == pthread_self());
+ return (pthread_equal(mainthread,pthread_self()));
#elif defined HAVE_WIN32_THREADS
return (mainthread == GetCurrentThreadId());
#elif defined HAVE_BEOS_THREADS
@@ -852,12 +861,6 @@
void
xmlInitThreads(void)
{
-#ifdef DEBUG_THREADS
- xmlGenericError(xmlGenericErrorContext, "xmlInitThreads()\n");
-#endif
-#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
- InitializeCriticalSection(&cleanup_helpers_cs);
-#endif
#ifdef HAVE_PTHREAD_H
if (libxml_is_threaded == -1) {
if ((pthread_once != NULL) &&
@@ -884,6 +887,8 @@
libxml_is_threaded = 0;
}
}
+#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
+ InitializeCriticalSection(&cleanup_helpers_cs);
#endif
}
@@ -892,6 +897,14 @@
*
* xmlCleanupThreads() is used to to cleanup all the thread related
* data of the libxml2 library once processing has ended.
+ *
+ * WARNING: if your application is multithreaded or has plugin support
+ * calling this may crash the application if another thread or
+ * a plugin is still using libxml2. It's sometimes very hard to
+ * guess if libxml2 is in use in the application, some libraries
+ * or plugins may use it without notice. In case of doubt abstain
+ * from calling this function or do it just before calling exit()
+ * to avoid leak reports from valgrind !
*/
void
xmlCleanupThreads(void)
@@ -899,7 +912,10 @@
#ifdef DEBUG_THREADS
xmlGenericError(xmlGenericErrorContext, "xmlCleanupThreads()\n");
#endif
-#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
+#ifdef HAVE_PTHREAD_H
+ if ((libxml_is_threaded) && (pthread_key_delete != NULL))
+ pthread_key_delete(globalkey);
+#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
if (globalkey != TLS_OUT_OF_INDEXES) {
xmlGlobalStateCleanupHelperParams *p;
@@ -918,9 +934,6 @@
globalkey = TLS_OUT_OF_INDEXES;
}
DeleteCriticalSection(&cleanup_helpers_cs);
-#elif defined HAVE_PTHREAD_H
- if ((libxml_is_threaded) && (pthread_key_delete != NULL))
- pthread_key_delete(globalkey);
#endif
}
@@ -941,9 +954,7 @@
#ifdef HAVE_PTHREAD_H
(void) pthread_key_create(&globalkey, xmlFreeGlobalState);
mainthread = pthread_self();
-#endif
-
-#if defined(HAVE_WIN32_THREADS)
+#elif defined(HAVE_WIN32_THREADS)
if (!run_once.done) {
if (InterlockedIncrement(&run_once.control) == 1) {
#if !defined(HAVE_COMPILER_TLS)
@@ -958,9 +969,7 @@
Sleep(0);
}
}
-#endif
-
-#ifdef HAVE_BEOS_THREADS
+#elif defined HAVE_BEOS_THREADS
if (atomic_add(&run_once_init, 1) == 0) {
globalkey = tls_allocate();
tls_set(globalkey, NULL);
@@ -982,7 +991,8 @@
*
* Returns TRUE always
*/
-#if defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
+#ifdef HAVE_PTHREAD_H
+#elif defined(HAVE_WIN32_THREADS) && !defined(HAVE_COMPILER_TLS) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
#if defined(LIBXML_STATIC_FOR_DLL)
BOOL XMLCALL
xmlDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
diff --git a/tree.c b/tree.c
index 8e393da..a2fdcbf 100644
--- a/tree.c
+++ b/tree.c
@@ -49,7 +49,8 @@
* *
************************************************************************/
-xmlNsPtr xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns);
+static xmlNsPtr
+xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns);
static xmlChar* xmlGetPropNodeValueInternal(xmlAttrPtr prop);
@@ -720,8 +721,19 @@
if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
return(NULL);
- if ((prefix != NULL) && (xmlStrEqual(prefix, BAD_CAST "xml")))
- return(NULL);
+ if ((prefix != NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
+ /* xml namespace is predefined, no need to add it */
+ if (xmlStrEqual(href, XML_XML_NAMESPACE))
+ return(NULL);
+
+ /*
+ * Problem, this is an attempt to bind xml prefix to a wrong
+ * namespace, which breaks
+ * Namespace constraint: Reserved Prefixes and Namespace Names
+ * from XML namespace. But documents authors may not care in
+ * their context so let's proceed.
+ */
+ }
/*
* Allocate a new Namespace and fill the fields.
@@ -1420,9 +1432,9 @@
node = xmlNewDocTextLen(doc, q, cur - q);
if (node == NULL) return(ret);
if (last == NULL) {
- last = ret = node;
+ ret = node;
} else {
- last = xmlAddNextSibling(last, node);
+ xmlAddNextSibling(last, node);
}
}
}
@@ -1589,8 +1601,6 @@
last = xmlAddNextSibling(last, node);
}
}
-
- charval = 0;
}
} else
cur++;
@@ -1800,7 +1810,7 @@
cur = (xmlAttrPtr) xmlMalloc(sizeof(xmlAttr));
if (cur == NULL) {
if ((eatname == 1) &&
- ((node->doc == NULL) ||
+ ((node == NULL) || (node->doc == NULL) ||
(!(xmlDictOwns(node->doc->dict, name)))))
xmlFree((xmlChar *) name);
xmlTreeErrMemory("building attribute");
@@ -1860,7 +1870,8 @@
}
}
- if (xmlIsID((node == NULL) ? NULL : node->doc, node, cur) == 1)
+ if ((value != NULL) && (node != NULL) &&
+ (xmlIsID(node->doc, node, cur) == 1))
xmlAddID(NULL, node->doc, value, cur);
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
@@ -3103,6 +3114,14 @@
return(NULL);
}
+ if (cur == elem) {
+#ifdef DEBUG_TREE
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlAddSibling : cur == elem\n");
+#endif
+ return(NULL);
+ }
+
/*
* Constant time is we can rely on the ->parent->last to find
* the last sibling.
@@ -3519,7 +3538,7 @@
while (node != NULL) {
if (node->type == XML_ELEMENT_NODE)
return(node);
- node = node->next;
+ node = node->prev;
}
return(NULL);
}
@@ -3713,6 +3732,8 @@
* @cur: the node
*
* Unlink a node from it's current context, the node is not freed
+ * If one need to free the node, use xmlNodeFree() routine after the
+ * unlink.
*/
void
xmlUnlinkNode(xmlNodePtr cur) {
@@ -4160,7 +4181,8 @@
if (!extended)
goto out;
- if ((node->type == XML_ELEMENT_NODE) && (node->nsDef != NULL))
+ if (((node->type == XML_ELEMENT_NODE) ||
+ (node->type == XML_XINCLUDE_START)) && (node->nsDef != NULL))
ret->nsDef = xmlCopyNamespaceList(node->nsDef);
if (node->ns != NULL) {
@@ -4179,6 +4201,8 @@
while (root->parent != NULL) root = root->parent;
ret->ns = xmlNewNs(root, ns->href, ns->prefix);
+ } else {
+ ret->ns = xmlNewReconciliedNs(doc, ret, node->ns);
}
} else {
/*
@@ -4187,7 +4211,8 @@
ret->ns = ns;
}
}
- if ((node->type == XML_ELEMENT_NODE) && (node->properties != NULL))
+ if (((node->type == XML_ELEMENT_NODE) ||
+ (node->type == XML_XINCLUDE_START)) && (node->properties != NULL))
ret->properties = xmlCopyPropList(ret, node->properties);
if (node->type == XML_ENTITY_REF_NODE) {
if ((doc == NULL) || (node->doc != doc)) {
@@ -5046,7 +5071,7 @@
void
xmlNodeSetBase(xmlNodePtr cur, const xmlChar* uri) {
xmlNsPtr ns;
- const xmlChar* fixed;
+ xmlChar* fixed;
if (cur == NULL) return;
switch(cur->type) {
@@ -5093,7 +5118,7 @@
fixed = xmlPathToURI(uri);
if (fixed != NULL) {
xmlSetNsProp(cur, ns, BAD_CAST "base", fixed);
- xmlFree((xmlChar *)fixed);
+ xmlFree(fixed);
} else {
xmlSetNsProp(cur, ns, BAD_CAST "base", uri);
}
@@ -5112,7 +5137,7 @@
* and
* 5.1.2. Base URI from the Encapsulating Entity
* However it does not return the document base (5.1.3), use
- * xmlDocumentGetBase() for this
+ * doc->URL in this case
*
* Returns a pointer to the base URL, or NULL if not found
* It's up to the caller to free the memory with xmlFree().
@@ -6045,7 +6070,7 @@
* @tree or on one of its ancestors then a new prefix is generated.
* Returns the (new) namespace definition or NULL in case of error
*/
-xmlNsPtr
+static xmlNsPtr
xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
xmlNsPtr def;
xmlChar prefix[50];
@@ -7061,11 +7086,13 @@
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
if (len + buf->use < buf->size) return(0);
-/*
- * Windows has a BIG problem on realloc timing, so we try to double
- * the buffer size (if that's enough) (bug 146697)
- */
-#ifdef WIN32
+ /*
+ * Windows has a BIG problem on realloc timing, so we try to double
+ * the buffer size (if that's enough) (bug 146697)
+ * Apparently BSD too, and it's probably best for linux too
+ * On an embedded system this may be something to change
+ */
+#if 1
if (buf->size > len)
size = buf->size * 2;
else
@@ -7765,8 +7792,11 @@
}
}
/* Create. */
- ns->next = xmlNewNs(NULL, nsName, prefix);
- return (ns->next);
+ if (ns != NULL) {
+ ns->next = xmlNewNs(NULL, nsName, prefix);
+ return (ns->next);
+ }
+ return(NULL);
}
/*
diff --git a/trio.c b/trio.c
index 3fac2e6..b116ccc 100644
--- a/trio.c
+++ b/trio.c
@@ -1,6 +1,6 @@
/*************************************************************************
*
- * $Id: trio.c 3600 2007-04-17 12:44:58Z veillard $
+ * $Id$
*
* Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
*
@@ -733,7 +733,7 @@
*
*************************************************************************/
-static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c 3600 2007-04-17 12:44:58Z veillard $";
+static TRIO_CONST char rcsid[] = "@(#)$Id$";
/*
* Need this to workaround a parser bug in HP C/iX compiler that fails
diff --git a/trio.h b/trio.h
index d998f35..eab1b6d 100644
--- a/trio.h
+++ b/trio.h
@@ -1,6 +1,6 @@
/*************************************************************************
*
- * $Id: trio.h 1886 2003-04-03 15:28:28Z veillard $
+ * $Id$
*
* Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
*
@@ -29,7 +29,7 @@
* HAVE_CONFIG_H as a compiler option themselves.
*/
#if defined(HAVE_CONFIG_H)
-# include <config.h>
+# include "config.h"
#endif
#include "triodef.h"
diff --git a/triodef.h b/triodef.h
index 9ab3af1..fa89416 100644
--- a/triodef.h
+++ b/triodef.h
@@ -1,6 +1,6 @@
/*************************************************************************
*
- * $Id: triodef.h 3473 2006-05-31 13:35:28Z veillard $
+ * $Id$
*
* Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
*
diff --git a/trionan.c b/trionan.c
index e160370..95baae1 100644
--- a/trionan.c
+++ b/trionan.c
@@ -1,6 +1,6 @@
/*************************************************************************
*
- * $Id: trionan.c 3790 2008-09-01 13:08:57Z veillard $
+ * $Id$
*
* Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
*
@@ -112,7 +112,7 @@
* Constants
*/
-static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c 3790 2008-09-01 13:08:57Z veillard $";
+static TRIO_CONST char rcsid[] = "@(#)$Id$";
#if defined(USE_IEEE_754)
diff --git a/trionan.h b/trionan.h
index 92de0fd..c5de32b 100644
--- a/trionan.h
+++ b/trionan.h
@@ -1,6 +1,6 @@
/*************************************************************************
*
- * $Id: trionan.h 2026 2003-08-06 04:43:55Z wbrack $
+ * $Id$
*
* Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
*
diff --git a/triop.h b/triop.h
index a062c96..8462c56 100644
--- a/triop.h
+++ b/triop.h
@@ -1,6 +1,6 @@
/*************************************************************************
*
- * $Id: triop.h 1886 2003-04-03 15:28:28Z veillard $
+ * $Id$
*
* Copyright (C) 2000 Bjorn Reese and Daniel Stenberg.
*
diff --git a/triostr.c b/triostr.c
index dc5592c..30d13ac 100644
--- a/triostr.c
+++ b/triostr.c
@@ -1,6 +1,6 @@
/*************************************************************************
*
- * $Id: triostr.c 3600 2007-04-17 12:44:58Z veillard $
+ * $Id$
*
* Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
*
@@ -101,7 +101,7 @@
*/
#if !defined(TRIO_MINIMAL)
-static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c 3600 2007-04-17 12:44:58Z veillard $";
+static TRIO_CONST char rcsid[] = "@(#)$Id$";
#endif
/*************************************************************************
diff --git a/triostr.h b/triostr.h
index 6b8d30f..27f4ace 100644
--- a/triostr.h
+++ b/triostr.h
@@ -1,6 +1,6 @@
/*************************************************************************
*
- * $Id: triostr.h 3600 2007-04-17 12:44:58Z veillard $
+ * $Id$
*
* Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
*
diff --git a/uri.c b/uri.c
index 28401c8..1ae5768 100644
--- a/uri.c
+++ b/uri.c
@@ -127,7 +127,7 @@
(((*(p) == '!')) || ((*(p) == '$')) || ((*(p) == '&')) || \
((*(p) == '(')) || ((*(p) == ')')) || ((*(p) == '*')) || \
((*(p) == '+')) || ((*(p) == ',')) || ((*(p) == ';')) || \
- ((*(p) == '=')))
+ ((*(p) == '=')) || ((*(p) == '\'')))
/*
* gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
@@ -558,10 +558,14 @@
}
if (uri != NULL) {
if (uri->path != NULL) xmlFree(uri->path);
- if (uri->cleanup & 2)
- uri->path = STRNDUP(*str, cur - *str);
- else
- uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (*str != cur) {
+ if (uri->cleanup & 2)
+ uri->path = STRNDUP(*str, cur - *str);
+ else
+ uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+ } else {
+ uri->path = NULL;
+ }
}
*str = cur;
return (0);
@@ -600,10 +604,14 @@
}
if (uri != NULL) {
if (uri->path != NULL) xmlFree(uri->path);
- if (uri->cleanup & 2)
- uri->path = STRNDUP(*str, cur - *str);
- else
- uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (cur != *str) {
+ if (uri->cleanup & 2)
+ uri->path = STRNDUP(*str, cur - *str);
+ else
+ uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+ } else {
+ uri->path = NULL;
+ }
}
*str = cur;
return (0);
@@ -638,10 +646,14 @@
}
if (uri != NULL) {
if (uri->path != NULL) xmlFree(uri->path);
- if (uri->cleanup & 2)
- uri->path = STRNDUP(*str, cur - *str);
- else
- uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (cur != *str) {
+ if (uri->cleanup & 2)
+ uri->path = STRNDUP(*str, cur - *str);
+ else
+ uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+ } else {
+ uri->path = NULL;
+ }
}
*str = cur;
return (0);
@@ -676,10 +688,14 @@
}
if (uri != NULL) {
if (uri->path != NULL) xmlFree(uri->path);
- if (uri->cleanup & 2)
- uri->path = STRNDUP(*str, cur - *str);
- else
- uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+ if (cur != *str) {
+ if (uri->cleanup & 2)
+ uri->path = STRNDUP(*str, cur - *str);
+ else
+ uri->path = xmlURIUnescapeString(*str, cur - *str, NULL);
+ } else {
+ uri->path = NULL;
+ }
}
*str = cur;
return (0);
@@ -1373,7 +1389,7 @@
}
ret = temp;
}
- ret[len++] = 0;
+ ret[len] = 0;
return(ret);
}
diff --git a/valid.c b/valid.c
index ea47142..5de491d 100644
--- a/valid.c
+++ b/valid.c
@@ -637,8 +637,6 @@
else if ((doc->intSubset == NULL) && \
(doc->extSubset == NULL)) return(0)
-xmlAttributePtr xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem);
-
#ifdef LIBXML_REGEXP_ENABLED
/************************************************************************
@@ -1833,53 +1831,6 @@
#ifdef LIBXML_VALID_ENABLED
/**
- * xmlScanAttributeDeclCallback:
- * @attr: the attribute decl
- * @list: the list to update
- *
- * Callback called by xmlScanAttributeDecl when a new attribute
- * has to be entered in the list.
- */
-static void
-xmlScanAttributeDeclCallback(xmlAttributePtr attr, xmlAttributePtr *list,
- const xmlChar* name ATTRIBUTE_UNUSED) {
- attr->nexth = *list;
- *list = attr;
-}
-
-/**
- * xmlScanAttributeDecl:
- * @dtd: pointer to the DTD
- * @elem: the element name
- *
- * When inserting a new element scan the DtD for existing attributes
- * for that element and initialize the Attribute chain
- *
- * Returns the pointer to the first attribute decl in the chain,
- * possibly NULL.
- */
-xmlAttributePtr
-xmlScanAttributeDecl(xmlDtdPtr dtd, const xmlChar *elem) {
- xmlAttributePtr ret = NULL;
- xmlAttributeTablePtr table;
-
- if (dtd == NULL) {
- return(NULL);
- }
- if (elem == NULL) {
- return(NULL);
- }
- table = (xmlAttributeTablePtr) dtd->attributes;
- if (table == NULL)
- return(NULL);
-
- /* WRONG !!! */
- xmlHashScan3(table, NULL, NULL, elem,
- (xmlHashScanner) xmlScanAttributeDeclCallback, &ret);
- return(ret);
-}
-
-/**
* xmlScanIDAttributeDecl:
* @ctxt: the validation context
* @elem: the element name
@@ -2728,7 +2679,8 @@
(!strcmp((char *) attr->ns->prefix, "xml")))
return(1);
if (doc == NULL) return(0);
- if ((doc->intSubset == NULL) && (doc->extSubset == NULL)) {
+ if ((doc->intSubset == NULL) && (doc->extSubset == NULL) &&
+ (doc->type != XML_HTML_DOCUMENT_NODE)) {
return(0);
} else if (doc->type == XML_HTML_DOCUMENT_NODE) {
if ((xmlStrEqual(BAD_CAST "id", attr->name)) ||
@@ -3399,7 +3351,8 @@
xmlValidateNotationUse(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
const xmlChar *notationName) {
xmlNotationPtr notaDecl;
- if ((doc == NULL) || (doc->intSubset == NULL)) return(-1);
+ if ((doc == NULL) || (doc->intSubset == NULL) ||
+ (notationName == NULL)) return(-1);
notaDecl = xmlGetDtdNotationDesc(doc->intSubset, notationName);
if ((notaDecl == NULL) && (doc->extSubset != NULL))
@@ -4100,13 +4053,10 @@
if ((elem->ns != NULL) && (elem->ns->prefix != NULL)) {
xmlChar fn[50];
xmlChar *fullname;
-
+
fullname = xmlBuildQName(elem->name, elem->ns->prefix, fn, 50);
if (fullname == NULL)
return(NULL);
- attrDecl = xmlGetDtdAttrDesc(doc->intSubset, fullname, name);
- if ((attrDecl == NULL) && (doc->extSubset != NULL))
- attrDecl = xmlGetDtdAttrDesc(doc->extSubset, fullname, name);
if ((fullname != fn) && (fullname != elem->name))
xmlFree(fullname);
}
@@ -4305,15 +4255,15 @@
while (next != NULL) {
if (next->type == XML_ELEMENT_CONTENT_ELEMENT) {
if ((xmlStrEqual(next->name, name)) &&
- (xmlStrEqual(next->prefix, cur->prefix))) {
- if (cur->prefix == NULL) {
+ (xmlStrEqual(next->prefix, cur->c1->prefix))) {
+ if (cur->c1->prefix == NULL) {
xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CONTENT_ERROR,
"Definition of %s has duplicate references of %s\n",
elem->name, name, NULL);
} else {
xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CONTENT_ERROR,
"Definition of %s has duplicate references of %s:%s\n",
- elem->name, cur->prefix, name);
+ elem->name, cur->c1->prefix, name);
}
ret = 0;
}
@@ -4322,15 +4272,15 @@
if (next->c1 == NULL) break;
if (next->c1->type != XML_ELEMENT_CONTENT_ELEMENT) break;
if ((xmlStrEqual(next->c1->name, name)) &&
- (xmlStrEqual(next->c1->prefix, cur->prefix))) {
- if (cur->prefix == NULL) {
+ (xmlStrEqual(next->c1->prefix, cur->c1->prefix))) {
+ if (cur->c1->prefix == NULL) {
xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CONTENT_ERROR,
"Definition of %s has duplicate references to %s\n",
elem->name, name, NULL);
} else {
xmlErrValidNode(ctxt, (xmlNodePtr) elem, XML_DTD_CONTENT_ERROR,
"Definition of %s has duplicate references to %s:%s\n",
- elem->name, cur->prefix, name);
+ elem->name, cur->c1->prefix, name);
}
ret = 0;
}
@@ -6609,6 +6559,7 @@
int
xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
xmlRefTablePtr table;
+ unsigned int save;
if (ctxt == NULL)
return(0);
@@ -6618,6 +6569,10 @@
return(0);
}
+ /* trick to get correct line id report */
+ save = ctxt->finishDtd;
+ ctxt->finishDtd = 0;
+
/*
* Check all the NOTATION/NOTATIONS attributes
*/
@@ -6631,6 +6586,8 @@
ctxt->doc = doc;
ctxt->valid = 1;
xmlHashScan(table, (xmlHashScanner) xmlValidateCheckRefCallback, ctxt);
+
+ ctxt->finishDtd = save;
return(ctxt->valid);
}
diff --git a/xinclude.c b/xinclude.c
index ae449f8..2916ffa 100644
--- a/xinclude.c
+++ b/xinclude.c
@@ -438,9 +438,9 @@
* try to ensure that new documents included are actually
* built with the same dictionary as the including document.
*/
- if ((ctxt->doc != NULL) && (ctxt->doc->dict != NULL) &&
- (pctxt->dict != NULL)) {
- xmlDictFree(pctxt->dict);
+ if ((ctxt->doc != NULL) && (ctxt->doc->dict != NULL)) {
+ if (pctxt->dict != NULL)
+ xmlDictFree(pctxt->dict);
pctxt->dict = ctxt->doc->dict;
xmlDictReference(pctxt->dict);
}
@@ -798,6 +798,10 @@
* *
************************************************************************/
+static xmlNodePtr
+xmlXIncludeCopyNodeList(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
+ xmlDocPtr source, xmlNodePtr elem);
+
/**
* xmlXIncludeCopyNode:
* @ctxt: the XInclude context
@@ -818,7 +822,10 @@
return(NULL);
if (elem->type == XML_DTD_NODE)
return(NULL);
- result = xmlDocCopyNode(elem, target, 1);
+ if (elem->type == XML_DOCUMENT_NODE)
+ result = xmlXIncludeCopyNodeList(ctxt, target, source, elem->children);
+ else
+ result = xmlDocCopyNode(elem, target, 1);
return(result);
}
@@ -967,7 +974,6 @@
if ((cur == start) && (index1 > 1)) {
content += (index1 - 1);
len -= (index1 - 1);
- index1 = 0;
} else {
len = index2;
}
@@ -2423,7 +2429,42 @@
ctxt->parseFlags = flags;
return(0);
}
-
+
+/**
+ * xmlXIncludeProcessTreeFlagsData:
+ * @tree: an XML node
+ * @flags: a set of xmlParserOption used for parsing XML includes
+ * @data: application data that will be passed to the parser context
+ * in the _private field of the parser context(s)
+ *
+ * Implement the XInclude substitution on the XML node @tree
+ *
+ * Returns 0 if no substitution were done, -1 if some processing failed
+ * or the number of substitutions done.
+ */
+
+int
+xmlXIncludeProcessTreeFlagsData(xmlNodePtr tree, int flags, void *data) {
+ xmlXIncludeCtxtPtr ctxt;
+ int ret = 0;
+
+ if ((tree == NULL) || (tree->doc == NULL))
+ return(-1);
+
+ ctxt = xmlXIncludeNewContext(tree->doc);
+ if (ctxt == NULL)
+ return(-1);
+ ctxt->_private = data;
+ ctxt->base = xmlStrdup((xmlChar *)tree->doc->URL);
+ xmlXIncludeSetFlags(ctxt, flags);
+ ret = xmlXIncludeDoProcess(ctxt, tree->doc, tree);
+ if ((ret >= 0) && (ctxt->nbErrors > 0))
+ ret = -1;
+
+ xmlXIncludeFreeContext(ctxt);
+ return(ret);
+}
+
/**
* xmlXIncludeProcessFlagsData:
* @doc: an XML document
@@ -2438,27 +2479,14 @@
*/
int
xmlXIncludeProcessFlagsData(xmlDocPtr doc, int flags, void *data) {
- xmlXIncludeCtxtPtr ctxt;
xmlNodePtr tree;
- int ret = 0;
if (doc == NULL)
return(-1);
tree = xmlDocGetRootElement(doc);
if (tree == NULL)
return(-1);
- ctxt = xmlXIncludeNewContext(doc);
- if (ctxt == NULL)
- return(-1);
- ctxt->_private = data;
- ctxt->base = xmlStrdup((xmlChar *)doc->URL);
- xmlXIncludeSetFlags(ctxt, flags);
- ret = xmlXIncludeDoProcess(ctxt, doc, tree);
- if ((ret >= 0) && (ctxt->nbErrors > 0))
- ret = -1;
-
- xmlXIncludeFreeContext(ctxt);
- return(ret);
+ return(xmlXIncludeProcessTreeFlagsData(tree, flags, data));
}
/**
diff --git a/xmlIO.c b/xmlIO.c
index d4dc364..73a995d 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -35,6 +35,9 @@
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif
+#ifdef HAVE_LZMA_H
+#include <lzma.h>
+#endif
#if defined(WIN32) || defined(_WIN32)
#include <windows.h>
@@ -142,7 +145,7 @@
/************************************************************************
* *
- * Tree memory error handler *
+ * Tree memory error handler *
* *
************************************************************************/
@@ -425,7 +428,7 @@
idx = 0;
if (code >= XML_IO_UNKNOWN) idx = code - XML_IO_UNKNOWN;
if (idx >= (sizeof(IOerr) / sizeof(IOerr[0]))) idx = 0;
-
+
__xmlSimpleError(domain, code, NULL, IOerr[idx], extra);
}
@@ -477,12 +480,12 @@
XML_IO_LOAD_ERROR, level, NULL, 0,
filename, NULL, NULL, 0, 0,
msg, filename);
-
+
}
/************************************************************************
* *
- * Tree memory error handler *
+ * Tree memory error handler *
* *
************************************************************************/
/**
@@ -504,7 +507,7 @@
* xmlCleanupInputCallbacks:
*
* clears the entire input callback table. this includes the
- * compiled-in I/O.
+ * compiled-in I/O.
*/
void
xmlCleanupInputCallbacks(void)
@@ -529,7 +532,7 @@
* xmlPopInputCallbacks:
*
* Clear the top input callback from the input stack. this includes the
- * compiled-in I/O.
+ * compiled-in I/O.
*
* Returns the number of input callback registered or -1 in case of error.
*/
@@ -541,7 +544,7 @@
if (xmlInputCallbackNr <= 0)
return(-1);
-
+
xmlInputCallbackNr--;
xmlInputCallbackTable[xmlInputCallbackNr].matchcallback = NULL;
xmlInputCallbackTable[xmlInputCallbackNr].opencallback = NULL;
@@ -556,7 +559,7 @@
* xmlCleanupOutputCallbacks:
*
* clears the entire output callback table. this includes the
- * compiled-in I/O callbacks.
+ * compiled-in I/O callbacks.
*/
void
xmlCleanupOutputCallbacks(void)
@@ -613,6 +616,34 @@
return fd;
}
+#ifdef HAVE_ZLIB_H
+static gzFile
+xmlWrapGzOpenUtf8(const char *path, const char *mode)
+{
+ gzFile fd;
+ wchar_t *wPath;
+
+ fd = gzopen (path, mode);
+ if (fd)
+ return fd;
+
+ wPath = __xmlIOWin32UTF8ToWChar(path);
+ if(wPath)
+ {
+ int d, m = (strstr(mode, "r") ? O_RDONLY : O_RDWR);
+#ifdef _O_BINARY
+ m |= (strstr(mode, "b") ? _O_BINARY : 0);
+#endif
+ d = _wopen(wPath, m);
+ if (d >= 0)
+ fd = gzdopen(d, mode);
+ xmlFree(wPath);
+ }
+
+ return fd;
+}
+#endif
+
/**
* xmlWrapStatUtf8:
* @path: the path in utf-8 encoding
@@ -679,7 +710,10 @@
static xmlWrapStatFunc xmlWrapStat = xmlWrapStatNative;
typedef FILE* (* xmlWrapOpenFunc)(const char *f,int mode);
static xmlWrapOpenFunc xmlWrapOpen = xmlWrapOpenNative;
-
+#ifdef HAVE_ZLIB_H
+typedef gzFile (* xmlWrapGzOpenFunc) (const char *f, const char *mode);
+static xmlWrapGzOpenFunc xmlWrapGzOpen = gzopen;
+#endif
/**
* xmlInitPlatformSpecificIo:
*
@@ -699,9 +733,15 @@
if(GetVersionEx(&osvi) && (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)) {
xmlWrapStat = xmlWrapStatUtf8;
xmlWrapOpen = xmlWrapOpenUtf8;
+#ifdef HAVE_ZLIB_H
+ xmlWrapGzOpen = xmlWrapGzOpenUtf8;
+#endif
} else {
xmlWrapStat = xmlWrapStatNative;
xmlWrapOpen = xmlWrapOpenNative;
+#ifdef HAVE_ZLIB_H
+ xmlWrapGzOpen = gzopen;
+#endif
}
xmlPlatformIoInitialized = 1;
@@ -866,7 +906,7 @@
#else
path = &filename[5];
#endif
- } else
+ } else
path = filename;
if (path == NULL)
@@ -941,7 +981,7 @@
#else
path = &filename[7];
#endif
- } else
+ } else
path = filename;
if (path == NULL)
@@ -950,7 +990,7 @@
#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
fd = xmlWrapOpen(path, 1);
#else
- fd = fopen(path, "wb");
+ fd = fopen(path, "wb");
#endif /* WIN32 */
if (fd == NULL) xmlIOErr(0, path);
@@ -971,7 +1011,7 @@
int
xmlFileRead (void * context, char * buffer, int len) {
int ret;
- if ((context == NULL) || (buffer == NULL))
+ if ((context == NULL) || (buffer == NULL))
return(-1);
ret = fread(&buffer[0], 1, len, (FILE *) context);
if (ret < 0) xmlIOErr(0, "fread()");
@@ -993,7 +1033,7 @@
xmlFileWrite (void * context, const char * buffer, int len) {
int items;
- if ((context == NULL) || (buffer == NULL))
+ if ((context == NULL) || (buffer == NULL))
return(-1);
items = fwrite(&buffer[0], len, 1, (FILE *) context);
if ((items == 0) && (ferror((FILE *) context))) {
@@ -1124,7 +1164,7 @@
#else
path = &filename[7];
#endif
- } else
+ } else
path = filename;
if (path == NULL)
@@ -1132,7 +1172,11 @@
if (!xmlCheckFilename(path))
return(NULL);
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+ fd = xmlWrapGzOpen(path, "rb");
+#else
fd = gzopen(path, "rb");
+#endif
return((void *) fd);
}
@@ -1194,13 +1238,17 @@
#else
path = &filename[7];
#endif
- } else
+ } else
path = filename;
if (path == NULL)
return(NULL);
+#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
+ fd = xmlWrapGzOpen(path, mode);
+#else
fd = gzopen(path, mode);
+#endif
return((void *) fd);
}
#endif /* LIBXML_OUTPUT_ENABLED */
@@ -1261,6 +1309,125 @@
}
#endif /* HAVE_ZLIB_H */
+#ifdef HAVE_LZMA_H
+/************************************************************************
+ * *
+ * I/O for compressed file accesses *
+ * *
+ ************************************************************************/
+#include "xzlib.h"
+/**
+ * xmlXzfileMatch:
+ * @filename: the URI for matching
+ *
+ * input from compressed file test
+ *
+ * Returns 1 if matches, 0 otherwise
+ */
+static int
+xmlXzfileMatch (const char *filename ATTRIBUTE_UNUSED) {
+ return(1);
+}
+
+/**
+ * xmlXzFileOpen_real:
+ * @filename: the URI for matching
+ *
+ * input from compressed file open
+ * if @filename is " " then the standard input is used
+ *
+ * Returns an I/O context or NULL in case of error
+ */
+static void *
+xmlXzfileOpen_real (const char *filename) {
+ const char *path = NULL;
+ xzFile fd;
+
+ if (!strcmp(filename, "-")) {
+ fd = __libxml2_xzdopen(dup(0), "rb");
+ return((void *) fd);
+ }
+
+ if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17)) {
+ path = &filename[16];
+ } else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
+ path = &filename[7];
+ } else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:/", 6)) {
+ /* lots of generators seems to lazy to read RFC 1738 */
+ path = &filename[5];
+ } else
+ path = filename;
+
+ if (path == NULL)
+ return(NULL);
+ if (!xmlCheckFilename(path))
+ return(NULL);
+
+ fd = __libxml2_xzopen(path, "rb");
+ return((void *) fd);
+}
+
+/**
+ * xmlXzfileOpen:
+ * @filename: the URI for matching
+ *
+ * Wrapper around xmlXzfileOpen_real that try it with an unescaped
+ * version of @filename, if this fails fallback to @filename
+ *
+ * Returns a handler or NULL in case or failure
+ */
+static void *
+xmlXzfileOpen (const char *filename) {
+ char *unescaped;
+ void *retval;
+
+ retval = xmlXzfileOpen_real(filename);
+ if (retval == NULL) {
+ unescaped = xmlURIUnescapeString(filename, 0, NULL);
+ if (unescaped != NULL) {
+ retval = xmlXzfileOpen_real(unescaped);
+ }
+ xmlFree(unescaped);
+ }
+
+ return retval;
+}
+
+/**
+ * xmlXzfileRead:
+ * @context: the I/O context
+ * @buffer: where to drop data
+ * @len: number of bytes to write
+ *
+ * Read @len bytes to @buffer from the compressed I/O channel.
+ *
+ * Returns the number of bytes written
+ */
+static int
+xmlXzfileRead (void * context, char * buffer, int len) {
+ int ret;
+
+ ret = __libxml2_xzread((xzFile) context, &buffer[0], len);
+ if (ret < 0) xmlIOErr(0, "xzread()");
+ return(ret);
+}
+
+/**
+ * xmlXzfileClose:
+ * @context: the I/O context
+ *
+ * Close a compressed I/O channel
+ */
+static int
+xmlXzfileClose (void * context) {
+ int ret;
+
+ ret = (__libxml2_xzclose((xzFile) context) == LZMA_OK ) ? 0 : -1;
+ if (ret < 0) xmlIOErr(0, "xzclose()");
+ return(ret);
+}
+#endif /* HAVE_LZMA_H */
+
#ifdef LIBXML_HTTP_ENABLED
/************************************************************************
* *
@@ -1322,7 +1489,7 @@
/*
** This is plagiarized from putLong in gzio.c (zlib source) where
- ** the number "4" is hardcoded. If zlib is ever patched to
+ ** the number "4" is hardcoded. If zlib is ever patched to
** support 64 bit file sizes, this code would need to be patched
** as well.
*/
@@ -1374,7 +1541,7 @@
*
* Create a memory buffer to hold the compressed XML document. The
* compressed document in memory will end up being identical to what
- * would be created if gzopen/gzwrite/gzclose were being used to
+ * would be created if gzopen/gzwrite/gzclose were being used to
* write the document to disk. The code for the header/trailer data to
* the compression is plagiarized from the zlib source files.
*/
@@ -1423,7 +1590,7 @@
buff->crc = crc32( 0L, NULL, 0 );
hdr_lgth = snprintf( (char *)buff->zbuff, buff->size,
"%c%c%c%c%c%c%c%c%c%c",
- GZ_MAGIC1, GZ_MAGIC2, Z_DEFLATED,
+ GZ_MAGIC1, GZ_MAGIC2, Z_DEFLATED,
0, 0, 0, 0, 0, 0, LXML_ZLIB_OS_CODE );
buff->zctrl.next_out = buff->zbuff + hdr_lgth;
buff->zctrl.avail_out = buff->size - hdr_lgth;
@@ -1461,11 +1628,11 @@
new_size = buff->size + ext_amt;
#ifdef DEBUG_HTTP
- if ( cur_used > new_size )
+ if ( cur_used > new_size )
xmlGenericError( xmlGenericErrorContext,
"xmlZMemBuffExtend: %s\n%s %d bytes.\n",
"Buffer overwrite detected during compressed memory",
- "buffer extension. Overflowed by",
+ "buffer extension. Overflowed by",
(cur_used - new_size ) );
#endif
@@ -1603,7 +1770,7 @@
"Error flushing zlib buffers. Error code", z_err );
xmlIOErr(XML_IO_WRITE, (const char *) msg);
}
-
+
return ( zlgth );
}
#endif /* LIBXML_OUTPUT_ENABLED */
@@ -1762,7 +1929,7 @@
*
* Returns the number of bytes written
*/
-int
+int
xmlIOHTTPRead(void * context, char * buffer, int len) {
if ((buffer == NULL) || (len < 0)) return(-1);
return(xmlNanoHTTPRead(context, &buffer[0], len));
@@ -1782,7 +1949,7 @@
*/
static int
-xmlIOHTTPWrite( void * context, const char * buffer, int len ) {
+xmlIOHTTPWrite( void * context, const char * buffer, int len ) {
xmlIOHTTPWriteCtxtPtr ctxt = context;
@@ -1794,7 +1961,7 @@
/* Use gzwrite or fwrite as previously setup in the open call */
#ifdef HAVE_ZLIB_H
- if ( ctxt->compression > 0 )
+ if ( ctxt->compression > 0 )
len = xmlZMemBuffAppend( ctxt->doc_buff, buffer, len );
else
@@ -1885,7 +2052,7 @@
else {
http_ctxt = xmlNanoHTTPMethod( ctxt->uri, http_mthd, http_content,
- &content_type, content_encoding,
+ &content_type, content_encoding,
content_lgth );
if ( http_ctxt != NULL ) {
@@ -1904,7 +2071,7 @@
/*
** Since either content or reply may be gzipped,
- ** dump them to separate files instead of the
+ ** dump them to separate files instead of the
** standard error context.
*/
@@ -2041,7 +2208,7 @@
*
* Returns the number of bytes written
*/
-int
+int
xmlIOFTPRead(void * context, char * buffer, int len) {
if ((buffer == NULL) || (len < 0)) return(-1);
return(xmlNanoFTPRead(context, &buffer[0], len));
@@ -2104,7 +2271,7 @@
xmlRegisterOutputCallbacks(xmlOutputMatchCallback matchFunc,
xmlOutputOpenCallback openFunc, xmlOutputWriteCallback writeFunc,
xmlOutputCloseCallback closeFunc) {
- if (xmlOutputCallbackNr >= MAX_INPUT_CALLBACK) {
+ if (xmlOutputCallbackNr >= MAX_OUTPUT_CALLBACK) {
return(-1);
}
xmlOutputCallbackTable[xmlOutputCallbackNr].matchcallback = matchFunc;
@@ -2136,6 +2303,10 @@
xmlRegisterInputCallbacks(xmlGzfileMatch, xmlGzfileOpen,
xmlGzfileRead, xmlGzfileClose);
#endif /* HAVE_ZLIB_H */
+#ifdef HAVE_LZMA_H
+ xmlRegisterInputCallbacks(xmlXzfileMatch, xmlXzfileOpen,
+ xmlXzfileRead, xmlXzfileClose);
+#endif /* HAVE_ZLIB_H */
#ifdef LIBXML_HTTP_ENABLED
xmlRegisterInputCallbacks(xmlIOHTTPMatch, xmlIOHTTPOpen,
@@ -2278,6 +2449,10 @@
return(NULL);
}
+ /* try to avoid a performance problem with Windows realloc() */
+ if (ret->buffer->alloc == XML_BUFFER_ALLOC_EXACT)
+ ret->buffer->alloc = XML_BUFFER_ALLOC_DOUBLEIT;
+
ret->encoder = encoder;
if (encoder != NULL) {
ret->conv = xmlBufferCreateSize(4000);
@@ -2289,7 +2464,7 @@
/*
* This call is designed to initiate the encoder state
*/
- xmlCharEncOutFunc(encoder, ret->conv, NULL);
+ xmlCharEncOutFunc(encoder, ret->conv, NULL);
} else
ret->conv = NULL;
ret->writecallback = NULL;
@@ -2344,7 +2519,7 @@
/*
* This call is designed to initiate the encoder state
*/
- xmlCharEncOutFunc(encoder, ret->conv, NULL);
+ xmlCharEncOutFunc(encoder, ret->conv, NULL);
} else
ret->conv = NULL;
ret->writecallback = NULL;
@@ -2469,6 +2644,9 @@
#ifdef HAVE_ZLIB_H
if ((xmlInputCallbackTable[i].opencallback == xmlGzfileOpen) &&
(strcmp(URI, "-") != 0)) {
+#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1230
+ ret->compressed = !gzdirect(context);
+#else
if (((z_stream *)context)->avail_in > 4) {
char *cptr, buff4[4];
cptr = (char *) ((z_stream *)context)->next_in;
@@ -2480,6 +2658,7 @@
gzrewind(context);
}
}
+#endif
}
#endif
}
@@ -2662,7 +2841,7 @@
/**
* xmlParserInputBufferCreateFile:
- * @file: a FILE*
+ * @file: a FILE*
* @enc: the charset encoding if known
*
* Create a buffered parser input for the progressive parsing of a FILE *
@@ -2692,7 +2871,7 @@
#ifdef LIBXML_OUTPUT_ENABLED
/**
* xmlOutputBufferCreateFile:
- * @file: a FILE*
+ * @file: a FILE*
* @encoder: the encoding converter or NULL
*
* Create a buffered output for the progressive saving to a FILE *
@@ -2856,7 +3035,7 @@
* @fd: a file descriptor number
* @encoder: the encoding converter or NULL
*
- * Create a buffered output for the progressive saving
+ * Create a buffered output for the progressive saving
* to a file descriptor
*
* Returns the new parser output or NULL
@@ -3138,7 +3317,7 @@
in->rawconsumed += (use - in->raw->use);
} else {
nbchars = len;
- in->buffer->use += nbchars;
+ in->buffer->use += nbchars;
buffer[nbchars] = 0;
}
#ifdef DEBUG_INPUT
@@ -3248,12 +3427,12 @@
* second write the stuff to the I/O channel
*/
if (out->encoder != NULL) {
- ret = out->writecallback(out->context,
+ ret = out->writecallback(out->context,
(const char *)out->conv->content, nbchars);
if (ret >= 0)
xmlBufferShrink(out->conv, ret);
} else {
- ret = out->writecallback(out->context,
+ ret = out->writecallback(out->context,
(const char *)out->buffer->content, nbchars);
if (ret >= 0)
xmlBufferShrink(out->buffer, ret);
@@ -3298,9 +3477,9 @@
const unsigned char* inend;
inend = in + (*inlen);
-
+
while ((in < inend) && (out < outend)) {
- if (*in == '<') {
+ if (*in == '<') {
if (outend - out < 4) break;
*out++ = '&';
*out++ = 'l';
@@ -3330,7 +3509,7 @@
*out++ = (unsigned char) *in;
}
++in;
- }
+ }
*outlen = out - outstart;
*inlen = in - base;
return(0);
@@ -3440,12 +3619,12 @@
* second write the stuff to the I/O channel
*/
if (out->encoder != NULL) {
- ret = out->writecallback(out->context,
+ ret = out->writecallback(out->context,
(const char *)out->conv->content, nbchars);
if (ret >= 0)
xmlBufferShrink(out->conv, ret);
} else {
- ret = out->writecallback(out->context,
+ ret = out->writecallback(out->context,
(const char *)out->buffer->content, nbchars);
if (ret >= 0)
xmlBufferShrink(out->buffer, ret);
@@ -3486,7 +3665,7 @@
int
xmlOutputBufferWriteString(xmlOutputBufferPtr out, const char *str) {
int len;
-
+
if ((out == NULL) || (out->error)) return(-1);
if (str == NULL)
return(-1);
@@ -3703,9 +3882,9 @@
#else
path = &URL[7];
#endif
- } else
+ } else
path = URL;
-
+
return xmlCheckFilename(path);
}
@@ -3893,9 +4072,9 @@
}
/************************************************************************
- * *
- * Disabling Network access *
- * *
+ * *
+ * Disabling Network access *
+ * *
************************************************************************/
/**
diff --git a/xmlcatalog.c b/xmlcatalog.c
index 6f193b1..489509f 100644
--- a/xmlcatalog.c
+++ b/xmlcatalog.c
@@ -124,7 +124,6 @@
free(cmdline);
continue;
}
- nbargs++;
/*
* Parse the argument string
@@ -138,8 +137,6 @@
arg[i++] = *cur++;
}
arg[i] = 0;
- if (i != 0)
- nbargs++;
/*
* Parse the arguments
diff --git a/xmllint.c b/xmllint.c
index 77c1e62..2acc7c5 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -108,15 +108,16 @@
typedef enum {
XMLLINT_RETURN_OK = 0, /* No error */
- XMLLINT_ERR_UNCLASS, /* Unclassified */
- XMLLINT_ERR_DTD, /* Error in DTD */
- XMLLINT_ERR_VALID, /* Validation error */
- XMLLINT_ERR_RDFILE, /* CtxtReadFile error */
- XMLLINT_ERR_SCHEMACOMP, /* Schema compilation */
- XMLLINT_ERR_OUT, /* Error writing output */
- XMLLINT_ERR_SCHEMAPAT, /* Error in schema pattern */
- XMLLINT_ERR_RDREGIS, /* Error in Reader registration */
- XMLLINT_ERR_MEM /* Out of memory error */
+ XMLLINT_ERR_UNCLASS = 1, /* Unclassified */
+ XMLLINT_ERR_DTD = 2, /* Error in DTD */
+ XMLLINT_ERR_VALID = 3, /* Validation error */
+ XMLLINT_ERR_RDFILE = 4, /* CtxtReadFile error */
+ XMLLINT_ERR_SCHEMACOMP = 5, /* Schema compilation */
+ XMLLINT_ERR_OUT = 6, /* Error writing output */
+ XMLLINT_ERR_SCHEMAPAT = 7, /* Error in schema pattern */
+ XMLLINT_ERR_RDREGIS = 8, /* Error in Reader registration */
+ XMLLINT_ERR_MEM = 9, /* Out of memory error */
+ XMLLINT_ERR_XPATH = 10 /* XPath evaluation error */
} xmllintReturnCode;
#ifdef LIBXML_DEBUG_ENABLED
static int shell = 0;
@@ -129,6 +130,7 @@
#endif /* LIBXML_TREE_ENABLED */
static int recovery = 0;
static int noent = 0;
+static int noenc = 0;
static int noblanks = 0;
static int noout = 0;
static int nowrap = 0;
@@ -161,6 +163,9 @@
static int xmlout = 0;
#endif
static int htmlout = 0;
+#if defined(LIBXML_HTML_ENABLED)
+static int nodefdtd = 0;
+#endif
#ifdef LIBXML_PUSH_ENABLED
static int push = 0;
#endif /* LIBXML_PUSH_ENABLED */
@@ -184,6 +189,7 @@
#endif
#ifdef LIBXML_C14N_ENABLED
static int canonical = 0;
+static int canonical_11 = 0;
static int exc_canonical = 0;
#endif
#ifdef LIBXML_READER_ENABLED
@@ -200,6 +206,9 @@
static xmlPatternPtr patternc = NULL;
static xmlStreamCtxtPtr patstream = NULL;
#endif
+#ifdef LIBXML_XPATH_ENABLED
+static const char *xpathquery = NULL;
+#endif
static int options = XML_PARSE_COMPACT;
static int sax = 0;
static int oldxml10 = 0;
@@ -247,7 +256,7 @@
static xmlExternalEntityLoader defaultEntityLoader = NULL;
-static xmlParserInputPtr
+static xmlParserInputPtr
xmllintExternalEntityLoader(const char *URL, const char *ID,
xmlParserCtxtPtr ctxt) {
xmlParserInputPtr ret;
@@ -305,10 +314,10 @@
ctxt->sax->error = err;
if (load_trace) {
fprintf \
- (stderr,
- "Loaded URL=\"%s\" ID=\"%s\"\n",
+ (stderr,
+ "Loaded URL=\"%s\" ID=\"%s\"\n",
newURL,
- ID ? ID : "(null)");
+ ID ? ID : "(null)");
}
xmlFree(newURL);
return(ret);
@@ -328,9 +337,9 @@
return(NULL);
}
/************************************************************************
- * *
+ * *
* Memory allocation consumption debugging *
- * *
+ * *
************************************************************************/
static void
@@ -391,13 +400,13 @@
return (ret);
}
/************************************************************************
- * *
+ * *
* Internal timing routines to remove the necessity to have *
* unix-specific function calls. *
- * *
+ * *
************************************************************************/
-#ifndef HAVE_GETTIMEOFDAY
+#ifndef HAVE_GETTIMEOFDAY
#ifdef HAVE_SYS_TIMEB_H
#ifdef HAVE_SYS_TIME_H
#ifdef HAVE_FTIME
@@ -523,9 +532,9 @@
}
#endif
/************************************************************************
- * *
- * HTML ouput *
- * *
+ * *
+ * HTML ouput *
+ * *
************************************************************************/
static char buffer[50000];
@@ -544,7 +553,7 @@
/**
* xmlHTMLPrintFileInfo:
* @input: an xmlParserInputPtr input
- *
+ *
* Displays the associated file and line informations for the current input
*/
@@ -568,7 +577,7 @@
/**
* xmlHTMLPrintFileContext:
* @input: an xmlParserInputPtr input
- *
+ *
* Displays current context within the input content for error tracking
*/
@@ -593,7 +602,7 @@
n = 0;
while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
len = strlen(buffer);
- snprintf(&buffer[len], sizeof(buffer) - len, "%c",
+ snprintf(&buffer[len], sizeof(buffer) - len, "%c",
(unsigned char) *cur++);
n++;
}
@@ -619,7 +628,7 @@
* @ctx: an XML parser context
* @msg: the message to display/transmit
* @...: extra parameters for the message display
- *
+ *
* Display and format an error messages, gives file, line, position and
* extra parameters.
*/
@@ -636,7 +645,7 @@
if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
input = ctxt->inputTab[ctxt->inputNr - 2];
}
-
+
xmlHTMLPrintFileInfo(input);
xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
@@ -656,7 +665,7 @@
* @ctx: 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.
*/
@@ -673,13 +682,13 @@
if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
input = ctxt->inputTab[ctxt->inputNr - 2];
}
-
+
xmlHTMLPrintFileInfo(input);
-
+
xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
va_start(args, msg);
- len = strlen(buffer);
+ len = strlen(buffer);
vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
va_end(args);
xmlHTMLEncodeSend();
@@ -694,7 +703,7 @@
* @ctx: an XML parser context
* @msg: the message to display/transmit
* @...: extra parameters for the message display
- *
+ *
* Display and format an validity error messages, gives file,
* line, position and extra parameters.
*/
@@ -710,7 +719,7 @@
input = ctxt->input;
if ((input->filename == NULL) && (ctxt->inputNr > 1))
input = ctxt->inputTab[ctxt->inputNr - 2];
-
+
xmlHTMLPrintFileInfo(input);
xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
@@ -731,7 +740,7 @@
* @ctx: an XML parser context
* @msg: the message to display/transmit
* @...: extra parameters for the message display
- *
+ *
* Display and format a validity warning messages, gives file, line,
* position and extra parameters.
*/
@@ -749,10 +758,10 @@
input = ctxt->inputTab[ctxt->inputNr - 2];
xmlHTMLPrintFileInfo(input);
-
+
xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
va_start(args, msg);
- len = strlen(buffer);
+ len = strlen(buffer);
vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
va_end(args);
xmlHTMLEncodeSend();
@@ -763,9 +772,9 @@
}
/************************************************************************
- * *
- * Shell Interface *
- * *
+ * *
+ * Shell Interface *
+ * *
************************************************************************/
#ifdef LIBXML_DEBUG_ENABLED
#ifdef LIBXML_XPATH_ENABLED
@@ -774,7 +783,7 @@
* @prompt: the prompt value
*
* Read a string
- *
+ *
* Returns a pointer to it or NULL on EOF the caller is expected to
* free the returned string.
*/
@@ -813,9 +822,9 @@
#endif /* LIBXML_DEBUG_ENABLED */
/************************************************************************
- * *
- * I/O Interfaces *
- * *
+ * *
+ * I/O Interfaces *
+ * *
************************************************************************/
static int myRead(FILE *f, char * buf, int len) {
@@ -829,7 +838,7 @@
/************************************************************************
* *
- * SAX based tests *
+ * SAX based tests *
* *
************************************************************************/
@@ -999,7 +1008,7 @@
return(NULL);
/* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
-
+
fprintf(stdout, "SAX.resolveEntity(");
if (publicId != NULL)
fprintf(stdout, "%s", (char *)publicId);
@@ -1054,8 +1063,8 @@
/**
* entityDeclDebug:
* @ctxt: An XML parser context
- * @name: the entity name
- * @type: the entity type
+ * @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).
@@ -1084,8 +1093,8 @@
/**
* attributeDeclDebug:
* @ctxt: An XML parser context
- * @name: the attribute name
- * @type: the attribute type
+ * @name: the attribute name
+ * @type: the attribute type
*
* An attribute definition has been parsed
*/
@@ -1109,8 +1118,8 @@
/**
* elementDeclDebug:
* @ctxt: An XML parser context
- * @name: the element name
- * @type: the element type
+ * @name: the element name
+ * @type: the element type
* @content: the element value (without processing).
*
* An element definition has been parsed
@@ -1296,7 +1305,7 @@
* @ctxt: An XML parser context
* @name: The entity name
*
- * called when an entity reference is detected.
+ * called when an entity reference is detected.
*/
static void
referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
@@ -1532,7 +1541,7 @@
else
fprintf(stdout, ", '%s'", (char *) URI);
fprintf(stdout, ", %d", nb_namespaces);
-
+
if (namespaces != NULL) {
for (i = 0;i < nb_namespaces * 2;i++) {
fprintf(stdout, ", xmlns");
@@ -1695,7 +1704,7 @@
goto error;
}
inputPush(ctxt, inputStream);
-
+
/* do the parsing */
xmlParseDocument(ctxt);
@@ -1714,9 +1723,9 @@
}
/************************************************************************
- * *
- * Stream Test processing *
- * *
+ * *
+ * Stream Test processing *
+ * *
************************************************************************/
#ifdef LIBXML_READER_ENABLED
static void processNode(xmlTextReaderPtr reader) {
@@ -1733,8 +1742,8 @@
value = xmlTextReaderConstValue(reader);
-
- printf("%d %d %s %d %d",
+
+ printf("%d %d %s %d %d",
xmlTextReaderDepth(reader),
type,
name,
@@ -1750,14 +1759,19 @@
if (patternc) {
xmlChar *path = NULL;
int match = -1;
-
+
if (type == XML_READER_TYPE_ELEMENT) {
/* do the check only on element start */
match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
if (match) {
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
printf("Node %s matches pattern %s\n", path, pattern);
+#else
+ printf("Node %s matches pattern %s\n",
+ xmlTextReaderConstName(reader), pattern);
+#endif
}
}
if (patstream != NULL) {
@@ -1772,19 +1786,23 @@
xmlFreeStreamCtxt(patstream);
patstream = NULL;
} else if (ret != match) {
+#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
if (path == NULL) {
path = xmlGetNodePath(
xmlTextReaderCurrentNode(reader));
}
+#endif
fprintf(stderr,
"xmlPatternMatch and xmlStreamPush disagree\n");
- fprintf(stderr,
- " pattern %s node %s\n",
- pattern, path);
+ if (path != NULL)
+ fprintf(stderr, " pattern %s node %s\n",
+ pattern, path);
+ else
+ fprintf(stderr, " pattern %s node %s\n",
+ pattern, xmlTextReaderConstName(reader));
}
-
- }
+ }
if ((type == XML_READER_TYPE_END_ELEMENT) ||
((type == XML_READER_TYPE_ELEMENT) && (empty))) {
ret = xmlStreamPop(patstream);
@@ -1811,7 +1829,7 @@
xmlParserInputBufferPtr input = NULL;
if (memory) {
- if (stat(filename, &info) < 0)
+ if (stat(filename, &info) < 0)
return;
if ((fd = open(filename, O_RDONLY)) < 0)
return;
@@ -1980,7 +1998,7 @@
namespaces[i++] = ns->prefix;
}
namespaces[i++] = NULL;
- namespaces[i++] = NULL;
+ namespaces[i] = NULL;
if (pattern != NULL) {
patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
@@ -2040,10 +2058,104 @@
}
#endif /* LIBXML_READER_ENABLED */
+#ifdef LIBXML_XPATH_ENABLED
/************************************************************************
- * *
- * Tree Test processing *
- * *
+ * *
+ * XPath Query *
+ * *
+ ************************************************************************/
+
+static void doXPathDump(xmlXPathObjectPtr cur) {
+ switch(cur->type) {
+ case XPATH_NODESET: {
+ int i;
+ xmlNodePtr node;
+#ifdef LIBXML_OUTPUT_ENABLED
+ xmlSaveCtxtPtr ctxt;
+
+ if (cur->nodesetval->nodeNr <= 0) {
+ fprintf(stderr, "XPath set is empty\n");
+ progresult = XMLLINT_ERR_XPATH;
+ break;
+ }
+ ctxt = xmlSaveToFd(1, NULL, 0);
+ if (ctxt == NULL) {
+ fprintf(stderr, "Out of memory for XPath\n");
+ progresult = XMLLINT_ERR_MEM;
+ return;
+ }
+ for (i = 0;i < cur->nodesetval->nodeNr;i++) {
+ node = cur->nodesetval->nodeTab[i];
+ xmlSaveTree(ctxt, node);
+ }
+ xmlSaveClose(ctxt);
+#else
+ printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
+#endif
+ break;
+ }
+ case XPATH_BOOLEAN:
+ if (cur->boolval) printf("true");
+ else printf("false");
+ break;
+ case XPATH_NUMBER:
+ switch (xmlXPathIsInf(cur->floatval)) {
+ case 1:
+ printf("Infinity");
+ break;
+ case -1:
+ printf("-Infinity");
+ break;
+ default:
+ if (xmlXPathIsNaN(cur->floatval)) {
+ printf("NaN");
+ } else {
+ printf("%0g", cur->floatval);
+ }
+ }
+ break;
+ case XPATH_STRING:
+ printf("%s", (const char *) cur->stringval);
+ break;
+ case XPATH_UNDEFINED:
+ fprintf(stderr, "XPath Object is uninitialized\n");
+ progresult = XMLLINT_ERR_XPATH;
+ break;
+ default:
+ fprintf(stderr, "XPath object of unexpected type\n");
+ progresult = XMLLINT_ERR_XPATH;
+ break;
+ }
+}
+
+static void doXPathQuery(xmlDocPtr doc, const char *query) {
+ xmlXPathContextPtr ctxt;
+ xmlXPathObjectPtr res;
+
+ ctxt = xmlXPathNewContext(doc);
+ if (ctxt == NULL) {
+ fprintf(stderr, "Out of memory for XPath\n");
+ progresult = XMLLINT_ERR_MEM;
+ return;
+ }
+ ctxt->node = xmlDocGetRootElement(doc);
+ res = xmlXPathEval(BAD_CAST query, ctxt);
+ xmlXPathFreeContext(ctxt);
+
+ if (res == NULL) {
+ fprintf(stderr, "XPath evaluation failure\n");
+ progresult = XMLLINT_ERR_XPATH;
+ return;
+ }
+ doXPathDump(res);
+ xmlXPathFreeObject(res);
+}
+#endif /* LIBXML_XPATH_ENABLED */
+
+/************************************************************************
+ * *
+ * Tree Test processing *
+ * *
************************************************************************/
static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
xmlDocPtr doc = NULL;
@@ -2053,7 +2165,7 @@
if ((timing) && (!repeat))
startTimer();
-
+
#ifdef LIBXML_TREE_ENABLED
if (filename == NULL) {
@@ -2104,7 +2216,7 @@
int fd;
struct stat info;
const char *base;
- if (stat(filename, &info) < 0)
+ if (stat(filename, &info) < 0)
return;
if ((fd = open(filename, O_RDONLY)) < 0)
return;
@@ -2114,7 +2226,7 @@
doc = htmlReadMemory((char *) base, info.st_size, filename,
NULL, options);
-
+
munmap((char *) base, info.st_size);
close(fd);
}
@@ -2165,6 +2277,8 @@
doc = NULL;
}
}
+ if (f != stdin)
+ fclose(f);
}
} else
#endif /* LIBXML_PUSH_ENABLED */
@@ -2199,7 +2313,7 @@
ctxt = xmlNewParserCtxt();
else
ctxt = rectxt;
- if (ctxt == NULL) {
+ if (ctxt == NULL) {
doc = NULL;
} else {
ctxt->sax->error = xmlHTMLError;
@@ -2217,7 +2331,7 @@
int fd;
struct stat info;
const char *base;
- if (stat(filename, &info) < 0)
+ if (stat(filename, &info) < 0)
return;
if ((fd = open(filename, O_RDONLY)) < 0)
return;
@@ -2231,7 +2345,7 @@
else
doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
filename, NULL, options);
-
+
munmap((char *) base, info.st_size);
close(fd);
#endif
@@ -2243,7 +2357,7 @@
ctxt = xmlNewParserCtxt();
else
ctxt = rectxt;
- if (ctxt == NULL) {
+ if (ctxt == NULL) {
doc = NULL;
} else {
doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
@@ -2306,6 +2420,12 @@
}
#endif
+#ifdef LIBXML_XPATH_ENABLED
+ if (xpathquery != NULL) {
+ doXPathQuery(doc, xpathquery);
+ }
+#endif
+
#ifdef LIBXML_DEBUG_ENABLED
#ifdef LIBXML_XPATH_ENABLED
/*
@@ -2364,7 +2484,7 @@
}
}
}
- }
+ }
}else
#endif /* LIBXML_VALID_ENABLED */
#ifdef LIBXML_READER_ENABLED
@@ -2391,14 +2511,14 @@
htmlSaveFile(output ? output : "-", doc);
}
else if (encoding != NULL) {
- if ( format ) {
+ if (format == 1) {
htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
}
else {
htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
}
}
- else if (format) {
+ else if (format == 1) {
htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
}
else {
@@ -2429,9 +2549,25 @@
xmlChar *result = NULL;
int size;
- size = xmlC14NDocDumpMemory(doc, NULL, 0, NULL, 1, &result);
+ size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
if (size >= 0) {
- write(1, result, size);
+ if (write(1, result, size) == -1) {
+ fprintf(stderr, "Can't write data\n");
+ }
+ xmlFree(result);
+ } else {
+ fprintf(stderr, "Failed to canonicalize\n");
+ progresult = XMLLINT_ERR_OUT;
+ }
+ } else if (canonical) {
+ xmlChar *result = NULL;
+ int size;
+
+ size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
+ if (size >= 0) {
+ if (write(1, result, size) == -1) {
+ fprintf(stderr, "Can't write data\n");
+ }
xmlFree(result);
} else {
fprintf(stderr, "Failed to canonicalize\n");
@@ -2442,9 +2578,11 @@
xmlChar *result = NULL;
int size;
- size = xmlC14NDocDumpMemory(doc, NULL, 1, NULL, 1, &result);
+ size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
if (size >= 0) {
- write(1, result, size);
+ if (write(1, result, size) == -1) {
+ fprintf(stderr, "Can't write data\n");
+ }
xmlFree(result);
} else {
fprintf(stderr, "Failed to canonicalize\n");
@@ -2458,13 +2596,13 @@
int len;
if (encoding != NULL) {
- if ( format ) {
+ if (format == 1) {
xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
- } else {
+ } else {
xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
}
} else {
- if (format)
+ if (format == 1)
xmlDocDumpFormatMemory(doc, &result, &len, 1);
else
xmlDocDumpMemory(doc, &result, &len);
@@ -2473,7 +2611,9 @@
fprintf(stderr, "Failed to save\n");
progresult = XMLLINT_ERR_OUT;
} else {
- write(1, result, len);
+ if (write(1, result, len) == -1) {
+ fprintf(stderr, "Can't write data\n");
+ }
xmlFree(result);
}
@@ -2483,7 +2623,7 @@
xmlSaveFile(output ? output : "-", doc);
} else if (oldout) {
if (encoding != NULL) {
- if ( format ) {
+ if (format == 1) {
ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
encoding, 1);
}
@@ -2496,7 +2636,7 @@
output ? output : "-");
progresult = XMLLINT_ERR_OUT;
}
- } else if (format) {
+ } else if (format == 1) {
ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
if (ret < 0) {
fprintf(stderr, "failed save to %s\n",
@@ -2525,8 +2665,15 @@
xmlSaveCtxtPtr ctxt;
int saveOpts = 0;
- if (format)
+ if (format == 1)
saveOpts |= XML_SAVE_FORMAT;
+ else if (format == 2)
+ saveOpts |= XML_SAVE_WSNONSIG;
+
+#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
+ if (xmlout)
+ saveOpts |= XML_SAVE_AS_XML;
+#endif
if (output == NULL)
ctxt = xmlSaveToFd(1, encoding, saveOpts);
@@ -2580,9 +2727,9 @@
startTimer();
}
if (dtdvalid != NULL)
- dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
+ dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
else
- dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
+ dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
if ((timing) && (!repeat)) {
endTimer("Parsing DTD");
}
@@ -2772,9 +2919,9 @@
}
/************************************************************************
- * *
- * Usage and Main *
- * *
+ * *
+ * Usage and Main *
+ * *
************************************************************************/
static void showVersion(const char *name) {
@@ -2788,29 +2935,30 @@
if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
- if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
- if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
+ if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
+ if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
- if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
- if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
- if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
- if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
- if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
- 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_ISO8859X)) fprintf(stderr, "ISO8859X ");
- if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
- if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
- if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
- if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
- if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
- if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
- if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
- if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
- if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
- if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
+ if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
+ if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
+ if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
+ if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
+ if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
+ 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_ISO8859X)) fprintf(stderr, "ISO8859X ");
+ if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
+ if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
+ if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
+ if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
+ if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
+ if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
+ if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
+ if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
+ if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
+ if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
+ if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma ");
fprintf(stderr, "\n");
}
@@ -2837,6 +2985,7 @@
printf("\t--recover : output what was parsable on broken XML documents\n");
printf("\t--huge : remove any internal arbitrary parser limits\n");
printf("\t--noent : substitute entity references by their value\n");
+ 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");
@@ -2862,6 +3011,7 @@
#ifdef LIBXML_HTML_ENABLED
printf("\t--html : use the HTML parser\n");
printf("\t--xmlout : force to use the XML serializer when using --html\n");
+ printf("\t--nodefdtd : do not default HTML doctype\n");
#endif
#ifdef LIBXML_PUSH_ENABLED
printf("\t--push : use the push mode of the parser\n");
@@ -2877,8 +3027,13 @@
printf("\t--format : reformat/reindent the input\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");
+ printf("\t 0 Do not pretty print\n");
+ printf("\t 1 Format the XML content, as --format\n");
+ printf("\t 2 Add whitespace inside tags, preserving content\n");
#endif /* LIBXML_OUTPUT_ENABLED */
- printf("\t--c14n : save in W3C canonical format (with comments)\n");
+ printf("\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
+ printf("\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
#ifdef LIBXML_C14N_ENABLED
#endif /* LIBXML_C14N_ENABLED */
@@ -2918,6 +3073,9 @@
#endif
printf("\t--sax: do not build a tree but work just at the SAX level\n");
printf("\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
+#ifdef LIBXML_XPATH_ENABLED
+ printf("\t--xpath expr: evaluate the XPath expression, inply --noout\n");
+#endif
printf("\nLibxml project home page: http://xmlsoft.org/\n");
printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
@@ -2944,7 +3102,7 @@
int files = 0;
int version = 0;
const char* indent;
-
+
if (argc <= 1) {
usage(argv[0]);
return(1);
@@ -2964,7 +3122,7 @@
(!strcmp(argv[i], "--shell"))) {
shell++;
noout = 1;
- } else
+ } else
#endif
#ifdef LIBXML_TREE_ENABLED
if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
@@ -2982,6 +3140,10 @@
(!strcmp(argv[i], "--noent"))) {
noent++;
options |= XML_PARSE_NOENT;
+ } else if ((!strcmp(argv[i], "-noenc")) ||
+ (!strcmp(argv[i], "--noenc"))) {
+ noenc++;
+ options |= XML_PARSE_IGNORE_ENC;
} else if ((!strcmp(argv[i], "-nsclean")) ||
(!strcmp(argv[i], "--nsclean"))) {
options |= XML_PARSE_NSCLEAN;
@@ -3020,6 +3182,10 @@
else if ((!strcmp(argv[i], "-xmlout")) ||
(!strcmp(argv[i], "--xmlout"))) {
xmlout++;
+ } else if ((!strcmp(argv[i], "-nodefdtd")) ||
+ (!strcmp(argv[i], "--nodefdtd"))) {
+ nodefdtd++;
+ options |= HTML_PARSE_NODEFDTD;
}
#endif /* LIBXML_HTML_ENABLED */
else if ((!strcmp(argv[i], "-loaddtd")) ||
@@ -3133,19 +3299,24 @@
(!strcmp(argv[i], "--debugent"))) {
debugent++;
xmlParserDebugEntities = 1;
- }
+ }
#endif
#ifdef LIBXML_C14N_ENABLED
else if ((!strcmp(argv[i], "-c14n")) ||
(!strcmp(argv[i], "--c14n"))) {
canonical++;
options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
- }
+ }
+ else if ((!strcmp(argv[i], "-c14n11")) ||
+ (!strcmp(argv[i], "--c14n11"))) {
+ canonical_11++;
+ options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
+ }
else if ((!strcmp(argv[i], "-exc-c14n")) ||
(!strcmp(argv[i], "--exc-c14n"))) {
exc_canonical++;
options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
- }
+ }
#endif
#ifdef LIBXML_CATALOG_ENABLED
else if ((!strcmp(argv[i], "-catalogs")) ||
@@ -3154,7 +3325,7 @@
} else if ((!strcmp(argv[i], "-nocatalogs")) ||
(!strcmp(argv[i], "--nocatalogs"))) {
nocatalogs++;
- }
+ }
#endif
else if ((!strcmp(argv[i], "-encode")) ||
(!strcmp(argv[i], "--encode"))) {
@@ -3184,10 +3355,21 @@
(!strcmp(argv[i], "--format"))) {
noblanks++;
#ifdef LIBXML_OUTPUT_ENABLED
- format++;
+ format = 1;
#endif /* LIBXML_OUTPUT_ENABLED */
xmlKeepBlanksDefault(0);
}
+ else if ((!strcmp(argv[i], "-pretty")) ||
+ (!strcmp(argv[i], "--pretty"))) {
+ i++;
+#ifdef LIBXML_OUTPUT_ENABLED
+ format = atoi(argv[i]);
+#endif /* LIBXML_OUTPUT_ENABLED */
+ if (format == 1) {
+ noblanks++;
+ xmlKeepBlanksDefault(0);
+ }
+ }
#ifdef LIBXML_READER_ENABLED
else if ((!strcmp(argv[i], "-stream")) ||
(!strcmp(argv[i], "--stream"))) {
@@ -3202,16 +3384,17 @@
#ifdef LIBXML_SAX1_ENABLED
else if ((!strcmp(argv[i], "-sax1")) ||
(!strcmp(argv[i], "--sax1"))) {
- sax1++;
+ sax1++;
+ options |= XML_PARSE_SAX1;
}
#endif /* LIBXML_SAX1_ENABLED */
else if ((!strcmp(argv[i], "-sax")) ||
(!strcmp(argv[i], "--sax"))) {
- sax++;
+ sax++;
}
else if ((!strcmp(argv[i], "-chkregister")) ||
(!strcmp(argv[i], "--chkregister"))) {
- chkregister++;
+ chkregister++;
#ifdef LIBXML_SCHEMAS_ENABLED
} else if ((!strcmp(argv[i], "-relaxng")) ||
(!strcmp(argv[i], "--relaxng"))) {
@@ -3252,6 +3435,13 @@
i++;
pattern = argv[i];
#endif
+#ifdef LIBXML_XPATH_ENABLED
+ } else if ((!strcmp(argv[i], "-xpath")) ||
+ (!strcmp(argv[i], "--xpath"))) {
+ i++;
+ noout++;
+ xpathquery = argv[i];
+#endif
} else if ((!strcmp(argv[i], "-oldxml10")) ||
(!strcmp(argv[i], "--oldxml10"))) {
oldxml10++;
@@ -3289,12 +3479,12 @@
xmlRegisterNodeDefault(registerNode);
xmlDeregisterNodeDefault(deregisterNode);
}
-
+
indent = getenv("XMLLINT_INDENT");
if(indent != NULL) {
xmlTreeIndentString = indent;
}
-
+
defaultEntityLoader = xmlGetExternalEntityLoader();
xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
@@ -3316,7 +3506,7 @@
xmlGenericError(xmlGenericErrorContext,
"<html><head><title>%s output</title></head>\n",
argv[0]);
- xmlGenericError(xmlGenericErrorContext,
+ xmlGenericError(xmlGenericErrorContext,
"<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
argv[0]);
}
@@ -3330,7 +3520,7 @@
xmlSchematronParserCtxtPtr ctxt;
/* forces loading the DTDs */
- xmlLoadExtDtdDefaultValue |= 1;
+ xmlLoadExtDtdDefaultValue |= 1;
options |= XML_PARSE_DTDLOAD;
if (timing) {
startTimer();
@@ -3364,7 +3554,7 @@
xmlRelaxNGParserCtxtPtr ctxt;
/* forces loading the DTDs */
- xmlLoadExtDtdDefaultValue |= 1;
+ xmlLoadExtDtdDefaultValue |= 1;
options |= XML_PARSE_DTDLOAD;
if (timing) {
startTimer();
@@ -3444,7 +3634,7 @@
(!strcmp(argv[i], "--dtdvalid"))) {
i++;
continue;
- }
+ }
if ((!strcmp(argv[i], "-path")) ||
(!strcmp(argv[i], "--path"))) {
i++;
@@ -3466,6 +3656,11 @@
i++;
continue;
}
+ if ((!strcmp(argv[i], "-pretty")) ||
+ (!strcmp(argv[i], "--pretty"))) {
+ i++;
+ continue;
+ }
if ((!strcmp(argv[i], "-schema")) ||
(!strcmp(argv[i], "--schema"))) {
i++;
@@ -3483,6 +3678,13 @@
continue;
}
#endif
+#ifdef LIBXML_XPATH_ENABLED
+ if ((!strcmp(argv[i], "-xpath")) ||
+ (!strcmp(argv[i], "--xpath"))) {
+ i++;
+ continue;
+ }
+#endif
if ((timing) && (repeat))
startTimer();
/* Remember file names. "-" means stdin. <sven@zen.org> */
@@ -3534,7 +3736,7 @@
}
}
}
- if (generate)
+ if (generate)
parseAndPrintFile(NULL, NULL);
if ((htmlout) && (!nowrap)) {
xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
diff --git a/xmlmemory.c b/xmlmemory.c
index 433abb8..a0ab953 100644
--- a/xmlmemory.c
+++ b/xmlmemory.c
@@ -205,7 +205,8 @@
if (xmlMemTraceBlockAt == ret) {
xmlGenericError(xmlGenericErrorContext,
- "%p : Malloc(%ld) Ok\n", xmlMemTraceBlockAt, size);
+ "%p : Malloc(%lu) Ok\n", xmlMemTraceBlockAt,
+ (long unsigned)size);
xmlMallocBreakpoint();
}
@@ -273,7 +274,8 @@
if (xmlMemTraceBlockAt == ret) {
xmlGenericError(xmlGenericErrorContext,
- "%p : Malloc(%ld) Ok\n", xmlMemTraceBlockAt, size);
+ "%p : Malloc(%lu) Ok\n", xmlMemTraceBlockAt,
+ (long unsigned)size);
xmlMallocBreakpoint();
}
@@ -348,8 +350,9 @@
}
if (xmlMemTraceBlockAt == ptr) {
xmlGenericError(xmlGenericErrorContext,
- "%p : Realloced(%ld -> %ld) Ok\n",
- xmlMemTraceBlockAt, p->mh_size, size);
+ "%p : Realloced(%lu -> %lu) Ok\n",
+ xmlMemTraceBlockAt, (long unsigned)p->mh_size,
+ (long unsigned)size);
xmlMallocBreakpoint();
}
p->mh_tag = MEMTAG;
diff --git a/xmlreader.c b/xmlreader.c
index d42b1a0..97c71ab 100644
--- a/xmlreader.c
+++ b/xmlreader.c
@@ -1,7 +1,7 @@
/*
* xmlreader.c: implements the xmlTextReader streaming node API
*
- * NOTE:
+ * NOTE:
* XmlTextReader.Normalization Property won't be supported, since
* it makes the parser non compliant to the XML recommendation
*
@@ -73,7 +73,7 @@
*
* macro to flag unimplemented blocks
*/
-#define TODO \
+#define TODO \
xmlGenericError(xmlGenericErrorContext, \
"Unimplemented block at %s:%d\n", \
__FILE__, __LINE__);
@@ -128,8 +128,8 @@
endElementNsSAX2Func endElementNs; /* idem */
charactersSAXFunc characters;
cdataBlockSAXFunc cdataBlock;
- unsigned int base; /* base of the segment in the input */
- unsigned int cur; /* current position in the input */
+ unsigned int base; /* base of the segment in the input */
+ unsigned int cur; /* current position in the input */
xmlNodePtr node; /* current node */
xmlNodePtr curnode;/* current attribute node */
int depth; /* depth of the current node */
@@ -207,7 +207,7 @@
* current scope
*/
#define DICT_FREE(str) \
- if ((str) && ((!dict) || \
+ if ((str) && ((!dict) || \
(xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
xmlFree((char *)(str));
@@ -252,7 +252,7 @@
if (doc == NULL) return(-1);
if (attr == NULL) return(-1);
table = (xmlIDTablePtr) doc->ids;
- if (table == NULL)
+ if (table == NULL)
return(-1);
ID = xmlNodeListGetString(doc, attr->children, 1);
@@ -842,7 +842,7 @@
break;
}
- } else
+ } else
break;
}
/*
@@ -891,7 +891,7 @@
if (reader->state != XML_TEXTREADER_DONE) {
s = inbuf->use - reader->cur;
val = xmlParseChunk(reader->ctxt,
- (const char *) &inbuf->content[reader->cur],
+ (const char *) &inbuf->content[reader->cur],
s, 1);
reader->cur = inbuf->use;
reader->state = XML_TEXTREADER_DONE;
@@ -1031,7 +1031,7 @@
int ret;
if (reader->rngFullNode != NULL) {
- if (node == reader->rngFullNode)
+ if (node == reader->rngFullNode)
reader->rngFullNode = NULL;
return;
}
@@ -1066,7 +1066,7 @@
*/
if ((node->children == NULL) && (ctxt->sax != NULL) &&
(ctxt->sax->getEntity != NULL)) {
- node->children = (xmlNodePtr)
+ node->children = (xmlNodePtr)
ctxt->sax->getEntity(ctxt, node->name);
}
@@ -1256,7 +1256,7 @@
xmlTextReaderState oldstate = XML_TEXTREADER_START;
xmlNodePtr oldnode = NULL;
-
+
if (reader == NULL)
return(-1);
reader->curnode = NULL;
@@ -1436,7 +1436,7 @@
/*
* Cleanup of the old node
*/
- if ((reader->preserves == 0) &&
+ if ((oldnode != NULL) && (reader->preserves == 0) &&
#ifdef LIBXML_XINCLUDE_ENABLED
(reader->in_xinclude == 0) &&
#endif
@@ -1489,7 +1489,7 @@
(xmlStrEqual(reader->node->ns->href, XINCLUDE_OLD_NS)))) {
if (reader->xincctxt == NULL) {
reader->xincctxt = xmlXIncludeNewContext(reader->ctxt->myDoc);
- xmlXIncludeSetFlags(reader->xincctxt,
+ xmlXIncludeSetFlags(reader->xincctxt,
reader->parserFlags & (~XML_PARSE_NOXINCNODE));
}
/*
@@ -1502,7 +1502,7 @@
if ((reader->node != NULL) && (reader->node->type == XML_XINCLUDE_START)) {
reader->in_xinclude++;
goto get_next_node;
- }
+ }
if ((reader->node != NULL) && (reader->node->type == XML_XINCLUDE_END)) {
reader->in_xinclude--;
goto get_next_node;
@@ -1520,7 +1520,7 @@
*/
if ((reader->node->children == NULL) && (reader->ctxt->sax != NULL) &&
(reader->ctxt->sax->getEntity != NULL)) {
- reader->node->children = (xmlNodePtr)
+ reader->node->children = (xmlNodePtr)
reader->ctxt->sax->getEntity(reader->ctxt, reader->node->name);
}
@@ -1548,7 +1548,7 @@
if ((reader->validate) && (reader->node != NULL)) {
xmlNodePtr node = reader->node;
- if ((node->type == XML_ELEMENT_NODE) &&
+ if ((node->type == XML_ELEMENT_NODE) &&
((reader->state != XML_TEXTREADER_END) &&
(reader->state != XML_TEXTREADER_BACKTRACK))) {
xmlTextReaderValidatePush(reader);
@@ -1573,7 +1573,7 @@
#endif /* LIBXML_PATTERN_ENABLED */
#ifdef LIBXML_SCHEMAS_ENABLED
if ((reader->validate == XML_TEXTREADER_VALIDATE_XSD) &&
- (reader->xsdValidErrors == 0) &&
+ (reader->xsdValidErrors == 0) &&
(reader->xsdValidCtxt != NULL)) {
reader->xsdValidErrors = !xmlSchemaIsValid(reader->xsdValidCtxt);
}
@@ -1664,7 +1664,7 @@
* Reads the contents of the current node, including child nodes and markup.
*
* Returns a string containing the XML content, or NULL if the current node
- * is neither an element nor attribute, or has no child nodes. The
+ * is neither an element nor attribute, or has no child nodes. The
* string must be deallocated by the caller.
*/
xmlChar *
@@ -1709,9 +1709,9 @@
*
* Reads the contents of the current node, including child nodes and markup.
*
- * Returns a string containing the XML content, or NULL if the current node
- * is neither an element nor attribute, or has no child nodes. The
- * string must be deallocated by the caller.
+ * Returns a string containing the node and any XML content, or NULL if the
+ * current node cannot be serialized. The string must be deallocated
+ * by the caller.
*/
xmlChar *
xmlTextReaderReadOuterXml(xmlTextReaderPtr reader ATTRIBUTE_UNUSED)
@@ -1726,7 +1726,11 @@
if (xmlTextReaderExpand(reader) == NULL) {
return NULL;
}
- node = xmlDocCopyNode(node, doc, 1);
+ if (node->type == XML_DTD_NODE) {
+ node = (xmlNodePtr) xmlCopyDtd((xmlDtdPtr) node);
+ } else {
+ node = xmlDocCopyNode(node, doc, 1);
+ }
buff = xmlBufferCreate();
if (xmlNodeDump(buff, doc, node, 0, 0) == -1) {
xmlFreeNode(node);
@@ -2106,7 +2110,7 @@
ret->base = 0;
ret->cur = 0;
}
-
+
if (ret->ctxt == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlNewTextReader : malloc failed\n");
@@ -2214,6 +2218,9 @@
xmlFree(reader->patternTab);
}
#endif
+ if (reader->faketext != NULL) {
+ xmlFreeNode(reader->faketext);
+ }
if (reader->ctxt != NULL) {
if (reader->dict == reader->ctxt->dict)
reader->dict = NULL;
@@ -2235,9 +2242,6 @@
xmlFree(reader->sax);
if ((reader->input != NULL) && (reader->allocs & XML_TEXTREADER_INPUT))
xmlFreeParserInputBuffer(reader->input);
- if (reader->faketext != NULL) {
- xmlFreeNode(reader->faketext);
- }
if (reader->buffer != NULL)
xmlBufferFree(reader->buffer);
if (reader->entTab != NULL)
@@ -2308,7 +2312,7 @@
if (reader->curnode != NULL)
return(NULL);
/* TODO: handle the xmlDecl */
- if (reader->node->type != XML_ELEMENT_NODE)
+ if (reader->node->type != XML_ELEMENT_NODE)
return(NULL);
ns = reader->node->nsDef;
@@ -2438,7 +2442,7 @@
}
ns = reader->node->nsDef;
while (ns != NULL) {
- if ((prefix == NULL && ns->prefix == NULL) ||
+ if ((prefix == NULL && ns->prefix == NULL) ||
((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) {
return xmlStrdup(ns->href);
}
@@ -2550,7 +2554,7 @@
if (reader->node == NULL)
return(-1);
/* TODO: handle the xmlDecl */
- if (reader->node->type != XML_ELEMENT_NODE)
+ if (reader->node->type != XML_ELEMENT_NODE)
return(-1);
reader->curnode = NULL;
@@ -2637,7 +2641,7 @@
}
return(0);
}
-
+
/*
* Namespace default decl
*/
@@ -2714,7 +2718,7 @@
}
ns = reader->node->nsDef;
while (ns != NULL) {
- if ((prefix == NULL && ns->prefix == NULL) ||
+ if ((prefix == NULL && ns->prefix == NULL) ||
((ns->prefix != NULL) && (xmlStrEqual(ns->prefix, localName)))) {
reader->curnode = (xmlNodePtr) ns;
return(1);
@@ -2860,7 +2864,7 @@
xmlNsPtr ns = (xmlNsPtr) reader->curnode;
if (reader->faketext == NULL) {
- reader->faketext = xmlNewDocText(reader->node->doc,
+ reader->faketext = xmlNewDocText(reader->node->doc,
ns->href);
} else {
if ((reader->faketext->content != NULL) &&
@@ -2898,7 +2902,7 @@
doc = reader->ctxt->myDoc;
if (doc == NULL)
return(NULL);
-
+
if (doc->encoding == NULL)
return(NULL);
else
@@ -2930,7 +2934,7 @@
return(-1);
if (reader->node == NULL)
return(0);
-
+
if (reader->curnode != NULL)
node = reader->curnode;
else
@@ -2968,7 +2972,7 @@
int
xmlTextReaderNodeType(xmlTextReaderPtr reader) {
xmlNodePtr node;
-
+
if (reader == NULL)
return(-1);
if (reader->node == NULL)
@@ -3064,7 +3068,8 @@
*
* The local name of the node.
*
- * Returns the local name or NULL if not available
+ * Returns the local name or NULL if not available,
+ * if non NULL it need to be freed by the caller.
*/
xmlChar *
xmlTextReaderLocalName(xmlTextReaderPtr reader) {
@@ -3125,7 +3130,8 @@
*
* The qualified name of the node, equal to Prefix :LocalName.
*
- * Returns the local name or NULL if not available
+ * Returns the local name or NULL if not available,
+ * if non NULL it need to be freed by the caller.
*/
xmlChar *
xmlTextReaderName(xmlTextReaderPtr reader) {
@@ -3144,7 +3150,7 @@
if ((node->ns == NULL) ||
(node->ns->prefix == NULL))
return(xmlStrdup(node->name));
-
+
ret = xmlStrdup(node->ns->prefix);
ret = xmlStrcat(ret, BAD_CAST ":");
ret = xmlStrcat(ret, node->name);
@@ -3268,7 +3274,8 @@
*
* A shorthand reference to the namespace associated with the node.
*
- * Returns the prefix or NULL if not available
+ * Returns the prefix or NULL if not available,
+ * if non NULL it need to be freed by the caller.
*/
xmlChar *
xmlTextReaderPrefix(xmlTextReaderPtr reader) {
@@ -3331,7 +3338,8 @@
*
* The URI defining the namespace associated with the node.
*
- * Returns the namespace URI or NULL if not available
+ * Returns the namespace URI or NULL if not available,
+ * if non NULL it need to be freed by the caller.
*/
xmlChar *
xmlTextReaderNamespaceUri(xmlTextReaderPtr reader) {
@@ -3386,7 +3394,8 @@
*
* The base URI of the node.
*
- * Returns the base URI or NULL if not available
+ * Returns the base URI or NULL if not available,
+ * if non NULL it need to be freed by the caller.
*/
xmlChar *
xmlTextReaderBaseUri(xmlTextReaderPtr reader) {
@@ -3644,7 +3653,8 @@
*
* The xml:lang scope within which the node resides.
*
- * Returns the xml:lang value or NULL if none exists.
+ * Returns the xml:lang value or NULL if none exists.,
+ * if non NULL it need to be freed by the caller.
*/
xmlChar *
xmlTextReaderXmlLang(xmlTextReaderPtr reader) {
@@ -3869,7 +3879,7 @@
xmlTextReaderCurrentNode(xmlTextReaderPtr reader) {
if (reader == NULL)
return(NULL);
-
+
if (reader->curnode != NULL)
return(reader->curnode);
return(reader->node);
@@ -3891,7 +3901,7 @@
if (reader == NULL)
return(NULL);
-
+
if (reader->curnode != NULL)
cur = reader->curnode;
else
@@ -3904,7 +3914,7 @@
cur->extra |= NODE_IS_SPRESERVED;
}
reader->preserves++;
-
+
parent = cur->parent;;
while (parent != NULL) {
if (parent->type == XML_ELEMENT_NODE)
@@ -3920,7 +3930,7 @@
* @reader: the xmlTextReaderPtr used
* @pattern: an XPath subset pattern
* @namespaces: the prefix definitions, array of [URI, prefix] or NULL
- *
+ *
* This tells the XML Reader to preserve all nodes matched by the
* pattern. The caller must also use xmlTextReaderCurrentDoc() to
* keep an handle on the resulting document once parsing has finished
@@ -3935,7 +3945,7 @@
if ((reader == NULL) || (pattern == NULL))
return(-1);
-
+
comp = xmlPatterncompile(pattern, reader->dict, 0, namespaces);
if (comp == NULL)
return(-1);
@@ -3972,7 +3982,7 @@
* @reader: the xmlTextReaderPtr used
*
* Hacking interface allowing to get the xmlDocPtr correponding to the
- * current document being accessed by the xmlTextReader.
+ * current document being accessed by the xmlTextReader.
* NOTE: as a result of this call, the reader will not destroy the
* associated XML document and calling xmlFreeDoc() on the result
* is needed once the reader parsing has finished.
@@ -3987,72 +3997,80 @@
return(reader->doc);
if ((reader->ctxt == NULL) || (reader->ctxt->myDoc == NULL))
return(NULL);
-
+
reader->preserve = 1;
return(reader->ctxt->myDoc);
}
#ifdef LIBXML_SCHEMAS_ENABLED
+static char *xmlTextReaderBuildMessage(const char *msg, va_list ap);
-static char *
-xmlTextReaderBuildMessage(const char *msg, va_list ap);
-
-static void XMLCDECL
+static void XMLCDECL
xmlTextReaderValidityError(void *ctxt, const char *msg, ...);
-static void XMLCDECL
+static void XMLCDECL
xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...);
-static void XMLCDECL xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...)
+static void XMLCDECL
+xmlTextReaderValidityErrorRelay(void *ctx, const char *msg, ...)
{
- xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
- char * str;
- va_list ap;
+ xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
- va_start(ap,msg);
- str = xmlTextReaderBuildMessage(msg,ap);
- if (!reader->errorFunc) {
- xmlTextReaderValidityError(ctx, "%s", str);
- } else {
- reader->errorFunc(reader->errorFuncArg, str, XML_PARSER_SEVERITY_VALIDITY_ERROR, NULL /* locator */);
- }
- if (str != NULL)
- xmlFree(str);
- va_end(ap);
+ char *str;
+
+ va_list ap;
+
+ va_start(ap, msg);
+ str = xmlTextReaderBuildMessage(msg, ap);
+ if (!reader->errorFunc) {
+ xmlTextReaderValidityError(ctx, "%s", str);
+ } else {
+ reader->errorFunc(reader->errorFuncArg, str,
+ XML_PARSER_SEVERITY_VALIDITY_ERROR,
+ NULL /* locator */ );
+ }
+ if (str != NULL)
+ xmlFree(str);
+ va_end(ap);
}
-static void XMLCDECL xmlTextReaderValidityWarningRelay(void *ctx, const char *msg, ...)
+static void XMLCDECL
+xmlTextReaderValidityWarningRelay(void *ctx, const char *msg, ...)
{
- xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
- char * str;
- va_list ap;
+ xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx;
- va_start(ap,msg);
- str = xmlTextReaderBuildMessage(msg,ap);
- if (!reader->errorFunc) {
- xmlTextReaderValidityWarning(ctx, "%s", str);
- } else {
- reader->errorFunc(reader->errorFuncArg, str, XML_PARSER_SEVERITY_VALIDITY_WARNING, NULL /* locator */);
- }
- if (str != NULL)
- xmlFree(str);
- va_end(ap);
+ char *str;
+
+ va_list ap;
+
+ va_start(ap, msg);
+ str = xmlTextReaderBuildMessage(msg, ap);
+ if (!reader->errorFunc) {
+ xmlTextReaderValidityWarning(ctx, "%s", str);
+ } else {
+ reader->errorFunc(reader->errorFuncArg, str,
+ XML_PARSER_SEVERITY_VALIDITY_WARNING,
+ NULL /* locator */ );
+ }
+ if (str != NULL)
+ xmlFree(str);
+ va_end(ap);
}
-static void
-xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error);
+static void
+ xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error);
-static void xmlTextReaderValidityStructuredRelay(void * userData, xmlErrorPtr error)
+static void
+xmlTextReaderValidityStructuredRelay(void *userData, xmlErrorPtr error)
{
- xmlTextReaderPtr reader = (xmlTextReaderPtr) userData;
+ xmlTextReaderPtr reader = (xmlTextReaderPtr) userData;
- if (reader->sErrorFunc) {
- reader->sErrorFunc(reader->errorFuncArg, error);
- } else {
- xmlTextReaderStructuredError(reader, error);
- }
+ if (reader->sErrorFunc) {
+ reader->sErrorFunc(reader->errorFuncArg, error);
+ } else {
+ xmlTextReaderStructuredError(reader, error);
+ }
}
-
/**
* xmlTextReaderRelaxNGSetSchema:
* @reader: the xmlTextReaderPtr used
@@ -4102,7 +4120,7 @@
reader);
}
if (reader->sErrorFunc != NULL) {
- xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
+ xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
xmlTextReaderValidityStructuredRelay,
reader);
}
@@ -4138,15 +4156,15 @@
if (reader->xsdValidCtxt != NULL) {
if (! reader->xsdPreserveCtxt)
xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
- reader->xsdValidCtxt = NULL;
+ reader->xsdValidCtxt = NULL;
}
reader->xsdPreserveCtxt = 0;
if (reader->xsdSchemas != NULL) {
xmlSchemaFree(reader->xsdSchemas);
reader->xsdSchemas = NULL;
- }
+ }
return(0);
- }
+ }
if (reader->mode != XML_TEXTREADER_MODE_INITIAL)
return(-1);
if (reader->xsdPlug != NULL) {
@@ -4155,7 +4173,7 @@
}
if (reader->xsdValidCtxt != NULL) {
if (! reader->xsdPreserveCtxt)
- xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
+ xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
reader->xsdValidCtxt = NULL;
}
reader->xsdPreserveCtxt = 0;
@@ -4213,7 +4231,7 @@
if (reader == NULL)
return(-1);
-
+
if (rng == NULL) {
if (reader->rngValidCtxt != NULL) {
xmlRelaxNGFreeValidCtxt(reader->rngValidCtxt);
@@ -4243,7 +4261,7 @@
reader);
}
if (reader->sErrorFunc != NULL) {
- xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
+ xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
xmlTextReaderValidityStructuredRelay,
reader);
}
@@ -4264,7 +4282,7 @@
reader);
}
if (reader->sErrorFunc != NULL) {
- xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
+ xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
xmlTextReaderValidityStructuredRelay,
reader);
}
@@ -4293,7 +4311,7 @@
const char *xsd,
xmlSchemaValidCtxtPtr ctxt,
int options ATTRIBUTE_UNUSED)
-{
+{
if (reader == NULL)
return(-1);
@@ -4304,7 +4322,7 @@
((reader->mode != XML_TEXTREADER_MODE_INITIAL) ||
(reader->ctxt == NULL)))
return(-1);
-
+
/* Cleanup previous validation stuff. */
if (reader->xsdPlug != NULL) {
xmlSchemaSAXUnplug(reader->xsdPlug);
@@ -4312,20 +4330,20 @@
}
if (reader->xsdValidCtxt != NULL) {
if (! reader->xsdPreserveCtxt)
- xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
+ xmlSchemaFreeValidCtxt(reader->xsdValidCtxt);
reader->xsdValidCtxt = NULL;
}
reader->xsdPreserveCtxt = 0;
if (reader->xsdSchemas != NULL) {
xmlSchemaFree(reader->xsdSchemas);
reader->xsdSchemas = NULL;
- }
+ }
if ((xsd == NULL) && (ctxt == NULL)) {
/* We just want to deactivate the validation, so get out. */
return(0);
- }
-
+ }
+
if (xsd != NULL) {
xmlSchemaParserCtxtPtr pctxt;
/* Parse the schema and create validation environment. */
@@ -4357,13 +4375,13 @@
return(-1);
}
} else {
- /* Use the given validation context. */
+ /* Use the given validation context. */
reader->xsdValidCtxt = ctxt;
reader->xsdPreserveCtxt = 1;
reader->xsdPlug = xmlSchemaSAXPlug(reader->xsdValidCtxt,
&(reader->ctxt->sax),
&(reader->ctxt->userData));
- if (reader->xsdPlug == NULL) {
+ if (reader->xsdPlug == NULL) {
reader->xsdValidCtxt = NULL;
reader->xsdPreserveCtxt = 0;
return(-1);
@@ -4382,7 +4400,7 @@
reader);
}
if (reader->sErrorFunc != NULL) {
- xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
+ xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
xmlTextReaderValidityStructuredRelay,
reader);
}
@@ -4453,7 +4471,7 @@
node = reader->curnode;
else
node = reader->node;
-
+
if (XML_NAMESPACE_DECL == node->type)
return(1);
else
@@ -4477,10 +4495,10 @@
if (reader->doc != NULL)
doc = reader->doc;
else if (reader->ctxt != NULL)
- doc = reader->ctxt->myDoc;
+ doc = reader->ctxt->myDoc;
if (doc == NULL)
return(NULL);
-
+
if (doc->version == NULL)
return(NULL);
else
@@ -4533,20 +4551,20 @@
va_end(aq);
if (chars < 0) {
xmlGenericError(xmlGenericErrorContext, "vsnprintf failed !\n");
- if (str)
- xmlFree(str);
- return NULL;
+ if (str)
+ xmlFree(str);
+ return NULL;
}
if ((chars < size) || (size == MAX_ERR_MSG_SIZE))
break;
if (chars < MAX_ERR_MSG_SIZE)
- size = chars + 1;
+ size = chars + 1;
else
size = MAX_ERR_MSG_SIZE;
if ((larger = (char *) xmlRealloc(str, size)) == NULL) {
xmlGenericError(xmlGenericErrorContext, "xmlRealloc failed !\n");
if (str)
- xmlFree(str);
+ xmlFree(str);
return NULL;
}
str = larger;
@@ -4582,7 +4600,7 @@
input = ctx->inputTab[ctx->inputNr - 2];
if (input != NULL) {
ret = input->line;
- }
+ }
else {
ret = -1;
}
@@ -4597,7 +4615,8 @@
*
* Obtain the base URI for the given locator.
*
- * Returns the base URI or NULL in case of error.
+ * Returns the base URI or NULL in case of error,
+ * if non NULL it need to be freed by the caller.
*/
xmlChar *
xmlTextReaderLocatorBaseURI(xmlTextReaderLocatorPtr locator) {
@@ -4618,7 +4637,7 @@
input = ctx->inputTab[ctx->inputNr - 2];
if (input != NULL) {
ret = xmlStrdup(BAD_CAST input->filename);
- }
+ }
else {
ret = NULL;
}
@@ -4628,87 +4647,95 @@
}
static void
-xmlTextReaderGenericError(void *ctxt, xmlParserSeverities severity, char *str) {
- xmlParserCtxtPtr ctx = (xmlParserCtxtPtr)ctxt;
- xmlTextReaderPtr reader = (xmlTextReaderPtr)ctx->_private;
+xmlTextReaderGenericError(void *ctxt, xmlParserSeverities severity,
+ char *str)
+{
+ xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;
+
+ xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;
if (str != NULL) {
- if (reader->errorFunc)
- reader->errorFunc(reader->errorFuncArg,
- str,
- severity,
- (xmlTextReaderLocatorPtr)ctx);
- xmlFree(str);
+ if (reader->errorFunc)
+ reader->errorFunc(reader->errorFuncArg, str, severity,
+ (xmlTextReaderLocatorPtr) ctx);
+ xmlFree(str);
}
}
-static void
-xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error) {
- xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;
- xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;
+static void
+xmlTextReaderStructuredError(void *ctxt, xmlErrorPtr error)
+{
+ xmlParserCtxtPtr ctx = (xmlParserCtxtPtr) ctxt;
- if (error && reader->sErrorFunc) {
- reader->sErrorFunc(reader->errorFuncArg,
- (xmlErrorPtr) error);
- }
+ xmlTextReaderPtr reader = (xmlTextReaderPtr) ctx->_private;
+
+ if (error && reader->sErrorFunc) {
+ reader->sErrorFunc(reader->errorFuncArg, (xmlErrorPtr) error);
+ }
}
-static void XMLCDECL
-xmlTextReaderError(void *ctxt, const char *msg, ...) {
+static void XMLCDECL
+xmlTextReaderError(void *ctxt, const char *msg, ...)
+{
va_list ap;
- va_start(ap,msg);
+ va_start(ap, msg);
xmlTextReaderGenericError(ctxt,
XML_PARSER_SEVERITY_ERROR,
- xmlTextReaderBuildMessage(msg,ap));
+ xmlTextReaderBuildMessage(msg, ap));
va_end(ap);
}
-static void XMLCDECL
-xmlTextReaderWarning(void *ctxt, const char *msg, ...) {
+static void XMLCDECL
+xmlTextReaderWarning(void *ctxt, const char *msg, ...)
+{
va_list ap;
- va_start(ap,msg);
+ va_start(ap, msg);
xmlTextReaderGenericError(ctxt,
XML_PARSER_SEVERITY_WARNING,
- xmlTextReaderBuildMessage(msg,ap));
+ xmlTextReaderBuildMessage(msg, ap));
va_end(ap);
}
-static void XMLCDECL
-xmlTextReaderValidityError(void *ctxt, const char *msg, ...) {
+static void XMLCDECL
+xmlTextReaderValidityError(void *ctxt, const char *msg, ...)
+{
va_list ap;
+
int len = xmlStrlen((const xmlChar *) msg);
if ((len > 1) && (msg[len - 2] != ':')) {
- /*
- * some callbacks only report locator information:
- * skip them (mimicking behaviour in error.c)
- */
- va_start(ap,msg);
- xmlTextReaderGenericError(ctxt,
- XML_PARSER_SEVERITY_VALIDITY_ERROR,
- xmlTextReaderBuildMessage(msg,ap));
- va_end(ap);
+ /*
+ * some callbacks only report locator information:
+ * skip them (mimicking behaviour in error.c)
+ */
+ va_start(ap, msg);
+ xmlTextReaderGenericError(ctxt,
+ XML_PARSER_SEVERITY_VALIDITY_ERROR,
+ xmlTextReaderBuildMessage(msg, ap));
+ va_end(ap);
}
}
-static void XMLCDECL
-xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...) {
+static void XMLCDECL
+xmlTextReaderValidityWarning(void *ctxt, const char *msg, ...)
+{
va_list ap;
+
int len = xmlStrlen((const xmlChar *) msg);
if ((len != 0) && (msg[len - 1] != ':')) {
- /*
- * some callbacks only report locator information:
- * skip them (mimicking behaviour in error.c)
- */
- va_start(ap,msg);
- xmlTextReaderGenericError(ctxt,
- XML_PARSER_SEVERITY_VALIDITY_WARNING,
- xmlTextReaderBuildMessage(msg,ap));
- va_end(ap);
+ /*
+ * some callbacks only report locator information:
+ * skip them (mimicking behaviour in error.c)
+ */
+ va_start(ap, msg);
+ xmlTextReaderGenericError(ctxt,
+ XML_PARSER_SEVERITY_VALIDITY_WARNING,
+ xmlTextReaderBuildMessage(msg, ap));
+ va_end(ap);
}
}
@@ -4723,53 +4750,58 @@
* If @f is NULL, the default error and warning handlers are restored.
*/
void
-xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader,
- xmlTextReaderErrorFunc f,
- void *arg) {
+xmlTextReaderSetErrorHandler(xmlTextReaderPtr reader,
+ xmlTextReaderErrorFunc f, void *arg)
+{
if (f != NULL) {
- reader->ctxt->sax->error = xmlTextReaderError;
- reader->ctxt->sax->serror = NULL;
- reader->ctxt->vctxt.error = xmlTextReaderValidityError;
- reader->ctxt->sax->warning = xmlTextReaderWarning;
- reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
- reader->errorFunc = f;
- reader->sErrorFunc = NULL;
- reader->errorFuncArg = arg;
+ reader->ctxt->sax->error = xmlTextReaderError;
+ reader->ctxt->sax->serror = NULL;
+ reader->ctxt->vctxt.error = xmlTextReaderValidityError;
+ reader->ctxt->sax->warning = xmlTextReaderWarning;
+ reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
+ reader->errorFunc = f;
+ reader->sErrorFunc = NULL;
+ reader->errorFuncArg = arg;
#ifdef LIBXML_SCHEMAS_ENABLED
- if (reader->rngValidCtxt) {
- xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
- xmlTextReaderValidityErrorRelay,
- xmlTextReaderValidityWarningRelay,
- reader);
- xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL, reader);
- }
- if (reader->xsdValidCtxt) {
- xmlSchemaSetValidErrors(reader->xsdValidCtxt,
- xmlTextReaderValidityErrorRelay,
- xmlTextReaderValidityWarningRelay,
- reader);
- xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL, reader);
- }
+ if (reader->rngValidCtxt) {
+ xmlRelaxNGSetValidErrors(reader->rngValidCtxt,
+ xmlTextReaderValidityErrorRelay,
+ xmlTextReaderValidityWarningRelay,
+ reader);
+ xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,
+ reader);
+ }
+ if (reader->xsdValidCtxt) {
+ xmlSchemaSetValidErrors(reader->xsdValidCtxt,
+ xmlTextReaderValidityErrorRelay,
+ xmlTextReaderValidityWarningRelay,
+ reader);
+ xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,
+ reader);
+ }
#endif
- }
- else {
- /* restore defaults */
- reader->ctxt->sax->error = xmlParserError;
- reader->ctxt->vctxt.error = xmlParserValidityError;
- reader->ctxt->sax->warning = xmlParserWarning;
- reader->ctxt->vctxt.warning = xmlParserValidityWarning;
- reader->errorFunc = NULL;
- reader->sErrorFunc = NULL;
- reader->errorFuncArg = NULL;
+ } else {
+ /* restore defaults */
+ reader->ctxt->sax->error = xmlParserError;
+ reader->ctxt->vctxt.error = xmlParserValidityError;
+ reader->ctxt->sax->warning = xmlParserWarning;
+ reader->ctxt->vctxt.warning = xmlParserValidityWarning;
+ reader->errorFunc = NULL;
+ reader->sErrorFunc = NULL;
+ reader->errorFuncArg = NULL;
#ifdef LIBXML_SCHEMAS_ENABLED
- if (reader->rngValidCtxt) {
- xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL, reader);
- xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL, reader);
- }
- if (reader->xsdValidCtxt) {
- xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL, reader);
- xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL, reader);
- }
+ if (reader->rngValidCtxt) {
+ xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,
+ reader);
+ xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,
+ reader);
+ }
+ if (reader->xsdValidCtxt) {
+ xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,
+ reader);
+ xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,
+ reader);
+ }
#endif
}
}
@@ -4785,54 +4817,59 @@
* If @f is NULL, the default error and warning handlers are restored.
*/
void
-xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader,
- xmlStructuredErrorFunc f,
- void *arg) {
- if (f != NULL) {
- reader->ctxt->sax->error = NULL;
- reader->ctxt->sax->serror = xmlTextReaderStructuredError;
- reader->ctxt->vctxt.error = xmlTextReaderValidityError;
- reader->ctxt->sax->warning = xmlTextReaderWarning;
- reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
- reader->sErrorFunc = f;
- reader->errorFunc = NULL;
- reader->errorFuncArg = arg;
+xmlTextReaderSetStructuredErrorHandler(xmlTextReaderPtr reader,
+ xmlStructuredErrorFunc f, void *arg)
+{
+ if (f != NULL) {
+ reader->ctxt->sax->error = NULL;
+ reader->ctxt->sax->serror = xmlTextReaderStructuredError;
+ reader->ctxt->vctxt.error = xmlTextReaderValidityError;
+ reader->ctxt->sax->warning = xmlTextReaderWarning;
+ reader->ctxt->vctxt.warning = xmlTextReaderValidityWarning;
+ reader->sErrorFunc = f;
+ reader->errorFunc = NULL;
+ reader->errorFuncArg = arg;
#ifdef LIBXML_SCHEMAS_ENABLED
- if (reader->rngValidCtxt) {
- xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL, reader);
- xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
- xmlTextReaderValidityStructuredRelay,
- reader);
- }
- if (reader->xsdValidCtxt) {
- xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL, reader);
- xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
- xmlTextReaderValidityStructuredRelay,
- reader);
- }
+ if (reader->rngValidCtxt) {
+ xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,
+ reader);
+ xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt,
+ xmlTextReaderValidityStructuredRelay,
+ reader);
+ }
+ if (reader->xsdValidCtxt) {
+ xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,
+ reader);
+ xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt,
+ xmlTextReaderValidityStructuredRelay,
+ reader);
+ }
#endif
- }
- else {
- /* restore defaults */
- reader->ctxt->sax->error = xmlParserError;
- reader->ctxt->sax->serror = NULL;
- reader->ctxt->vctxt.error = xmlParserValidityError;
- reader->ctxt->sax->warning = xmlParserWarning;
- reader->ctxt->vctxt.warning = xmlParserValidityWarning;
- reader->errorFunc = NULL;
- reader->sErrorFunc = NULL;
- reader->errorFuncArg = NULL;
+ } else {
+ /* restore defaults */
+ reader->ctxt->sax->error = xmlParserError;
+ reader->ctxt->sax->serror = NULL;
+ reader->ctxt->vctxt.error = xmlParserValidityError;
+ reader->ctxt->sax->warning = xmlParserWarning;
+ reader->ctxt->vctxt.warning = xmlParserValidityWarning;
+ reader->errorFunc = NULL;
+ reader->sErrorFunc = NULL;
+ reader->errorFuncArg = NULL;
#ifdef LIBXML_SCHEMAS_ENABLED
- if (reader->rngValidCtxt) {
- xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL, reader);
- xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL, reader);
- }
- if (reader->xsdValidCtxt) {
- xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL, reader);
- xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL, reader);
- }
+ if (reader->rngValidCtxt) {
+ xmlRelaxNGSetValidErrors(reader->rngValidCtxt, NULL, NULL,
+ reader);
+ xmlRelaxNGSetValidStructuredErrors(reader->rngValidCtxt, NULL,
+ reader);
+ }
+ if (reader->xsdValidCtxt) {
+ xmlSchemaSetValidErrors(reader->xsdValidCtxt, NULL, NULL,
+ reader);
+ xmlSchemaSetValidStructuredErrors(reader->xsdValidCtxt, NULL,
+ reader);
+ }
#endif
- }
+ }
}
/**
@@ -4844,17 +4881,19 @@
* Returns the flag value 1 if valid, 0 if no, and -1 in case of error
*/
int
-xmlTextReaderIsValid(xmlTextReaderPtr reader) {
- if (reader == NULL) return(-1);
+xmlTextReaderIsValid(xmlTextReaderPtr reader)
+{
+ if (reader == NULL)
+ return (-1);
#ifdef LIBXML_SCHEMAS_ENABLED
if (reader->validate == XML_TEXTREADER_VALIDATE_RNG)
- return(reader->rngValidErrors == 0);
+ return (reader->rngValidErrors == 0);
if (reader->validate == XML_TEXTREADER_VALIDATE_XSD)
- return(reader->xsdValidErrors == 0);
+ return (reader->xsdValidErrors == 0);
#endif
if ((reader->ctxt != NULL) && (reader->ctxt->validate == 1))
- return(reader->ctxt->valid);
- return(0);
+ return (reader->ctxt->valid);
+ return (0);
}
/**
@@ -4866,14 +4905,14 @@
* Retrieve the error callback function and user argument.
*/
void
-xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader,
- xmlTextReaderErrorFunc *f,
- void **arg) {
- if (f != NULL) *f = reader->errorFunc;
- if (arg != NULL) *arg = reader->errorFuncArg;
+xmlTextReaderGetErrorHandler(xmlTextReaderPtr reader,
+ xmlTextReaderErrorFunc * f, void **arg)
+{
+ if (f != NULL)
+ *f = reader->errorFunc;
+ if (arg != NULL)
+ *arg = reader->errorFuncArg;
}
-
-
/************************************************************************
* *
* New set (2.6.0) of simpler and more flexible APIs *
@@ -4890,7 +4929,7 @@
* @options: a combination of xmlParserOption
*
* Setup an XML reader with new options
- *
+ *
* Returns 0 in case of success and -1 in case of error.
*/
int
@@ -5003,8 +5042,8 @@
inputStream->buf = buf;
inputStream->base = inputStream->buf->buffer->content;
inputStream->cur = inputStream->buf->buffer->content;
- inputStream->end =
- &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
+ inputStream->end =
+ &inputStream->buf->buffer->content[inputStream->buf->buffer->use];
inputPush(reader->ctxt, inputStream);
reader->cur = 0;
@@ -5105,14 +5144,14 @@
return(-1);
return(xmlByteConsumed(reader->ctxt));
}
-
+
/**
* xmlReaderWalker:
* @doc: a preparsed document
*
* Create an xmltextReader for a preparsed document.
- *
+ *
* Returns the new reader or NULL in case of error.
*/
xmlTextReaderPtr
@@ -5153,7 +5192,7 @@
*
* Create an xmltextReader for an XML in-memory document.
* The parsing flags @options are a combination of xmlParserOption.
- *
+ *
* Returns the new reader or NULL in case of error.
*/
xmlTextReaderPtr
@@ -5178,7 +5217,7 @@
*
* parse an XML file from the filesystem or the network.
* The parsing flags @options are a combination of xmlParserOption.
- *
+ *
* Returns the new reader or NULL in case of error.
*/
xmlTextReaderPtr
@@ -5203,7 +5242,7 @@
*
* Create an xmltextReader for an XML in-memory document.
* The parsing flags @options are a combination of xmlParserOption.
- *
+ *
* Returns the new reader or NULL in case of error.
*/
xmlTextReaderPtr
@@ -5239,7 +5278,7 @@
* The parsing flags @options are a combination of xmlParserOption.
* NOTE that the file descriptor will not be closed when the
* reader is closed or reset.
- *
+ *
* Returns the new reader or NULL in case of error.
*/
xmlTextReaderPtr
@@ -5276,7 +5315,7 @@
*
* Create an xmltextReader for an XML document from I/O functions and source.
* The parsing flags @options are a combination of xmlParserOption.
- *
+ *
* Returns the new reader or NULL in case of error.
*/
xmlTextReaderPtr
@@ -5311,7 +5350,7 @@
*
* Setup an xmltextReader to parse a preparsed XML document.
* This reuses the existing @reader xmlTextReader.
- *
+ *
* Returns 0 in case of success and -1 in case of error
*/
int
@@ -5359,7 +5398,7 @@
* Setup an xmltextReader to parse an XML in-memory document.
* The parsing flags @options are a combination of xmlParserOption.
* This reuses the existing @reader xmlTextReader.
- *
+ *
* Returns 0 in case of success and -1 in case of error
*/
int
@@ -5389,7 +5428,7 @@
* parse an XML file from the filesystem or the network.
* The parsing flags @options are a combination of xmlParserOption.
* This reuses the existing @reader xmlTextReader.
- *
+ *
* Returns 0 in case of success and -1 in case of error
*/
int
@@ -5423,7 +5462,7 @@
* Setup an xmltextReader to parse an XML in-memory document.
* The parsing flags @options are a combination of xmlParserOption.
* This reuses the existing @reader xmlTextReader.
- *
+ *
* Returns 0 in case of success and -1 in case of error
*/
int
@@ -5458,7 +5497,7 @@
* reader is closed or reset.
* The parsing flags @options are a combination of xmlParserOption.
* This reuses the existing @reader xmlTextReader.
- *
+ *
* Returns 0 in case of success and -1 in case of error
*/
int
@@ -5493,7 +5532,7 @@
* and source.
* The parsing flags @options are a combination of xmlParserOption.
* This reuses the existing @reader xmlTextReader.
- *
+ *
* Returns 0 in case of success and -1 in case of error
*/
int
@@ -5520,6 +5559,7 @@
* *
************************************************************************/
#ifdef NOT_USED_YET
+
/**
* xmlBase64Decode:
* @in: the input buffer
@@ -5535,22 +5575,34 @@
*/
static int
xmlBase64Decode(const unsigned char *in, unsigned long *inlen,
- unsigned char *to, unsigned long *tolen) {
- unsigned long incur; /* current index in in[] */
- unsigned long inblk; /* last block index in in[] */
- unsigned long outcur; /* current index in out[] */
- unsigned long inmax; /* size of in[] */
- unsigned long outmax; /* size of out[] */
- unsigned char cur; /* the current value read from in[] */
- unsigned char intmp[4], outtmp[4]; /* temporary buffers for the convert */
- int nbintmp; /* number of byte in intmp[] */
- int is_ignore; /* cur should be ignored */
- int is_end = 0; /* the end of the base64 was found */
+ unsigned char *to, unsigned long *tolen)
+{
+ unsigned long incur; /* current index in in[] */
+
+ unsigned long inblk; /* last block index in in[] */
+
+ unsigned long outcur; /* current index in out[] */
+
+ unsigned long inmax; /* size of in[] */
+
+ unsigned long outmax; /* size of out[] */
+
+ unsigned char cur; /* the current value read from in[] */
+
+ unsigned char intmp[4], outtmp[4]; /* temporary buffers for the convert */
+
+ int nbintmp; /* number of byte in intmp[] */
+
+ int is_ignore; /* cur should be ignored */
+
+ int is_end = 0; /* the end of the base64 was found */
+
int retval = 1;
+
int i;
if ((in == NULL) || (inlen == NULL) || (to == NULL) || (tolen == NULL))
- return(-1);
+ return (-1);
incur = 0;
inblk = 0;
@@ -5576,16 +5628,17 @@
cur = 63;
else if (cur == '.')
cur = 0;
- else if (cur == '=') /*no op , end of the base64 stream */
+ else if (cur == '=') /*no op , end of the base64 stream */
is_end = 1;
else {
is_ignore = 1;
- if (nbintmp == 0)
- inblk = incur;
- }
+ if (nbintmp == 0)
+ inblk = incur;
+ }
if (!is_ignore) {
int nbouttmp = 3;
+
int is_break = 0;
if (is_end) {
@@ -5599,30 +5652,30 @@
is_break = 1;
}
intmp[nbintmp++] = cur;
- /*
- * if intmp is full, push the 4byte sequence as a 3 byte
- * sequence out
- */
+ /*
+ * if intmp is full, push the 4byte sequence as a 3 byte
+ * sequence out
+ */
if (nbintmp == 4) {
nbintmp = 0;
outtmp[0] = (intmp[0] << 2) | ((intmp[1] & 0x30) >> 4);
outtmp[1] =
((intmp[1] & 0x0F) << 4) | ((intmp[2] & 0x3C) >> 2);
outtmp[2] = ((intmp[2] & 0x03) << 6) | (intmp[3] & 0x3F);
- if (outcur + 3 >= outmax) {
- retval = 2;
- break;
- }
+ if (outcur + 3 >= outmax) {
+ retval = 2;
+ break;
+ }
for (i = 0; i < nbouttmp; i++)
- to[outcur++] = outtmp[i];
- inblk = incur;
+ to[outcur++] = outtmp[i];
+ inblk = incur;
}
if (is_break) {
- retval = 0;
+ retval = 0;
break;
- }
+ }
}
}
@@ -5635,14 +5688,23 @@
* Test routine for the xmlBase64Decode function
*/
#if 0
-int main(int argc, char **argv) {
+int
+main(int argc, char **argv)
+{
char *input = " VW4 gcGV0 \n aXQgdGVzdCAuCg== ";
+
char output[100];
+
char output2[100];
+
char output3[100];
+
unsigned long inlen = strlen(input);
+
unsigned long outlen = 100;
+
int ret;
+
unsigned long cons, tmp, tmp2, prod;
/*
@@ -5651,25 +5713,28 @@
ret = xmlBase64Decode(input, &inlen, output, &outlen);
output[outlen] = 0;
- printf("ret: %d, inlen: %ld , outlen: %ld, output: '%s'\n", ret, inlen, outlen, output);
-
+ printf("ret: %d, inlen: %ld , outlen: %ld, output: '%s'\n", ret, inlen,
+ outlen, output)indent: Standard input:179: Error:Unmatched #endif
+;
+
/*
* output chunking
*/
cons = 0;
prod = 0;
while (cons < inlen) {
- tmp = 5;
- tmp2 = inlen - cons;
+ tmp = 5;
+ tmp2 = inlen - cons;
- printf("%ld %ld\n", cons, prod);
- ret = xmlBase64Decode(&input[cons], &tmp2, &output2[prod], &tmp);
- cons += tmp2;
- prod += tmp;
- printf("%ld %ld\n", cons, prod);
+ printf("%ld %ld\n", cons, prod);
+ ret = xmlBase64Decode(&input[cons], &tmp2, &output2[prod], &tmp);
+ cons += tmp2;
+ prod += tmp;
+ printf("%ld %ld\n", cons, prod);
}
output2[outlen] = 0;
- printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons, prod, output2);
+ printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons,
+ prod, output2);
/*
* input chunking
@@ -5677,20 +5742,21 @@
cons = 0;
prod = 0;
while (cons < inlen) {
- tmp = 100 - prod;
- tmp2 = inlen - cons;
- if (tmp2 > 5)
- tmp2 = 5;
+ tmp = 100 - prod;
+ tmp2 = inlen - cons;
+ if (tmp2 > 5)
+ tmp2 = 5;
- printf("%ld %ld\n", cons, prod);
- ret = xmlBase64Decode(&input[cons], &tmp2, &output3[prod], &tmp);
- cons += tmp2;
- prod += tmp;
- printf("%ld %ld\n", cons, prod);
+ printf("%ld %ld\n", cons, prod);
+ ret = xmlBase64Decode(&input[cons], &tmp2, &output3[prod], &tmp);
+ cons += tmp2;
+ prod += tmp;
+ printf("%ld %ld\n", cons, prod);
}
output3[outlen] = 0;
- printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons, prod, output3);
- return(0);
+ printf("ret: %d, cons: %ld , prod: %ld, output: '%s'\n", ret, cons,
+ prod, output3);
+ return (0);
}
#endif
diff --git a/xmlregexp.c b/xmlregexp.c
index 4258a08..aaff33e 100644
--- a/xmlregexp.c
+++ b/xmlregexp.c
@@ -233,6 +233,8 @@
typedef struct _xmlAutomata xmlRegParserCtxt;
typedef xmlRegParserCtxt *xmlRegParserCtxtPtr;
+#define AM_AUTOMATA_RNG 1
+
struct _xmlAutomata {
xmlChar *string;
xmlChar *cur;
@@ -260,6 +262,7 @@
int determinist;
int negs;
+ int flags;
};
struct _xmlRegexp {
@@ -271,6 +274,7 @@
int nbCounters;
xmlRegCounter *counters;
int determinist;
+ int flags;
/*
* That's the compact form for determinists automatas
*/
@@ -353,6 +357,8 @@
static int xmlRegCheckCharacterRange(xmlRegAtomType type, int codepoint,
int neg, int start, int end, const xmlChar *blockName);
+void xmlAutomataSetFlags(xmlAutomataPtr am, int flags);
+
/************************************************************************
* *
* Regexp memory error handler *
@@ -434,6 +440,7 @@
ret->nbCounters = ctxt->nbCounters;
ret->counters = ctxt->counters;
ret->determinist = ctxt->determinist;
+ ret->flags = ctxt->flags;
if (ret->determinist == -1) {
xmlRegexpIsDeterminist(ret);
}
@@ -1569,8 +1576,13 @@
* 1. set transition from atom start to new state
* 2. set transition from atom end to this state.
*/
- xmlFAGenerateEpsilonTransition(ctxt, atom->start, 0);
- xmlFAGenerateEpsilonTransition(ctxt, atom->stop, ctxt->state);
+ if (to == NULL) {
+ xmlFAGenerateEpsilonTransition(ctxt, atom->start, 0);
+ xmlFAGenerateEpsilonTransition(ctxt, atom->stop,
+ ctxt->state);
+ } else {
+ xmlFAGenerateEpsilonTransition(ctxt, atom->start, to);
+ }
break;
case XML_REGEXP_QUANT_MULT:
atom->quant = XML_REGEXP_QUANT_ONCE;
@@ -2083,12 +2095,13 @@
(range2->type == XML_REGEXP_EPSILON)) {
return(0);
} else if (range1->type == range2->type) {
- if ((range1->type != XML_REGEXP_CHARVAL) ||
- (range1->end < range2->start) ||
- (range2->end < range1->start))
- ret = 1;
- else
+ if (range1->type != XML_REGEXP_CHARVAL)
+ ret = 1;
+ else if ((range1->end < range2->start) ||
+ (range2->end < range1->start))
ret = 0;
+ else
+ ret = 1;
} else if (range1->type == XML_REGEXP_CHARVAL) {
int codepoint;
int neg = 0;
@@ -2215,7 +2228,7 @@
if (((range1->neg == 0) && (range2->neg != 0)) ||
((range1->neg != 0) && (range2->neg == 0)))
ret = !ret;
- return(1);
+ return(ret);
}
/**
@@ -2423,6 +2436,7 @@
* xmlFAEqualAtoms:
* @atom1: an atom
* @atom2: an atom
+ * @deep: if not set only compare string pointers
*
* Compares two atoms to check whether they are the same exactly
* this is used to remove equivalent transitions
@@ -2430,7 +2444,7 @@
* Returns 1 if same and 0 otherwise
*/
static int
-xmlFAEqualAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2) {
+xmlFAEqualAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2, int deep) {
int ret = 0;
if (atom1 == atom2)
@@ -2445,8 +2459,11 @@
ret = 0;
break;
case XML_REGEXP_STRING:
- ret = xmlStrEqual((xmlChar *)atom1->valuep,
- (xmlChar *)atom2->valuep);
+ if (!deep)
+ ret = (atom1->valuep == atom2->valuep);
+ else
+ ret = xmlStrEqual((xmlChar *)atom1->valuep,
+ (xmlChar *)atom2->valuep);
break;
case XML_REGEXP_CHARVAL:
ret = (atom1->codepoint == atom2->codepoint);
@@ -2464,6 +2481,7 @@
* xmlFACompareAtoms:
* @atom1: an atom
* @atom2: an atom
+ * @deep: if not set only compare string pointers
*
* Compares two atoms to check whether they intersect in some ways,
* this is used by xmlFAComputesDeterminism and xmlFARecurseDeterminism only
@@ -2471,7 +2489,7 @@
* Returns 1 if yes and 0 otherwise
*/
static int
-xmlFACompareAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2) {
+xmlFACompareAtoms(xmlRegAtomPtr atom1, xmlRegAtomPtr atom2, int deep) {
int ret = 1;
if (atom1 == atom2)
@@ -2497,8 +2515,11 @@
}
switch (atom1->type) {
case XML_REGEXP_STRING:
- ret = xmlRegStrEqualWildcard((xmlChar *)atom1->valuep,
- (xmlChar *)atom2->valuep);
+ if (!deep)
+ ret = (atom1->valuep != atom2->valuep);
+ else
+ ret = xmlRegStrEqualWildcard((xmlChar *)atom1->valuep,
+ (xmlChar *)atom2->valuep);
break;
case XML_REGEXP_EPSILON:
goto not_determinist;
@@ -2561,9 +2582,14 @@
int res;
int transnr, nbTrans;
xmlRegTransPtr t1;
+ int deep = 1;
if (state == NULL)
return(ret);
+
+ if (ctxt->flags & AM_AUTOMATA_RNG)
+ deep = 0;
+
/*
* don't recurse on transitions potentially added in the course of
* the elimination.
@@ -2587,7 +2613,7 @@
}
if (t1->to != to)
continue;
- if (xmlFACompareAtoms(t1->atom, atom)) {
+ if (xmlFACompareAtoms(t1->atom, atom, deep)) {
ret = 0;
/* mark the transition as non-deterministic */
t1->nd = 1;
@@ -2611,6 +2637,7 @@
xmlRegTransPtr t1, t2, last;
int i;
int ret = 1;
+ int deep = 1;
#ifdef DEBUG_REGEXP_GRAPH
printf("xmlFAComputesDeterminism\n");
@@ -2619,6 +2646,9 @@
if (ctxt->determinist != -1)
return(ctxt->determinist);
+ if (ctxt->flags & AM_AUTOMATA_RNG)
+ deep = 0;
+
/*
* First cleanup the automata removing cancelled transitions
*/
@@ -2646,7 +2676,13 @@
continue;
if (t2->atom != NULL) {
if (t1->to == t2->to) {
- if (xmlFAEqualAtoms(t1->atom, t2->atom))
+ /*
+ * Here we use deep because we want to keep the
+ * transitions which indicate a conflict
+ */
+ if (xmlFAEqualAtoms(t1->atom, t2->atom, deep) &&
+ (t1->counter == t2->counter) &&
+ (t1->count == t2->count))
t2->to = -1; /* eliminated */
}
}
@@ -2681,8 +2717,11 @@
if (t2->to == -1) /* eliminated */
continue;
if (t2->atom != NULL) {
- /* not determinist ! */
- if (xmlFACompareAtoms(t1->atom, t2->atom)) {
+ /*
+ * But here we don't use deep because we want to
+ * find transitions which indicate a conflict
+ */
+ if (xmlFACompareAtoms(t1->atom, t2->atom, 1)) {
ret = 0;
/* mark the transitions as non-deterministic ones */
t1->nd = 1;
@@ -4853,6 +4892,17 @@
}
}
} else if (ctxt->atom->type == XML_REGEXP_RANGES) {
+ switch (cur) {
+ case 'n':
+ cur = '\n';
+ break;
+ case 'r':
+ cur = '\r';
+ break;
+ case 't':
+ cur = '\t';
+ break;
+ }
xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
XML_REGEXP_CHARVAL, cur, cur, NULL);
}
@@ -5470,10 +5520,12 @@
am->nbStates = comp->nbStates;
am->states = comp->states;
am->determinist = -1;
+ am->flags = comp->flags;
ret = xmlFAComputesDeterminism(am);
am->atoms = NULL;
am->states = NULL;
xmlFreeAutomata(am);
+ comp->determinist = ret;
return(ret);
}
@@ -5551,6 +5603,7 @@
xmlFreeAutomata(ctxt);
return(NULL);
}
+ ctxt->flags = 0;
return(ctxt);
}
@@ -5569,6 +5622,20 @@
}
/**
+ * xmlAutomataSetFlags:
+ * @am: an automata
+ * @flags: a set of internal flags
+ *
+ * Set some flags on the automata
+ */
+void
+xmlAutomataSetFlags(xmlAutomataPtr am, int flags) {
+ if (am == NULL)
+ return;
+ am->flags |= flags;
+}
+
+/**
* xmlAutomataGetInitState:
* @am: an automata
*
@@ -6254,6 +6321,7 @@
int size;
int nbElems;
int nb_nodes;
+ int maxNodes;
const char *expr;
const char *cur;
int nb_cons;
@@ -6283,6 +6351,7 @@
memset(ret, 0, sizeof(xmlExpCtxt));
ret->size = size;
ret->nbElems = 0;
+ ret->maxNodes = maxNodes;
ret->table = xmlMalloc(size * sizeof(xmlExpNodePtr));
if (ret->table == NULL) {
xmlFree(ret);
@@ -6401,7 +6470,7 @@
if (name != NULL) {
value += 30 * (*name);
while ((ch = *name++) != 0) {
- value = value ^ ((value << 5) + (value >> 3) + (unsigned short)ch);
+ value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
}
}
return (value);
@@ -6868,7 +6937,7 @@
return(0);
if (nb >= len)
return(-2);
- list[nb++] = exp->exp_str;
+ list[nb] = exp->exp_str;
return(1);
case XML_EXP_COUNT:
exp = exp->exp_left;
@@ -6923,7 +6992,7 @@
return(0);
if (nb >= len)
return(-2);
- list[nb++] = exp->exp_str;
+ list[nb] = exp->exp_str;
return(1);
case XML_EXP_COUNT:
exp = exp->exp_left;
diff --git a/xmlsave.c b/xmlsave.c
index 53b23e6..23c3bcc 100644
--- a/xmlsave.c
+++ b/xmlsave.c
@@ -248,7 +248,7 @@
/*
* We assume we have UTF-8 input.
*/
- if (outend - out < 10) break;
+ if (outend - out < 11) break;
if (*in < 0xC0) {
xmlSaveErr(XML_SAVE_NOT_UTF8, NULL, NULL);
@@ -408,6 +408,8 @@
ret->options = options;
if (options & XML_SAVE_FORMAT)
ret->format = 1;
+ else if (options & XML_SAVE_WSNONSIG)
+ ret->format = 2;
return(ret);
}
@@ -501,32 +503,90 @@
static int xmlDocContentDumpOutput(xmlSaveCtxtPtr ctxt, xmlDocPtr cur);
/**
+ * xmlOutputBufferWriteWSNonSig:
+ * @ctxt: The save context
+ * @extra: Number of extra indents to apply to ctxt->level
+ *
+ * Write out formatting for non-significant whitespace output.
+ */
+static void
+xmlOutputBufferWriteWSNonSig(xmlSaveCtxtPtr ctxt, int extra)
+{
+ int i;
+ if ((ctxt == NULL) || (ctxt->buf == NULL))
+ return;
+ xmlOutputBufferWrite(ctxt->buf, 1, "\n");
+ for (i = 0; i < (ctxt->level + extra); i += ctxt->indent_nr) {
+ xmlOutputBufferWrite(ctxt->buf, ctxt->indent_size *
+ ((ctxt->level + extra - i) > ctxt->indent_nr ?
+ ctxt->indent_nr : (ctxt->level + extra - i)),
+ ctxt->indent);
+ }
+}
+
+/**
* xmlNsDumpOutput:
* @buf: the XML buffer output
* @cur: a namespace
+ * @ctxt: the output save context. Optional.
*
* Dump a local Namespace definition.
* Should be called in the context of attributes dumps.
+ * If @ctxt is supplied, @buf should be its buffer.
*/
static void
-xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
+xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur, xmlSaveCtxtPtr ctxt) {
if ((cur == NULL) || (buf == NULL)) return;
if ((cur->type == XML_LOCAL_NAMESPACE) && (cur->href != NULL)) {
if (xmlStrEqual(cur->prefix, BAD_CAST "xml"))
return;
+ if (ctxt != NULL && ctxt->format == 2)
+ xmlOutputBufferWriteWSNonSig(ctxt, 2);
+ else
+ xmlOutputBufferWrite(buf, 1, " ");
+
/* Within the context of an element attributes */
if (cur->prefix != NULL) {
- xmlOutputBufferWrite(buf, 7, " xmlns:");
+ xmlOutputBufferWrite(buf, 6, "xmlns:");
xmlOutputBufferWriteString(buf, (const char *)cur->prefix);
} else
- xmlOutputBufferWrite(buf, 6, " xmlns");
+ xmlOutputBufferWrite(buf, 5, "xmlns");
xmlOutputBufferWrite(buf, 1, "=");
xmlBufferWriteQuotedString(buf->buffer, cur->href);
}
}
/**
+ * xmlNsDumpOutputCtxt
+ * @ctxt: the save context
+ * @cur: a namespace
+ *
+ * Dump a local Namespace definition to a save context.
+ * Should be called in the context of attribute dumps.
+ */
+static void
+xmlNsDumpOutputCtxt(xmlSaveCtxtPtr ctxt, xmlNsPtr cur) {
+ xmlNsDumpOutput(ctxt->buf, cur, ctxt);
+}
+
+/**
+ * xmlNsListDumpOutputCtxt
+ * @ctxt: the save context
+ * @cur: the first namespace
+ *
+ * Dump a list of local namespace definitions to a save context.
+ * Should be called in the context of attribute dumps.
+ */
+static void
+xmlNsListDumpOutputCtxt(xmlSaveCtxtPtr ctxt, xmlNsPtr cur) {
+ while (cur != NULL) {
+ xmlNsDumpOutput(ctxt->buf, cur, ctxt);
+ cur = cur->next;
+ }
+}
+
+/**
* xmlNsListDumpOutput:
* @buf: the XML buffer output
* @cur: the first namespace
@@ -537,7 +597,7 @@
void
xmlNsListDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur) {
while (cur != NULL) {
- xmlNsDumpOutput(buf, cur);
+ xmlNsDumpOutput(buf, cur, NULL);
cur = cur->next;
}
}
@@ -612,7 +672,10 @@
if (cur == NULL) return;
buf = ctxt->buf;
if (buf == NULL) return;
- xmlOutputBufferWrite(buf, 1, " ");
+ if (ctxt->format == 2)
+ xmlOutputBufferWriteWSNonSig(ctxt, 2);
+ else
+ xmlOutputBufferWrite(buf, 1, " ");
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
xmlOutputBufferWrite(buf, 1, ":");
@@ -656,7 +719,7 @@
if (cur == NULL) return;
buf = ctxt->buf;
while (cur != NULL) {
- if ((ctxt->format) && (xmlIndentTreeOutput) &&
+ if ((ctxt->format == 1) && (xmlIndentTreeOutput) &&
((cur->type == XML_ELEMENT_NODE) ||
(cur->type == XML_COMMENT_NODE) ||
(cur->type == XML_PI_NODE)))
@@ -665,7 +728,7 @@
ctxt->indent_nr : ctxt->level),
ctxt->indent);
xmlNodeDumpOutputInternal(ctxt, cur);
- if (ctxt->format) {
+ if (ctxt->format == 1) {
xmlOutputBufferWrite(buf, 1, "\n");
}
cur = cur->next;
@@ -690,8 +753,8 @@
xmlInitParser();
- doc = cur->doc; {
- if (doc != NULL)
+ doc = cur->doc;
+ if (doc != NULL) {
oldenc = doc->encoding;
if (ctxt->encoding != NULL) {
doc->encoding = BAD_CAST ctxt->encoding;
@@ -808,13 +871,18 @@
xmlOutputBufferWrite(buf, 2, "<?");
xmlOutputBufferWriteString(buf, (const char *)cur->name);
if (cur->content != NULL) {
- xmlOutputBufferWrite(buf, 1, " ");
+ if (ctxt->format == 2)
+ xmlOutputBufferWriteWSNonSig(ctxt, 0);
+ else
+ xmlOutputBufferWrite(buf, 1, " ");
xmlOutputBufferWriteString(buf, (const char *)cur->content);
}
xmlOutputBufferWrite(buf, 2, "?>");
} else {
xmlOutputBufferWrite(buf, 2, "<?");
xmlOutputBufferWriteString(buf, (const char *)cur->name);
+ if (ctxt->format == 2)
+ xmlOutputBufferWriteWSNonSig(ctxt, 0);
xmlOutputBufferWrite(buf, 2, "?>");
}
return;
@@ -862,7 +930,7 @@
return;
}
if (cur->type == XML_NAMESPACE_DECL) {
- xmlNsDumpOutput(buf, (xmlNsPtr) cur);
+ xmlNsDumpOutputCtxt(ctxt, (xmlNsPtr) cur);
return;
}
@@ -887,26 +955,30 @@
xmlOutputBufferWriteString(buf, (const char *)cur->name);
if (cur->nsDef)
- xmlNsListDumpOutput(buf, cur->nsDef);
+ xmlNsListDumpOutputCtxt(ctxt, cur->nsDef);
if (cur->properties != NULL)
xmlAttrListDumpOutput(ctxt, cur->properties);
if (((cur->type == XML_ELEMENT_NODE) || (cur->content == NULL)) &&
(cur->children == NULL) && ((ctxt->options & XML_SAVE_NO_EMPTY) == 0)) {
+ if (ctxt->format == 2)
+ xmlOutputBufferWriteWSNonSig(ctxt, 0);
xmlOutputBufferWrite(buf, 2, "/>");
ctxt->format = format;
return;
}
+ if (ctxt->format == 2)
+ xmlOutputBufferWriteWSNonSig(ctxt, 1);
xmlOutputBufferWrite(buf, 1, ">");
if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape);
}
if (cur->children != NULL) {
- if (ctxt->format) xmlOutputBufferWrite(buf, 1, "\n");
+ if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n");
if (ctxt->level >= 0) ctxt->level++;
xmlNodeListDumpOutput(ctxt, cur->children);
if (ctxt->level > 0) ctxt->level--;
- if ((xmlIndentTreeOutput) && (ctxt->format))
+ if ((xmlIndentTreeOutput) && (ctxt->format == 1))
xmlOutputBufferWrite(buf, ctxt->indent_size *
(ctxt->level > ctxt->indent_nr ?
ctxt->indent_nr : ctxt->level),
@@ -919,6 +991,8 @@
}
xmlOutputBufferWriteString(buf, (const char *)cur->name);
+ if (ctxt->format == 2)
+ xmlOutputBufferWriteWSNonSig(ctxt, 0);
xmlOutputBufferWrite(buf, 1, ">");
ctxt->format = format;
}
@@ -976,7 +1050,6 @@
cur->encoding = oldenc;
return(-1);
}
- switched_encoding = 1;
}
if (ctxt->options & XML_SAVE_FORMAT)
htmlDocContentDumpFormatOutput(buf, cur,
@@ -1255,14 +1328,14 @@
if (cur == NULL) return;
buf = ctxt->buf;
while (cur != NULL) {
- if ((ctxt->format) && (xmlIndentTreeOutput) &&
+ if ((ctxt->format == 1) && (xmlIndentTreeOutput) &&
(cur->type == XML_ELEMENT_NODE))
xmlOutputBufferWrite(buf, ctxt->indent_size *
(ctxt->level > ctxt->indent_nr ?
ctxt->indent_nr : ctxt->level),
ctxt->indent);
xhtmlNodeDumpOutput(ctxt, cur);
- if (ctxt->format) {
+ if (ctxt->format == 1) {
xmlOutputBufferWrite(buf, 1, "\n");
}
cur = cur->next;
@@ -1411,7 +1484,7 @@
xmlOutputBufferWriteString(buf, (const char *)cur->name);
if (cur->nsDef)
- xmlNsListDumpOutput(buf, cur->nsDef);
+ xmlNsListDumpOutputCtxt(ctxt, cur->nsDef);
if ((xmlStrEqual(cur->name, BAD_CAST "html") &&
(cur->ns == NULL) && (cur->nsDef == NULL))) {
/*
@@ -1459,7 +1532,7 @@
} else {
if (addmeta == 1) {
xmlOutputBufferWrite(buf, 1, ">");
- if (ctxt->format) {
+ if (ctxt->format == 1) {
xmlOutputBufferWrite(buf, 1, "\n");
if (xmlIndentTreeOutput)
xmlOutputBufferWrite(buf, ctxt->indent_size *
@@ -1474,7 +1547,7 @@
xmlOutputBufferWrite(buf, 5, "UTF-8");
}
xmlOutputBufferWrite(buf, 4, "\" />");
- if (ctxt->format)
+ if (ctxt->format == 1)
xmlOutputBufferWrite(buf, 1, "\n");
} else {
xmlOutputBufferWrite(buf, 1, ">");
@@ -1494,7 +1567,7 @@
}
xmlOutputBufferWrite(buf, 1, ">");
if (addmeta == 1) {
- if (ctxt->format) {
+ if (ctxt->format == 1) {
xmlOutputBufferWrite(buf, 1, "\n");
if (xmlIndentTreeOutput)
xmlOutputBufferWrite(buf, ctxt->indent_size *
@@ -1589,13 +1662,13 @@
if (cur->children != NULL) {
int indent = ctxt->format;
- if (format) xmlOutputBufferWrite(buf, 1, "\n");
+ if (format == 1) xmlOutputBufferWrite(buf, 1, "\n");
if (ctxt->level >= 0) ctxt->level++;
ctxt->format = format;
xhtmlNodeListDumpOutput(ctxt, cur->children);
if (ctxt->level > 0) ctxt->level--;
ctxt->format = indent;
- if ((xmlIndentTreeOutput) && (format))
+ if ((xmlIndentTreeOutput) && (format == 1))
xmlOutputBufferWrite(buf, ctxt->indent_size *
(ctxt->level > ctxt->indent_nr ?
ctxt->indent_nr : ctxt->level),
@@ -1929,7 +2002,7 @@
/*
* We assume we have UTF-8 content.
*/
- unsigned char tmp[10];
+ unsigned char tmp[12];
int val = 0, l = 1;
if (base != cur)
@@ -2133,7 +2206,7 @@
ctxt.doc = doc;
ctxt.buf = buf;
ctxt.level = level;
- ctxt.format = format;
+ ctxt.format = format ? 1 : 0;
ctxt.encoding = (const xmlChar *) encoding;
xmlSaveCtxtInit(&ctxt);
ctxt.options |= XML_SAVE_AS_XML;
@@ -2219,7 +2292,7 @@
ctxt.doc = out_doc;
ctxt.buf = out_buff;
ctxt.level = 0;
- ctxt.format = format;
+ ctxt.format = format ? 1 : 0;
ctxt.encoding = (const xmlChar *) txt_encoding;
xmlSaveCtxtInit(&ctxt);
ctxt.options |= XML_SAVE_AS_XML;
@@ -2338,7 +2411,7 @@
ctxt.doc = cur;
ctxt.buf = buf;
ctxt.level = 0;
- ctxt.format = format;
+ ctxt.format = format ? 1 : 0;
ctxt.encoding = (const xmlChar *) encoding;
xmlSaveCtxtInit(&ctxt);
ctxt.options |= XML_SAVE_AS_XML;
@@ -2428,7 +2501,7 @@
ctxt.doc = cur;
ctxt.buf = buf;
ctxt.level = 0;
- ctxt.format = format;
+ ctxt.format = format ? 1 : 0;
ctxt.encoding = (const xmlChar *) encoding;
xmlSaveCtxtInit(&ctxt);
ctxt.options |= XML_SAVE_AS_XML;
@@ -2483,7 +2556,7 @@
ctxt.doc = cur;
ctxt.buf = buf;
ctxt.level = 0;
- ctxt.format = format;
+ ctxt.format = format ? 1 : 0;
ctxt.encoding = (const xmlChar *) encoding;
xmlSaveCtxtInit(&ctxt);
ctxt.options |= XML_SAVE_AS_XML;
diff --git a/xmlschemas.c b/xmlschemas.c
index 47451b1..ddb31d6 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -6797,7 +6797,7 @@
tmp->next = NULL;
if (wildc->nsSet == NULL)
wildc->nsSet = tmp;
- else
+ else if (lastNs != NULL)
lastNs->next = tmp;
lastNs = tmp;
}
@@ -10343,27 +10343,39 @@
/* Did we already fetch the doc? */
if (bkt != NULL) {
- /* TODO: The following nasty cases will produce an error. */
if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
- /* We included/redefined and then try to import a schema. */
+ /*
+ * We included/redefined and then try to import a schema,
+ * but the new location provided for import was different.
+ */
if (schemaLocation == NULL)
schemaLocation = BAD_CAST "in_memory_buffer";
- xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
- invokingNode, NULL,
- "The schema document '%s' cannot be imported, since "
- "it was already included or redefined",
- schemaLocation, NULL);
- goto exit;
+ if (!xmlStrEqual(schemaLocation,
+ bkt->schemaLocation)) {
+ xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
+ invokingNode, NULL,
+ "The schema document '%s' cannot be imported, since "
+ "it was already included or redefined",
+ schemaLocation, NULL);
+ goto exit;
+ }
} else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
- /* We imported and then try to include/redefine a schema. */
+ /*
+ * We imported and then try to include/redefine a schema,
+ * but the new location provided for the include/redefine
+ * was different.
+ */
if (schemaLocation == NULL)
schemaLocation = BAD_CAST "in_memory_buffer";
- xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
- invokingNode, NULL,
- "The schema document '%s' cannot be included or "
- "redefined, since it was already imported",
- schemaLocation, NULL);
- goto exit;
+ if (!xmlStrEqual(schemaLocation,
+ bkt->schemaLocation)) {
+ xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
+ invokingNode, NULL,
+ "The schema document '%s' cannot be included or "
+ "redefined, since it was already imported",
+ schemaLocation, NULL);
+ goto exit;
+ }
}
}
@@ -10519,9 +10531,9 @@
/* Parse from memory buffer. */
doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
NULL, NULL, SCHEMAS_PARSE_OPTIONS);
- schemaLocation = xmlStrdup(BAD_CAST "in_memory_buffer");
+ schemaLocation = BAD_CAST "in_memory_buffer";
if (doc != NULL)
- doc->URL = schemaLocation;
+ doc->URL = xmlStrdup(schemaLocation);
}
/*
* For <import>:
@@ -11027,14 +11039,15 @@
*/
isChameleon = 1;
if (bucket->parsed &&
- (bucket->targetNamespace != pctxt->targetNamespace)) {
- /*
- * This is a sanity check, I dunno yet if this can happen.
- */
- PERROR_INT("xmlSchemaParseIncludeOrRedefine",
- "trying to use an already parsed schema for a "
- "different targetNamespace");
- return(-1);
+ bucket->origTargetNamespace != NULL) {
+ xmlSchemaCustomErr(ACTXT_CAST pctxt,
+ XML_SCHEMAP_SRC_INCLUDE,
+ node, NULL,
+ "The target namespace of the included/redefined schema "
+ "'%s' has to be absent or the same as the "
+ "including/redefining schema's target namespace",
+ schemaLocation, NULL);
+ goto exit_error;
}
bucket->targetNamespace = pctxt->targetNamespace;
}
@@ -12512,7 +12525,12 @@
* *
************************************************************************/
-static void
+/**
+ * xmlSchemaBuildContentModelForSubstGroup:
+ *
+ * Returns 1 if nillable, 0 otherwise
+ */
+static int
xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
{
@@ -12520,6 +12538,7 @@
xmlSchemaElementPtr elemDecl, member;
xmlSchemaSubstGroupPtr substGroup;
int i;
+ int ret = 0;
elemDecl = (xmlSchemaElementPtr) particle->children;
/*
@@ -12535,7 +12554,7 @@
"Internal error: xmlSchemaBuildContentModelForSubstGroup, "
"declaration is marked having a subst. group but none "
"available.\n", elemDecl->name, NULL);
- return;
+ return(0);
}
if (counter >= 0) {
/*
@@ -12615,21 +12634,31 @@
xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
}
- if (particle->minOccurs == 0)
+ if (particle->minOccurs == 0) {
xmlAutomataNewEpsilon(pctxt->am, start, end);
+ ret = 1;
+ }
pctxt->state = end;
+ return(ret);
}
-static void
+/**
+ * xmlSchemaBuildContentModelForElement:
+ *
+ * Returns 1 if nillable, 0 otherwise
+ */
+static int
xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaParticlePtr particle)
{
+ int ret = 0;
+
if (((xmlSchemaElementPtr) particle->children)->flags &
XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
/*
* Substitution groups.
*/
- xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
+ ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
} else {
xmlSchemaElementPtr elemDecl;
xmlAutomataStatePtr start;
@@ -12637,7 +12666,7 @@
elemDecl = (xmlSchemaElementPtr) particle->children;
if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
- return;
+ return(0);
if (particle->maxOccurs == 1) {
start = ctxt->state;
ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
@@ -12665,9 +12694,12 @@
ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
NULL, counter);
}
- if (particle->minOccurs == 0)
+ if (particle->minOccurs == 0) {
xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
+ ret = 1;
+ }
}
+ return(ret);
}
/**
@@ -12678,21 +12710,24 @@
*
* Create the automaton for the {content type} of a complex type.
*
+ * Returns 1 if the content is nillable, 0 otherwise
*/
-static void
+static int
xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
xmlSchemaParticlePtr particle)
{
+ int ret = 0, tmp2;
+
if (particle == NULL) {
PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
- return;
+ return(1);
}
if (particle->children == NULL) {
/*
* Just return in this case. A missing "term" of the particle
* might arise due to an invalid "term" component.
*/
- return;
+ return(1);
}
switch (particle->children->type) {
@@ -12744,7 +12779,8 @@
int counter;
xmlAutomataStatePtr hop;
int maxOccurs =
- particle->maxOccurs == UNBOUNDED ? UNBOUNDED : particle->maxOccurs - 1;
+ particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
+ particle->maxOccurs - 1;
int minOccurs =
particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
@@ -12779,243 +12815,273 @@
}
if (particle->minOccurs == 0) {
xmlAutomataNewEpsilon(pctxt->am, start, end);
+ ret = 1;
}
pctxt->state = end;
break;
}
case XML_SCHEMA_TYPE_ELEMENT:
- xmlSchemaBuildContentModelForElement(pctxt, particle);
+ ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
break;
case XML_SCHEMA_TYPE_SEQUENCE:{
- xmlSchemaTreeItemPtr sub;
+ xmlSchemaTreeItemPtr sub;
- /*
- * If max and min occurances are default (1) then
- * simply iterate over the particles of the <sequence>.
- */
- if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
- sub = particle->children->children;
- while (sub != NULL) {
- xmlSchemaBuildAContentModel(pctxt,
- (xmlSchemaParticlePtr) sub);
- sub = sub->next;
- }
- } else {
- xmlAutomataStatePtr oldstate = pctxt->state;
+ ret = 1;
+ /*
+ * If max and min occurances are default (1) then
+ * simply iterate over the particles of the <sequence>.
+ */
+ if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
+ sub = particle->children->children;
- if (particle->maxOccurs >= UNBOUNDED) {
- if (particle->minOccurs > 1) {
- xmlAutomataStatePtr tmp;
- int counter;
+ while (sub != NULL) {
+ tmp2 = xmlSchemaBuildAContentModel(pctxt,
+ (xmlSchemaParticlePtr) sub);
+ if (tmp2 != 1) ret = 0;
+ sub = sub->next;
+ }
+ } else {
+ xmlAutomataStatePtr oldstate = pctxt->state;
- pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
- oldstate, NULL);
- oldstate = pctxt->state;
-
- counter = xmlAutomataNewCounter(pctxt->am,
- particle->minOccurs - 1, UNBOUNDED);
-
- sub = particle->children->children;
- while (sub != NULL) {
- xmlSchemaBuildAContentModel(pctxt,
- (xmlSchemaParticlePtr) sub);
- sub = sub->next;
- }
- tmp = pctxt->state;
- xmlAutomataNewCountedTrans(pctxt->am, tmp,
- oldstate, counter);
- pctxt->state =
- xmlAutomataNewCounterTrans(pctxt->am, tmp,
- NULL, counter);
-
- } else {
- pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
- oldstate, NULL);
- oldstate = pctxt->state;
-
- sub = particle->children->children;
- while (sub != NULL) {
- xmlSchemaBuildAContentModel(pctxt,
- (xmlSchemaParticlePtr) sub);
- sub = sub->next;
- }
- xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
- oldstate);
- /*
- * epsilon needed to block previous trans from
- * being allowed to enter back from another
- * construct
- */
- pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
- pctxt->state, NULL);
- if (particle->minOccurs == 0) {
- xmlAutomataNewEpsilon(pctxt->am,
- oldstate, pctxt->state);
- }
- }
- } else if ((particle->maxOccurs > 1)
- || (particle->minOccurs > 1)) {
+ if (particle->maxOccurs >= UNBOUNDED) {
+ if (particle->minOccurs > 1) {
xmlAutomataStatePtr tmp;
int counter;
pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
- oldstate, NULL);
+ oldstate, NULL);
oldstate = pctxt->state;
counter = xmlAutomataNewCounter(pctxt->am,
- particle->minOccurs - 1,
- particle->maxOccurs - 1);
+ particle->minOccurs - 1, UNBOUNDED);
sub = particle->children->children;
while (sub != NULL) {
- xmlSchemaBuildAContentModel(pctxt,
- (xmlSchemaParticlePtr) sub);
+ tmp2 = xmlSchemaBuildAContentModel(pctxt,
+ (xmlSchemaParticlePtr) sub);
+ if (tmp2 != 1) ret = 0;
sub = sub->next;
}
tmp = pctxt->state;
- xmlAutomataNewCountedTrans(pctxt->am,
- tmp, oldstate, counter);
+ xmlAutomataNewCountedTrans(pctxt->am, tmp,
+ oldstate, counter);
pctxt->state =
- xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
- counter);
- if (particle->minOccurs == 0) {
+ xmlAutomataNewCounterTrans(pctxt->am, tmp,
+ NULL, counter);
+ if (ret == 1)
xmlAutomataNewEpsilon(pctxt->am,
- oldstate, pctxt->state);
- }
+ oldstate, pctxt->state);
+
} else {
+ pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
+ oldstate, NULL);
+ oldstate = pctxt->state;
+
sub = particle->children->children;
while (sub != NULL) {
- xmlSchemaBuildAContentModel(pctxt,
- (xmlSchemaParticlePtr) sub);
+ tmp2 = xmlSchemaBuildAContentModel(pctxt,
+ (xmlSchemaParticlePtr) sub);
+ if (tmp2 != 1) ret = 0;
sub = sub->next;
}
+ xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
+ oldstate);
+ /*
+ * epsilon needed to block previous trans from
+ * being allowed to enter back from another
+ * construct
+ */
+ pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
+ pctxt->state, NULL);
if (particle->minOccurs == 0) {
- xmlAutomataNewEpsilon(pctxt->am, oldstate,
- pctxt->state);
+ xmlAutomataNewEpsilon(pctxt->am,
+ oldstate, pctxt->state);
+ ret = 1;
}
}
- }
- break;
- }
- case XML_SCHEMA_TYPE_CHOICE:{
- xmlSchemaTreeItemPtr sub;
- xmlAutomataStatePtr start, end;
+ } else if ((particle->maxOccurs > 1)
+ || (particle->minOccurs > 1)) {
+ xmlAutomataStatePtr tmp;
+ int counter;
- start = pctxt->state;
- end = xmlAutomataNewState(pctxt->am);
+ pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
+ oldstate, NULL);
+ oldstate = pctxt->state;
- /*
- * iterate over the subtypes and remerge the end with an
- * epsilon transition
- */
- if (particle->maxOccurs == 1) {
- sub = particle->children->children;
+ counter = xmlAutomataNewCounter(pctxt->am,
+ particle->minOccurs - 1,
+ particle->maxOccurs - 1);
+
+ sub = particle->children->children;
while (sub != NULL) {
- pctxt->state = start;
- xmlSchemaBuildAContentModel(pctxt,
- (xmlSchemaParticlePtr) sub);
- xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
+ tmp2 = xmlSchemaBuildAContentModel(pctxt,
+ (xmlSchemaParticlePtr) sub);
+ if (tmp2 != 1) ret = 0;
sub = sub->next;
}
+ tmp = pctxt->state;
+ xmlAutomataNewCountedTrans(pctxt->am,
+ tmp, oldstate, counter);
+ pctxt->state =
+ xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
+ counter);
+ if ((particle->minOccurs == 0) || (ret == 1)) {
+ xmlAutomataNewEpsilon(pctxt->am,
+ oldstate, pctxt->state);
+ ret = 1;
+ }
} else {
- int counter;
- xmlAutomataStatePtr hop, base;
- int maxOccurs = particle->maxOccurs == UNBOUNDED ?
- UNBOUNDED : particle->maxOccurs - 1;
- int minOccurs =
- particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
-
- /*
- * use a counter to keep track of the number of transtions
- * which went through the choice.
- */
- counter =
- xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
- hop = xmlAutomataNewState(pctxt->am);
- base = xmlAutomataNewState(pctxt->am);
-
- sub = particle->children->children;
+ sub = particle->children->children;
while (sub != NULL) {
- pctxt->state = base;
- xmlSchemaBuildAContentModel(pctxt,
- (xmlSchemaParticlePtr) sub);
- xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
+ tmp2 = xmlSchemaBuildAContentModel(pctxt,
+ (xmlSchemaParticlePtr) sub);
+ if (tmp2 != 1) ret = 0;
sub = sub->next;
}
- xmlAutomataNewEpsilon(pctxt->am, start, base);
- xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
- xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
+ if (particle->minOccurs == 0) {
+ xmlAutomataNewEpsilon(pctxt->am, oldstate,
+ pctxt->state);
+ ret = 1;
+ }
}
- if (particle->minOccurs == 0) {
- xmlAutomataNewEpsilon(pctxt->am, start, end);
- }
- pctxt->state = end;
- break;
}
- case XML_SCHEMA_TYPE_ALL:{
- xmlAutomataStatePtr start;
- xmlSchemaParticlePtr sub;
- xmlSchemaElementPtr elemDecl;
- int lax;
+ break;
+ }
+ case XML_SCHEMA_TYPE_CHOICE:{
+ xmlSchemaTreeItemPtr sub;
+ xmlAutomataStatePtr start, end;
- sub = (xmlSchemaParticlePtr) particle->children->children;
- if (sub == NULL)
- break;
- start = pctxt->state;
+ ret = 0;
+ start = pctxt->state;
+ end = xmlAutomataNewState(pctxt->am);
+
+ /*
+ * iterate over the subtypes and remerge the end with an
+ * epsilon transition
+ */
+ if (particle->maxOccurs == 1) {
+ sub = particle->children->children;
while (sub != NULL) {
pctxt->state = start;
-
- elemDecl = (xmlSchemaElementPtr) sub->children;
- if (elemDecl == NULL) {
- PERROR_INT("xmlSchemaBuildAContentModel",
- "<element> particle has no term");
- return;
- };
- /*
- * NOTE: The {max occurs} of all the particles in the
- * {particles} of the group must be 0 or 1; this is
- * already ensured during the parse of the content of
- * <all>.
- */
- if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
- int counter;
-
- /*
- * This is an abstract group, we need to share
- * the same counter for all the element transitions
- * derived from the group
- */
- counter = xmlAutomataNewCounter(pctxt->am,
- sub->minOccurs, sub->maxOccurs);
- xmlSchemaBuildContentModelForSubstGroup(pctxt,
- sub, counter, pctxt->state);
- } else {
- if ((sub->minOccurs == 1) &&
- (sub->maxOccurs == 1)) {
- xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
- pctxt->state,
- elemDecl->name,
- elemDecl->targetNamespace,
- 1, 1, elemDecl);
- } else if ((sub->minOccurs == 0) &&
- (sub->maxOccurs == 1)) {
-
- xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
- pctxt->state,
- elemDecl->name,
- elemDecl->targetNamespace,
- 0,
- 1,
- elemDecl);
- }
- }
- sub = (xmlSchemaParticlePtr) sub->next;
+ tmp2 = xmlSchemaBuildAContentModel(pctxt,
+ (xmlSchemaParticlePtr) sub);
+ if (tmp2 == 1) ret = 1;
+ xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
+ sub = sub->next;
}
- lax = particle->minOccurs == 0;
- pctxt->state =
- xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, lax);
- break;
+ } else {
+ int counter;
+ xmlAutomataStatePtr hop, base;
+ int maxOccurs = particle->maxOccurs == UNBOUNDED ?
+ UNBOUNDED : particle->maxOccurs - 1;
+ int minOccurs =
+ particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
+
+ /*
+ * use a counter to keep track of the number of transtions
+ * which went through the choice.
+ */
+ counter =
+ xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
+ hop = xmlAutomataNewState(pctxt->am);
+ base = xmlAutomataNewState(pctxt->am);
+
+ sub = particle->children->children;
+ while (sub != NULL) {
+ pctxt->state = base;
+ tmp2 = xmlSchemaBuildAContentModel(pctxt,
+ (xmlSchemaParticlePtr) sub);
+ if (tmp2 == 1) ret = 1;
+ xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
+ sub = sub->next;
+ }
+ xmlAutomataNewEpsilon(pctxt->am, start, base);
+ xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
+ xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
+ if (ret == 1)
+ xmlAutomataNewEpsilon(pctxt->am, base, end);
}
+ if (particle->minOccurs == 0) {
+ xmlAutomataNewEpsilon(pctxt->am, start, end);
+ ret = 1;
+ }
+ pctxt->state = end;
+ break;
+ }
+ case XML_SCHEMA_TYPE_ALL:{
+ xmlAutomataStatePtr start, tmp;
+ xmlSchemaParticlePtr sub;
+ xmlSchemaElementPtr elemDecl;
+
+ ret = 1;
+
+ sub = (xmlSchemaParticlePtr) particle->children->children;
+ if (sub == NULL)
+ break;
+
+ ret = 0;
+
+ start = pctxt->state;
+ tmp = xmlAutomataNewState(pctxt->am);
+ xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
+ pctxt->state = tmp;
+ while (sub != NULL) {
+ pctxt->state = tmp;
+
+ elemDecl = (xmlSchemaElementPtr) sub->children;
+ if (elemDecl == NULL) {
+ PERROR_INT("xmlSchemaBuildAContentModel",
+ "<element> particle has no term");
+ return(ret);
+ };
+ /*
+ * NOTE: The {max occurs} of all the particles in the
+ * {particles} of the group must be 0 or 1; this is
+ * already ensured during the parse of the content of
+ * <all>.
+ */
+ if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
+ int counter;
+
+ /*
+ * This is an abstract group, we need to share
+ * the same counter for all the element transitions
+ * derived from the group
+ */
+ counter = xmlAutomataNewCounter(pctxt->am,
+ sub->minOccurs, sub->maxOccurs);
+ xmlSchemaBuildContentModelForSubstGroup(pctxt,
+ sub, counter, pctxt->state);
+ } else {
+ if ((sub->minOccurs == 1) &&
+ (sub->maxOccurs == 1)) {
+ xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
+ pctxt->state,
+ elemDecl->name,
+ elemDecl->targetNamespace,
+ 1, 1, elemDecl);
+ } else if ((sub->minOccurs == 0) &&
+ (sub->maxOccurs == 1)) {
+
+ xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
+ pctxt->state,
+ elemDecl->name,
+ elemDecl->targetNamespace,
+ 0,
+ 1,
+ elemDecl);
+ }
+ }
+ sub = (xmlSchemaParticlePtr) sub->next;
+ }
+ pctxt->state =
+ xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
+ if (particle->minOccurs == 0) {
+ xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
+ ret = 1;
+ }
+ break;
+ }
case XML_SCHEMA_TYPE_GROUP:
/*
* If we hit a model group definition, then this means that
@@ -13024,14 +13090,16 @@
* TODO: But the group should be substituted and not occur at
* all in the content model at this point. Fix this.
*/
+ ret = 1;
break;
default:
xmlSchemaInternalErr2(ACTXT_CAST pctxt,
"xmlSchemaBuildAContentModel",
"found unexpected term of type '%s' in content model",
WXS_ITEM_TYPE_NAME(particle->children), NULL);
- return;
+ return(ret);
}
+ return(ret);
}
/**
@@ -15088,9 +15156,10 @@
FREE_AND_NULL(str)
return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
}
- if ( (WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
- (WXS_IS_RESTRICTION(type) == 0) &&
- (! WXS_IS_ANY_SIMPLE_TYPE(baseType))) {
+ if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
+ (WXS_IS_RESTRICTION(type) == 0) &&
+ ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
+ (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
xmlSchemaPCustomErr(ctxt,
XML_SCHEMAP_ST_PROPS_CORRECT_1,
WXS_BASIC_CAST type, NULL,
@@ -15567,7 +15636,8 @@
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
}
member = member->next;
- baseMember = baseMember->next;
+ if (baseMember != NULL)
+ baseMember = baseMember->next;
}
}
}
@@ -17289,7 +17359,7 @@
flength = bflength;
if (flength) {
if (! fminlen)
- flength = bflength;
+ fminlen = bfminlen;
if (fminlen) {
/* (1.1) length >= minLength */
res = xmlSchemaCompareValues(flength->val, fminlen->val);
@@ -23653,12 +23723,14 @@
parBind->dupls = bind->dupls;
bind->dupls = NULL;
}
- if (*parTable == NULL)
- *parTable = parBind;
- else {
- parBind->next = *parTable;
- *parTable = parBind;
- }
+ if (parTable != NULL) {
+ if (*parTable == NULL)
+ *parTable = parBind;
+ else {
+ parBind->next = *parTable;
+ *parTable = parBind;
+ }
+ }
}
next_binding:
@@ -24461,10 +24533,10 @@
/* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
if (valNeeded)
ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
- value, &val, NULL);
+ value, &val, node);
else
ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
- value, NULL, NULL);
+ value, NULL, node);
break;
}
} else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
@@ -25222,7 +25294,6 @@
if (vctxt->nbAttrInfos == 0)
return (0);
- nbUses = vctxt->nbAttrInfos;
/*
* Validate against the wildcard.
*/
@@ -25313,16 +25384,18 @@
* whose {attribute declaration}'s {type definition}
* is or is derived from ID."
*/
- for (j = 0; j < attrUseList->nbItems; j++) {
- if (xmlSchemaIsDerivedFromBuiltInType(
- WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
- XML_SCHEMAS_ID)) {
- /* URGENT VAL TODO: implement */
- iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
- TODO
- break;
- }
- }
+ if (attrUseList != NULL) {
+ for (j = 0; j < attrUseList->nbItems; j++) {
+ if (xmlSchemaIsDerivedFromBuiltInType(
+ WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
+ XML_SCHEMAS_ID)) {
+ /* URGENT VAL TODO: implement */
+ iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
+ TODO
+ break;
+ }
+ }
+ }
}
} else if (type->attributeWildcard->processContents ==
XML_SCHEMAS_ANY_LAX) {
@@ -26739,6 +26812,11 @@
vctxt->skipDepth = 0;
return(ret);
}
+ /*
+ * Augment the IDC definitions for the main schema and all imported ones
+ * NOTE: main schema is the first in the imported list
+ */
+ xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
}
if (vctxt->depth > 0) {
/*
diff --git a/xmlschemastypes.c b/xmlschemastypes.c
index 0d967d0..834b261 100644
--- a/xmlschemastypes.c
+++ b/xmlschemastypes.c
@@ -2389,9 +2389,11 @@
normOnTheFly);
break;
case XML_SCHEMAS_FLOAT:
- case XML_SCHEMAS_DOUBLE:{
+ case XML_SCHEMAS_DOUBLE: {
const xmlChar *cur = value;
int neg = 0;
+ int digits_before = 0;
+ int digits_after = 0;
if (normOnTheFly)
while IS_WSP_BLANK_CH(*cur) cur++;
@@ -2464,12 +2466,17 @@
goto return1;
while ((*cur >= '0') && (*cur <= '9')) {
cur++;
+ digits_before++;
}
if (*cur == '.') {
cur++;
- while ((*cur >= '0') && (*cur <= '9'))
+ while ((*cur >= '0') && (*cur <= '9')) {
cur++;
+ digits_after++;
+ }
}
+ if ((digits_before == 0) && (digits_after == 0))
+ goto return1;
if ((*cur == 'e') || (*cur == 'E')) {
cur++;
if ((*cur == '-') || (*cur == '+'))
@@ -2899,12 +2906,23 @@
case XML_SCHEMAS_ANYURI:{
if (*value != 0) {
xmlURIPtr uri;
+ xmlChar *tmpval, *cur;
if (normOnTheFly) {
norm = xmlSchemaCollapseString(value);
if (norm != NULL)
value = norm;
}
- uri = xmlParseURI((const char *) value);
+ tmpval = xmlStrdup(value);
+ for (cur = tmpval; *cur; ++cur) {
+ if (*cur < 32 || *cur >= 127 || *cur == ' ' ||
+ *cur == '<' || *cur == '>' || *cur == '"' ||
+ *cur == '{' || *cur == '}' || *cur == '|' ||
+ *cur == '\\' || *cur == '^' || *cur == '`' ||
+ *cur == '\'')
+ *cur = '_';
+ }
+ uri = xmlParseURI((const char *) tmpval);
+ xmlFree(tmpval);
if (uri == NULL)
goto return1;
xmlFreeURI(uri);
@@ -3551,8 +3569,8 @@
/* seconds */
sec = x->value.dur.sec - y->value.dur.sec;
- carry = (long)sec / SECS_PER_DAY;
- sec -= (double)(carry * SECS_PER_DAY);
+ carry = (long)(sec / SECS_PER_DAY);
+ sec -= ((double)carry) * SECS_PER_DAY;
/* days */
day = x->value.dur.day - y->value.dur.day + carry;
diff --git a/xmlstring.c b/xmlstring.c
index 4f3b373..910f244 100644
--- a/xmlstring.c
+++ b/xmlstring.c
@@ -366,7 +366,7 @@
*/
const xmlChar *
-xmlStrcasestr(const xmlChar *str, xmlChar *val) {
+xmlStrcasestr(const xmlChar *str, const xmlChar *val) {
int n;
if (str == NULL) return(NULL);
diff --git a/xmlwriter.c b/xmlwriter.c
index f0eef34..11b15e0 100644
--- a/xmlwriter.c
+++ b/xmlwriter.c
@@ -242,8 +242,8 @@
out = xmlOutputBufferCreateFilename(uri, NULL, compression);
if (out == NULL) {
- xmlWriterErrMsg(NULL, XML_ERR_NO_MEMORY,
- "xmlNewTextWriterFilename : out of memory!\n");
+ xmlWriterErrMsg(NULL, XML_IO_EIO,
+ "xmlNewTextWriterFilename : cannot open uri\n");
return NULL;
}
@@ -370,7 +370,7 @@
ctxt = xmlCreatePushParserCtxt(&saxHandler, NULL, NULL, 0, NULL);
if (ctxt == NULL) {
xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
- "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
+ "xmlNewTextWriterDoc : error at xmlCreatePushParserCtxt!\n");
return NULL;
}
/*
@@ -389,8 +389,10 @@
ret = xmlNewTextWriterPushParser(ctxt, compression);
if (ret == NULL) {
+ xmlFreeDoc(ctxt->myDoc);
+ xmlFreeParserCtxt(ctxt);
xmlWriterErrMsg(NULL, XML_ERR_INTERNAL_ERROR,
- "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
+ "xmlNewTextWriterDoc : error at xmlNewTextWriterPushParser!\n");
return NULL;
}
@@ -898,8 +900,8 @@
}
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteComment(writer, buf);
@@ -1323,8 +1325,8 @@
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteRaw(writer, buf);
@@ -1452,8 +1454,8 @@
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteString(writer, buf);
@@ -1510,12 +1512,13 @@
if (buf != NULL) {
count = xmlTextWriterWriteRaw(writer, buf);
- if (count < 0)
- return -1;
- sum += count;
if (buf != content) /* buf was allocated by us, so free it */
xmlFree(buf);
+
+ if (count < 0)
+ return -1;
+ sum += count;
}
return sum;
@@ -1997,8 +2000,8 @@
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteAttribute(writer, name, buf);
@@ -2099,8 +2102,8 @@
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteAttributeNS(writer, prefix, name, namespaceURI,
buf);
@@ -2200,8 +2203,8 @@
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteElement(writer, name, buf);
@@ -2302,8 +2305,8 @@
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteElementNS(writer, prefix, name, namespaceURI,
buf);
@@ -2551,8 +2554,8 @@
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWritePI(writer, target, buf);
@@ -2764,8 +2767,8 @@
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteCDATA(writer, buf);
@@ -3082,8 +3085,8 @@
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteDTD(writer, name, pubid, sysid, buf);
@@ -3320,8 +3323,8 @@
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteDTDElement(writer, name, buf);
@@ -3557,8 +3560,8 @@
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteDTDAttlist(writer, name, buf);
@@ -3819,8 +3822,8 @@
return -1;
buf = xmlTextWriterVSprintf(format, argptr);
- if (buf == 0)
- return 0;
+ if (buf == NULL)
+ return -1;
rc = xmlTextWriterWriteDTDInternalEntity(writer, pe, name, buf);
diff --git a/xpath.c b/xpath.c
index 4783c0e..d9d902c 100644
--- a/xpath.c
+++ b/xpath.c
@@ -252,6 +252,7 @@
"Encoding error\n",
"Char out of XML range\n",
"Invalid or incomplete context\n",
+ "Stack usage errror\n",
"?? Unknown error ??\n" /* Must be last in the list! */
};
#define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) / \
@@ -2398,6 +2399,42 @@
************************************************************************/
/**
+ * xmlXPathSetFrame:
+ * @ctxt: an XPath parser context
+ *
+ * Set the callee evaluation frame
+ *
+ * Returns the previous frame value to be restored once done
+ */
+static int
+xmlXPathSetFrame(xmlXPathParserContextPtr ctxt) {
+ int ret;
+
+ if (ctxt == NULL)
+ return(0);
+ ret = ctxt->valueFrame;
+ ctxt->valueFrame = ctxt->valueNr;
+ return(ret);
+}
+
+/**
+ * xmlXPathPopFrame:
+ * @ctxt: an XPath parser context
+ * @frame: the previous frame value
+ *
+ * Remove the callee evaluation frame
+ */
+static void
+xmlXPathPopFrame(xmlXPathParserContextPtr ctxt, int frame) {
+ if (ctxt == NULL)
+ return;
+ if (ctxt->valueNr < ctxt->valueFrame) {
+ xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
+ }
+ ctxt->valueFrame = frame;
+}
+
+/**
* valuePop:
* @ctxt: an XPath evaluation context
*
@@ -2412,6 +2449,12 @@
if ((ctxt == NULL) || (ctxt->valueNr <= 0))
return (NULL);
+
+ if (ctxt->valueNr <= ctxt->valueFrame) {
+ xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
+ return (NULL);
+ }
+
ctxt->valueNr--;
if (ctxt->valueNr > 0)
ctxt->value = ctxt->valueTab[ctxt->valueNr - 1];
@@ -2442,6 +2485,7 @@
sizeof(ctxt->valueTab[0]));
if (tmp == NULL) {
xmlGenericError(xmlGenericErrorContext, "realloc failed !\n");
+ ctxt->error = XPATH_MEMORY_ERROR;
return (0);
}
ctxt->valueMax *= 2;
@@ -3522,13 +3566,13 @@
} else if (cur->nodeNr == cur->nodeMax) {
xmlNodePtr *temp;
- cur->nodeMax *= 2;
- temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
+ temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
sizeof(xmlNodePtr));
if (temp == NULL) {
xmlXPathErrMemory(NULL, "growing nodeset\n");
return;
}
+ cur->nodeMax *= 2;
cur->nodeTab = temp;
}
cur->nodeTab[cur->nodeNr++] = xmlXPathNodeSetDupNs(node, ns);
@@ -3575,13 +3619,13 @@
} else if (cur->nodeNr == cur->nodeMax) {
xmlNodePtr *temp;
- cur->nodeMax *= 2;
- temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
+ temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
sizeof(xmlNodePtr));
if (temp == NULL) {
xmlXPathErrMemory(NULL, "growing nodeset\n");
return;
}
+ cur->nodeMax *= 2;
cur->nodeTab = temp;
}
if (val->type == XML_NAMESPACE_DECL) {
@@ -3627,14 +3671,14 @@
} else if (cur->nodeNr == cur->nodeMax) {
xmlNodePtr *temp;
- cur->nodeMax *= 2;
- temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
+ temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax * 2 *
sizeof(xmlNodePtr));
if (temp == NULL) {
xmlXPathErrMemory(NULL, "growing nodeset\n");
return;
}
cur->nodeTab = temp;
+ cur->nodeMax *= 2;
}
if (val->type == XML_NAMESPACE_DECL) {
xmlNsPtr ns = (xmlNsPtr) val;
@@ -3738,14 +3782,14 @@
} else if (val1->nodeNr == val1->nodeMax) {
xmlNodePtr *temp;
- val1->nodeMax *= 2;
- temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
+ temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax * 2 *
sizeof(xmlNodePtr));
if (temp == NULL) {
xmlXPathErrMemory(NULL, "merging nodeset\n");
return(NULL);
}
val1->nodeTab = temp;
+ val1->nodeMax *= 2;
}
if (n2->type == XML_NAMESPACE_DECL) {
xmlNsPtr ns = (xmlNsPtr) n2;
@@ -3907,14 +3951,14 @@
} else if (set1->nodeNr >= set1->nodeMax) {
xmlNodePtr *temp;
- set1->nodeMax *= 2;
temp = (xmlNodePtr *) xmlRealloc(
- set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
+ set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
if (temp == NULL) {
xmlXPathErrMemory(NULL, "merging nodeset\n");
return(NULL);
}
set1->nodeTab = temp;
+ set1->nodeMax *= 2;
}
if (n2->type == XML_NAMESPACE_DECL) {
xmlNsPtr ns = (xmlNsPtr) n2;
@@ -3991,14 +4035,14 @@
} else if (set1->nodeNr >= set1->nodeMax) {
xmlNodePtr *temp;
- set1->nodeMax *= 2;
temp = (xmlNodePtr *) xmlRealloc(
- set1->nodeTab, set1->nodeMax * sizeof(xmlNodePtr));
+ set1->nodeTab, set1->nodeMax * 2 * sizeof(xmlNodePtr));
if (temp == NULL) {
xmlXPathErrMemory(NULL, "merging nodeset\n");
return(NULL);
}
set1->nodeTab = temp;
+ set1->nodeMax *= 2;
}
set1->nodeTab[set1->nodeNr++] = n2;
}
@@ -5003,7 +5047,7 @@
/**
* xmlXPathRegisterNs:
* @ctxt: the XPath context
- * @prefix: the namespace prefix
+ * @prefix: the namespace prefix cannot be NULL or empty string
* @ns_uri: the namespace name
*
* Register a new namespace. If @ns_uri is NULL it unregisters
@@ -5018,6 +5062,8 @@
return(-1);
if (prefix == NULL)
return(-1);
+ if (prefix[0] == 0)
+ return(-1);
if (ctxt->nsHash == NULL)
ctxt->nsHash = xmlHashCreate(10);
@@ -6152,6 +6198,7 @@
ret->valueNr = 0;
ret->valueMax = 10;
ret->value = NULL;
+ ret->valueFrame = 0;
ret->context = ctxt;
ret->comp = comp;
@@ -8104,9 +8151,17 @@
xmlNodePtr
xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
- if (cur != NULL && cur->children != NULL)
- return cur->children ;
- if (cur == NULL) cur = ctxt->context->node;
+ if ((cur != NULL) && (cur->type != XML_ATTRIBUTE_NODE) &&
+ (cur->type != XML_NAMESPACE_DECL) && (cur->children != NULL))
+ return(cur->children);
+
+ if (cur == NULL) {
+ cur = ctxt->context->node;
+ if (cur->type == XML_NAMESPACE_DECL)
+ return(NULL);
+ if (cur->type == XML_ATTRIBUTE_NODE)
+ cur = cur->parent;
+ }
if (cur == NULL) return(NULL) ; /* ERROR */
if (cur->next != NULL) return(cur->next) ;
do {
@@ -8160,8 +8215,13 @@
xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur)
{
if ((ctxt == NULL) || (ctxt->context == NULL)) return(NULL);
- if (cur == NULL)
+ if (cur == NULL) {
cur = ctxt->context->node;
+ if (cur->type == XML_NAMESPACE_DECL)
+ return(NULL);
+ if (cur->type == XML_ATTRIBUTE_NODE)
+ return(cur->parent);
+ }
if (cur == NULL)
return (NULL);
if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
@@ -8205,8 +8265,8 @@
cur = ctxt->context->node;
if (cur == NULL)
return (NULL);
- if (cur->type == XML_NAMESPACE_DECL)
- cur = (xmlNodePtr)((xmlNsPtr)cur)->next;
+ if (cur->type == XML_NAMESPACE_DECL)
+ return (NULL);
ctxt->ancestor = cur->parent;
}
if ((cur->prev != NULL) && (cur->prev->type == XML_DTD_NODE))
@@ -9020,7 +9080,7 @@
* the index is NaN, the length is NaN, or both
* arguments are infinity (relying on Inf + -Inf = NaN)
*/
- if (!xmlXPathIsNaN(in + le) && !xmlXPathIsInf(in)) {
+ if (!xmlXPathIsInf(in) && !xmlXPathIsNaN(in + le)) {
/*
* To meet the requirements of the spec, the arguments
* must be converted to integer format before
@@ -9281,6 +9341,7 @@
if ( (ch & 0xc0) != 0xc0 ) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathTranslateFunction: Invalid UTF8 string\n");
+ /* not asserting an XPath error is probably better */
break;
}
/* then skip over remaining bytes for this char */
@@ -9288,6 +9349,7 @@
if ( (*cptr++ & 0xc0) != 0x80 ) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathTranslateFunction: Invalid UTF8 string\n");
+ /* not asserting an XPath error is probably better */
break;
}
if (ch & 0x80) /* must have had error encountered */
@@ -10029,7 +10091,6 @@
xmlXPathCompNumber(xmlXPathParserContextPtr ctxt)
{
double ret = 0.0;
- double mult = 1;
int ok = 0;
int exponent = 0;
int is_exponent_negative = 0;
@@ -10065,15 +10126,23 @@
}
#endif
if (CUR == '.') {
+ int v, frac = 0;
+ double fraction = 0;
+
NEXT;
if (((CUR < '0') || (CUR > '9')) && (!ok)) {
XP_ERROR(XPATH_NUMBER_ERROR);
}
- while ((CUR >= '0') && (CUR <= '9')) {
- mult /= 10;
- ret = ret + (CUR - '0') * mult;
+ while ((CUR >= '0') && (CUR <= '9') && (frac < MAX_FRAC)) {
+ v = (CUR - '0');
+ fraction = fraction * 10 + v;
+ frac = frac + 1;
NEXT;
}
+ fraction /= my_pow10[frac];
+ ret = ret + fraction;
+ while ((CUR >= '0') && (CUR <= '9'))
+ NEXT;
}
if ((CUR == 'e') || (CUR == 'E')) {
NEXT;
@@ -10866,7 +10935,6 @@
xmlXPathCompAndExpr(ctxt);
CHECK_ERROR;
PUSH_BINARY_EXPR(XPATH_OP_OR, op1, ctxt->comp->last, 0, 0);
- op1 = ctxt->comp->nbStep;
SKIP_BLANKS;
}
if ((sort) && (ctxt->comp->steps[ctxt->comp->last].op != XPATH_OP_VALUE)) {
@@ -11248,7 +11316,10 @@
}
}
- CHECK_ERROR;
+ if (ctxt->error != XPATH_EXPRESSION_OK) {
+ xmlFree(name);
+ return;
+ }
name = xmlXPathCompNodeTest(ctxt, &test, &type, &prefix, name);
if (test == 0)
@@ -11332,6 +11403,7 @@
SKIP_BLANKS;
}
xmlXPathCompStep(ctxt);
+ CHECK_ERROR;
SKIP_BLANKS;
while (CUR == '/') {
if ((CUR == '/') && (NXT(1) == '/')) {
@@ -11391,6 +11463,7 @@
(CUR == '@') || (CUR == '*')))
xmlXPathCompRelativeLocationPath(ctxt);
}
+ CHECK_ERROR;
}
}
}
@@ -11685,6 +11758,7 @@
xmlXPathObjectPtr contextObj = NULL, exprRes = NULL;
xmlNodePtr oldContextNode, contextNode = NULL;
xmlXPathContextPtr xpctxt = ctxt->context;
+ int frame;
#ifdef LIBXML_XPTR_ENABLED
/*
@@ -11704,6 +11778,8 @@
*/
exprOp = &ctxt->comp->steps[op->ch2];
for (i = 0; i < set->nodeNr; i++) {
+ xmlXPathObjectPtr tmp;
+
if (set->nodeTab[i] == NULL)
continue;
@@ -11731,23 +11807,25 @@
xmlXPathNodeSetAddUnique(contextObj->nodesetval,
contextNode);
+ frame = xmlXPathSetFrame(ctxt);
valuePush(ctxt, contextObj);
res = xmlXPathCompOpEvalToBoolean(ctxt, exprOp, 1);
+ tmp = valuePop(ctxt);
+ xmlXPathPopFrame(ctxt, frame);
if ((ctxt->error != XPATH_EXPRESSION_OK) || (res == -1)) {
- xmlXPathObjectPtr tmp;
- /* pop the result if any */
- tmp = valuePop(ctxt);
- while (tmp != contextObj) {
- /*
- * Free up the result
- * then pop off contextObj, which will be freed later
- */
- xmlXPathReleaseObject(xpctxt, tmp);
- tmp = valuePop(ctxt);
- }
+ while (tmp != contextObj) {
+ /*
+ * Free up the result
+ * then pop off contextObj, which will be freed later
+ */
+ xmlXPathReleaseObject(xpctxt, tmp);
+ tmp = valuePop(ctxt);
+ }
goto evaluation_error;
}
+ /* push the result back onto the stack */
+ valuePush(ctxt, tmp);
if (res)
pos++;
@@ -11984,7 +12062,6 @@
* avoid a duplicate-aware merge, if the axis to be traversed is e.g.
* the descendant-or-self axis.
*/
- addNode = xmlXPathNodeSetAdd;
mergeAndClear = xmlXPathNodeSetMergeAndClear;
switch (axis) {
case AXIS_ANCESTOR:
@@ -12658,7 +12735,7 @@
return (total);
#ifdef XP_OPTIMIZED_FILTER_FIRST
case XPATH_OP_FILTER:
- total =+ xmlXPathCompOpEvalFilterFirst(ctxt, op, first);
+ total += xmlXPathCompOpEvalFilterFirst(ctxt, op, first);
return (total);
#endif
default:
@@ -13336,6 +13413,7 @@
xmlGenericError(xmlGenericErrorContext,
"xmlXPathCompOpEval: variable %s bound to undefined prefix %s\n",
(char *) op->value4, (char *)op->value5);
+ ctxt->error = XPATH_UNDEF_PREFIX_ERROR;
return (total);
}
val = xmlXPathVariableLookupNS(ctxt->context,
@@ -13352,7 +13430,9 @@
xmlXPathFunction func;
const xmlChar *oldFunc, *oldFuncURI;
int i;
+ int frame;
+ frame = xmlXPathSetFrame(ctxt);
if (op->ch1 != -1)
total +=
xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
@@ -13360,15 +13440,18 @@
xmlGenericError(xmlGenericErrorContext,
"xmlXPathCompOpEval: parameter error\n");
ctxt->error = XPATH_INVALID_OPERAND;
+ xmlXPathPopFrame(ctxt, frame);
return (total);
}
- for (i = 0; i < op->value; i++)
+ for (i = 0; i < op->value; i++) {
if (ctxt->valueTab[(ctxt->valueNr - 1) - i] == NULL) {
xmlGenericError(xmlGenericErrorContext,
"xmlXPathCompOpEval: parameter error\n");
ctxt->error = XPATH_INVALID_OPERAND;
+ xmlXPathPopFrame(ctxt, frame);
return (total);
}
+ }
if (op->cache != NULL)
XML_CAST_FPTR(func) = op->cache;
else {
@@ -13384,6 +13467,8 @@
xmlGenericError(xmlGenericErrorContext,
"xmlXPathCompOpEval: function %s bound to undefined prefix %s\n",
(char *)op->value4, (char *)op->value5);
+ xmlXPathPopFrame(ctxt, frame);
+ ctxt->error = XPATH_UNDEF_PREFIX_ERROR;
return (total);
}
func = xmlXPathFunctionLookupNS(ctxt->context,
@@ -13405,6 +13490,7 @@
func(ctxt, op->value);
ctxt->context->function = oldFunc;
ctxt->context->functionURI = oldFuncURI;
+ xmlXPathPopFrame(ctxt, frame);
return (total);
}
case XPATH_OP_ARG:
@@ -13961,6 +14047,7 @@
}
xmlGenericError(xmlGenericErrorContext,
"XPath: unknown precompiled operation %d\n", op->op);
+ ctxt->error = XPATH_INVALID_OPERAND;
return (total);
}
@@ -14308,6 +14395,7 @@
ctxt->valueNr = 0;
ctxt->valueMax = 10;
ctxt->value = NULL;
+ ctxt->valueFrame = 0;
}
#ifdef XPATH_STREAMING
if (ctxt->comp->stream) {
@@ -14508,7 +14596,7 @@
namespaces[i++] = ns->prefix;
}
namespaces[i++] = NULL;
- namespaces[i++] = NULL;
+ namespaces[i] = NULL;
}
}
diff --git a/xpointer.c b/xpointer.c
index 5298fa5..37afa3a 100644
--- a/xpointer.c
+++ b/xpointer.c
@@ -1152,10 +1152,12 @@
if (name == NULL)
XP_ERROR(XPATH_EXPR_ERROR);
while (name != NULL) {
+ ctxt->error = XPATH_EXPRESSION_OK;
xmlXPtrEvalXPtrPart(ctxt, name);
/* in case of syntax error, break here */
- if (ctxt->error != XPATH_EXPRESSION_OK)
+ if ((ctxt->error != XPATH_EXPRESSION_OK) &&
+ (ctxt->error != XML_XPTR_UNKNOWN_SCHEME))
return;
/*
@@ -1267,6 +1269,7 @@
ctxt->valueNr = 0;
ctxt->valueMax = 10;
ctxt->value = NULL;
+ ctxt->valueFrame = 0;
}
SKIP_BLANKS;
if (CUR == '/') {
@@ -1299,12 +1302,19 @@
* *
************************************************************************/
+static
void xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs);
+static
void xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs);
+static
void xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs);
+static
void xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs);
+static
void xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs);
+static
void xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs);
+static
void xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs);
/**
@@ -1732,7 +1742,7 @@
* Function implementing here() operation
* as described in 5.4.3
*/
-void
+static void
xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs) {
CHECK_ARITY(0);
@@ -1750,7 +1760,7 @@
* Function implementing origin() operation
* as described in 5.4.3
*/
-void
+static void
xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs) {
CHECK_ARITY(0);
@@ -1783,7 +1793,7 @@
* ----------------
*
*/
-void
+static void
xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
xmlXPathObjectPtr tmp, obj, point;
xmlLocationSetPtr newset = NULL;
@@ -1877,7 +1887,7 @@
* syntax error.
* ----------------------------
*/
-void
+static void
xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
xmlXPathObjectPtr tmp, obj, point;
xmlLocationSetPtr newset = NULL;
@@ -2022,7 +2032,7 @@
* location-set, a range location representing the covering range of
* x is added to the result location-set.
*/
-void
+static void
xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
int i;
xmlXPathObjectPtr set;
@@ -2168,7 +2178,7 @@
* location children of x.
*
*/
-void
+static void
xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) {
int i;
xmlXPathObjectPtr set;
@@ -2622,13 +2632,12 @@
if (cur == NULL)
return(-1);
-
+
if ((cur->type == XML_ELEMENT_NODE) ||
(cur->type == XML_DOCUMENT_NODE) ||
(cur->type == XML_HTML_DOCUMENT_NODE)) {
if (pos > 0) {
cur = xmlXPtrGetNthChild(cur, pos);
- pos = 0;
}
}
while (cur != NULL) {
@@ -2757,7 +2766,7 @@
* all be character points.
* ------------------------------
*/
-void
+static void
xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
int i, startindex, endindex = 0, fendindex;
xmlNodePtr start, end = 0, fend;