xml2: Import upstream release 2.9.13.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2022-04-07 12:21:04 +02:00
parent 6644b6b667
commit a279c2783c
24 changed files with 373 additions and 278 deletions

View File

@ -2517,6 +2517,8 @@ htmlNewDocNoDtD(const xmlChar *URI, const xmlChar *ExternalID) {
if ((ExternalID != NULL) || if ((ExternalID != NULL) ||
(URI != NULL)) (URI != NULL))
xmlCreateIntSubset(cur, BAD_CAST "html", ExternalID, URI); xmlCreateIntSubset(cur, BAD_CAST "html", ExternalID, URI);
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur); return(cur);
} }
@ -3045,7 +3047,7 @@ htmlParsePubidLiteral(htmlParserCtxtPtr ctxt) {
NEXT; NEXT;
} }
if (CUR != '"') { if (CUR != quote) {
htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED, htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
"Unfinished PubidLiteral\n", NULL, NULL); "Unfinished PubidLiteral\n", NULL, NULL);
} else { } else {
@ -3958,13 +3960,25 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED, htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
"htmlParseStartTag: invalid element name\n", "htmlParseStartTag: invalid element name\n",
NULL, NULL); NULL, NULL);
/*
* The recovery code is disabled for now as it can result in
* quadratic behavior with the push parser. htmlParseStartTag
* must consume all content up to the final '>' in order to avoid
* rescanning for this terminator.
*
* For a proper fix in line with HTML5, htmlParseStartTag and
* htmlParseElement should only be called when there's an ASCII
* alpha character following the initial '<'. Otherwise, the '<'
* should be emitted as text (unless followed by '!', '/' or '?').
*/
#if 0
/* if recover preserve text on classic misconstructs */ /* if recover preserve text on classic misconstructs */
if ((ctxt->recovery) && ((IS_BLANK_CH(CUR)) || (CUR == '<') || if ((ctxt->recovery) && ((IS_BLANK_CH(CUR)) || (CUR == '<') ||
(CUR == '=') || (CUR == '>') || (((CUR >= '0') && (CUR <= '9'))))) { (CUR == '=') || (CUR == '>') || (((CUR >= '0') && (CUR <= '9'))))) {
htmlParseCharDataInternal(ctxt, '<'); htmlParseCharDataInternal(ctxt, '<');
return(-1); return(-1);
} }
#endif
/* Dump the bogus tag like browsers do */ /* Dump the bogus tag like browsers do */
while ((CUR != 0) && (CUR != '>') && while ((CUR != 0) && (CUR != '>') &&
@ -5185,6 +5199,7 @@ htmlCreateMemoryParserCtxt(const char *buffer, int size) {
input = xmlNewInputStream(ctxt); input = xmlNewInputStream(ctxt);
if (input == NULL) { if (input == NULL) {
xmlFreeParserInputBuffer(buf);
xmlFreeParserCtxt(ctxt); xmlFreeParserCtxt(ctxt);
return(NULL); return(NULL);
} }
@ -5992,32 +6007,12 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
} else if (cur == '<') { } else if (cur == '<') {
if ((!terminate) && (next == 0)) if ((!terminate) && (next == 0))
goto done; goto done;
/* ctxt->instate = XML_PARSER_START_TAG;
* Only switch to START_TAG if the next character ctxt->checkIndex = 0;
* starts a valid name. Otherwise, htmlParseStartTag
* might return without consuming all characters
* up to the final '>'.
*/
if ((IS_ASCII_LETTER(next)) ||
(next == '_') || (next == ':') || (next == '.')) {
ctxt->instate = XML_PARSER_START_TAG;
ctxt->checkIndex = 0;
#ifdef DEBUG_PUSH #ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext, xmlGenericError(xmlGenericErrorContext,
"HPP: entering START_TAG\n"); "HPP: entering START_TAG\n");
#endif #endif
} else {
htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
"htmlParseTryOrFinish: "
"invalid element name\n",
NULL, NULL);
htmlCheckParagraph(ctxt);
if ((ctxt->sax != NULL) &&
(ctxt->sax->characters != NULL))
ctxt->sax->characters(ctxt->userData,
in->cur, 1);
NEXT;
}
break; break;
} else { } else {
/* /*
@ -6999,7 +6994,9 @@ htmlReadMemory(const char *buffer, int size, const char *URL, const char *encodi
* @encoding: the document encoding, or NULL * @encoding: the document encoding, or NULL
* @options: a combination of htmlParserOption(s) * @options: a combination of htmlParserOption(s)
* *
* parse an XML from a file descriptor and build a tree. * parse an HTML from a file descriptor and build a tree.
* NOTE that the file descriptor will not be closed when the
* reader is closed or reset.
* *
* Returns the resulting document tree * Returns the resulting document tree
*/ */
@ -7008,17 +7005,17 @@ htmlReadFd(int fd, const char *URL, const char *encoding, int options)
{ {
htmlParserCtxtPtr ctxt; htmlParserCtxtPtr ctxt;
xmlParserInputBufferPtr input; xmlParserInputBufferPtr input;
xmlParserInputPtr stream; htmlParserInputPtr stream;
if (fd < 0) if (fd < 0)
return (NULL); return (NULL);
xmlInitParser();
xmlInitParser(); xmlInitParser();
input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE); input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
if (input == NULL) if (input == NULL)
return (NULL); return (NULL);
ctxt = xmlNewParserCtxt(); input->closecallback = NULL;
ctxt = htmlNewParserCtxt();
if (ctxt == NULL) { if (ctxt == NULL) {
xmlFreeParserInputBuffer(input); xmlFreeParserInputBuffer(input);
return (NULL); return (NULL);
@ -7026,7 +7023,7 @@ htmlReadFd(int fd, const char *URL, const char *encoding, int options)
stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE); stream = xmlNewIOInputStream(ctxt, input, XML_CHAR_ENCODING_NONE);
if (stream == NULL) { if (stream == NULL) {
xmlFreeParserInputBuffer(input); xmlFreeParserInputBuffer(input);
xmlFreeParserCtxt(ctxt); htmlFreeParserCtxt(ctxt);
return (NULL); return (NULL);
} }
inputPush(ctxt, stream); inputPush(ctxt, stream);

View File

@ -744,7 +744,7 @@ void
htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
xmlNodePtr cur, const char *encoding ATTRIBUTE_UNUSED, xmlNodePtr cur, const char *encoding ATTRIBUTE_UNUSED,
int format) { int format) {
xmlNodePtr root; xmlNodePtr root, parent;
xmlAttrPtr attr; xmlAttrPtr attr;
const htmlElemDesc * info; const htmlElemDesc * info;
@ -755,6 +755,7 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
} }
root = cur; root = cur;
parent = cur->parent;
while (1) { while (1) {
switch (cur->type) { switch (cur->type) {
case XML_HTML_DOCUMENT_NODE: case XML_HTML_DOCUMENT_NODE:
@ -763,12 +764,28 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
htmlDtdDumpOutput(buf, (xmlDocPtr) cur, NULL); htmlDtdDumpOutput(buf, (xmlDocPtr) cur, NULL);
} }
if (cur->children != NULL) { if (cur->children != NULL) {
cur = cur->children; /* Always validate cur->parent when descending. */
continue; if (cur->parent == parent) {
parent = cur;
cur = cur->children;
continue;
}
} else {
xmlOutputBufferWriteString(buf, "\n");
} }
break; break;
case XML_ELEMENT_NODE: case XML_ELEMENT_NODE:
/*
* Some users like lxml are known to pass nodes with a corrupted
* tree structure. Fall back to a recursive call to handle this
* case.
*/
if ((cur->parent != parent) && (cur->children != NULL)) {
htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format);
break;
}
/* /*
* Get specific HTML info for that node. * Get specific HTML info for that node.
*/ */
@ -817,6 +834,7 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
(cur->name != NULL) && (cur->name != NULL) &&
(cur->name[0] != 'p')) /* p, pre, param */ (cur->name[0] != 'p')) /* p, pre, param */
xmlOutputBufferWriteString(buf, "\n"); xmlOutputBufferWriteString(buf, "\n");
parent = cur;
cur = cur->children; cur = cur->children;
continue; continue;
} }
@ -825,9 +843,9 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
(info != NULL) && (!info->isinline)) { (info != NULL) && (!info->isinline)) {
if ((cur->next->type != HTML_TEXT_NODE) && if ((cur->next->type != HTML_TEXT_NODE) &&
(cur->next->type != HTML_ENTITY_REF_NODE) && (cur->next->type != HTML_ENTITY_REF_NODE) &&
(cur->parent != NULL) && (parent != NULL) &&
(cur->parent->name != NULL) && (parent->name != NULL) &&
(cur->parent->name[0] != 'p')) /* p, pre, param */ (parent->name[0] != 'p')) /* p, pre, param */
xmlOutputBufferWriteString(buf, "\n"); xmlOutputBufferWriteString(buf, "\n");
} }
@ -842,9 +860,9 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
break; break;
if (((cur->name == (const xmlChar *)xmlStringText) || if (((cur->name == (const xmlChar *)xmlStringText) ||
(cur->name != (const xmlChar *)xmlStringTextNoenc)) && (cur->name != (const xmlChar *)xmlStringTextNoenc)) &&
((cur->parent == NULL) || ((parent == NULL) ||
((xmlStrcasecmp(cur->parent->name, BAD_CAST "script")) && ((xmlStrcasecmp(parent->name, BAD_CAST "script")) &&
(xmlStrcasecmp(cur->parent->name, BAD_CAST "style"))))) { (xmlStrcasecmp(parent->name, BAD_CAST "style"))))) {
xmlChar *buffer; xmlChar *buffer;
buffer = xmlEncodeEntitiesReentrant(doc, cur->content); buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
@ -902,13 +920,9 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
break; break;
} }
/* cur = parent;
* The parent should never be NULL here but we want to handle /* cur->parent was validated when descending. */
* corrupted documents gracefully. parent = cur->parent;
*/
if (cur->parent == NULL)
return;
cur = cur->parent;
if ((cur->type == XML_HTML_DOCUMENT_NODE) || if ((cur->type == XML_HTML_DOCUMENT_NODE) ||
(cur->type == XML_DOCUMENT_NODE)) { (cur->type == XML_DOCUMENT_NODE)) {
@ -939,9 +953,9 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
(cur->next != NULL)) { (cur->next != NULL)) {
if ((cur->next->type != HTML_TEXT_NODE) && if ((cur->next->type != HTML_TEXT_NODE) &&
(cur->next->type != HTML_ENTITY_REF_NODE) && (cur->next->type != HTML_ENTITY_REF_NODE) &&
(cur->parent != NULL) && (parent != NULL) &&
(cur->parent->name != NULL) && (parent->name != NULL) &&
(cur->parent->name[0] != 'p')) /* p, pre, param */ (parent->name[0] != 'p')) /* p, pre, param */
xmlOutputBufferWriteString(buf, "\n"); xmlOutputBufferWriteString(buf, "\n");
} }
} }

View File

@ -742,6 +742,7 @@ xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR, xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
"SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n", "SAX.xmlSAX2AttributeDecl(%s) called while not in subset\n",
name, NULL); name, NULL);
xmlFree(name);
xmlFreeEnumeration(tree); xmlFreeEnumeration(tree);
return; return;
} }
@ -1622,10 +1623,10 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
ctxt->nodemem = -1; ctxt->nodemem = -1;
if (ctxt->linenumbers) { if (ctxt->linenumbers) {
if (ctxt->input != NULL) { if (ctxt->input != NULL) {
if (ctxt->input->line < 65535) if (ctxt->input->line < USHRT_MAX)
ret->line = (short) ctxt->input->line; ret->line = (unsigned short) ctxt->input->line;
else else
ret->line = 65535; ret->line = USHRT_MAX;
} }
} }
@ -1886,10 +1887,10 @@ skip:
if (ctxt->linenumbers) { if (ctxt->linenumbers) {
if (ctxt->input != NULL) { if (ctxt->input != NULL) {
if (ctxt->input->line < 65535) if (ctxt->input->line < USHRT_MAX)
ret->line = (short) ctxt->input->line; ret->line = (unsigned short) ctxt->input->line;
else { else {
ret->line = 65535; ret->line = USHRT_MAX;
if (ctxt->options & XML_PARSE_BIG_LINES) if (ctxt->options & XML_PARSE_BIG_LINES)
ret->psvi = (void *) (ptrdiff_t) ctxt->input->line; ret->psvi = (void *) (ptrdiff_t) ctxt->input->line;
} }
@ -2266,10 +2267,10 @@ xmlSAX2StartElementNs(void *ctx,
} }
if (ctxt->linenumbers) { if (ctxt->linenumbers) {
if (ctxt->input != NULL) { if (ctxt->input != NULL) {
if (ctxt->input->line < 65535) if (ctxt->input->line < USHRT_MAX)
ret->line = (short) ctxt->input->line; ret->line = (unsigned short) ctxt->input->line;
else else
ret->line = 65535; ret->line = USHRT_MAX;
} }
} }
@ -2688,10 +2689,10 @@ xmlSAX2ProcessingInstruction(void *ctx, const xmlChar *target,
if (ctxt->linenumbers) { if (ctxt->linenumbers) {
if (ctxt->input != NULL) { if (ctxt->input != NULL) {
if (ctxt->input->line < 65535) if (ctxt->input->line < USHRT_MAX)
ret->line = (short) ctxt->input->line; ret->line = (unsigned short) ctxt->input->line;
else else
ret->line = 65535; ret->line = USHRT_MAX;
} }
} }
if (ctxt->inSubset == 1) { if (ctxt->inSubset == 1) {
@ -2748,10 +2749,10 @@ xmlSAX2Comment(void *ctx, const xmlChar *value)
if (ret == NULL) return; if (ret == NULL) return;
if (ctxt->linenumbers) { if (ctxt->linenumbers) {
if (ctxt->input != NULL) { if (ctxt->input != NULL) {
if (ctxt->input->line < 65535) if (ctxt->input->line < USHRT_MAX)
ret->line = (short) ctxt->input->line; ret->line = (unsigned short) ctxt->input->line;
else else
ret->line = 65535; ret->line = USHRT_MAX;
} }
} }

View File

@ -915,6 +915,7 @@ xmlParseCatalogFile(const char *filename) {
inputStream = xmlNewInputStream(ctxt); inputStream = xmlNewInputStream(ctxt);
if (inputStream == NULL) { if (inputStream == NULL) {
xmlFreeParserInputBuffer(buf);
xmlFreeParserCtxt(ctxt); xmlFreeParserCtxt(ctxt);
return(NULL); return(NULL);
} }
@ -2358,6 +2359,7 @@ xmlParseSGMLCatalog(xmlCatalogPtr catal, const xmlChar *value,
} }
if (!IS_BLANK_CH(*cur)) { if (!IS_BLANK_CH(*cur)) {
/* error */ /* error */
xmlFree(name);
break; break;
} }
SKIP_BLANKS; SKIP_BLANKS;

View File

@ -7973,6 +7973,18 @@ extern __typeof (xmlPopInputCallbacks) xmlPopInputCallbacks__internal_alias __at
#endif #endif
#endif #endif
#if defined(LIBXML_OUTPUT_ENABLED)
#ifdef bottom_xmlIO
#undef xmlPopOutputCallbacks
extern __typeof (xmlPopOutputCallbacks) xmlPopOutputCallbacks __attribute((alias("xmlPopOutputCallbacks__internal_alias")));
#else
#ifndef xmlPopOutputCallbacks
extern __typeof (xmlPopOutputCallbacks) xmlPopOutputCallbacks__internal_alias __attribute((visibility("hidden")));
#define xmlPopOutputCallbacks xmlPopOutputCallbacks__internal_alias
#endif
#endif
#endif
#if defined(LIBXML_TREE_ENABLED) #if defined(LIBXML_TREE_ENABLED)
#ifdef bottom_tree #ifdef bottom_tree
#undef xmlPreviousElementSibling #undef xmlPreviousElementSibling

View File

@ -527,7 +527,7 @@ UTF16LEToUTF8(unsigned char* out, int *outlen,
in++; in++;
} }
if ((c & 0xFC00) == 0xD800) { /* surrogates */ if ((c & 0xFC00) == 0xD800) { /* surrogates */
if (in >= inend) { /* (in > inend) shouldn't happens */ if (in >= inend) { /* handle split mutli-byte characters */
break; break;
} }
if (xmlLittleEndian) { if (xmlLittleEndian) {
@ -744,38 +744,39 @@ UTF16BEToUTF8(unsigned char* out, int *outlen,
{ {
unsigned char* outstart = out; unsigned char* outstart = out;
const unsigned char* processed = inb; const unsigned char* processed = inb;
unsigned char* outend = out + *outlen; unsigned char* outend;
unsigned short* in = (unsigned short*) inb; unsigned short* in = (unsigned short*) inb;
unsigned short* inend; unsigned short* inend;
unsigned int c, d, inlen; unsigned int c, d, inlen;
unsigned char *tmp; unsigned char *tmp;
int bits; int bits;
if (*outlen == 0) {
*inlenb = 0;
return(0);
}
outend = out + *outlen;
if ((*inlenb % 2) == 1) if ((*inlenb % 2) == 1)
(*inlenb)--; (*inlenb)--;
inlen = *inlenb / 2; inlen = *inlenb / 2;
inend= in + inlen; inend= in + inlen;
while (in < inend) { while ((in < inend) && (out - outstart + 5 < *outlen)) {
if (xmlLittleEndian) { if (xmlLittleEndian) {
tmp = (unsigned char *) in; tmp = (unsigned char *) in;
c = *tmp++; c = *tmp++;
c = c << 8; c = (c << 8) | (unsigned int) *tmp;
c = c | (unsigned int) *tmp;
in++; in++;
} else { } else {
c= *in++; c= *in++;
} }
if ((c & 0xFC00) == 0xD800) { /* surrogates */ if ((c & 0xFC00) == 0xD800) { /* surrogates */
if (in >= inend) { /* (in > inend) shouldn't happens */ if (in >= inend) { /* handle split mutli-byte characters */
*outlen = out - outstart; break;
*inlenb = processed - inb;
return(-2);
} }
if (xmlLittleEndian) { if (xmlLittleEndian) {
tmp = (unsigned char *) in; tmp = (unsigned char *) in;
d = *tmp++; d = *tmp++;
d = d << 8; d = (d << 8) | (unsigned int) *tmp;
d = d | (unsigned int) *tmp;
in++; in++;
} else { } else {
d= *in++; d= *in++;
@ -1822,7 +1823,7 @@ xmlIconvWrapper(iconv_t cd, unsigned char *out, int *outlen,
size_t icv_inlen, icv_outlen; size_t icv_inlen, icv_outlen;
const char *icv_in = (const char *) in; const char *icv_in = (const char *) in;
char *icv_out = (char *) out; char *icv_out = (char *) out;
int ret; size_t ret;
if ((out == NULL) || (outlen == NULL) || (inlen == NULL) || (in == NULL)) { if ((out == NULL) || (outlen == NULL) || (inlen == NULL) || (in == NULL)) {
if (outlen != NULL) *outlen = 0; if (outlen != NULL) *outlen = 0;
@ -1833,7 +1834,7 @@ xmlIconvWrapper(iconv_t cd, unsigned char *out, int *outlen,
ret = iconv(cd, (ICONV_CONST char **) &icv_in, &icv_inlen, &icv_out, &icv_outlen); ret = iconv(cd, (ICONV_CONST char **) &icv_in, &icv_inlen, &icv_out, &icv_outlen);
*inlen -= icv_inlen; *inlen -= icv_inlen;
*outlen -= icv_outlen; *outlen -= icv_outlen;
if ((icv_inlen != 0) || (ret == -1)) { if ((icv_inlen != 0) || (ret == (size_t) -1)) {
#ifdef EILSEQ #ifdef EILSEQ
if (errno == EILSEQ) { if (errno == EILSEQ) {
return -2; return -2;
@ -2495,7 +2496,7 @@ retry:
*/ */
toconv = xmlBufUse(in); toconv = xmlBufUse(in);
if (toconv == 0) if (toconv == 0)
return (0); return (writtentot);
if (toconv > 64 * 1024) if (toconv > 64 * 1024)
toconv = 64 * 1024; toconv = 64 * 1024;
if (toconv * 4 >= written) { if (toconv * 4 >= written) {
@ -2629,7 +2630,6 @@ xmlCharEncOutFunc(xmlCharEncodingHandler *handler, xmlBufferPtr out,
int written; int written;
int writtentot = 0; int writtentot = 0;
int toconv; int toconv;
int output = 0;
if (handler == NULL) return(-1); if (handler == NULL) return(-1);
if (out == NULL) return(-1); if (out == NULL) return(-1);
@ -2682,8 +2682,6 @@ retry:
ret = -3; ret = -3;
} }
if (ret >= 0) output += ret;
/* /*
* Attempt to handle error cases * Attempt to handle error cases
*/ */

View File

@ -86,7 +86,7 @@ static unsigned long
xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name, xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name,
const xmlChar *name2, const xmlChar *name3) { const xmlChar *name2, const xmlChar *name3) {
unsigned long value = 0L; unsigned long value = 0L;
char ch; unsigned long ch;
#ifdef HASH_RANDOMIZATION #ifdef HASH_RANDOMIZATION
value = table->random_seed; value = table->random_seed;
@ -94,19 +94,19 @@ xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name,
if (name != NULL) { if (name != NULL) {
value += 30 * (*name); value += 30 * (*name);
while ((ch = *name++) != 0) { while ((ch = *name++) != 0) {
value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); value = value ^ ((value << 5) + (value >> 3) + ch);
} }
} }
value = value ^ ((value << 5) + (value >> 3)); value = value ^ ((value << 5) + (value >> 3));
if (name2 != NULL) { if (name2 != NULL) {
while ((ch = *name2++) != 0) { while ((ch = *name2++) != 0) {
value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); value = value ^ ((value << 5) + (value >> 3) + ch);
} }
} }
value = value ^ ((value << 5) + (value >> 3)); value = value ^ ((value << 5) + (value >> 3));
if (name3 != NULL) { if (name3 != NULL) {
while ((ch = *name3++) != 0) { while ((ch = *name3++) != 0) {
value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); value = value ^ ((value << 5) + (value >> 3) + ch);
} }
} }
return (value % table->size); return (value % table->size);
@ -121,7 +121,7 @@ xmlHashComputeQKey(xmlHashTablePtr table,
const xmlChar *prefix2, const xmlChar *name2, const xmlChar *prefix2, const xmlChar *name2,
const xmlChar *prefix3, const xmlChar *name3) { const xmlChar *prefix3, const xmlChar *name3) {
unsigned long value = 0L; unsigned long value = 0L;
char ch; unsigned long ch;
#ifdef HASH_RANDOMIZATION #ifdef HASH_RANDOMIZATION
value = table->random_seed; value = table->random_seed;
@ -133,37 +133,37 @@ xmlHashComputeQKey(xmlHashTablePtr table,
if (prefix != NULL) { if (prefix != NULL) {
while ((ch = *prefix++) != 0) { while ((ch = *prefix++) != 0) {
value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); value = value ^ ((value << 5) + (value >> 3) + ch);
} }
value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':'); value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':');
} }
if (name != NULL) { if (name != NULL) {
while ((ch = *name++) != 0) { while ((ch = *name++) != 0) {
value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); value = value ^ ((value << 5) + (value >> 3) + ch);
} }
} }
value = value ^ ((value << 5) + (value >> 3)); value = value ^ ((value << 5) + (value >> 3));
if (prefix2 != NULL) { if (prefix2 != NULL) {
while ((ch = *prefix2++) != 0) { while ((ch = *prefix2++) != 0) {
value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); value = value ^ ((value << 5) + (value >> 3) + ch);
} }
value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':'); value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':');
} }
if (name2 != NULL) { if (name2 != NULL) {
while ((ch = *name2++) != 0) { while ((ch = *name2++) != 0) {
value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); value = value ^ ((value << 5) + (value >> 3) + ch);
} }
} }
value = value ^ ((value << 5) + (value >> 3)); value = value ^ ((value << 5) + (value >> 3));
if (prefix3 != NULL) { if (prefix3 != NULL) {
while ((ch = *prefix3++) != 0) { while ((ch = *prefix3++) != 0) {
value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); value = value ^ ((value << 5) + (value >> 3) + ch);
} }
value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':'); value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':');
} }
if (name3 != NULL) { if (name3 != NULL) {
while ((ch = *name3++) != 0) { while ((ch = *name3++) != 0) {
value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); value = value ^ ((value << 5) + (value >> 3) + ch);
} }
} }
return (value % table->size); return (value % table->size);

View File

@ -29,28 +29,28 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
* *
* the version string like "1.2.3" * the version string like "1.2.3"
*/ */
#define LIBXML_DOTTED_VERSION "2.9.12" #define LIBXML_DOTTED_VERSION "2.9.13"
/** /**
* LIBXML_VERSION: * LIBXML_VERSION:
* *
* the version number: 1.2.3 value is 10203 * the version number: 1.2.3 value is 10203
*/ */
#define LIBXML_VERSION 20912 #define LIBXML_VERSION 20913
/** /**
* LIBXML_VERSION_STRING: * LIBXML_VERSION_STRING:
* *
* the version number string, 1.2.3 value is "10203" * the version number string, 1.2.3 value is "10203"
*/ */
#define LIBXML_VERSION_STRING "20912" #define LIBXML_VERSION_STRING "20913"
/** /**
* LIBXML_VERSION_EXTRA: * LIBXML_VERSION_EXTRA:
* *
* extra version information, used to show a CVS compilation * extra version information, used to show a git commit description
*/ */
#define LIBXML_VERSION_EXTRA "-GITv2.9.11" #define LIBXML_VERSION_EXTRA "-GITv2.9.12-115-ga075d256f"
/** /**
* LIBXML_TEST_VERSION: * LIBXML_TEST_VERSION:
@ -58,7 +58,7 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
* Macro to check that the libxml version in use is compatible with * Macro to check that the libxml version in use is compatible with
* the version the software has been compiled against * the version the software has been compiled against
*/ */
#define LIBXML_TEST_VERSION xmlCheckVersion(20912); #define LIBXML_TEST_VERSION xmlCheckVersion(20913);
#ifndef VMS #ifndef VMS
#if 0 #if 0

View File

@ -2194,7 +2194,8 @@ xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
* It's Okay to use CUR/NEXT here since all the blanks are on * It's Okay to use CUR/NEXT here since all the blanks are on
* the ASCII range. * the ASCII range.
*/ */
if (ctxt->instate != XML_PARSER_DTD) { if (((ctxt->inputNr == 1) && (ctxt->instate != XML_PARSER_DTD)) ||
(ctxt->instate == XML_PARSER_START)) {
const xmlChar *cur; const xmlChar *cur;
/* /*
* if we are in the document content, go really fast * if we are in the document content, go really fast
@ -4587,6 +4588,9 @@ xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
} }
} }
COPY_BUF(l,buf,nbchar,cur); COPY_BUF(l,buf,nbchar,cur);
/* move current position before possible calling of ctxt->sax->characters */
NEXTL(l);
cur = CUR_CHAR(l);
if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) { if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
buf[nbchar] = 0; buf[nbchar] = 0;
@ -4620,8 +4624,6 @@ xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
if (ctxt->instate == XML_PARSER_EOF) if (ctxt->instate == XML_PARSER_EOF)
return; return;
} }
NEXTL(l);
cur = CUR_CHAR(l);
} }
if (nbchar != 0) { if (nbchar != 0) {
buf[nbchar] = 0; buf[nbchar] = 0;
@ -4980,7 +4982,7 @@ get_more:
ctxt->input->cur = in; ctxt->input->cur = in;
in++; in++;
ctxt->input->line++; ctxt->input->col = 1; ctxt->input->line++; ctxt->input->col = 1;
continue; /* while */ goto get_more;
} }
in--; in--;
} }
@ -10657,16 +10659,16 @@ xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
void void
xmlParseMisc(xmlParserCtxtPtr ctxt) { xmlParseMisc(xmlParserCtxtPtr ctxt) {
while ((ctxt->instate != XML_PARSER_EOF) && while (ctxt->instate != XML_PARSER_EOF) {
(((RAW == '<') && (NXT(1) == '?')) || SKIP_BLANKS;
(CMP4(CUR_PTR, '<', '!', '-', '-')) || GROW;
IS_BLANK_CH(CUR))) {
if ((RAW == '<') && (NXT(1) == '?')) { if ((RAW == '<') && (NXT(1) == '?')) {
xmlParsePI(ctxt); xmlParsePI(ctxt);
} else if (IS_BLANK_CH(CUR)) { } else if (CMP4(CUR_PTR, '<', '!', '-', '-')) {
NEXT;
} else
xmlParseComment(ctxt); xmlParseComment(ctxt);
} else {
break;
}
} }
} }
@ -10772,7 +10774,6 @@ xmlParseDocument(xmlParserCtxtPtr ctxt) {
/* /*
* The Misc part of the Prolog * The Misc part of the Prolog
*/ */
GROW;
xmlParseMisc(ctxt); xmlParseMisc(ctxt);
/* /*
@ -12625,6 +12626,7 @@ xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
xmlFree(ctxt->sax); xmlFree(ctxt->sax);
ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler)); ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
if (ctxt->sax == NULL) { if (ctxt->sax == NULL) {
xmlFreeParserInputBuffer(buf);
xmlErrMemory(ctxt, NULL); xmlErrMemory(ctxt, NULL);
xmlFreeParserCtxt(ctxt); xmlFreeParserCtxt(ctxt);
return(NULL); return(NULL);
@ -14672,7 +14674,8 @@ xmlInitParser(void) {
return; return;
#if defined(_WIN32) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL)) #if defined(_WIN32) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
atexit(xmlCleanupParser); if (xmlFree == free)
atexit(xmlCleanupParser);
#endif #endif
#ifdef LIBXML_THREAD_ENABLED #ifdef LIBXML_THREAD_ENABLED

View File

@ -1546,8 +1546,10 @@ xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
} }
inputStream = xmlNewInputStream(ctxt); inputStream = xmlNewInputStream(ctxt);
if (inputStream == NULL) if (inputStream == NULL) {
xmlFreeParserInputBuffer(buf);
return(NULL); return(NULL);
}
inputStream->buf = buf; inputStream->buf = buf;
inputStream = xmlCheckHTTPInput(ctxt, inputStream); inputStream = xmlCheckHTTPInput(ctxt, inputStream);

View File

@ -3654,6 +3654,7 @@ xmlRelaxNGParseData(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node)
def = xmlRelaxNGNewDefine(ctxt, node); def = xmlRelaxNGNewDefine(ctxt, node);
if (def == NULL) { if (def == NULL) {
xmlFree(library);
xmlFree(type); xmlFree(type);
return (NULL); return (NULL);
} }
@ -6838,6 +6839,7 @@ xmlRelaxNGNewDocParserCtxt(xmlDocPtr doc)
(xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt)); (xmlRelaxNGParserCtxtPtr) xmlMalloc(sizeof(xmlRelaxNGParserCtxt));
if (ret == NULL) { if (ret == NULL) {
xmlRngPErrMemory(NULL, "building parser\n"); xmlRngPErrMemory(NULL, "building parser\n");
xmlFreeDoc(copy);
return (NULL); return (NULL);
} }
memset(ret, 0, sizeof(xmlRelaxNGParserCtxt)); memset(ret, 0, sizeof(xmlRelaxNGParserCtxt));

View File

@ -1596,6 +1596,10 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
*/ */
if (!xmlBufIsEmpty(buf)) { if (!xmlBufIsEmpty(buf)) {
node = xmlNewDocText(doc, NULL); node = xmlNewDocText(doc, NULL);
if (node == NULL) {
if (val != NULL) xmlFree(val);
goto out;
}
node->content = xmlBufDetach(buf); node->content = xmlBufDetach(buf);
if (last == NULL) { if (last == NULL) {
@ -2852,8 +2856,15 @@ xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) {
prop = prop->next; prop = prop->next;
} }
} }
if (tree->children != NULL) if (tree->type == XML_ENTITY_REF_NODE) {
/*
* Clear 'children' which points to the entity declaration
* from the original document.
*/
tree->children = NULL;
} else if (tree->children != NULL) {
xmlSetListDoc(tree->children, doc); xmlSetListDoc(tree->children, doc);
}
tree->doc = doc; tree->doc = doc;
} }
} }
@ -3691,17 +3702,14 @@ xmlFreeNodeList(xmlNodePtr cur) {
xmlFreeNsList((xmlNsPtr) cur); xmlFreeNsList((xmlNsPtr) cur);
return; return;
} }
if ((cur->type == XML_DOCUMENT_NODE) ||
#ifdef LIBXML_DOCB_ENABLED
(cur->type == XML_DOCB_DOCUMENT_NODE) ||
#endif
(cur->type == XML_HTML_DOCUMENT_NODE)) {
xmlFreeDoc((xmlDocPtr) cur);
return;
}
if (cur->doc != NULL) dict = cur->doc->dict; if (cur->doc != NULL) dict = cur->doc->dict;
while (1) { while (1) {
while ((cur->children != NULL) && while ((cur->children != NULL) &&
(cur->type != XML_DOCUMENT_NODE) &&
#ifdef LIBXML_DOCB_ENABLED
(cur->type != XML_DOCB_DOCUMENT_NODE) &&
#endif
(cur->type != XML_HTML_DOCUMENT_NODE) &&
(cur->type != XML_DTD_NODE) && (cur->type != XML_DTD_NODE) &&
(cur->type != XML_ENTITY_REF_NODE)) { (cur->type != XML_ENTITY_REF_NODE)) {
cur = cur->children; cur = cur->children;
@ -3710,7 +3718,13 @@ xmlFreeNodeList(xmlNodePtr cur) {
next = cur->next; next = cur->next;
parent = cur->parent; parent = cur->parent;
if (cur->type != XML_DTD_NODE) { if ((cur->type == XML_DOCUMENT_NODE) ||
#ifdef LIBXML_DOCB_ENABLED
(cur->type == XML_DOCB_DOCUMENT_NODE) ||
#endif
(cur->type == XML_HTML_DOCUMENT_NODE)) {
xmlFreeDoc((xmlDocPtr) cur);
} else if (cur->type != XML_DTD_NODE) {
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue)) if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
xmlDeregisterNodeDefaultValue(cur); xmlDeregisterNodeDefaultValue(cur);
@ -3724,11 +3738,6 @@ xmlFreeNodeList(xmlNodePtr cur) {
(cur->type != XML_XINCLUDE_START) && (cur->type != XML_XINCLUDE_START) &&
(cur->type != XML_XINCLUDE_END) && (cur->type != XML_XINCLUDE_END) &&
(cur->type != XML_ENTITY_REF_NODE) && (cur->type != XML_ENTITY_REF_NODE) &&
(cur->type != XML_DOCUMENT_NODE) &&
#ifdef LIBXML_DOCB_ENABLED
(cur->type != XML_DOCB_DOCUMENT_NODE) &&
#endif
(cur->type != XML_HTML_DOCUMENT_NODE) &&
(cur->content != (xmlChar *) &(cur->properties))) { (cur->content != (xmlChar *) &(cur->properties))) {
DICT_FREE(cur->content) DICT_FREE(cur->content)
} }

View File

@ -1638,23 +1638,24 @@ xmlURIUnescapeString(const char *str, int len, char *target) {
out = ret; out = ret;
while(len > 0) { while(len > 0) {
if ((len > 2) && (*in == '%') && (is_hex(in[1])) && (is_hex(in[2]))) { if ((len > 2) && (*in == '%') && (is_hex(in[1])) && (is_hex(in[2]))) {
int c = 0;
in++; in++;
if ((*in >= '0') && (*in <= '9')) if ((*in >= '0') && (*in <= '9'))
*out = (*in - '0'); c = (*in - '0');
else if ((*in >= 'a') && (*in <= 'f')) else if ((*in >= 'a') && (*in <= 'f'))
*out = (*in - 'a') + 10; c = (*in - 'a') + 10;
else if ((*in >= 'A') && (*in <= 'F')) else if ((*in >= 'A') && (*in <= 'F'))
*out = (*in - 'A') + 10; c = (*in - 'A') + 10;
in++; in++;
if ((*in >= '0') && (*in <= '9')) if ((*in >= '0') && (*in <= '9'))
*out = *out * 16 + (*in - '0'); c = c * 16 + (*in - '0');
else if ((*in >= 'a') && (*in <= 'f')) else if ((*in >= 'a') && (*in <= 'f'))
*out = *out * 16 + (*in - 'a') + 10; c = c * 16 + (*in - 'a') + 10;
else if ((*in >= 'A') && (*in <= 'F')) else if ((*in >= 'A') && (*in <= 'F'))
*out = *out * 16 + (*in - 'A') + 10; c = c * 16 + (*in - 'A') + 10;
in++; in++;
len -= 3; len -= 3;
out++; *out++ = (char) c;
} else { } else {
*out++ = *in++; *out++ = *in++;
len--; len--;

View File

@ -479,6 +479,35 @@ nodeVPop(xmlValidCtxtPtr ctxt)
return (ret); return (ret);
} }
/**
* xmlValidNormalizeString:
* @str: a string
*
* Normalize a string in-place.
*/
static void
xmlValidNormalizeString(xmlChar *str) {
xmlChar *dst;
const xmlChar *src;
if (str == NULL)
return;
src = str;
dst = str;
while (*src == 0x20) src++;
while (*src != 0) {
if (*src == 0x20) {
while (*src == 0x20) src++;
if (*src != 0)
*dst++ = 0x20;
} else {
*dst++ = *src++;
}
}
*dst = 0;
}
#ifdef DEBUG_VALID_ALGO #ifdef DEBUG_VALID_ALGO
static void static void
xmlValidPrintNode(xmlNodePtr cur) { xmlValidPrintNode(xmlNodePtr cur) {
@ -2607,6 +2636,24 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
(xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \ (xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
xmlFree((char *)(str)); xmlFree((char *)(str));
static int
xmlIsStreaming(xmlValidCtxtPtr ctxt) {
xmlParserCtxtPtr pctxt;
if (ctxt == NULL)
return(0);
/*
* These magic values are also abused to detect whether we're validating
* while parsing a document. In this case, userData points to the parser
* context.
*/
if ((ctxt->finishDtd != XML_CTXT_FINISH_DTD_0) &&
(ctxt->finishDtd != XML_CTXT_FINISH_DTD_1))
return(0);
pctxt = ctxt->userData;
return(pctxt->parseMode == XML_PARSE_READER);
}
/** /**
* xmlFreeID: * xmlFreeID:
* @not: A id * @not: A id
@ -2650,7 +2697,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
if (doc == NULL) { if (doc == NULL) {
return(NULL); return(NULL);
} }
if (value == NULL) { if ((value == NULL) || (value[0] == 0)) {
return(NULL); return(NULL);
} }
if (attr == NULL) { if (attr == NULL) {
@ -2681,7 +2728,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
*/ */
ret->value = xmlStrdup(value); ret->value = xmlStrdup(value);
ret->doc = doc; ret->doc = doc;
if ((ctxt != NULL) && (ctxt->vstateNr != 0)) { if (xmlIsStreaming(ctxt)) {
/* /*
* Operating in streaming mode, attr is gonna disappear * Operating in streaming mode, attr is gonna disappear
*/ */
@ -2820,6 +2867,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
ID = xmlNodeListGetString(doc, attr->children, 1); ID = xmlNodeListGetString(doc, attr->children, 1);
if (ID == NULL) if (ID == NULL)
return(-1); return(-1);
xmlValidNormalizeString(ID);
id = xmlHashLookup(table, ID); id = xmlHashLookup(table, ID);
if (id == NULL || id->attr != attr) { if (id == NULL || id->attr != attr) {
@ -3009,7 +3057,7 @@ xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
* fill the structure. * fill the structure.
*/ */
ret->value = xmlStrdup(value); ret->value = xmlStrdup(value);
if ((ctxt != NULL) && (ctxt->vstateNr != 0)) { if (xmlIsStreaming(ctxt)) {
/* /*
* Operating in streaming mode, attr is gonna disappear * Operating in streaming mode, attr is gonna disappear
*/ */
@ -4028,8 +4076,7 @@ xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlChar * xmlChar *
xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlNodePtr elem, const xmlChar *name, const xmlChar *value) { xmlNodePtr elem, const xmlChar *name, const xmlChar *value) {
xmlChar *ret, *dst; xmlChar *ret;
const xmlChar *src;
xmlAttributePtr attrDecl = NULL; xmlAttributePtr attrDecl = NULL;
int extsubset = 0; int extsubset = 0;
@ -4070,19 +4117,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
ret = xmlStrdup(value); ret = xmlStrdup(value);
if (ret == NULL) if (ret == NULL)
return(NULL); return(NULL);
src = value; xmlValidNormalizeString(ret);
dst = ret;
while (*src == 0x20) src++;
while (*src != 0) {
if (*src == 0x20) {
while (*src == 0x20) src++;
if (*src != 0)
*dst++ = 0x20;
} else {
*dst++ = *src++;
}
}
*dst = 0;
if ((doc->standalone) && (extsubset == 1) && (!xmlStrEqual(value, ret))) { if ((doc->standalone) && (extsubset == 1) && (!xmlStrEqual(value, ret))) {
xmlErrValidNode(ctxt, elem, XML_DTD_NOT_STANDALONE, xmlErrValidNode(ctxt, elem, XML_DTD_NOT_STANDALONE,
"standalone: %s on %s value had to be normalized based on external subset declaration\n", "standalone: %s on %s value had to be normalized based on external subset declaration\n",
@ -4114,8 +4149,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlChar * xmlChar *
xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem, xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
const xmlChar *name, const xmlChar *value) { const xmlChar *name, const xmlChar *value) {
xmlChar *ret, *dst; xmlChar *ret;
const xmlChar *src;
xmlAttributePtr attrDecl = NULL; xmlAttributePtr attrDecl = NULL;
if (doc == NULL) return(NULL); if (doc == NULL) return(NULL);
@ -4145,19 +4179,7 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
ret = xmlStrdup(value); ret = xmlStrdup(value);
if (ret == NULL) if (ret == NULL)
return(NULL); return(NULL);
src = value; xmlValidNormalizeString(ret);
dst = ret;
while (*src == 0x20) src++;
while (*src != 0) {
if (*src == 0x20) {
while (*src == 0x20) src++;
if (*src != 0)
*dst++ = 0x20;
} else {
*dst++ = *src++;
}
}
*dst = 0;
return(ret); return(ret);
} }

View File

@ -1014,15 +1014,15 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
if (list == NULL) { if (list == NULL) {
list = tmp; list = tmp;
listParent = cur->parent; listParent = cur->parent;
last = tmp;
} else { } else {
if (level == lastLevel) if (level == lastLevel)
xmlAddNextSibling(last, tmp); last = xmlAddNextSibling(last, tmp);
else { else {
xmlAddChild(last, tmp); last = xmlAddChild(last, tmp);
lastLevel = level; lastLevel = level;
} }
} }
last = tmp;
if (index2 > 1) { if (index2 > 1) {
end = xmlXIncludeGetNthChild(cur, index2 - 1); end = xmlXIncludeGetNthChild(cur, index2 - 1);
@ -1103,12 +1103,11 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
} }
if (tmp != NULL) { if (tmp != NULL) {
if (level == lastLevel) if (level == lastLevel)
xmlAddNextSibling(last, tmp); last = xmlAddNextSibling(last, tmp);
else { else {
xmlAddChild(last, tmp); last = xmlAddChild(last, tmp);
lastLevel = level; lastLevel = level;
} }
last = tmp;
} }
} }
/* /*
@ -1186,8 +1185,7 @@ xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
if (last == NULL) { if (last == NULL) {
list = last = tmp; list = last = tmp;
} else { } else {
xmlAddNextSibling(last, tmp); last = xmlAddNextSibling(last, tmp);
last = tmp;
} }
cur = cur->next; cur = cur->next;
continue; continue;

View File

@ -2735,6 +2735,8 @@ __xmlOutputBufferCreateFilename(const char *URI,
ret->writecallback = xmlGzfileWrite; ret->writecallback = xmlGzfileWrite;
ret->closecallback = xmlGzfileClose; ret->closecallback = xmlGzfileClose;
} }
else
xmlGzfileClose(context);
return(ret); return(ret);
} }
} }
@ -3401,12 +3403,18 @@ xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
out->error = XML_IO_ENCODER; out->error = XML_IO_ENCODER;
return(-1); return(-1);
} }
nbchars = ret >= 0 ? ret : 0; if (out->writecallback)
nbchars = xmlBufUse(out->conv);
else
nbchars = ret >= 0 ? ret : 0;
} else { } else {
ret = xmlBufAdd(out->buffer, (const xmlChar *) buf, chunk); ret = xmlBufAdd(out->buffer, (const xmlChar *) buf, chunk);
if (ret != 0) if (ret != 0)
return(-1); return(-1);
nbchars = chunk; if (out->writecallback)
nbchars = xmlBufUse(out->buffer);
else
nbchars = chunk;
} }
buf += chunk; buf += chunk;
len -= chunk; len -= chunk;
@ -3593,13 +3601,19 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str,
out->error = XML_IO_ENCODER; out->error = XML_IO_ENCODER;
return(-1); return(-1);
} }
nbchars = ret >= 0 ? ret : 0; if (out->writecallback)
nbchars = xmlBufUse(out->conv);
else
nbchars = ret >= 0 ? ret : 0;
} else { } else {
ret = escaping(xmlBufEnd(out->buffer), &chunk, str, &cons); ret = escaping(xmlBufEnd(out->buffer), &chunk, str, &cons);
if ((ret < 0) || (chunk == 0)) /* chunk==0 => nothing done */ if ((ret < 0) || (chunk == 0)) /* chunk==0 => nothing done */
return(-1); return(-1);
xmlBufAddLen(out->buffer, chunk); xmlBufAddLen(out->buffer, chunk);
nbchars = chunk; if (out->writecallback)
nbchars = xmlBufUse(out->buffer);
else
nbchars = chunk;
} }
str += cons; str += cons;
len -= cons; len -= cons;

View File

@ -78,7 +78,7 @@ void xmlMallocBreakpoint(void);
* Each of the blocks allocated begin with a header containing information * Each of the blocks allocated begin with a header containing information
*/ */
#define MEMTAG 0x5aa5 #define MEMTAG 0x5aa5U
#define MALLOC_TYPE 1 #define MALLOC_TYPE 1
#define REALLOC_TYPE 2 #define REALLOC_TYPE 2

View File

@ -1892,6 +1892,12 @@ xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt, int fromnr,
* then X and Y are semantically equivalent and X can be eliminated * then X and Y are semantically equivalent and X can be eliminated
* If X is the start state then make Y the start state, else replace the * If X is the start state then make Y the start state, else replace the
* target of all transitions to X by transitions to Y. * target of all transitions to X by transitions to Y.
*
* If X is a final state, skip it.
* Otherwise it would be necessary to manipulate counters for this case when
* eliminating state 2:
* State 1 has a transition with an atom to state 2.
* State 2 is final and has an epsilon transition to state 1.
*/ */
static void static void
xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtxtPtr ctxt) { xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
@ -1904,7 +1910,8 @@ xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
continue; continue;
if (state->nbTrans != 1) if (state->nbTrans != 1)
continue; continue;
if (state->type == XML_REGEXP_UNREACH_STATE) if (state->type == XML_REGEXP_UNREACH_STATE ||
state->type == XML_REGEXP_FINAL_STATE)
continue; continue;
/* is the only transition out a basic transition */ /* is the only transition out a basic transition */
if ((state->trans[0].atom == NULL) && if ((state->trans[0].atom == NULL) &&

View File

@ -847,7 +847,7 @@ htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
static void static void
xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
int format = ctxt->format; int format = ctxt->format;
xmlNodePtr tmp, root, unformattedNode = NULL; xmlNodePtr tmp, root, unformattedNode = NULL, parent;
xmlAttrPtr attr; xmlAttrPtr attr;
xmlChar *start, *end; xmlChar *start, *end;
xmlOutputBufferPtr buf; xmlOutputBufferPtr buf;
@ -856,6 +856,7 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
buf = ctxt->buf; buf = ctxt->buf;
root = cur; root = cur;
parent = cur->parent;
while (1) { while (1) {
switch (cur->type) { switch (cur->type) {
case XML_DOCUMENT_NODE: case XML_DOCUMENT_NODE:
@ -868,7 +869,9 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
break; break;
case XML_DOCUMENT_FRAG_NODE: case XML_DOCUMENT_FRAG_NODE:
if (cur->children != NULL) { /* Always validate cur->parent when descending. */
if ((cur->parent == parent) && (cur->children != NULL)) {
parent = cur;
cur = cur->children; cur = cur->children;
continue; continue;
} }
@ -887,12 +890,23 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
break; break;
case XML_ELEMENT_NODE: case XML_ELEMENT_NODE:
if ((cur != root) && (ctxt->format == 1) && (xmlIndentTreeOutput)) if ((cur != root) && (ctxt->format == 1) &&
(xmlIndentTreeOutput))
xmlOutputBufferWrite(buf, ctxt->indent_size * xmlOutputBufferWrite(buf, ctxt->indent_size *
(ctxt->level > ctxt->indent_nr ? (ctxt->level > ctxt->indent_nr ?
ctxt->indent_nr : ctxt->level), ctxt->indent_nr : ctxt->level),
ctxt->indent); ctxt->indent);
/*
* Some users like lxml are known to pass nodes with a corrupted
* tree structure. Fall back to a recursive call to handle this
* case.
*/
if ((cur->parent != parent) && (cur->children != NULL)) {
xmlNodeDumpOutputInternal(ctxt, cur);
break;
}
xmlOutputBufferWrite(buf, 1, "<"); xmlOutputBufferWrite(buf, 1, "<");
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) { if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix); xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
@ -942,6 +956,7 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
xmlOutputBufferWrite(buf, 1, ">"); xmlOutputBufferWrite(buf, 1, ">");
if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n"); if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n");
if (ctxt->level >= 0) ctxt->level++; if (ctxt->level >= 0) ctxt->level++;
parent = cur;
cur = cur->children; cur = cur->children;
continue; continue;
} }
@ -1058,13 +1073,9 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
break; break;
} }
/* cur = parent;
* The parent should never be NULL here but we want to handle /* cur->parent was validated when descending. */
* corrupted documents gracefully. parent = cur->parent;
*/
if (cur->parent == NULL)
return;
cur = cur->parent;
if (cur->type == XML_ELEMENT_NODE) { if (cur->type == XML_ELEMENT_NODE) {
if (ctxt->level > 0) ctxt->level--; if (ctxt->level > 0) ctxt->level--;

View File

@ -1342,6 +1342,9 @@ xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
static const xmlChar * static const xmlChar *
xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item) xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
{ {
if (item == NULL) {
return (NULL);
}
switch (item->type) { switch (item->type) {
case XML_SCHEMA_TYPE_ELEMENT: case XML_SCHEMA_TYPE_ELEMENT:
return (((xmlSchemaElementPtr) item)->name); return (((xmlSchemaElementPtr) item)->name);
@ -1397,6 +1400,9 @@ xmlSchemaGetQNameRefTargetNs(void *ref)
static const xmlChar * static const xmlChar *
xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item) xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
{ {
if (item == NULL) {
return (NULL);
}
switch (item->type) { switch (item->type) {
case XML_SCHEMA_TYPE_ELEMENT: case XML_SCHEMA_TYPE_ELEMENT:
return (((xmlSchemaElementPtr) item)->targetNamespace); return (((xmlSchemaElementPtr) item)->targetNamespace);
@ -5893,7 +5899,7 @@ xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
if (!strchr((char *) value, ':')) { if (!strchr((char *) value, ':')) {
ns = xmlSearchNs(attr->doc, attr->parent, NULL); ns = xmlSearchNs(attr->doc, attr->parent, NULL);
if (ns) if (ns && ns->href && ns->href[0])
*uri = xmlDictLookup(ctxt->dict, ns->href, -1); *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) { else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
/* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
@ -28136,10 +28142,6 @@ xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
VERROR(1, NULL, "The document has no document element"); VERROR(1, NULL, "The document has no document element");
return (1); return (1);
} }
for (node = valRoot->next; node != NULL; node = node->next) {
if (node->type == XML_ELEMENT_NODE)
VERROR(1, NULL, "The document has more than one top element");
}
vctxt->depth = -1; vctxt->depth = -1;
vctxt->validationRoot = valRoot; vctxt->validationRoot = valRoot;
node = valRoot; node = valRoot;

View File

@ -5431,7 +5431,6 @@ xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet,
xmlSchemaWhitespaceValueType ws) xmlSchemaWhitespaceValueType ws)
{ {
int ret; int ret;
int stringType;
if (facet == NULL) if (facet == NULL)
return(-1); return(-1);
@ -5449,10 +5448,16 @@ xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet,
* the datatype. * the datatype.
* See https://www.w3.org/TR/xmlschema-2/#rf-pattern * See https://www.w3.org/TR/xmlschema-2/#rf-pattern
*/ */
stringType = val && ((val->type >= XML_SCHEMAS_STRING && val->type <= XML_SCHEMAS_NORMSTRING) if (val &&
|| (val->type >= XML_SCHEMAS_TOKEN && val->type <= XML_SCHEMAS_NCNAME)); val->value.str &&
ret = xmlRegexpExec(facet->regexp, ((val->type >= XML_SCHEMAS_STRING &&
(stringType && val->value.str) ? val->value.str : value); val->type <= XML_SCHEMAS_NORMSTRING) ||
(val->type >= XML_SCHEMAS_TOKEN &&
val->type <= XML_SCHEMAS_ENTITIES &&
val->type != XML_SCHEMAS_QNAME))) {
value = val->value.str;
}
ret = xmlRegexpExec(facet->regexp, value);
if (ret == 1) if (ret == 1)
return(0); return(0);
if (ret == 0) if (ret == 0)

View File

@ -18,6 +18,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <limits.h>
#include <libxml/xmlmemory.h> #include <libxml/xmlmemory.h>
#include <libxml/parserInternals.h> #include <libxml/parserInternals.h>
#include <libxml/xmlstring.h> #include <libxml/xmlstring.h>
@ -42,7 +43,7 @@ xmlStrndup(const xmlChar *cur, int len) {
xmlChar *ret; xmlChar *ret;
if ((cur == NULL) || (len < 0)) return(NULL); if ((cur == NULL) || (len < 0)) return(NULL);
ret = (xmlChar *) xmlMallocAtomic((len + 1) * sizeof(xmlChar)); ret = (xmlChar *) xmlMallocAtomic(((size_t) len + 1) * sizeof(xmlChar));
if (ret == NULL) { if (ret == NULL) {
xmlErrMemory(NULL, NULL); xmlErrMemory(NULL, NULL);
return(NULL); return(NULL);
@ -87,7 +88,7 @@ xmlCharStrndup(const char *cur, int len) {
xmlChar *ret; xmlChar *ret;
if ((cur == NULL) || (len < 0)) return(NULL); if ((cur == NULL) || (len < 0)) return(NULL);
ret = (xmlChar *) xmlMallocAtomic((len + 1) * sizeof(xmlChar)); ret = (xmlChar *) xmlMallocAtomic(((size_t) len + 1) * sizeof(xmlChar));
if (ret == NULL) { if (ret == NULL) {
xmlErrMemory(NULL, NULL); xmlErrMemory(NULL, NULL);
return(NULL); return(NULL);
@ -423,14 +424,14 @@ xmlStrsub(const xmlChar *str, int start, int len) {
int int
xmlStrlen(const xmlChar *str) { xmlStrlen(const xmlChar *str) {
int len = 0; size_t len = 0;
if (str == NULL) return(0); if (str == NULL) return(0);
while (*str != 0) { /* non input consuming */ while (*str != 0) { /* non input consuming */
str++; str++;
len++; len++;
} }
return(len); return(len > INT_MAX ? 0 : len);
} }
/** /**
@ -460,9 +461,9 @@ xmlStrncat(xmlChar *cur, const xmlChar *add, int len) {
return(xmlStrndup(add, len)); return(xmlStrndup(add, len));
size = xmlStrlen(cur); size = xmlStrlen(cur);
if (size < 0) if ((size < 0) || (size > INT_MAX - len))
return(NULL); return(NULL);
ret = (xmlChar *) xmlRealloc(cur, (size + len + 1) * sizeof(xmlChar)); ret = (xmlChar *) xmlRealloc(cur, ((size_t) size + len + 1) * sizeof(xmlChar));
if (ret == NULL) { if (ret == NULL) {
xmlErrMemory(NULL, NULL); xmlErrMemory(NULL, NULL);
return(cur); return(cur);
@ -500,9 +501,9 @@ xmlStrncatNew(const xmlChar *str1, const xmlChar *str2, int len) {
return(xmlStrndup(str2, len)); return(xmlStrndup(str2, len));
size = xmlStrlen(str1); size = xmlStrlen(str1);
if (size < 0) if ((size < 0) || (size > INT_MAX - len))
return(NULL); return(NULL);
ret = (xmlChar *) xmlMalloc((size + len + 1) * sizeof(xmlChar)); ret = (xmlChar *) xmlMalloc(((size_t) size + len + 1) * sizeof(xmlChar));
if (ret == NULL) { if (ret == NULL) {
xmlErrMemory(NULL, NULL); xmlErrMemory(NULL, NULL);
return(xmlStrndup(str1, size)); return(xmlStrndup(str1, size));
@ -667,7 +668,7 @@ xmlUTF8Charcmp(const xmlChar *utf1, const xmlChar *utf2) {
*/ */
int int
xmlUTF8Strlen(const xmlChar *utf) { xmlUTF8Strlen(const xmlChar *utf) {
int ret = 0; size_t ret = 0;
if (utf == NULL) if (utf == NULL)
return(-1); return(-1);
@ -694,7 +695,7 @@ xmlUTF8Strlen(const xmlChar *utf) {
} }
ret++; ret++;
} }
return(ret); return(ret > INT_MAX ? 0 : ret);
} }
/** /**
@ -796,26 +797,28 @@ xmlCheckUTF8(const unsigned char *utf)
* 1110xxxx 10xxxxxx 10xxxxxx valid 3-byte * 1110xxxx 10xxxxxx 10xxxxxx valid 3-byte
* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx valid 4-byte * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx valid 4-byte
*/ */
for (ix = 0; (c = utf[ix]);) { /* string is 0-terminated */ while ((c = utf[0])) { /* string is 0-terminated */
ix = 0;
if ((c & 0x80) == 0x00) { /* 1-byte code, starts with 10 */ if ((c & 0x80) == 0x00) { /* 1-byte code, starts with 10 */
ix++; ix = 1;
} else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */ } else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
if ((utf[ix+1] & 0xc0 ) != 0x80) if ((utf[1] & 0xc0 ) != 0x80)
return 0; return 0;
ix += 2; ix = 2;
} else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */ } else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
if (((utf[ix+1] & 0xc0) != 0x80) || if (((utf[1] & 0xc0) != 0x80) ||
((utf[ix+2] & 0xc0) != 0x80)) ((utf[2] & 0xc0) != 0x80))
return 0; return 0;
ix += 3; ix = 3;
} else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */ } else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
if (((utf[ix+1] & 0xc0) != 0x80) || if (((utf[1] & 0xc0) != 0x80) ||
((utf[ix+2] & 0xc0) != 0x80) || ((utf[2] & 0xc0) != 0x80) ||
((utf[ix+3] & 0xc0) != 0x80)) ((utf[3] & 0xc0) != 0x80))
return 0; return 0;
ix += 4; ix = 4;
} else /* unknown encoding */ } else /* unknown encoding */
return 0; return 0;
utf += ix;
} }
return(1); return(1);
} }
@ -834,8 +837,9 @@ xmlCheckUTF8(const unsigned char *utf)
int int
xmlUTF8Strsize(const xmlChar *utf, int len) { xmlUTF8Strsize(const xmlChar *utf, int len) {
const xmlChar *ptr=utf; const xmlChar *ptr=utf;
xmlChar ch; int ch;
size_t ret;
if (utf == NULL) if (utf == NULL)
return(0); return(0);
@ -852,7 +856,8 @@ xmlUTF8Strsize(const xmlChar *utf, int len) {
ptr++; ptr++;
} }
} }
return (ptr - utf); ret = ptr - utf;
return (ret > INT_MAX ? 0 : ret);
} }
@ -872,11 +877,8 @@ xmlUTF8Strndup(const xmlChar *utf, int len) {
if ((utf == NULL) || (len < 0)) return(NULL); if ((utf == NULL) || (len < 0)) return(NULL);
i = xmlUTF8Strsize(utf, len); i = xmlUTF8Strsize(utf, len);
ret = (xmlChar *) xmlMallocAtomic((i + 1) * sizeof(xmlChar)); ret = (xmlChar *) xmlMallocAtomic(((size_t) i + 1) * sizeof(xmlChar));
if (ret == NULL) { if (ret == NULL) {
xmlGenericError(xmlGenericErrorContext,
"malloc of %ld byte failed\n",
(len + 1) * (long)sizeof(xmlChar));
return(NULL); return(NULL);
} }
memcpy(ret, utf, i * sizeof(xmlChar)); memcpy(ret, utf, i * sizeof(xmlChar));
@ -896,7 +898,7 @@ xmlUTF8Strndup(const xmlChar *utf, int len) {
*/ */
const xmlChar * const xmlChar *
xmlUTF8Strpos(const xmlChar *utf, int pos) { xmlUTF8Strpos(const xmlChar *utf, int pos) {
xmlChar ch; int ch;
if (utf == NULL) return(NULL); if (utf == NULL) return(NULL);
if (pos < 0) if (pos < 0)
@ -928,14 +930,15 @@ xmlUTF8Strpos(const xmlChar *utf, int pos) {
*/ */
int int
xmlUTF8Strloc(const xmlChar *utf, const xmlChar *utfchar) { xmlUTF8Strloc(const xmlChar *utf, const xmlChar *utfchar) {
int i, size; size_t i;
xmlChar ch; int size;
int ch;
if (utf==NULL || utfchar==NULL) return -1; if (utf==NULL || utfchar==NULL) return -1;
size = xmlUTF8Strsize(utfchar, 1); size = xmlUTF8Strsize(utfchar, 1);
for(i=0; (ch=*utf) != 0; i++) { for(i=0; (ch=*utf) != 0; i++) {
if (xmlStrncmp(utf, utfchar, size)==0) if (xmlStrncmp(utf, utfchar, size)==0)
return(i); return(i > INT_MAX ? 0 : i);
utf++; utf++;
if ( ch & 0x80 ) { if ( ch & 0x80 ) {
/* if not simple ascii, verify proper format */ /* if not simple ascii, verify proper format */
@ -965,8 +968,8 @@ xmlUTF8Strloc(const xmlChar *utf, const xmlChar *utfchar) {
xmlChar * xmlChar *
xmlUTF8Strsub(const xmlChar *utf, int start, int len) { xmlUTF8Strsub(const xmlChar *utf, int start, int len) {
int i; int i;
xmlChar ch; int ch;
if (utf == NULL) return(NULL); if (utf == NULL) return(NULL);
if (start < 0) return(NULL); if (start < 0) return(NULL);
@ -1022,6 +1025,8 @@ xmlEscapeFormatString(xmlChar **msg)
if (count == 0) if (count == 0)
return(*msg); return(*msg);
if ((count > INT_MAX) || (msgLen > INT_MAX - count))
return(NULL);
resultLen = msgLen + count + 1; resultLen = msgLen + count + 1;
result = (xmlChar *) xmlMallocAtomic(resultLen * sizeof(xmlChar)); result = (xmlChar *) xmlMallocAtomic(resultLen * sizeof(xmlChar));
if (result == NULL) { if (result == NULL) {

View File

@ -10981,7 +10981,7 @@ xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) {
} }
if (xpctxt != NULL) if (xpctxt != NULL)
xpctxt->depth -= 1; xpctxt->depth -= 10;
} }
/** /**
@ -11118,7 +11118,9 @@ xmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
name = NULL; name = NULL;
if (CUR != ')') { if (CUR != ')') {
name = xmlXPathParseLiteral(ctxt); name = xmlXPathParseLiteral(ctxt);
CHECK_ERROR NULL; if (name == NULL) {
XP_ERRORNULL(XPATH_EXPR_ERROR);
}
*test = NODE_TEST_PI; *test = NODE_TEST_PI;
SKIP_BLANKS; SKIP_BLANKS;
} }

View File

@ -851,7 +851,6 @@ static void xmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name);
* *
* Dirty macros, i.e. one need to make assumption on the context to use them * Dirty macros, i.e. one need to make assumption on the context to use them
* *
* CUR_PTR return the current pointer to the xmlChar to be parsed.
* CUR returns the current xmlChar value, i.e. a 8 bit value * CUR returns the current xmlChar value, i.e. a 8 bit value
* in ISO-Latin or UTF-8. * in ISO-Latin or UTF-8.
* This should be used internally by the parser * This should be used internally by the parser
@ -871,7 +870,6 @@ static void xmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name);
#define CUR (*ctxt->cur) #define CUR (*ctxt->cur)
#define SKIP(val) ctxt->cur += (val) #define SKIP(val) ctxt->cur += (val)
#define NXT(val) ctxt->cur[(val)] #define NXT(val) ctxt->cur[(val)]
#define CUR_PTR ctxt->cur
#define SKIP_BLANKS \ #define SKIP_BLANKS \
while (IS_BLANK_CH(*(ctxt->cur))) NEXT while (IS_BLANK_CH(*(ctxt->cur))) NEXT
@ -999,9 +997,10 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
} }
if (xmlStrEqual(name, (xmlChar *) "xpointer")) { if (xmlStrEqual(name, (xmlChar *) "xpointer")) {
const xmlChar *left = CUR_PTR; const xmlChar *oldBase = ctxt->base;
const xmlChar *oldCur = ctxt->cur;
CUR_PTR = buffer; ctxt->cur = ctxt->base = buffer;
/* /*
* To evaluate an xpointer scheme element (4.3) we need: * To evaluate an xpointer scheme element (4.3) we need:
* context initialized to the root * context initialized to the root
@ -1012,42 +1011,49 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
ctxt->context->proximityPosition = 1; ctxt->context->proximityPosition = 1;
ctxt->context->contextSize = 1; ctxt->context->contextSize = 1;
xmlXPathEvalExpr(ctxt); xmlXPathEvalExpr(ctxt);
CUR_PTR=left; ctxt->base = oldBase;
ctxt->cur = oldCur;
} else if (xmlStrEqual(name, (xmlChar *) "element")) { } else if (xmlStrEqual(name, (xmlChar *) "element")) {
const xmlChar *left = CUR_PTR; const xmlChar *oldBase = ctxt->base;
const xmlChar *oldCur = ctxt->cur;
xmlChar *name2; xmlChar *name2;
CUR_PTR = buffer; ctxt->cur = ctxt->base = buffer;
if (buffer[0] == '/') { if (buffer[0] == '/') {
xmlXPathRoot(ctxt); xmlXPathRoot(ctxt);
xmlXPtrEvalChildSeq(ctxt, NULL); xmlXPtrEvalChildSeq(ctxt, NULL);
} else { } else {
name2 = xmlXPathParseName(ctxt); name2 = xmlXPathParseName(ctxt);
if (name2 == NULL) { if (name2 == NULL) {
CUR_PTR = left; ctxt->base = oldBase;
ctxt->cur = oldCur;
xmlFree(buffer); xmlFree(buffer);
xmlFree(name); xmlFree(name);
XP_ERROR(XPATH_EXPR_ERROR); XP_ERROR(XPATH_EXPR_ERROR);
} }
xmlXPtrEvalChildSeq(ctxt, name2); xmlXPtrEvalChildSeq(ctxt, name2);
} }
CUR_PTR = left; ctxt->base = oldBase;
ctxt->cur = oldCur;
#ifdef XPTR_XMLNS_SCHEME #ifdef XPTR_XMLNS_SCHEME
} else if (xmlStrEqual(name, (xmlChar *) "xmlns")) { } else if (xmlStrEqual(name, (xmlChar *) "xmlns")) {
const xmlChar *left = CUR_PTR; const xmlChar *oldBase = ctxt->base;
const xmlChar *oldCur = ctxt->cur;
xmlChar *prefix; xmlChar *prefix;
xmlChar *URI;
xmlURIPtr value;
CUR_PTR = buffer; ctxt->cur = ctxt->base = buffer;
prefix = xmlXPathParseNCName(ctxt); prefix = xmlXPathParseNCName(ctxt);
if (prefix == NULL) { if (prefix == NULL) {
ctxt->base = oldBase;
ctxt->cur = oldCur;
xmlFree(buffer); xmlFree(buffer);
xmlFree(name); xmlFree(name);
XP_ERROR(XPTR_SYNTAX_ERROR); XP_ERROR(XPTR_SYNTAX_ERROR);
} }
SKIP_BLANKS; SKIP_BLANKS;
if (CUR != '=') { if (CUR != '=') {
ctxt->base = oldBase;
ctxt->cur = oldCur;
xmlFree(prefix); xmlFree(prefix);
xmlFree(buffer); xmlFree(buffer);
xmlFree(name); xmlFree(name);
@ -1055,27 +1061,10 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
} }
NEXT; NEXT;
SKIP_BLANKS; SKIP_BLANKS;
/* @@ check escaping in the XPointer WD */
value = xmlParseURI((const char *)ctxt->cur); xmlXPathRegisterNs(ctxt->context, prefix, ctxt->cur);
if (value == NULL) { ctxt->base = oldBase;
xmlFree(prefix); ctxt->cur = oldCur;
xmlFree(buffer);
xmlFree(name);
XP_ERROR(XPTR_SYNTAX_ERROR);
}
URI = xmlSaveUri(value);
xmlFreeURI(value);
if (URI == NULL) {
xmlFree(prefix);
xmlFree(buffer);
xmlFree(name);
XP_ERROR(XPATH_MEMORY_ERROR);
}
xmlXPathRegisterNs(ctxt->context, prefix, URI);
CUR_PTR = left;
xmlFree(URI);
xmlFree(prefix); xmlFree(prefix);
#endif /* XPTR_XMLNS_SCHEME */ #endif /* XPTR_XMLNS_SCHEME */
} else { } else {
@ -1470,16 +1459,16 @@ xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
return(list); return(list);
} else { } else {
tmp = xmlCopyNode(cur, 0); tmp = xmlCopyNode(cur, 0);
if (list == NULL) if (list == NULL) {
list = tmp; list = tmp;
else { parent = tmp;
} else {
if (last != NULL) if (last != NULL)
xmlAddNextSibling(last, tmp); parent = xmlAddNextSibling(last, tmp);
else else
xmlAddChild(parent, tmp); parent = xmlAddChild(parent, tmp);
} }
last = NULL; last = NULL;
parent = tmp;
if (index2 > 1) { if (index2 > 1) {
end = xmlXPtrGetNthChild(cur, index2 - 1); end = xmlXPtrGetNthChild(cur, index2 - 1);
@ -1561,8 +1550,7 @@ xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
if (last != NULL) if (last != NULL)
xmlAddNextSibling(last, tmp); xmlAddNextSibling(last, tmp);
else { else {
xmlAddChild(parent, tmp); last = xmlAddChild(parent, tmp);
last = tmp;
} }
} }
} }