Skip to content
This repository was archived by the owner on Jan 26, 2026. It is now read-only.

Commit 3a95572

Browse files
committed
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.
1 parent 239e25f commit 3a95572

4 files changed

Lines changed: 36 additions & 13 deletions

File tree

fuzz/api.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2522,30 +2522,38 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) {
25222522
}
25232523

25242524
case OP_XML_NODE_LIST_GET_STRING: {
2525+
xmlDocPtr doc;
2526+
xmlNodePtr list;
25252527
xmlChar *string;
25262528

25272529
startOp("xmlNodeListGetString");
25282530
incStrIdx();
2531+
doc = getDoc(0);
2532+
list = getNode(1);
25292533
string = xmlNodeListGetString(
2530-
getDoc(0),
2531-
getNode(1),
2534+
doc,
2535+
list,
25322536
getInt(0));
2533-
oomReport = (string == NULL);
2537+
oomReport = (list != NULL && string == NULL);
25342538
moveStr(0, string);
25352539
endOp();
25362540
break;
25372541
}
25382542

25392543
case OP_XML_NODE_LIST_GET_RAW_STRING: {
2544+
xmlDocPtr doc;
2545+
xmlNodePtr list;
25402546
xmlChar *string;
25412547

25422548
startOp("xmlNodeListGetRawString");
25432549
incStrIdx();
2550+
doc = getDoc(0);
2551+
list = getNode(1);
25442552
string = xmlNodeListGetRawString(
2545-
getDoc(0),
2546-
getNode(1),
2553+
doc,
2554+
list,
25472555
getInt(0));
2548-
oomReport = (string == NULL);
2556+
oomReport = (list != NULL && string == NULL);
25492557
moveStr(0, string);
25502558
endOp();
25512559
break;

tree.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,11 +1594,11 @@ xmlNodeListGetStringInternal(xmlDocPtr doc, const xmlNode *node, int escMode) {
15941594
/**
15951595
* xmlNodeListGetString:
15961596
* @doc: a document (optional)
1597-
* @list: a node list of attribute children (optional)
1597+
* @list: a node list of attribute children
15981598
* @inLine: whether entity references are substituted
15991599
*
16001600
* Serializes attribute children (text and entity reference nodes)
1601-
* into a string. An empty list produces an empty string.
1601+
* into a string.
16021602
*
16031603
* If @inLine is true, entity references will be substituted.
16041604
* Otherwise, entity references will be kept and special characters
@@ -1612,11 +1612,14 @@ xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
16121612
{
16131613
int escMode;
16141614

1615+
/* backward compatibility */
1616+
if (list == NULL)
1617+
return(NULL);
1618+
16151619
if (inLine) {
16161620
escMode = 0;
16171621
} else {
1618-
if ((list != NULL) &&
1619-
(list->parent != NULL) &&
1622+
if ((list->parent != NULL) &&
16201623
(list->parent->type == XML_ATTRIBUTE_NODE))
16211624
escMode = 2;
16221625
else
@@ -1630,11 +1633,11 @@ xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
16301633
/**
16311634
* xmlNodeListGetRawString:
16321635
* @doc: a document (optional)
1633-
* @list: a node list of attribute children (optional)
1636+
* @list: a node list of attribute children
16341637
* @inLine: whether entity references are substituted
16351638
*
16361639
* Serializes attribute children (text and entity reference nodes)
1637-
* into a string. An empty list produces an empty string.
1640+
* into a string.
16381641
*
16391642
* If @inLine is true, entity references will be substituted.
16401643
* Otherwise, entity references will be kept and special characters
@@ -1646,6 +1649,11 @@ xmlChar *
16461649
xmlNodeListGetRawString(const xmlDoc *doc, const xmlNode *list, int inLine)
16471650
{
16481651
int escMode = inLine ? 0 : 3;
1652+
1653+
/* backward compatibility */
1654+
if (list == NULL)
1655+
return(NULL);
1656+
16491657
return(xmlNodeListGetStringInternal((xmlDocPtr) doc, list, escMode));
16501658
}
16511659
#endif /* LIBXML_TREE_ENABLED */

valid.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6224,7 +6224,10 @@ xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr root) {
62246224
if (elem->type == XML_ELEMENT_NODE) {
62256225
attr = elem->properties;
62266226
while (attr != NULL) {
6227-
value = xmlNodeListGetString(doc, attr->children, 0);
6227+
if (attr->children == NULL)
6228+
value = xmlStrdup(BAD_CAST "");
6229+
else
6230+
value = xmlNodeListGetString(doc, attr->children, 0);
62286231
if (value == NULL) {
62296232
xmlVErrMemory(ctxt);
62306233
ret = 0;

xmlreader.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2340,6 +2340,8 @@ xmlTextReaderGetAttributeNo(xmlTextReaderPtr reader, int no) {
23402340
}
23412341
/* TODO walk the DTD if present */
23422342

2343+
if (cur->children == NULL)
2344+
return(NULL);
23432345
ret = xmlNodeListGetString(reader->node->doc, cur->children, 1);
23442346
if (ret == NULL)
23452347
xmlTextReaderErrMemory(reader);
@@ -3585,6 +3587,8 @@ xmlTextReaderValue(xmlTextReaderPtr reader) {
35853587
xmlDocPtr doc = NULL;
35863588
xmlChar *ret;
35873589

3590+
if (attr->children == NULL)
3591+
return(NULL);
35883592
if (attr->parent != NULL)
35893593
doc = attr->parent->doc;
35903594
ret = xmlNodeListGetString(doc, attr->children, 1);

0 commit comments

Comments
 (0)