diff --git a/HTMLtree.c b/HTMLtree.c index a415a88e..49e9d137 100644 --- a/HTMLtree.c +++ b/HTMLtree.c @@ -787,7 +787,7 @@ htmlAttrDumpOutput(xmlOutputBufferPtr buf, xmlAttrPtr cur) { if (isUri) { htmlSerializeUri(buf, content); } else { - xmlSerializeText(buf, content, + xmlSerializeText(buf, content, SIZE_MAX, XML_ESCAPE_HTML | XML_ESCAPE_ATTR); } } else if (child->type == XML_ENTITY_REF_NODE) { @@ -917,21 +917,18 @@ htmlNodeDumpInternal(xmlOutputBufferPtr buf, xmlNodePtr cur, if ((!isMeta) || (attr != menc.attr)) { htmlAttrDumpOutput(buf, attr); } else { - xmlChar *newVal; - xmlOutputBufferWrite(buf, 1, " "); xmlOutputBufferWriteString(buf, (char *) attr->name); - newVal = htmlUpdateMetaEncoding(&menc, encoding); - if (newVal == NULL) { - buf->error = XML_ERR_NO_MEMORY; - return; - } xmlOutputBufferWrite(buf, 2, "=\""); - xmlSerializeText(buf, newVal, + xmlSerializeText(buf, menc.attrValue, menc.off.start, + XML_ESCAPE_HTML | XML_ESCAPE_ATTR); + xmlSerializeText(buf, BAD_CAST encoding, SIZE_MAX, + XML_ESCAPE_HTML | XML_ESCAPE_ATTR); + xmlSerializeText(buf, menc.attrValue + menc.off.end, + menc.off.size - menc.off.end, XML_ESCAPE_HTML | XML_ESCAPE_ATTR); xmlOutputBufferWrite(buf, 1, "\""); - xmlFree(newVal); } attr = attr->next; } @@ -941,7 +938,7 @@ htmlNodeDumpInternal(xmlOutputBufferPtr buf, xmlNodePtr cur, } else if (cur->children == NULL) { if (addMeta) { xmlOutputBufferWrite(buf, 16, ">"); if ((format) && @@ -1008,7 +1005,7 @@ htmlNodeDumpInternal(xmlOutputBufferPtr buf, xmlNodePtr cur, (isRaw)) { xmlOutputBufferWriteString(buf, (const char *)cur->content); } else { - xmlSerializeText(buf, cur->content, XML_ESCAPE_HTML); + xmlSerializeText(buf, cur->content, SIZE_MAX, XML_ESCAPE_HTML); } break; diff --git a/include/private/io.h b/include/private/io.h index f0b6d85f..9f2b12ac 100644 --- a/include/private/io.h +++ b/include/private/io.h @@ -5,6 +5,10 @@ #include #include +#ifndef SIZE_MAX + #define SIZE_MAX ((size_t)(-1)) +#endif + /* * Initial buffer size should include * @@ -24,7 +28,7 @@ XML_HIDDEN xmlChar * xmlEscapeText(const xmlChar *text, int flags); #ifdef LIBXML_OUTPUT_ENABLED XML_HIDDEN void -xmlSerializeText(xmlOutputBufferPtr buf, const xmlChar *string, +xmlSerializeText(xmlOutputBufferPtr buf, const xmlChar *string, size_t maxSize, unsigned flags); #endif diff --git a/xmlIO.c b/xmlIO.c index 7cd76854..80390f4b 100644 --- a/xmlIO.c +++ b/xmlIO.c @@ -374,9 +374,9 @@ xmlEscapeText(const xmlChar *string, int flags) { #ifdef LIBXML_OUTPUT_ENABLED void -xmlSerializeText(xmlOutputBufferPtr buf, const xmlChar *string, +xmlSerializeText(xmlOutputBufferPtr buf, const xmlChar *string, size_t maxSize, unsigned flags) { - const char *cur; + const xmlChar *cur; const signed char *tab; if (string == NULL) @@ -400,10 +400,10 @@ xmlSerializeText(xmlOutputBufferPtr buf, const xmlChar *string, tab = xmlEscapeTab; } - cur = (const char *) string; + cur = string; - while (*cur != 0) { - const char *base; + while (1) { + const xmlChar *base; int c; int offset; @@ -411,6 +411,9 @@ xmlSerializeText(xmlOutputBufferPtr buf, const xmlChar *string, offset = -1; while (1) { + if ((size_t) (cur - string) >= maxSize) + break; + c = (unsigned char) *cur; if (c < 0x80) { @@ -425,7 +428,10 @@ xmlSerializeText(xmlOutputBufferPtr buf, const xmlChar *string, } if (cur > base) - xmlOutputBufferWrite(buf, cur - base, base); + xmlOutputBufferWrite(buf, cur - base, (char *) base); + + if ((size_t) (cur - string) >= maxSize) + break; if (offset >= 0) { if (c == 0) @@ -439,7 +445,7 @@ xmlSerializeText(xmlOutputBufferPtr buf, const xmlChar *string, int tempSize; int val = 0, len = 4; - val = xmlGetUTF8Char((const xmlChar *) cur, &len); + val = xmlGetUTF8Char(cur, &len); if (val < 0) { val = 0xFFFD; cur += 1; diff --git a/xmlsave.c b/xmlsave.c index 53908d9d..73439e90 100644 --- a/xmlsave.c +++ b/xmlsave.c @@ -227,7 +227,7 @@ xmlSaveWriteText(xmlSaveCtxt *ctxt, const xmlChar *text, unsigned flags) { if (ctxt->encoding == NULL) flags |= XML_ESCAPE_NON_ASCII; - xmlSerializeText(ctxt->buf, text, flags); + xmlSerializeText(ctxt->buf, text, SIZE_MAX, flags); } /** @@ -780,7 +780,7 @@ xmlNsDumpOutput(xmlOutputBufferPtr buf, xmlNsPtr cur, xmlSaveCtxtPtr ctxt) { } else xmlOutputBufferWrite(buf, 5, "xmlns"); xmlOutputBufferWrite(buf, 2, "=\""); - xmlSerializeText(buf, cur->href, escapeFlags); + xmlSerializeText(buf, cur->href, SIZE_MAX, escapeFlags); xmlOutputBufferWrite(buf, 1, "\""); } } @@ -2137,7 +2137,7 @@ xmlBufAttrSerializeTxtContent(xmlOutputBufferPtr buf, xmlDocPtr doc, if ((doc == NULL) || (doc->encoding == NULL)) flags |= XML_ESCAPE_NON_ASCII; - xmlSerializeText(buf, string, flags); + xmlSerializeText(buf, string, SIZE_MAX, flags); } /**