1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-10-24 13:33:01 +03:00

tree: Restore return value of xmlNodeListGetString with NULL list

When passing a NULL list to xmlNodeListGetString or
xmlNodeListGetRawString, return NULL instead of "" to match the old
behavior.

Fixes #783.
This commit is contained in:
Nick Wellnhofer
2024-08-12 21:38:50 +02:00
parent b45a0f0eca
commit 0c56eb8215
4 changed files with 36 additions and 13 deletions

View File

@@ -2521,30 +2521,38 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
} }
case OP_XML_NODE_LIST_GET_STRING: { case OP_XML_NODE_LIST_GET_STRING: {
xmlDocPtr doc;
xmlNodePtr list;
xmlChar *string; xmlChar *string;
startOp("xmlNodeListGetString"); startOp("xmlNodeListGetString");
incStrIdx(); incStrIdx();
doc = getDoc(0);
list = getNode(1);
string = xmlNodeListGetString( string = xmlNodeListGetString(
getDoc(0), doc,
getNode(1), list,
getInt(0)); getInt(0));
oomReport = (string == NULL); oomReport = (list != NULL && string == NULL);
moveStr(0, string); moveStr(0, string);
endOp(); endOp();
break; break;
} }
case OP_XML_NODE_LIST_GET_RAW_STRING: { case OP_XML_NODE_LIST_GET_RAW_STRING: {
xmlDocPtr doc;
xmlNodePtr list;
xmlChar *string; xmlChar *string;
startOp("xmlNodeListGetRawString"); startOp("xmlNodeListGetRawString");
incStrIdx(); incStrIdx();
doc = getDoc(0);
list = getNode(1);
string = xmlNodeListGetRawString( string = xmlNodeListGetRawString(
getDoc(0), doc,
getNode(1), list,
getInt(0)); getInt(0));
oomReport = (string == NULL); oomReport = (list != NULL && string == NULL);
moveStr(0, string); moveStr(0, string);
endOp(); endOp();
break; break;

20
tree.c
View File

@@ -1559,11 +1559,11 @@ error:
/** /**
* xmlNodeListGetString: * xmlNodeListGetString:
* @doc: a document (optional) * @doc: a document (optional)
* @list: a node list of attribute children (optional) * @list: a node list of attribute children
* @inLine: whether entity references are substituted * @inLine: whether entity references are substituted
* *
* Serializes attribute children (text and entity reference nodes) * Serializes attribute children (text and entity reference nodes)
* into a string. An empty list produces an empty string. * into a string.
* *
* If @inLine is true, entity references will be substituted. * If @inLine is true, entity references will be substituted.
* Otherwise, entity references will be kept and special characters * Otherwise, entity references will be kept and special characters
@@ -1577,11 +1577,14 @@ xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
{ {
int escMode; int escMode;
/* backward compatibility */
if (list == NULL)
return(NULL);
if (inLine) { if (inLine) {
escMode = 0; escMode = 0;
} else { } else {
if ((list != NULL) && if ((list->parent != NULL) &&
(list->parent != NULL) &&
(list->parent->type == XML_ATTRIBUTE_NODE)) (list->parent->type == XML_ATTRIBUTE_NODE))
escMode = 2; escMode = 2;
else else
@@ -1594,11 +1597,11 @@ xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
/** /**
* xmlNodeListGetRawString: * xmlNodeListGetRawString:
* @doc: a document (optional) * @doc: a document (optional)
* @list: a node list of attribute children (optional) * @list: a node list of attribute children
* @inLine: whether entity references are substituted * @inLine: whether entity references are substituted
* *
* Serializes attribute children (text and entity reference nodes) * Serializes attribute children (text and entity reference nodes)
* into a string. An empty list produces an empty string. * into a string.
* *
* If @inLine is true, entity references will be substituted. * If @inLine is true, entity references will be substituted.
* Otherwise, entity references will be kept and special characters * Otherwise, entity references will be kept and special characters
@@ -1610,6 +1613,11 @@ xmlChar *
xmlNodeListGetRawString(const xmlDoc *doc, const xmlNode *list, int inLine) xmlNodeListGetRawString(const xmlDoc *doc, const xmlNode *list, int inLine)
{ {
int escMode = inLine ? 0 : 3; int escMode = inLine ? 0 : 3;
/* backward compatibility */
if (list == NULL)
return(NULL);
return(xmlNodeListGetStringInternal((xmlDocPtr) doc, list, escMode)); return(xmlNodeListGetStringInternal((xmlDocPtr) doc, list, escMode));
} }

View File

@@ -6190,7 +6190,10 @@ xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr root) {
if (elem->type == XML_ELEMENT_NODE) { if (elem->type == XML_ELEMENT_NODE) {
attr = elem->properties; attr = elem->properties;
while (attr != NULL) { while (attr != NULL) {
value = xmlNodeListGetString(doc, attr->children, 0); if (attr->children == NULL)
value = xmlStrdup(BAD_CAST "");
else
value = xmlNodeListGetString(doc, attr->children, 0);
if (value == NULL) { if (value == NULL) {
xmlVErrMemory(ctxt); xmlVErrMemory(ctxt);
ret = 0; ret = 0;

View File

@@ -2279,6 +2279,8 @@ xmlTextReaderGetAttributeNo(xmlTextReaderPtr reader, int no) {
} }
/* TODO walk the DTD if present */ /* TODO walk the DTD if present */
if (cur->children == NULL)
return(NULL);
ret = xmlNodeListGetString(reader->node->doc, cur->children, 1); ret = xmlNodeListGetString(reader->node->doc, cur->children, 1);
if (ret == NULL) if (ret == NULL)
xmlTextReaderErrMemory(reader); xmlTextReaderErrMemory(reader);
@@ -3524,6 +3526,8 @@ xmlTextReaderValue(xmlTextReaderPtr reader) {
xmlDocPtr doc = NULL; xmlDocPtr doc = NULL;
xmlChar *ret; xmlChar *ret;
if (attr->children == NULL)
return(NULL);
if (attr->parent != NULL) if (attr->parent != NULL)
doc = attr->parent->doc; doc = attr->parent->doc;
ret = xmlNodeListGetString(doc, attr->children, 1); ret = xmlNodeListGetString(doc, attr->children, 1);