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) ||
(URI != NULL))
xmlCreateIntSubset(cur, BAD_CAST "html", ExternalID, URI);
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur);
}
@ -3045,7 +3047,7 @@ htmlParsePubidLiteral(htmlParserCtxtPtr ctxt) {
NEXT;
}
if (CUR != '"') {
if (CUR != quote) {
htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
"Unfinished PubidLiteral\n", NULL, NULL);
} else {
@ -3958,13 +3960,25 @@ htmlParseStartTag(htmlParserCtxtPtr ctxt) {
htmlParseErr(ctxt, XML_ERR_NAME_REQUIRED,
"htmlParseStartTag: invalid element name\n",
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 ((ctxt->recovery) && ((IS_BLANK_CH(CUR)) || (CUR == '<') ||
(CUR == '=') || (CUR == '>') || (((CUR >= '0') && (CUR <= '9'))))) {
htmlParseCharDataInternal(ctxt, '<');
return(-1);
}
#endif
/* Dump the bogus tag like browsers do */
while ((CUR != 0) && (CUR != '>') &&
@ -5185,6 +5199,7 @@ htmlCreateMemoryParserCtxt(const char *buffer, int size) {
input = xmlNewInputStream(ctxt);
if (input == NULL) {
xmlFreeParserInputBuffer(buf);
xmlFreeParserCtxt(ctxt);
return(NULL);
}
@ -5992,32 +6007,12 @@ htmlParseTryOrFinish(htmlParserCtxtPtr ctxt, int terminate) {
} else if (cur == '<') {
if ((!terminate) && (next == 0))
goto done;
/*
* Only switch to START_TAG if the next character
* 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;
ctxt->instate = XML_PARSER_START_TAG;
ctxt->checkIndex = 0;
#ifdef DEBUG_PUSH
xmlGenericError(xmlGenericErrorContext,
"HPP: entering START_TAG\n");
xmlGenericError(xmlGenericErrorContext,
"HPP: entering START_TAG\n");
#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;
} else {
/*
@ -6999,7 +6994,9 @@ htmlReadMemory(const char *buffer, int size, const char *URL, const char *encodi
* @encoding: the document encoding, or NULL
* @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
*/
@ -7008,17 +7005,17 @@ htmlReadFd(int fd, const char *URL, const char *encoding, int options)
{
htmlParserCtxtPtr ctxt;
xmlParserInputBufferPtr input;
xmlParserInputPtr stream;
htmlParserInputPtr stream;
if (fd < 0)
return (NULL);
xmlInitParser();
xmlInitParser();
input = xmlParserInputBufferCreateFd(fd, XML_CHAR_ENCODING_NONE);
if (input == NULL)
return (NULL);
ctxt = xmlNewParserCtxt();
input->closecallback = NULL;
ctxt = htmlNewParserCtxt();
if (ctxt == NULL) {
xmlFreeParserInputBuffer(input);
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);
if (stream == NULL) {
xmlFreeParserInputBuffer(input);
xmlFreeParserCtxt(ctxt);
htmlFreeParserCtxt(ctxt);
return (NULL);
}
inputPush(ctxt, stream);

View File

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

View File

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

View File

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

View File

@ -7973,6 +7973,18 @@ extern __typeof (xmlPopInputCallbacks) xmlPopInputCallbacks__internal_alias __at
#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)
#ifdef bottom_tree
#undef xmlPreviousElementSibling

View File

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

View File

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

View File

@ -29,28 +29,28 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
*
* the version string like "1.2.3"
*/
#define LIBXML_DOTTED_VERSION "2.9.12"
#define LIBXML_DOTTED_VERSION "2.9.13"
/**
* LIBXML_VERSION:
*
* the version number: 1.2.3 value is 10203
*/
#define LIBXML_VERSION 20912
#define LIBXML_VERSION 20913
/**
* LIBXML_VERSION_STRING:
*
* the version number string, 1.2.3 value is "10203"
*/
#define LIBXML_VERSION_STRING "20912"
#define LIBXML_VERSION_STRING "20913"
/**
* 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:
@ -58,7 +58,7 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
* Macro to check that the libxml version in use is compatible with
* the version the software has been compiled against
*/
#define LIBXML_TEST_VERSION xmlCheckVersion(20912);
#define LIBXML_TEST_VERSION xmlCheckVersion(20913);
#ifndef VMS
#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
* 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;
/*
* 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);
/* move current position before possible calling of ctxt->sax->characters */
NEXTL(l);
cur = CUR_CHAR(l);
if (nbchar >= XML_PARSER_BIG_BUFFER_SIZE) {
buf[nbchar] = 0;
@ -4620,8 +4624,6 @@ xmlParseCharDataComplex(xmlParserCtxtPtr ctxt, int cdata) {
if (ctxt->instate == XML_PARSER_EOF)
return;
}
NEXTL(l);
cur = CUR_CHAR(l);
}
if (nbchar != 0) {
buf[nbchar] = 0;
@ -4980,7 +4982,7 @@ get_more:
ctxt->input->cur = in;
in++;
ctxt->input->line++; ctxt->input->col = 1;
continue; /* while */
goto get_more;
}
in--;
}
@ -10657,16 +10659,16 @@ xmlParseXMLDecl(xmlParserCtxtPtr ctxt) {
void
xmlParseMisc(xmlParserCtxtPtr ctxt) {
while ((ctxt->instate != XML_PARSER_EOF) &&
(((RAW == '<') && (NXT(1) == '?')) ||
(CMP4(CUR_PTR, '<', '!', '-', '-')) ||
IS_BLANK_CH(CUR))) {
while (ctxt->instate != XML_PARSER_EOF) {
SKIP_BLANKS;
GROW;
if ((RAW == '<') && (NXT(1) == '?')) {
xmlParsePI(ctxt);
} else if (IS_BLANK_CH(CUR)) {
NEXT;
} else
} else if (CMP4(CUR_PTR, '<', '!', '-', '-')) {
xmlParseComment(ctxt);
} else {
break;
}
}
}
@ -10772,7 +10774,6 @@ xmlParseDocument(xmlParserCtxtPtr ctxt) {
/*
* The Misc part of the Prolog
*/
GROW;
xmlParseMisc(ctxt);
/*
@ -12625,6 +12626,7 @@ xmlCreateIOParserCtxt(xmlSAXHandlerPtr sax, void *user_data,
xmlFree(ctxt->sax);
ctxt->sax = (xmlSAXHandlerPtr) xmlMalloc(sizeof(xmlSAXHandler));
if (ctxt->sax == NULL) {
xmlFreeParserInputBuffer(buf);
xmlErrMemory(ctxt, NULL);
xmlFreeParserCtxt(ctxt);
return(NULL);
@ -14672,7 +14674,8 @@ xmlInitParser(void) {
return;
#if defined(_WIN32) && (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
atexit(xmlCleanupParser);
if (xmlFree == free)
atexit(xmlCleanupParser);
#endif
#ifdef LIBXML_THREAD_ENABLED

View File

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

View File

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

View File

@ -1596,6 +1596,10 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
*/
if (!xmlBufIsEmpty(buf)) {
node = xmlNewDocText(doc, NULL);
if (node == NULL) {
if (val != NULL) xmlFree(val);
goto out;
}
node->content = xmlBufDetach(buf);
if (last == NULL) {
@ -2852,8 +2856,15 @@ xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) {
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);
}
tree->doc = doc;
}
}
@ -3691,17 +3702,14 @@ xmlFreeNodeList(xmlNodePtr cur) {
xmlFreeNsList((xmlNsPtr) cur);
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;
while (1) {
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_ENTITY_REF_NODE)) {
cur = cur->children;
@ -3710,7 +3718,13 @@ xmlFreeNodeList(xmlNodePtr cur) {
next = cur->next;
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))
xmlDeregisterNodeDefaultValue(cur);
@ -3724,11 +3738,6 @@ xmlFreeNodeList(xmlNodePtr cur) {
(cur->type != XML_XINCLUDE_START) &&
(cur->type != XML_XINCLUDE_END) &&
(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))) {
DICT_FREE(cur->content)
}

View File

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

View File

@ -479,6 +479,35 @@ nodeVPop(xmlValidCtxtPtr ctxt)
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
static void
xmlValidPrintNode(xmlNodePtr cur) {
@ -2607,6 +2636,24 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
(xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
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:
* @not: A id
@ -2650,7 +2697,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
if (doc == NULL) {
return(NULL);
}
if (value == NULL) {
if ((value == NULL) || (value[0] == 0)) {
return(NULL);
}
if (attr == NULL) {
@ -2681,7 +2728,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
*/
ret->value = xmlStrdup(value);
ret->doc = doc;
if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
if (xmlIsStreaming(ctxt)) {
/*
* Operating in streaming mode, attr is gonna disappear
*/
@ -2820,6 +2867,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
ID = xmlNodeListGetString(doc, attr->children, 1);
if (ID == NULL)
return(-1);
xmlValidNormalizeString(ID);
id = xmlHashLookup(table, ID);
if (id == NULL || id->attr != attr) {
@ -3009,7 +3057,7 @@ xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
* fill the structure.
*/
ret->value = xmlStrdup(value);
if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
if (xmlIsStreaming(ctxt)) {
/*
* Operating in streaming mode, attr is gonna disappear
*/
@ -4028,8 +4076,7 @@ xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlChar *
xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
xmlNodePtr elem, const xmlChar *name, const xmlChar *value) {
xmlChar *ret, *dst;
const xmlChar *src;
xmlChar *ret;
xmlAttributePtr attrDecl = NULL;
int extsubset = 0;
@ -4070,19 +4117,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
ret = xmlStrdup(value);
if (ret == NULL)
return(NULL);
src = value;
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;
xmlValidNormalizeString(ret);
if ((doc->standalone) && (extsubset == 1) && (!xmlStrEqual(value, ret))) {
xmlErrValidNode(ctxt, elem, XML_DTD_NOT_STANDALONE,
"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 *
xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
const xmlChar *name, const xmlChar *value) {
xmlChar *ret, *dst;
const xmlChar *src;
xmlChar *ret;
xmlAttributePtr attrDecl = NULL;
if (doc == NULL) return(NULL);
@ -4145,19 +4179,7 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
ret = xmlStrdup(value);
if (ret == NULL)
return(NULL);
src = value;
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;
xmlValidNormalizeString(ret);
return(ret);
}

View File

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

View File

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

View File

@ -78,7 +78,7 @@ void xmlMallocBreakpoint(void);
* Each of the blocks allocated begin with a header containing information
*/
#define MEMTAG 0x5aa5
#define MEMTAG 0x5aa5U
#define MALLOC_TYPE 1
#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
* 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.
*
* 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
xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
@ -1904,7 +1910,8 @@ xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
continue;
if (state->nbTrans != 1)
continue;
if (state->type == XML_REGEXP_UNREACH_STATE)
if (state->type == XML_REGEXP_UNREACH_STATE ||
state->type == XML_REGEXP_FINAL_STATE)
continue;
/* is the only transition out a basic transition */
if ((state->trans[0].atom == NULL) &&

View File

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

View File

@ -1342,6 +1342,9 @@ xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
static const xmlChar *
xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
{
if (item == NULL) {
return (NULL);
}
switch (item->type) {
case XML_SCHEMA_TYPE_ELEMENT:
return (((xmlSchemaElementPtr) item)->name);
@ -1397,6 +1400,9 @@ xmlSchemaGetQNameRefTargetNs(void *ref)
static const xmlChar *
xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
{
if (item == NULL) {
return (NULL);
}
switch (item->type) {
case XML_SCHEMA_TYPE_ELEMENT:
return (((xmlSchemaElementPtr) item)->targetNamespace);
@ -5893,7 +5899,7 @@ xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
if (!strchr((char *) value, ':')) {
ns = xmlSearchNs(attr->doc, attr->parent, NULL);
if (ns)
if (ns && ns->href && ns->href[0])
*uri = xmlDictLookup(ctxt->dict, ns->href, -1);
else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
/* 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");
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->validationRoot = valRoot;
node = valRoot;

View File

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

View File

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

View File

@ -10981,7 +10981,7 @@ xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) {
}
if (xpctxt != NULL)
xpctxt->depth -= 1;
xpctxt->depth -= 10;
}
/**
@ -11118,7 +11118,9 @@ xmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
name = NULL;
if (CUR != ')') {
name = xmlXPathParseLiteral(ctxt);
CHECK_ERROR NULL;
if (name == NULL) {
XP_ERRORNULL(XPATH_EXPR_ERROR);
}
*test = NODE_TEST_PI;
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
*
* CUR_PTR return the current pointer to the xmlChar to be parsed.
* CUR returns the current xmlChar value, i.e. a 8 bit value
* in ISO-Latin or UTF-8.
* This should be used internally by the parser
@ -871,7 +870,6 @@ static void xmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name);
#define CUR (*ctxt->cur)
#define SKIP(val) ctxt->cur += (val)
#define NXT(val) ctxt->cur[(val)]
#define CUR_PTR ctxt->cur
#define SKIP_BLANKS \
while (IS_BLANK_CH(*(ctxt->cur))) NEXT
@ -999,9 +997,10 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
}
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:
* context initialized to the root
@ -1012,42 +1011,49 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
ctxt->context->proximityPosition = 1;
ctxt->context->contextSize = 1;
xmlXPathEvalExpr(ctxt);
CUR_PTR=left;
ctxt->base = oldBase;
ctxt->cur = oldCur;
} else if (xmlStrEqual(name, (xmlChar *) "element")) {
const xmlChar *left = CUR_PTR;
const xmlChar *oldBase = ctxt->base;
const xmlChar *oldCur = ctxt->cur;
xmlChar *name2;
CUR_PTR = buffer;
ctxt->cur = ctxt->base = buffer;
if (buffer[0] == '/') {
xmlXPathRoot(ctxt);
xmlXPtrEvalChildSeq(ctxt, NULL);
} else {
name2 = xmlXPathParseName(ctxt);
if (name2 == NULL) {
CUR_PTR = left;
ctxt->base = oldBase;
ctxt->cur = oldCur;
xmlFree(buffer);
xmlFree(name);
XP_ERROR(XPATH_EXPR_ERROR);
}
xmlXPtrEvalChildSeq(ctxt, name2);
}
CUR_PTR = left;
ctxt->base = oldBase;
ctxt->cur = oldCur;
#ifdef XPTR_XMLNS_SCHEME
} else if (xmlStrEqual(name, (xmlChar *) "xmlns")) {
const xmlChar *left = CUR_PTR;
const xmlChar *oldBase = ctxt->base;
const xmlChar *oldCur = ctxt->cur;
xmlChar *prefix;
xmlChar *URI;
xmlURIPtr value;
CUR_PTR = buffer;
ctxt->cur = ctxt->base = buffer;
prefix = xmlXPathParseNCName(ctxt);
if (prefix == NULL) {
ctxt->base = oldBase;
ctxt->cur = oldCur;
xmlFree(buffer);
xmlFree(name);
XP_ERROR(XPTR_SYNTAX_ERROR);
}
SKIP_BLANKS;
if (CUR != '=') {
ctxt->base = oldBase;
ctxt->cur = oldCur;
xmlFree(prefix);
xmlFree(buffer);
xmlFree(name);
@ -1055,27 +1061,10 @@ xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
}
NEXT;
SKIP_BLANKS;
/* @@ check escaping in the XPointer WD */
value = xmlParseURI((const char *)ctxt->cur);
if (value == NULL) {
xmlFree(prefix);
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);
xmlXPathRegisterNs(ctxt->context, prefix, ctxt->cur);
ctxt->base = oldBase;
ctxt->cur = oldCur;
xmlFree(prefix);
#endif /* XPTR_XMLNS_SCHEME */
} else {
@ -1470,16 +1459,16 @@ xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
return(list);
} else {
tmp = xmlCopyNode(cur, 0);
if (list == NULL)
if (list == NULL) {
list = tmp;
else {
parent = tmp;
} else {
if (last != NULL)
xmlAddNextSibling(last, tmp);
parent = xmlAddNextSibling(last, tmp);
else
xmlAddChild(parent, tmp);
parent = xmlAddChild(parent, tmp);
}
last = NULL;
parent = tmp;
if (index2 > 1) {
end = xmlXPtrGetNthChild(cur, index2 - 1);
@ -1561,8 +1550,7 @@ xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
if (last != NULL)
xmlAddNextSibling(last, tmp);
else {
xmlAddChild(parent, tmp);
last = tmp;
last = xmlAddChild(parent, tmp);
}
}
}