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, ">");
} else {
@@ -967,7 +964,7 @@ htmlNodeDumpInternal(xmlOutputBufferPtr buf, xmlNodePtr cur,
xmlOutputBufferWrite(buf, 1, "\n");
if (addMeta) {
xmlOutputBufferWrite(buf, 15, "");
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);
}
/**