From: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> --- dlls/msxml3/msxml_private.h | 9 ++++++++- dlls/msxml3/node.c | 12 +++++++++++- dlls/msxml3/saxreader.c | 15 +++++++++++---- dlls/msxml3/saxreader_extensions.idl | 4 +++- 4 files changed, 33 insertions(+), 7 deletions(-) diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index 8aff42fe51a..794053c5390 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -235,7 +235,11 @@ struct domnode BSTR data; BSTR uri; - struct domdoc_properties *properties; + union + { + struct domdoc_properties *properties; + struct dtd *dtd; + }; struct domnode *parent; struct domnode *owner; @@ -342,6 +346,9 @@ extern struct domnode *get_node_obj(void *iface); extern bool parser_is_valid_qualified_name(const WCHAR *name); extern HRESULT parse_xml_decl_body(const WCHAR *text, BSTR *version, BSTR *encoding, BSTR *standalone); +extern struct dtd * parser_dtd_addref(struct dtd *dtd); +extern void parser_dtd_release(struct dtd *dtd); + extern HRESULT node_append_child(struct domnode*,IXMLDOMNode*,IXMLDOMNode**); extern HRESULT node_attribute_get_namespace_uri(struct domnode *, BSTR *); extern HRESULT node_get_name(struct domnode*,BSTR*); diff --git a/dlls/msxml3/node.c b/dlls/msxml3/node.c index bd48c6d822d..ca95e7e229f 100644 --- a/dlls/msxml3/node.c +++ b/dlls/msxml3/node.c @@ -1355,6 +1355,12 @@ void domnode_destroy_tree(struct domnode *tree) list_remove(&node->entry); domnode_destroy_tree(node); } + + if (tree->type == NODE_DOCUMENT_TYPE) + { + parser_dtd_release(tree->dtd); + tree->dtd = NULL; + } } if (tree->prefix) @@ -1401,6 +1407,8 @@ HRESULT node_clone_domnode(struct domnode *node, bool deep, struct domnode **clo if (node->type == NODE_DOCUMENT) object->properties = domdoc_properties_clone(node->properties); + else if (node->type == NODE_DOCUMENT_TYPE) + object->dtd = parser_dtd_addref(node->dtd); if (deep) { @@ -3938,7 +3946,8 @@ static HRESULT WINAPI parse_extension_handler_xmldecl(ISAXExtensionHandler *ifac return c->status; } -static HRESULT WINAPI parse_extension_handler_dtd(ISAXExtensionHandler *iface, BSTR data) +static HRESULT WINAPI parse_extension_handler_dtd(ISAXExtensionHandler *iface, + BSTR data, struct dtd *dtd) { struct parse_context *c = impl_from_ISAXExtensionHandler(iface); @@ -3946,6 +3955,7 @@ static HRESULT WINAPI parse_extension_handler_dtd(ISAXExtensionHandler *iface, B { if (!(c->node->data = SysAllocStringLen(data, SysStringLen(data)))) c->status = E_OUTOFMEMORY; + c->node->dtd = parser_dtd_addref(dtd); } return c->status; diff --git a/dlls/msxml3/saxreader.c b/dlls/msxml3/saxreader.c index 2708882e350..c69fe294b94 100644 --- a/dlls/msxml3/saxreader.c +++ b/dlls/msxml3/saxreader.c @@ -1102,13 +1102,20 @@ static void saxreader_free_element_decl(struct element_decl *decl) free(decl); } -static void parser_release_dtd(struct dtd *dtd) +struct dtd *parser_dtd_addref(struct dtd *dtd) +{ + if (dtd) + ++dtd->refcount; + return dtd; +} + +void parser_dtd_release(struct dtd *dtd) { struct element_decl *element, *element_next; struct entity_decl *entity, *entity_next; struct attlist_decl *attr, *attr_next; - if (--dtd->refcount) + if (!dtd || --dtd->refcount) return; LIST_FOR_EACH_ENTRY_SAFE(entity, entity_next, &dtd->entities, struct entity_decl, entry) @@ -1988,7 +1995,7 @@ static ULONG WINAPI isaxlocator_Release(ISAXLocator *iface) saxreader_clear_strings(locator); if (locator->dtd) - parser_release_dtd(locator->dtd); + parser_dtd_release(locator->dtd); locator->dtd = NULL; /* element stack */ @@ -3178,7 +3185,7 @@ static void saxlocator_extension_dtd(struct saxlocator *locator) if (saxreader_has_handler(locator, SAXExtensionHandler)) { if (!locator->vbInterface) - hr = ISAXExtensionHandler_dtd(handler->handler, str); + hr = ISAXExtensionHandler_dtd(handler->handler, str, locator->dtd); } SysFreeString(str); diff --git a/dlls/msxml3/saxreader_extensions.idl b/dlls/msxml3/saxreader_extensions.idl index 19fc2476c6b..a341e44df71 100644 --- a/dlls/msxml3/saxreader_extensions.idl +++ b/dlls/msxml3/saxreader_extensions.idl @@ -22,6 +22,8 @@ import "unknwn.idl"; import "objidl.idl"; import "oaidl.idl"; +struct dtd; + [ object, local, @@ -30,7 +32,7 @@ import "oaidl.idl"; interface ISAXExtensionHandler : IUnknown { HRESULT xmldecl([in] BSTR version, [in] BSTR encoding,[in] BSTR standalone); - HRESULT dtd([in] BSTR data); + HRESULT dtd([in] BSTR data, [in] struct dtd *dtd); } [ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10786