1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2024-10-26 12:25:09 +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: {
xmlDocPtr doc;
xmlNodePtr list;
xmlChar *string;
startOp("xmlNodeListGetString");
incStrIdx();
doc = getDoc(0);
list = getNode(1);
string = xmlNodeListGetString(
getDoc(0),
getNode(1),
doc,
list,
getInt(0));
oomReport = (string == NULL);
oomReport = (list != NULL && string == NULL);
moveStr(0, string);
endOp();
break;
}
case OP_XML_NODE_LIST_GET_RAW_STRING: {
xmlDocPtr doc;
xmlNodePtr list;
xmlChar *string;
startOp("xmlNodeListGetRawString");
incStrIdx();
doc = getDoc(0);
list = getNode(1);
string = xmlNodeListGetRawString(
getDoc(0),
getNode(1),
doc,
list,
getInt(0));
oomReport = (string == NULL);
oomReport = (list != NULL && string == NULL);
moveStr(0, string);
endOp();
break;

20
tree.c
View File

@ -1559,11 +1559,11 @@ error:
/**
* xmlNodeListGetString:
* @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
*
* 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.
* Otherwise, entity references will be kept and special characters
@ -1577,11 +1577,14 @@ xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
{
int escMode;
/* backward compatibility */
if (list == NULL)
return(NULL);
if (inLine) {
escMode = 0;
} else {
if ((list != NULL) &&
(list->parent != NULL) &&
if ((list->parent != NULL) &&
(list->parent->type == XML_ATTRIBUTE_NODE))
escMode = 2;
else
@ -1594,11 +1597,11 @@ xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
/**
* xmlNodeListGetRawString:
* @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
*
* 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.
* Otherwise, entity references will be kept and special characters
@ -1610,6 +1613,11 @@ xmlChar *
xmlNodeListGetRawString(const xmlDoc *doc, const xmlNode *list, int inLine)
{
int escMode = inLine ? 0 : 3;
/* backward compatibility */
if (list == NULL)
return(NULL);
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) {
attr = elem->properties;
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) {
xmlVErrMemory(ctxt);
ret = 0;

View File

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