[MSXML3] Sync with Wine Staging 1.9.4. CORE-10912

svn path=/trunk/; revision=70885
This commit is contained in:
Amine Khaldi 2016-03-03 14:00:49 +00:00
parent 565ee09080
commit ce187684eb
5 changed files with 169 additions and 65 deletions

View file

@ -428,7 +428,14 @@ static void sax_characters(void *ctx, const xmlChar *ch, int len)
(!ctxt->node->last ||
((ctxt->node->last && (cur == '<' || ctxt->node->last->type != XML_TEXT_NODE))
)))
{
/* Keep information about ignorable whitespace text node in previous or parent node */
if (ctxt->node->last)
*(DWORD*)&ctxt->node->last->_private |= NODE_PRIV_TRAILING_IGNORABLE_WS;
else if (ctxt->node->type != XML_DOCUMENT_NODE)
*(DWORD*)&ctxt->node->_private |= NODE_PRIV_CHILD_IGNORABLE_WS;
return;
}
}
xmlSAX2Characters(ctxt, ch, len);
@ -1217,8 +1224,31 @@ static HRESULT WINAPI domdoc_cloneNode(
IXMLDOMNode** outNode)
{
domdoc *This = impl_from_IXMLDOMDocument3( iface );
xmlNodePtr clone;
TRACE("(%p)->(%d %p)\n", This, deep, outNode);
return node_clone( &This->node, deep, outNode );
if (!outNode)
return E_INVALIDARG;
*outNode = NULL;
clone = xmlCopyNode((xmlNodePtr)get_doc(This), deep ? 1 : 2);
if (!clone)
return E_FAIL;
clone->doc->_private = create_priv();
xmldoc_add_orphan(clone->doc, clone);
xmldoc_add_ref(clone->doc);
priv_from_xmlDocPtr(clone->doc)->properties = copy_properties(This->properties);
if (!(*outNode = (IXMLDOMNode*)create_domdoc(clone)))
{
xmldoc_release(clone->doc);
return E_FAIL;
}
return S_OK;
}
@ -3613,16 +3643,16 @@ HRESULT DOMDocument_create(MSXML_VERSION version, void **ppObj)
IUnknown* create_domdoc( xmlNodePtr document )
{
void* pObj = NULL;
IUnknown *obj = NULL;
HRESULT hr;
TRACE("(%p)\n", document);
hr = get_domdoc_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&pObj);
hr = get_domdoc_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&obj);
if (FAILED(hr))
return NULL;
return pObj;
return obj;
}
#else

View file

@ -152,6 +152,19 @@ static void free_response_headers(httprequest *This)
This->raw_respheaders = NULL;
}
static void free_request_headers(httprequest *This)
{
struct httpheader *header, *header2;
LIST_FOR_EACH_ENTRY_SAFE(header, header2, &This->reqheaders, struct httpheader, entry)
{
list_remove(&header->entry);
SysFreeString(header->header);
SysFreeString(header->value);
heap_free(header);
}
}
struct BindStatusCallback
{
IBindStatusCallback IBindStatusCallback_iface;
@ -864,6 +877,7 @@ static HRESULT httprequest_open(httprequest *This, BSTR method, BSTR url,
SysFreeString(This->user);
SysFreeString(This->password);
This->user = This->password = NULL;
free_request_headers(This);
if (!strcmpiW(method, MethodGetW))
{
@ -1249,8 +1263,6 @@ static HRESULT httprequest_put_onreadystatechange(httprequest *This, IDispatch *
static void httprequest_release(httprequest *This)
{
struct httpheader *header, *header2;
if (This->site)
IUnknown_Release( This->site );
if (This->uri)
@ -1262,15 +1274,8 @@ static void httprequest_release(httprequest *This)
SysFreeString(This->user);
SysFreeString(This->password);
/* request headers */
LIST_FOR_EACH_ENTRY_SAFE(header, header2, &This->reqheaders, struct httpheader, entry)
{
list_remove(&header->entry);
SysFreeString(header->header);
SysFreeString(header->value);
heap_free(header);
}
/* response headers */
/* cleanup headers lists */
free_request_headers(This);
free_response_headers(This);
SysFreeString(This->status_text);

View file

@ -559,4 +559,7 @@ HRESULT detach_bsc(bsc_t*) DECLSPEC_HIDDEN;
/* ... */
#define E_XML_REQUIRED_ATTRIBUTE_MISSING 0xC00CE020
#define NODE_PRIV_TRAILING_IGNORABLE_WS 0x40000000
#define NODE_PRIV_CHILD_IGNORABLE_WS 0x80000000
#define NODE_PRIV_REFCOUNT_MASK ~(NODE_PRIV_TRAILING_IGNORABLE_WS|NODE_PRIV_CHILD_IGNORABLE_WS)
#endif /* __MSXML_PRIVATE__ */

View file

@ -379,7 +379,7 @@ HRESULT node_get_next_sibling(xmlnode *This, IXMLDOMNode **ret)
static int node_get_inst_cnt(xmlNodePtr node)
{
int ret = *(LONG *)&node->_private;
int ret = *(LONG *)&node->_private & NODE_PRIV_REFCOUNT_MASK;
xmlNodePtr child;
/* add attribute counts */
@ -410,6 +410,20 @@ int xmlnode_get_inst_cnt(xmlnode *node)
return node_get_inst_cnt(node->node);
}
/* _private field holds a number of COM instances spawned from this libxml2 node
* most significant bits are used to store information about ignorrable whitespace nodes */
static void xmlnode_add_ref(xmlNodePtr node)
{
if (node->type == XML_DOCUMENT_NODE) return;
InterlockedIncrement((LONG*)&node->_private);
}
static void xmlnode_release(xmlNodePtr node)
{
if (node->type == XML_DOCUMENT_NODE) return;
InterlockedDecrement((LONG*)&node->_private);
}
HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT *ref_child,
IXMLDOMNode **ret)
{
@ -470,6 +484,7 @@ HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT
if(before)
{
xmlNodePtr new_node;
xmlnode *before_node_obj = get_node_obj(before);
/* refs count including subtree */
@ -477,19 +492,35 @@ HRESULT node_insert_before(xmlnode *This, IXMLDOMNode *new_child, const VARIANT
refcount = xmlnode_get_inst_cnt(node_obj);
if (refcount) xmldoc_add_refs(before_node_obj->node->doc, refcount);
node_obj->node = xmlAddPrevSibling(before_node_obj->node, node_obj->node);
new_node = xmlAddPrevSibling(before_node_obj->node, node_obj->node);
if (new_node != node_obj->node)
{
if (refcount != 1)
FIXME("referenced xmlNode was freed, expect crashes\n");
xmlnode_add_ref(new_node);
node_obj->node = new_node;
}
if (refcount) xmldoc_release_refs(doc, refcount);
node_obj->parent = This->parent;
}
else
{
xmlNodePtr new_node;
if (doc != This->node->doc)
refcount = xmlnode_get_inst_cnt(node_obj);
if (refcount) xmldoc_add_refs(This->node->doc, refcount);
/* xmlAddChild doesn't unlink node from previous parent */
xmlUnlinkNode(node_obj->node);
node_obj->node = xmlAddChild(This->node, node_obj->node);
new_node = xmlAddChild(This->node, node_obj->node);
if (new_node != node_obj->node)
{
if (refcount != 1)
FIXME("referenced xmlNode was freed, expect crashes\n");
xmlnode_add_ref(new_node);
node_obj->node = new_node;
}
if (refcount) xmldoc_release_refs(doc, refcount);
node_obj->parent = This->iface;
}
@ -673,48 +704,63 @@ HRESULT node_clone(xmlnode *This, VARIANT_BOOL deep, IXMLDOMNode **cloneNode)
return S_OK;
}
static inline xmlChar* trim_whitespace(xmlChar* str)
{
xmlChar* ret = str;
int len;
if (!str)
return NULL;
while (*ret && isspace(*ret))
++ret;
len = xmlStrlen(ret);
if (len)
while (isspace(ret[len-1])) --len;
ret = xmlStrndup(ret, len);
xmlFree(str);
return ret;
}
static xmlChar* do_get_text(xmlNodePtr node)
static xmlChar* do_get_text(xmlNodePtr node, BOOL trim, DWORD *first, DWORD *last, BOOL *trail_ig_ws)
{
xmlNodePtr child;
xmlChar* str;
BOOL preserving = is_preserving_whitespace(node);
*first = -1;
*last = 0;
if (!node->children)
{
str = xmlNodeGetContent(node);
*trail_ig_ws = *(DWORD*)&node->_private & NODE_PRIV_CHILD_IGNORABLE_WS;
}
else
{
xmlElementType prev_type = XML_TEXT_NODE;
BOOL ig_ws = FALSE;
xmlChar* tmp;
DWORD pos = 0;
str = xmlStrdup(BAD_CAST "");
if (node->type != XML_DOCUMENT_NODE)
ig_ws = *(DWORD*)&node->_private & NODE_PRIV_CHILD_IGNORABLE_WS;
*trail_ig_ws = FALSE;
for (child = node->children; child != NULL; child = child->next)
{
switch (child->type)
{
case XML_ELEMENT_NODE:
tmp = do_get_text(child);
case XML_ELEMENT_NODE: {
DWORD node_first, node_last;
tmp = do_get_text(child, FALSE, &node_first, &node_last, trail_ig_ws);
if (node_first!=-1 && pos+node_first<*first)
*first = pos+node_first;
if (node_last && pos+node_last>*last)
*last = pos+node_last;
break;
}
case XML_TEXT_NODE:
tmp = xmlNodeGetContent(child);
if (!preserving && tmp[0])
{
xmlChar *beg;
for (beg = tmp; *beg; beg++)
if (!isspace(*beg)) break;
if (!*beg)
{
ig_ws = TRUE;
xmlFree(tmp);
tmp = NULL;
}
}
break;
case XML_CDATA_SECTION_NODE:
case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE:
@ -725,18 +771,33 @@ static xmlChar* do_get_text(xmlNodePtr node)
break;
}
if (tmp)
if ((tmp && *tmp) || child->type==XML_CDATA_SECTION_NODE)
{
if (*tmp)
if (ig_ws && str[0])
{
if (prev_type == XML_ELEMENT_NODE && child->type == XML_ELEMENT_NODE)
str = xmlStrcat(str, BAD_CAST " ");
str = xmlStrcat(str, tmp);
prev_type = child->type;
str = xmlStrcat(str, BAD_CAST " ");
pos++;
}
xmlFree(tmp);
if (tmp && *tmp) str = xmlStrcat(str, tmp);
if (child->type==XML_CDATA_SECTION_NODE && pos<*first)
*first = pos;
if (tmp && *tmp) pos += xmlStrlen(tmp);
if (child->type==XML_CDATA_SECTION_NODE && pos>*last)
*last = pos;
ig_ws = FALSE;
}
if (tmp) xmlFree(tmp);
if (!ig_ws)
{
ig_ws = *(DWORD*)&child->_private & NODE_PRIV_TRAILING_IGNORABLE_WS;
}
if (!ig_ws)
ig_ws = *trail_ig_ws;
*trail_ig_ws = FALSE;
}
*trail_ig_ws = ig_ws;
}
switch (node->type)
@ -747,8 +808,24 @@ static xmlChar* do_get_text(xmlNodePtr node)
case XML_ENTITY_NODE:
case XML_DOCUMENT_NODE:
case XML_DOCUMENT_FRAG_NODE:
if (!preserving)
str = trim_whitespace(str);
if (trim && !preserving)
{
xmlChar* ret = str;
int len;
if (!str)
break;
for (ret = str; *ret && isspace(*ret) && (*first)--; ret++)
if (*last) (*last)--;
for (len = xmlStrlen(ret)-1; len >= 0 && len >= *last; len--)
if(!isspace(ret[len])) break;
ret = xmlStrndup(ret, len+1);
xmlFree(str);
str = ret;
break;
}
break;
default:
break;
@ -761,10 +838,12 @@ HRESULT node_get_text(const xmlnode *This, BSTR *text)
{
BSTR str = NULL;
xmlChar *content;
DWORD first, last;
BOOL tmp;
if (!text) return E_INVALIDARG;
content = do_get_text(This->node);
content = do_get_text(This->node, TRUE, &first, &last, &tmp);
if (content)
{
str = bstr_from_xmlChar(content);
@ -1373,19 +1452,6 @@ HRESULT node_get_base_name(xmlnode *This, BSTR *name)
return S_OK;
}
/* _private field holds a number of COM instances spawned from this libxml2 node */
static void xmlnode_add_ref(xmlNodePtr node)
{
if (node->type == XML_DOCUMENT_NODE) return;
InterlockedIncrement((LONG*)&node->_private);
}
static void xmlnode_release(xmlNodePtr node)
{
if (node->type == XML_DOCUMENT_NODE) return;
InterlockedDecrement((LONG*)&node->_private);
}
void destroy_xmlnode(xmlnode *This)
{
if(This->node)

View file

@ -131,7 +131,7 @@ reactos/dll/win32/msvfw32 # Synced to WineStaging-1.7.55
reactos/dll/win32/msvidc32 # Synced to WineStaging-1.7.55
reactos/dll/win32/msxml # Synced to WineStaging-1.7.55
reactos/dll/win32/msxml2 # Synced to WineStaging-1.7.55
reactos/dll/win32/msxml3 # Synced to WineStaging-1.7.55
reactos/dll/win32/msxml3 # Synced to WineStaging-1.9.4
reactos/dll/win32/msxml4 # Synced to WineStaging-1.7.55
reactos/dll/win32/msxml6 # Synced to WineStaging-1.7.55
reactos/dll/win32/nddeapi # Synced to WineStaging-1.7.55