diff --git a/fuzz/api.c b/fuzz/api.c index e875df36..10b4b0cd 100644 --- a/fuzz/api.c +++ b/fuzz/api.c @@ -441,13 +441,13 @@ moveStr(int offset, xmlChar *str) { * injection. */ static xmlChar * -uncheckedStrdup(const xmlChar *str) { +uncheckedStrndup(const xmlChar *str, int size) { xmlChar *copy; if (str == NULL) return NULL; - copy = BAD_CAST strndup((const char *) str, MAX_CONTENT); + copy = BAD_CAST strndup((const char *) str, size); if (copy == NULL) { fprintf(stderr, "out of memory\n"); abort(); @@ -456,6 +456,11 @@ uncheckedStrdup(const xmlChar *str) { return copy; } +static xmlChar * +uncheckedStrdup(const xmlChar *str) { + return uncheckedStrndup(str, MAX_CONTENT); +} + static void copyStr(int offset, const xmlChar *str) { setStr(offset, uncheckedStrdup(str)); @@ -1958,18 +1963,36 @@ LLVMFuzzerTestOneInput(const char *data, size_t size) { case OP_XML_SET_PROP: { xmlNodePtr node; xmlAttrPtr oldAttr, attr; - const xmlChar *name, *value; + xmlNsPtr ns = NULL; + const xmlChar *name, *value, *localName; + xmlChar *prefix; + int prefixLen; startOp("xmlSetProp"); incNodeIdx(); node = getNode(1); name = getStr(0); value = getStr(1); - oldAttr = xmlHasProp(node, name); + + /* + * Find the old attribute node which will be deleted. + */ + localName = xmlSplitQName3(name, &prefixLen); + if (localName != NULL) { + prefix = uncheckedStrndup(name, prefixLen); + ns = xmlSearchNs(NULL, node, prefix); + xmlFree(prefix); + } + if (ns == NULL) + oldAttr = xmlHasNsProp(node, name, NULL); + else + oldAttr = xmlHasNsProp(node, localName, ns->href); xmlFuzzResetMallocFailed(); if (oldAttr != NULL) removeChildren((xmlNodePtr) oldAttr, 0); + attr = xmlSetProp(node, name, value); + oomReport = (node != NULL && node->type == XML_ELEMENT_NODE && name != NULL &&