mirror of
https://gitlab.gnome.org/GNOME/libxml2
synced 2025-03-28 21:33:13 +00:00
save: Handle invalid parent pointers in xhtmlNodeDumpOutput
See #255 and commit 85b1792e.
This commit is contained in:
parent
8711320065
commit
2d2336ee30
34
xmlsave.c
34
xmlsave.c
@ -1391,13 +1391,14 @@ xhtmlAttrListDumpOutput(xmlSaveCtxtPtr ctxt, xmlAttrPtr cur) {
|
|||||||
static void
|
static void
|
||||||
xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||||
int format = ctxt->format, addmeta;
|
int format = ctxt->format, addmeta;
|
||||||
xmlNodePtr tmp, root, unformattedNode = NULL;
|
xmlNodePtr tmp, root, unformattedNode = NULL, parent;
|
||||||
xmlChar *start, *end;
|
xmlChar *start, *end;
|
||||||
xmlOutputBufferPtr buf = ctxt->buf;
|
xmlOutputBufferPtr buf = ctxt->buf;
|
||||||
|
|
||||||
if (cur == NULL) return;
|
if (cur == NULL) return;
|
||||||
|
|
||||||
root = cur;
|
root = cur;
|
||||||
|
parent = cur->parent;
|
||||||
while (1) {
|
while (1) {
|
||||||
switch (cur->type) {
|
switch (cur->type) {
|
||||||
case XML_DOCUMENT_NODE:
|
case XML_DOCUMENT_NODE:
|
||||||
@ -1414,7 +1415,9 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case XML_DOCUMENT_FRAG_NODE:
|
case XML_DOCUMENT_FRAG_NODE:
|
||||||
if (cur->children) {
|
/* Always validate cur->parent when descending. */
|
||||||
|
if ((cur->parent == parent) && (cur->children != NULL)) {
|
||||||
|
parent = cur;
|
||||||
cur = cur->children;
|
cur = cur->children;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1441,6 +1444,16 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
|||||||
ctxt->indent_nr : ctxt->level),
|
ctxt->indent_nr : ctxt->level),
|
||||||
ctxt->indent);
|
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)) {
|
||||||
|
xhtmlNodeDumpOutput(ctxt, cur);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
xmlOutputBufferWrite(buf, 1, "<");
|
xmlOutputBufferWrite(buf, 1, "<");
|
||||||
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
|
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
|
||||||
xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
|
xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
|
||||||
@ -1461,10 +1474,10 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
|||||||
if (cur->properties != NULL)
|
if (cur->properties != NULL)
|
||||||
xhtmlAttrListDumpOutput(ctxt, cur->properties);
|
xhtmlAttrListDumpOutput(ctxt, cur->properties);
|
||||||
|
|
||||||
if ((cur->parent != NULL) &&
|
if ((parent != NULL) &&
|
||||||
(cur->parent->parent == (xmlNodePtr) cur->doc) &&
|
(parent->parent == (xmlNodePtr) cur->doc) &&
|
||||||
xmlStrEqual(cur->name, BAD_CAST"head") &&
|
xmlStrEqual(cur->name, BAD_CAST"head") &&
|
||||||
xmlStrEqual(cur->parent->name, BAD_CAST"html")) {
|
xmlStrEqual(parent->name, BAD_CAST"html")) {
|
||||||
|
|
||||||
tmp = cur->children;
|
tmp = cur->children;
|
||||||
while (tmp != NULL) {
|
while (tmp != NULL) {
|
||||||
@ -1570,6 +1583,7 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
|||||||
|
|
||||||
if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n");
|
if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n");
|
||||||
if (ctxt->level >= 0) ctxt->level++;
|
if (ctxt->level >= 0) ctxt->level++;
|
||||||
|
parent = cur;
|
||||||
cur = cur->children;
|
cur = cur->children;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1664,13 +1678,9 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
cur = parent;
|
||||||
* The parent should never be NULL here but we want to handle
|
/* cur->parent was validated when descending. */
|
||||||
* corrupted documents gracefully.
|
parent = cur->parent;
|
||||||
*/
|
|
||||||
if (cur->parent == NULL)
|
|
||||||
return;
|
|
||||||
cur = cur->parent;
|
|
||||||
|
|
||||||
if (cur->type == XML_ELEMENT_NODE) {
|
if (cur->type == XML_ELEMENT_NODE) {
|
||||||
if (ctxt->level > 0) ctxt->level--;
|
if (ctxt->level > 0) ctxt->level--;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user