mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-01-12 09:17:37 +03:00
Make xhtmlNodeDumpOutput non-recursive
Fixes stack overflow with deeply nested documents.
This commit is contained in:
parent
b79ab6e6d9
commit
5330153da4
621
xmlsave.c
621
xmlsave.c
@ -1395,40 +1395,6 @@ xhtmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* xhtmlNodeListDumpOutput:
|
||||
* @buf: the XML buffer output
|
||||
* @doc: the XHTML document
|
||||
* @cur: the first node
|
||||
* @level: the imbrication level for indenting
|
||||
* @format: is formatting allowed
|
||||
* @encoding: an optional encoding string
|
||||
*
|
||||
* Dump an XML node list, recursive behaviour, children are printed too.
|
||||
* Note that @format = 1 provide node indenting only if xmlIndentTreeOutput = 1
|
||||
* or xmlKeepBlanksDefault(0) was called
|
||||
*/
|
||||
static void
|
||||
xhtmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
xmlOutputBufferPtr buf;
|
||||
|
||||
if (cur == NULL) return;
|
||||
buf = ctxt->buf;
|
||||
while (cur != NULL) {
|
||||
if ((ctxt->format == 1) && (xmlIndentTreeOutput) &&
|
||||
(cur->type == XML_ELEMENT_NODE))
|
||||
xmlOutputBufferWrite(buf, ctxt->indent_size *
|
||||
(ctxt->level > ctxt->indent_nr ?
|
||||
ctxt->indent_nr : ctxt->level),
|
||||
ctxt->indent);
|
||||
xhtmlNodeDumpOutput(ctxt, cur);
|
||||
if (ctxt->format == 1) {
|
||||
xmlOutputBufferWrite(buf, 1, "\n");
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* xhtmlNodeDumpOutput:
|
||||
* @buf: the XML buffer output
|
||||
@ -1442,48 +1408,195 @@ xhtmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
*/
|
||||
static void
|
||||
xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
int format, addmeta = 0;
|
||||
xmlNodePtr tmp;
|
||||
int format = ctxt->format, addmeta;
|
||||
xmlNodePtr tmp, root, unformattedNode = NULL;
|
||||
xmlChar *start, *end;
|
||||
xmlOutputBufferPtr buf;
|
||||
xmlOutputBufferPtr buf = ctxt->buf;
|
||||
|
||||
if (cur == NULL) return;
|
||||
if ((cur->type == XML_DOCUMENT_NODE) ||
|
||||
(cur->type == XML_HTML_DOCUMENT_NODE)) {
|
||||
xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
|
||||
return;
|
||||
}
|
||||
if (cur->type == XML_XINCLUDE_START)
|
||||
return;
|
||||
if (cur->type == XML_XINCLUDE_END)
|
||||
return;
|
||||
if (cur->type == XML_NAMESPACE_DECL) {
|
||||
xmlNsDumpOutputCtxt(ctxt, (xmlNsPtr) cur);
|
||||
return;
|
||||
}
|
||||
if (cur->type == XML_DTD_NODE) {
|
||||
xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
|
||||
return;
|
||||
}
|
||||
if (cur->type == XML_DOCUMENT_FRAG_NODE) {
|
||||
xhtmlNodeListDumpOutput(ctxt, cur->children);
|
||||
return;
|
||||
}
|
||||
buf = ctxt->buf;
|
||||
if (cur->type == XML_ELEMENT_DECL) {
|
||||
xmlBufDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
|
||||
return;
|
||||
}
|
||||
if (cur->type == XML_ATTRIBUTE_DECL) {
|
||||
xmlBufDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
|
||||
return;
|
||||
}
|
||||
if (cur->type == XML_ENTITY_DECL) {
|
||||
xmlBufDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
|
||||
return;
|
||||
}
|
||||
if (cur->type == XML_TEXT_NODE) {
|
||||
if (cur->content != NULL) {
|
||||
|
||||
root = cur;
|
||||
while (1) {
|
||||
switch (cur->type) {
|
||||
case XML_DOCUMENT_NODE:
|
||||
case XML_HTML_DOCUMENT_NODE:
|
||||
xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
|
||||
break;
|
||||
|
||||
case XML_NAMESPACE_DECL:
|
||||
xmlNsDumpOutputCtxt(ctxt, (xmlNsPtr) cur);
|
||||
break;
|
||||
|
||||
case XML_DTD_NODE:
|
||||
xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
|
||||
break;
|
||||
|
||||
case XML_DOCUMENT_FRAG_NODE:
|
||||
if (cur->children) {
|
||||
cur = cur->children;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case XML_ELEMENT_DECL:
|
||||
xmlBufDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
|
||||
break;
|
||||
|
||||
case XML_ATTRIBUTE_DECL:
|
||||
xmlBufDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
|
||||
break;
|
||||
|
||||
case XML_ENTITY_DECL:
|
||||
xmlBufDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
|
||||
break;
|
||||
|
||||
case XML_ELEMENT_NODE:
|
||||
addmeta = 0;
|
||||
|
||||
if ((cur != root) && (ctxt->format == 1) && (xmlIndentTreeOutput))
|
||||
xmlOutputBufferWrite(buf, ctxt->indent_size *
|
||||
(ctxt->level > ctxt->indent_nr ?
|
||||
ctxt->indent_nr : ctxt->level),
|
||||
ctxt->indent);
|
||||
|
||||
xmlOutputBufferWrite(buf, 1, "<");
|
||||
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
|
||||
xmlOutputBufferWrite(buf, 1, ":");
|
||||
}
|
||||
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
||||
if (cur->nsDef)
|
||||
xmlNsListDumpOutputCtxt(ctxt, cur->nsDef);
|
||||
if ((xmlStrEqual(cur->name, BAD_CAST "html") &&
|
||||
(cur->ns == NULL) && (cur->nsDef == NULL))) {
|
||||
/*
|
||||
* 3.1.1. Strictly Conforming Documents A.3.1.1 3/
|
||||
*/
|
||||
xmlOutputBufferWriteString(buf,
|
||||
" xmlns=\"http://www.w3.org/1999/xhtml\"");
|
||||
}
|
||||
if (cur->properties != NULL)
|
||||
xhtmlAttrListDumpOutput(ctxt, cur->properties);
|
||||
|
||||
if ((cur->parent != NULL) &&
|
||||
(cur->parent->parent == (xmlNodePtr) cur->doc) &&
|
||||
xmlStrEqual(cur->name, BAD_CAST"head") &&
|
||||
xmlStrEqual(cur->parent->name, BAD_CAST"html")) {
|
||||
|
||||
tmp = cur->children;
|
||||
while (tmp != NULL) {
|
||||
if (xmlStrEqual(tmp->name, BAD_CAST"meta")) {
|
||||
xmlChar *httpequiv;
|
||||
|
||||
httpequiv = xmlGetProp(tmp, BAD_CAST"http-equiv");
|
||||
if (httpequiv != NULL) {
|
||||
if (xmlStrcasecmp(httpequiv,
|
||||
BAD_CAST"Content-Type") == 0) {
|
||||
xmlFree(httpequiv);
|
||||
break;
|
||||
}
|
||||
xmlFree(httpequiv);
|
||||
}
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
if (tmp == NULL)
|
||||
addmeta = 1;
|
||||
}
|
||||
|
||||
if (cur->children == NULL) {
|
||||
if (((cur->ns == NULL) || (cur->ns->prefix == NULL)) &&
|
||||
((xhtmlIsEmpty(cur) == 1) && (addmeta == 0))) {
|
||||
/*
|
||||
* C.2. Empty Elements
|
||||
*/
|
||||
xmlOutputBufferWrite(buf, 3, " />");
|
||||
} else {
|
||||
if (addmeta == 1) {
|
||||
xmlOutputBufferWrite(buf, 1, ">");
|
||||
if (ctxt->format == 1) {
|
||||
xmlOutputBufferWrite(buf, 1, "\n");
|
||||
if (xmlIndentTreeOutput)
|
||||
xmlOutputBufferWrite(buf, ctxt->indent_size *
|
||||
(ctxt->level + 1 > ctxt->indent_nr ?
|
||||
ctxt->indent_nr : ctxt->level + 1),
|
||||
ctxt->indent);
|
||||
}
|
||||
xmlOutputBufferWriteString(buf,
|
||||
"<meta http-equiv=\"Content-Type\" "
|
||||
"content=\"text/html; charset=");
|
||||
if (ctxt->encoding) {
|
||||
xmlOutputBufferWriteString(buf,
|
||||
(const char *)ctxt->encoding);
|
||||
} else {
|
||||
xmlOutputBufferWrite(buf, 5, "UTF-8");
|
||||
}
|
||||
xmlOutputBufferWrite(buf, 4, "\" />");
|
||||
if (ctxt->format == 1)
|
||||
xmlOutputBufferWrite(buf, 1, "\n");
|
||||
} else {
|
||||
xmlOutputBufferWrite(buf, 1, ">");
|
||||
}
|
||||
/*
|
||||
* C.3. Element Minimization and Empty Element Content
|
||||
*/
|
||||
xmlOutputBufferWrite(buf, 2, "</");
|
||||
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
|
||||
xmlOutputBufferWriteString(buf,
|
||||
(const char *)cur->ns->prefix);
|
||||
xmlOutputBufferWrite(buf, 1, ":");
|
||||
}
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
||||
xmlOutputBufferWrite(buf, 1, ">");
|
||||
}
|
||||
} else {
|
||||
xmlOutputBufferWrite(buf, 1, ">");
|
||||
if (addmeta == 1) {
|
||||
if (ctxt->format == 1) {
|
||||
xmlOutputBufferWrite(buf, 1, "\n");
|
||||
if (xmlIndentTreeOutput)
|
||||
xmlOutputBufferWrite(buf, ctxt->indent_size *
|
||||
(ctxt->level + 1 > ctxt->indent_nr ?
|
||||
ctxt->indent_nr : ctxt->level + 1),
|
||||
ctxt->indent);
|
||||
}
|
||||
xmlOutputBufferWriteString(buf,
|
||||
"<meta http-equiv=\"Content-Type\" "
|
||||
"content=\"text/html; charset=");
|
||||
if (ctxt->encoding) {
|
||||
xmlOutputBufferWriteString(buf,
|
||||
(const char *)ctxt->encoding);
|
||||
} else {
|
||||
xmlOutputBufferWrite(buf, 5, "UTF-8");
|
||||
}
|
||||
xmlOutputBufferWrite(buf, 4, "\" />");
|
||||
}
|
||||
|
||||
if (ctxt->format == 1) {
|
||||
tmp = cur->children;
|
||||
while (tmp != NULL) {
|
||||
if ((tmp->type == XML_TEXT_NODE) ||
|
||||
(tmp->type == XML_ENTITY_REF_NODE)) {
|
||||
unformattedNode = cur;
|
||||
ctxt->format = 0;
|
||||
break;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n");
|
||||
if (ctxt->level >= 0) ctxt->level++;
|
||||
cur = cur->children;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case XML_TEXT_NODE:
|
||||
if (cur->content == NULL)
|
||||
break;
|
||||
if ((cur->name == xmlStringText) ||
|
||||
(cur->name != xmlStringTextNoenc)) {
|
||||
xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape);
|
||||
@ -1493,286 +1606,106 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
*/
|
||||
xmlOutputBufferWriteString(buf, (const char *) cur->content);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
return;
|
||||
}
|
||||
if (cur->type == XML_PI_NODE) {
|
||||
if (cur->content != NULL) {
|
||||
xmlOutputBufferWrite(buf, 2, "<?");
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
||||
if (cur->content != NULL) {
|
||||
xmlOutputBufferWrite(buf, 1, " ");
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->content);
|
||||
}
|
||||
xmlOutputBufferWrite(buf, 2, "?>");
|
||||
} else {
|
||||
xmlOutputBufferWrite(buf, 2, "<?");
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
||||
xmlOutputBufferWrite(buf, 2, "?>");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (cur->type == XML_COMMENT_NODE) {
|
||||
if (cur->content != NULL) {
|
||||
xmlOutputBufferWrite(buf, 4, "<!--");
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->content);
|
||||
xmlOutputBufferWrite(buf, 3, "-->");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (cur->type == XML_ENTITY_REF_NODE) {
|
||||
xmlOutputBufferWrite(buf, 1, "&");
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
||||
xmlOutputBufferWrite(buf, 1, ";");
|
||||
return;
|
||||
}
|
||||
if (cur->type == XML_CDATA_SECTION_NODE) {
|
||||
if (cur->content == NULL || *cur->content == '\0') {
|
||||
xmlOutputBufferWrite(buf, 12, "<![CDATA[]]>");
|
||||
} else {
|
||||
start = end = cur->content;
|
||||
while (*end != '\0') {
|
||||
if (*end == ']' && *(end + 1) == ']' && *(end + 2) == '>') {
|
||||
end = end + 2;
|
||||
xmlOutputBufferWrite(buf, 9, "<![CDATA[");
|
||||
xmlOutputBufferWrite(buf, end - start, (const char *)start);
|
||||
xmlOutputBufferWrite(buf, 3, "]]>");
|
||||
start = end;
|
||||
}
|
||||
end++;
|
||||
}
|
||||
if (start != end) {
|
||||
xmlOutputBufferWrite(buf, 9, "<![CDATA[");
|
||||
xmlOutputBufferWriteString(buf, (const char *)start);
|
||||
xmlOutputBufferWrite(buf, 3, "]]>");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (cur->type == XML_ATTRIBUTE_NODE) {
|
||||
xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur);
|
||||
return;
|
||||
}
|
||||
case XML_PI_NODE:
|
||||
if (cur->content != NULL) {
|
||||
xmlOutputBufferWrite(buf, 2, "<?");
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
||||
if (cur->content != NULL) {
|
||||
xmlOutputBufferWrite(buf, 1, " ");
|
||||
xmlOutputBufferWriteString(buf,
|
||||
(const char *)cur->content);
|
||||
}
|
||||
xmlOutputBufferWrite(buf, 2, "?>");
|
||||
} else {
|
||||
xmlOutputBufferWrite(buf, 2, "<?");
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
||||
xmlOutputBufferWrite(buf, 2, "?>");
|
||||
}
|
||||
break;
|
||||
|
||||
format = ctxt->format;
|
||||
if (format == 1) {
|
||||
tmp = cur->children;
|
||||
while (tmp != NULL) {
|
||||
if ((tmp->type == XML_TEXT_NODE) ||
|
||||
(tmp->type == XML_ENTITY_REF_NODE)) {
|
||||
format = 0;
|
||||
break;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
xmlOutputBufferWrite(buf, 1, "<");
|
||||
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
|
||||
xmlOutputBufferWrite(buf, 1, ":");
|
||||
}
|
||||
case XML_COMMENT_NODE:
|
||||
if (cur->content != NULL) {
|
||||
xmlOutputBufferWrite(buf, 4, "<!--");
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->content);
|
||||
xmlOutputBufferWrite(buf, 3, "-->");
|
||||
}
|
||||
break;
|
||||
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
||||
if (cur->nsDef)
|
||||
xmlNsListDumpOutputCtxt(ctxt, cur->nsDef);
|
||||
if ((xmlStrEqual(cur->name, BAD_CAST "html") &&
|
||||
(cur->ns == NULL) && (cur->nsDef == NULL))) {
|
||||
/*
|
||||
* 3.1.1. Strictly Conforming Documents A.3.1.1 3/
|
||||
*/
|
||||
xmlOutputBufferWriteString(buf,
|
||||
" xmlns=\"http://www.w3.org/1999/xhtml\"");
|
||||
}
|
||||
if (cur->properties != NULL)
|
||||
xhtmlAttrListDumpOutput(ctxt, cur->properties);
|
||||
case XML_ENTITY_REF_NODE:
|
||||
xmlOutputBufferWrite(buf, 1, "&");
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
||||
xmlOutputBufferWrite(buf, 1, ";");
|
||||
break;
|
||||
|
||||
if ((cur->type == XML_ELEMENT_NODE) &&
|
||||
(cur->parent != NULL) &&
|
||||
(cur->parent->parent == (xmlNodePtr) cur->doc) &&
|
||||
xmlStrEqual(cur->name, BAD_CAST"head") &&
|
||||
xmlStrEqual(cur->parent->name, BAD_CAST"html")) {
|
||||
|
||||
tmp = cur->children;
|
||||
while (tmp != NULL) {
|
||||
if (xmlStrEqual(tmp->name, BAD_CAST"meta")) {
|
||||
xmlChar *httpequiv;
|
||||
|
||||
httpequiv = xmlGetProp(tmp, BAD_CAST"http-equiv");
|
||||
if (httpequiv != NULL) {
|
||||
if (xmlStrcasecmp(httpequiv, BAD_CAST"Content-Type") == 0) {
|
||||
xmlFree(httpequiv);
|
||||
break;
|
||||
case XML_CDATA_SECTION_NODE:
|
||||
if (cur->content == NULL || *cur->content == '\0') {
|
||||
xmlOutputBufferWrite(buf, 12, "<![CDATA[]]>");
|
||||
} else {
|
||||
start = end = cur->content;
|
||||
while (*end != '\0') {
|
||||
if (*end == ']' && *(end + 1) == ']' &&
|
||||
*(end + 2) == '>') {
|
||||
end = end + 2;
|
||||
xmlOutputBufferWrite(buf, 9, "<![CDATA[");
|
||||
xmlOutputBufferWrite(buf, end - start,
|
||||
(const char *)start);
|
||||
xmlOutputBufferWrite(buf, 3, "]]>");
|
||||
start = end;
|
||||
}
|
||||
xmlFree(httpequiv);
|
||||
end++;
|
||||
}
|
||||
if (start != end) {
|
||||
xmlOutputBufferWrite(buf, 9, "<![CDATA[");
|
||||
xmlOutputBufferWriteString(buf, (const char *)start);
|
||||
xmlOutputBufferWrite(buf, 3, "]]>");
|
||||
}
|
||||
}
|
||||
tmp = tmp->next;
|
||||
break;
|
||||
|
||||
case XML_ATTRIBUTE_NODE:
|
||||
xmlAttrDumpOutput(ctxt, (xmlAttrPtr) cur);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (cur == root)
|
||||
return;
|
||||
if (ctxt->format == 1) {
|
||||
xmlOutputBufferWrite(buf, 1, "\n");
|
||||
}
|
||||
if (cur->next != NULL) {
|
||||
cur = cur->next;
|
||||
break;
|
||||
}
|
||||
|
||||
cur = cur->parent;
|
||||
|
||||
if (ctxt->level > 0) ctxt->level--;
|
||||
if ((xmlIndentTreeOutput) && (ctxt->format == 1))
|
||||
xmlOutputBufferWrite(buf, ctxt->indent_size *
|
||||
(ctxt->level > ctxt->indent_nr ?
|
||||
ctxt->indent_nr : ctxt->level),
|
||||
ctxt->indent);
|
||||
if (cur == unformattedNode) {
|
||||
ctxt->format = format;
|
||||
unformattedNode = NULL;
|
||||
}
|
||||
|
||||
xmlOutputBufferWrite(buf, 2, "</");
|
||||
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
|
||||
xmlOutputBufferWrite(buf, 1, ":");
|
||||
}
|
||||
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
||||
xmlOutputBufferWrite(buf, 1, ">");
|
||||
}
|
||||
if (tmp == NULL)
|
||||
addmeta = 1;
|
||||
}
|
||||
|
||||
if ((cur->type == XML_ELEMENT_NODE) && (cur->children == NULL)) {
|
||||
if (((cur->ns == NULL) || (cur->ns->prefix == NULL)) &&
|
||||
((xhtmlIsEmpty(cur) == 1) && (addmeta == 0))) {
|
||||
/*
|
||||
* C.2. Empty Elements
|
||||
*/
|
||||
xmlOutputBufferWrite(buf, 3, " />");
|
||||
} else {
|
||||
if (addmeta == 1) {
|
||||
xmlOutputBufferWrite(buf, 1, ">");
|
||||
if (ctxt->format == 1) {
|
||||
xmlOutputBufferWrite(buf, 1, "\n");
|
||||
if (xmlIndentTreeOutput)
|
||||
xmlOutputBufferWrite(buf, ctxt->indent_size *
|
||||
(ctxt->level + 1 > ctxt->indent_nr ?
|
||||
ctxt->indent_nr : ctxt->level + 1), ctxt->indent);
|
||||
}
|
||||
xmlOutputBufferWriteString(buf,
|
||||
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=");
|
||||
if (ctxt->encoding) {
|
||||
xmlOutputBufferWriteString(buf, (const char *)ctxt->encoding);
|
||||
} else {
|
||||
xmlOutputBufferWrite(buf, 5, "UTF-8");
|
||||
}
|
||||
xmlOutputBufferWrite(buf, 4, "\" />");
|
||||
if (ctxt->format == 1)
|
||||
xmlOutputBufferWrite(buf, 1, "\n");
|
||||
} else {
|
||||
xmlOutputBufferWrite(buf, 1, ">");
|
||||
}
|
||||
/*
|
||||
* C.3. Element Minimization and Empty Element Content
|
||||
*/
|
||||
xmlOutputBufferWrite(buf, 2, "</");
|
||||
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
|
||||
xmlOutputBufferWrite(buf, 1, ":");
|
||||
}
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
||||
xmlOutputBufferWrite(buf, 1, ">");
|
||||
}
|
||||
return;
|
||||
}
|
||||
xmlOutputBufferWrite(buf, 1, ">");
|
||||
if (addmeta == 1) {
|
||||
if (ctxt->format == 1) {
|
||||
xmlOutputBufferWrite(buf, 1, "\n");
|
||||
if (xmlIndentTreeOutput)
|
||||
xmlOutputBufferWrite(buf, ctxt->indent_size *
|
||||
(ctxt->level + 1 > ctxt->indent_nr ?
|
||||
ctxt->indent_nr : ctxt->level + 1), ctxt->indent);
|
||||
}
|
||||
xmlOutputBufferWriteString(buf,
|
||||
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=");
|
||||
if (ctxt->encoding) {
|
||||
xmlOutputBufferWriteString(buf, (const char *)ctxt->encoding);
|
||||
} else {
|
||||
xmlOutputBufferWrite(buf, 5, "UTF-8");
|
||||
}
|
||||
xmlOutputBufferWrite(buf, 4, "\" />");
|
||||
}
|
||||
if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
|
||||
xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* This was removed due to problems with HTML processors.
|
||||
* See bug #345147.
|
||||
*/
|
||||
/*
|
||||
* 4.8. Script and Style elements
|
||||
*/
|
||||
if ((cur->type == XML_ELEMENT_NODE) &&
|
||||
((xmlStrEqual(cur->name, BAD_CAST "script")) ||
|
||||
(xmlStrEqual(cur->name, BAD_CAST "style"))) &&
|
||||
((cur->ns == NULL) ||
|
||||
(xmlStrEqual(cur->ns->href, XHTML_NS_NAME)))) {
|
||||
xmlNodePtr child = cur->children;
|
||||
|
||||
while (child != NULL) {
|
||||
if (child->type == XML_TEXT_NODE) {
|
||||
if ((xmlStrchr(child->content, '<') == NULL) &&
|
||||
(xmlStrchr(child->content, '&') == NULL) &&
|
||||
(xmlStrstr(child->content, BAD_CAST "]]>") == NULL)) {
|
||||
/* Nothing to escape, so just output as is... */
|
||||
/* FIXME: Should we do something about "--" also? */
|
||||
int level = ctxt->level;
|
||||
int indent = ctxt->format;
|
||||
|
||||
ctxt->level = 0;
|
||||
ctxt->format = 0;
|
||||
xmlOutputBufferWriteString(buf, (const char *) child->content);
|
||||
/* (We cannot use xhtmlNodeDumpOutput() here because
|
||||
* we wish to leave '>' unescaped!) */
|
||||
ctxt->level = level;
|
||||
ctxt->format = indent;
|
||||
} else {
|
||||
/* We must use a CDATA section. Unfortunately,
|
||||
* this will break CSS and JavaScript when read by
|
||||
* a browser in HTML4-compliant mode. :-( */
|
||||
start = end = child->content;
|
||||
while (*end != '\0') {
|
||||
if (*end == ']' &&
|
||||
*(end + 1) == ']' &&
|
||||
*(end + 2) == '>') {
|
||||
end = end + 2;
|
||||
xmlOutputBufferWrite(buf, 9, "<![CDATA[");
|
||||
xmlOutputBufferWrite(buf, end - start,
|
||||
(const char *)start);
|
||||
xmlOutputBufferWrite(buf, 3, "]]>");
|
||||
start = end;
|
||||
}
|
||||
end++;
|
||||
}
|
||||
if (start != end) {
|
||||
xmlOutputBufferWrite(buf, 9, "<![CDATA[");
|
||||
xmlOutputBufferWrite(buf, end - start,
|
||||
(const char *)start);
|
||||
xmlOutputBufferWrite(buf, 3, "]]>");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int level = ctxt->level;
|
||||
int indent = ctxt->format;
|
||||
|
||||
ctxt->level = 0;
|
||||
ctxt->format = 0;
|
||||
xhtmlNodeDumpOutput(ctxt, child);
|
||||
ctxt->level = level;
|
||||
ctxt->format = indent;
|
||||
}
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cur->children != NULL) {
|
||||
int indent = ctxt->format;
|
||||
|
||||
if (format == 1) xmlOutputBufferWrite(buf, 1, "\n");
|
||||
if (ctxt->level >= 0) ctxt->level++;
|
||||
ctxt->format = format;
|
||||
xhtmlNodeListDumpOutput(ctxt, cur->children);
|
||||
if (ctxt->level > 0) ctxt->level--;
|
||||
ctxt->format = indent;
|
||||
if ((xmlIndentTreeOutput) && (format == 1))
|
||||
xmlOutputBufferWrite(buf, ctxt->indent_size *
|
||||
(ctxt->level > ctxt->indent_nr ?
|
||||
ctxt->indent_nr : ctxt->level),
|
||||
ctxt->indent);
|
||||
}
|
||||
xmlOutputBufferWrite(buf, 2, "</");
|
||||
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
|
||||
xmlOutputBufferWrite(buf, 1, ":");
|
||||
}
|
||||
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
||||
xmlOutputBufferWrite(buf, 1, ">");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user