https://bugs.winehq.org/show_bug.cgi?id=53531
--- Comment #2 from Damjan Jovanovic damjan.jov@gmail.com --- The problematic XML document, is just this single node:
<IDEConfig xmlns="http:///ide/MySchema.xsd%5C%22/%3E
libxml2 converts namespace definition attributes ("xmlns:XYZ") into "struct xmlNs" and makes them available as a linked list on their parent struct xmlNode, pointed to by struct xmlNode's "nsDef" field. These "struct xmlNs" instances are not xmlNode subtypes, but just a simple struct with little more than "prefix" and "href" fields, and the linked list pointers. All other (non-namespace-definition) attributes go into struct xmlNode's "properties" and are (closer to) full-blown xmlNode subtypes with their many fields.
MSXML on the other hand, treats namespace definition attributes as ordinary attributes, and provides the full IXMLDOMAttribute interface for them.
Before the commit causing the "regression", Wine just provided the non-namespace-definition attributes in IXMLDOMNode::get_attributes(). In the IXMLDOMNamedNodeMap returned by that method, IXMLDOMNamedNodeMap::get_length() returned 0 for the XML tag in question here.
The application was happy with this and proceeded further.
The commit then changed this behaviour, by starting to returning the union of struct xmlNode's "properties" and "nsDef" lists from IXMLDOMNode::get_attributes(). IXMLDOMNamedNodeMap::get_length() then became 1, and IXMLDOMNamedNodeMap::get_item(0) failed as originally described.
Now converting xmlns:XYZ="href" attributes to IXMLDOMAttributes works well, but the default namespace attribute xmlns="href" fails and returns the error. Why?
Once the namespace for the given index to IXMLDOMNamedNodeMap::get_item() is found (variable "ns"), the code in domelem_get_item() first creates a new namespace with prefix "xmlns" and href "http://www.w3.org/2000/xmlns/", then creates an attribute node using that new namespace, and the matched namespace's prefix and href (so as to produce xmlns:prefix=href). When the matched namespace is the default namespace, prefix is NULL, and xmlNewNsProp() does not allow a NULL name argument (prefix parameter).
---snip--- xmlns = xmlNewNs(NULL, BAD_CAST "http://www.w3.org/2000/xmlns/", BAD_CAST "xmlns"); if (!xmlns) return E_OUTOFMEMORY;
curr = xmlNewNsProp(NULL, xmlns, ns->prefix, ns->href); if (!curr) { xmlFreeNs(xmlns); return E_OUTOFMEMORY; } ---snip---
One way to fix, is when ns->prefix is NULL, create "curr" using xmlNewProp(NULL, "xmlns", ns->href) instead of xmlNewNsProp(). I am not sure whether that will behave correctly in other calls though.