mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-01-26 10:03:34 +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:
|
* xhtmlNodeDumpOutput:
|
||||||
* @buf: the XML buffer output
|
* @buf: the XML buffer output
|
||||||
@ -1442,48 +1408,195 @@ xhtmlNodeListDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||||
int format, addmeta = 0;
|
int format = ctxt->format, addmeta;
|
||||||
xmlNodePtr tmp;
|
xmlNodePtr tmp, root, unformattedNode = NULL;
|
||||||
xmlChar *start, *end;
|
xmlChar *start, *end;
|
||||||
xmlOutputBufferPtr buf;
|
xmlOutputBufferPtr buf = ctxt->buf;
|
||||||
|
|
||||||
if (cur == NULL) return;
|
if (cur == NULL) return;
|
||||||
if ((cur->type == XML_DOCUMENT_NODE) ||
|
|
||||||
(cur->type == XML_HTML_DOCUMENT_NODE)) {
|
root = cur;
|
||||||
xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
|
while (1) {
|
||||||
return;
|
switch (cur->type) {
|
||||||
}
|
case XML_DOCUMENT_NODE:
|
||||||
if (cur->type == XML_XINCLUDE_START)
|
case XML_HTML_DOCUMENT_NODE:
|
||||||
return;
|
xmlDocContentDumpOutput(ctxt, (xmlDocPtr) cur);
|
||||||
if (cur->type == XML_XINCLUDE_END)
|
break;
|
||||||
return;
|
|
||||||
if (cur->type == XML_NAMESPACE_DECL) {
|
case XML_NAMESPACE_DECL:
|
||||||
xmlNsDumpOutputCtxt(ctxt, (xmlNsPtr) cur);
|
xmlNsDumpOutputCtxt(ctxt, (xmlNsPtr) cur);
|
||||||
return;
|
break;
|
||||||
}
|
|
||||||
if (cur->type == XML_DTD_NODE) {
|
case XML_DTD_NODE:
|
||||||
xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
|
xmlDtdDumpOutput(ctxt, (xmlDtdPtr) cur);
|
||||||
return;
|
break;
|
||||||
}
|
|
||||||
if (cur->type == XML_DOCUMENT_FRAG_NODE) {
|
case XML_DOCUMENT_FRAG_NODE:
|
||||||
xhtmlNodeListDumpOutput(ctxt, cur->children);
|
if (cur->children) {
|
||||||
return;
|
cur = cur->children;
|
||||||
}
|
continue;
|
||||||
buf = ctxt->buf;
|
}
|
||||||
if (cur->type == XML_ELEMENT_DECL) {
|
break;
|
||||||
xmlBufDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
|
|
||||||
return;
|
case XML_ELEMENT_DECL:
|
||||||
}
|
xmlBufDumpElementDecl(buf->buffer, (xmlElementPtr) cur);
|
||||||
if (cur->type == XML_ATTRIBUTE_DECL) {
|
break;
|
||||||
xmlBufDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
|
|
||||||
return;
|
case XML_ATTRIBUTE_DECL:
|
||||||
}
|
xmlBufDumpAttributeDecl(buf->buffer, (xmlAttributePtr) cur);
|
||||||
if (cur->type == XML_ENTITY_DECL) {
|
break;
|
||||||
xmlBufDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
|
|
||||||
return;
|
case XML_ENTITY_DECL:
|
||||||
}
|
xmlBufDumpEntityDecl(buf->buffer, (xmlEntityPtr) cur);
|
||||||
if (cur->type == XML_TEXT_NODE) {
|
break;
|
||||||
if (cur->content != NULL) {
|
|
||||||
|
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) ||
|
if ((cur->name == xmlStringText) ||
|
||||||
(cur->name != xmlStringTextNoenc)) {
|
(cur->name != xmlStringTextNoenc)) {
|
||||||
xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape);
|
xmlOutputBufferWriteEscape(buf, cur->content, ctxt->escape);
|
||||||
@ -1493,286 +1606,106 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
|||||||
*/
|
*/
|
||||||
xmlOutputBufferWriteString(buf, (const char *) cur->content);
|
xmlOutputBufferWriteString(buf, (const char *) cur->content);
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
|
||||||
return;
|
case XML_PI_NODE:
|
||||||
}
|
if (cur->content != NULL) {
|
||||||
if (cur->type == XML_PI_NODE) {
|
xmlOutputBufferWrite(buf, 2, "<?");
|
||||||
if (cur->content != NULL) {
|
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
||||||
xmlOutputBufferWrite(buf, 2, "<?");
|
if (cur->content != NULL) {
|
||||||
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
xmlOutputBufferWrite(buf, 1, " ");
|
||||||
if (cur->content != NULL) {
|
xmlOutputBufferWriteString(buf,
|
||||||
xmlOutputBufferWrite(buf, 1, " ");
|
(const char *)cur->content);
|
||||||
xmlOutputBufferWriteString(buf, (const char *)cur->content);
|
}
|
||||||
}
|
xmlOutputBufferWrite(buf, 2, "?>");
|
||||||
xmlOutputBufferWrite(buf, 2, "?>");
|
} else {
|
||||||
} else {
|
xmlOutputBufferWrite(buf, 2, "<?");
|
||||||
xmlOutputBufferWrite(buf, 2, "<?");
|
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
||||||
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
xmlOutputBufferWrite(buf, 2, "?>");
|
||||||
xmlOutputBufferWrite(buf, 2, "?>");
|
}
|
||||||
}
|
break;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
format = ctxt->format;
|
case XML_COMMENT_NODE:
|
||||||
if (format == 1) {
|
if (cur->content != NULL) {
|
||||||
tmp = cur->children;
|
xmlOutputBufferWrite(buf, 4, "<!--");
|
||||||
while (tmp != NULL) {
|
xmlOutputBufferWriteString(buf, (const char *)cur->content);
|
||||||
if ((tmp->type == XML_TEXT_NODE) ||
|
xmlOutputBufferWrite(buf, 3, "-->");
|
||||||
(tmp->type == XML_ENTITY_REF_NODE)) {
|
}
|
||||||
format = 0;
|
break;
|
||||||
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, ":");
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
case XML_ENTITY_REF_NODE:
|
||||||
if (cur->nsDef)
|
xmlOutputBufferWrite(buf, 1, "&");
|
||||||
xmlNsListDumpOutputCtxt(ctxt, cur->nsDef);
|
xmlOutputBufferWriteString(buf, (const char *)cur->name);
|
||||||
if ((xmlStrEqual(cur->name, BAD_CAST "html") &&
|
xmlOutputBufferWrite(buf, 1, ";");
|
||||||
(cur->ns == NULL) && (cur->nsDef == NULL))) {
|
break;
|
||||||
/*
|
|
||||||
* 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->type == XML_ELEMENT_NODE) &&
|
case XML_CDATA_SECTION_NODE:
|
||||||
(cur->parent != NULL) &&
|
if (cur->content == NULL || *cur->content == '\0') {
|
||||||
(cur->parent->parent == (xmlNodePtr) cur->doc) &&
|
xmlOutputBufferWrite(buf, 12, "<![CDATA[]]>");
|
||||||
xmlStrEqual(cur->name, BAD_CAST"head") &&
|
} else {
|
||||||
xmlStrEqual(cur->parent->name, BAD_CAST"html")) {
|
start = end = cur->content;
|
||||||
|
while (*end != '\0') {
|
||||||
tmp = cur->children;
|
if (*end == ']' && *(end + 1) == ']' &&
|
||||||
while (tmp != NULL) {
|
*(end + 2) == '>') {
|
||||||
if (xmlStrEqual(tmp->name, BAD_CAST"meta")) {
|
end = end + 2;
|
||||||
xmlChar *httpequiv;
|
xmlOutputBufferWrite(buf, 9, "<![CDATA[");
|
||||||
|
xmlOutputBufferWrite(buf, end - start,
|
||||||
httpequiv = xmlGetProp(tmp, BAD_CAST"http-equiv");
|
(const char *)start);
|
||||||
if (httpequiv != NULL) {
|
xmlOutputBufferWrite(buf, 3, "]]>");
|
||||||
if (xmlStrcasecmp(httpequiv, BAD_CAST"Content-Type") == 0) {
|
start = end;
|
||||||
xmlFree(httpequiv);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
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
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user