[PATCH v2 06/12] mshtml: Stringify attribute values in IE8+ mode when using setAttribute.
Gabriel Ivăncescu
gabrielopcode at gmail.com
Tue Nov 16 11:58:21 CST 2021
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
Simplifies the next patch.
dlls/mshtml/htmlelem.c | 40 ++++++++++++++++++++++++++++--------
dlls/mshtml/mshtml_private.h | 1 +
dlls/mshtml/nsembed.c | 19 +++++++++++++++++
3 files changed, 51 insertions(+), 9 deletions(-)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index f5500a3..07dea49 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -1086,34 +1086,56 @@ static HRESULT WINAPI HTMLElement_setAttribute(IHTMLElement *iface, BSTR strAttr
VARIANT AttributeValue, LONG lFlags)
{
HTMLElement *This = impl_from_IHTMLElement(iface);
+ compat_mode_t compat_mode = dispex_compat_mode(&This->node.event_target.dispex);
+ BOOL stringify = compat_mode >= COMPAT_MODE_IE8;
+ nsAString name_str, value_str;
+ BOOL needs_free = FALSE;
+ nsresult nsres;
DISPID dispid;
HRESULT hres;
TRACE("(%p)->(%s %s %08x)\n", This, debugstr_w(strAttributeName), debugstr_variant(&AttributeValue), lFlags);
- if(This->dom_element && dispex_compat_mode(&This->node.event_target.dispex) >= COMPAT_MODE_IE8) {
- nsAString name_str, value_str;
- nsresult nsres;
-
- hres = variant_to_nsstr(&AttributeValue, 0, &value_str);
+ if(stringify) {
+ hres = variant_to_nsstr(&AttributeValue, VARIANT_TO_NSSTR_BSTR_DEPEND, &value_str);
if(FAILED(hres))
return hres;
+ if((V_VT(&AttributeValue) & ~VT_BYREF) != VT_BSTR)
+ needs_free = TRUE;
+
+ V_VT(&AttributeValue) = VT_BSTR;
+ nsAString_GetData(&value_str, (const WCHAR**)&V_BSTR(&AttributeValue));
+
+ if(!V_BSTR(&AttributeValue)) {
+ V_VT(&AttributeValue) = VT_NULL;
+ needs_free = FALSE;
+ }
+ }
+
+ if(stringify && This->dom_element) {
nsAString_InitDepend(&name_str, strAttributeName);
nsres = nsIDOMElement_SetAttribute(This->dom_element, &name_str, &value_str);
nsAString_Finish(&name_str);
- nsAString_Finish(&value_str);
if(NS_FAILED(nsres))
WARN("SetAttribute failed: %08x\n", nsres);
- return map_nsresult(nsres);
+ hres = map_nsresult(nsres);
+ goto done;
}
hres = IDispatchEx_GetDispID(&This->node.event_target.dispex.IDispatchEx_iface, strAttributeName,
(lFlags&ATTRFLAG_CASESENSITIVE ? fdexNameCaseSensitive : fdexNameCaseInsensitive) | fdexNameEnsure, &dispid);
if(FAILED(hres))
- return hres;
+ goto done;
+
+ hres = set_elem_attr_value_by_dispid(This, dispid, &AttributeValue);
- return set_elem_attr_value_by_dispid(This, dispid, &AttributeValue);
+done:
+ if(stringify)
+ nsAString_Finish(&value_str);
+ if(needs_free)
+ SysFreeString(V_BSTR(&AttributeValue));
+ return hres;
}
HRESULT get_elem_attr_value_by_dispid(HTMLElement *elem, DISPID dispid, VARIANT *ret)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 66cd10a..3f04c62 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -1016,6 +1016,7 @@ HRESULT variant_to_nsstr(VARIANT*,DWORD,nsAString*) DECLSPEC_HIDDEN;
HRESULT return_nsform(nsresult,nsIDOMHTMLFormElement*,IHTMLFormElement**) DECLSPEC_HIDDEN;
#define VARIANT_TO_NSSTR_HEX_INT 0x01
+#define VARIANT_TO_NSSTR_BSTR_DEPEND 0x02
nsICommandParams *create_nscommand_params(void) DECLSPEC_HIDDEN;
HRESULT nsnode_to_nsstring(nsIDOMNode*,nsAString*) DECLSPEC_HIDDEN;
diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c
index 6381f7c..1e8fdbc 100644
--- a/dlls/mshtml/nsembed.c
+++ b/dlls/mshtml/nsembed.c
@@ -1012,6 +1012,13 @@ HRESULT variant_to_nsstr(VARIANT *v, DWORD flags, nsAString *nsstr)
case VT_I4:
wsprintfW(buf, (flags & VARIANT_TO_NSSTR_HEX_INT) ? L"#%06x" : L"%d", V_I4(v));
+ if(flags & VARIANT_TO_NSSTR_BSTR_DEPEND) {
+ BSTR bstr = SysAllocString(buf);
+ if(!bstr)
+ return E_OUTOFMEMORY;
+ nsAString_InitDepend(nsstr, bstr);
+ break;
+ }
nsAString_Init(nsstr, buf);
break;
@@ -1022,6 +1029,10 @@ HRESULT variant_to_nsstr(VARIANT *v, DWORD flags, nsAString *nsstr)
if(FAILED(hres))
return hres;
+ if(flags & VARIANT_TO_NSSTR_BSTR_DEPEND) {
+ nsAString_InitDepend(nsstr, V_BSTR(&strv));
+ break;
+ }
nsAString_Init(nsstr, V_BSTR(&strv));
SysFreeString(V_BSTR(&strv));
break;
@@ -1046,6 +1057,10 @@ HRESULT variant_to_nsstr(VARIANT *v, DWORD flags, nsAString *nsstr)
hres = IDispatch_Invoke(disp, dispid, &IID_NULL, lcid, DISPATCH_METHOD, ¶ms, &strv, NULL, NULL);
if(SUCCEEDED(hres)) {
if(V_VT(&strv) == VT_BSTR) {
+ if(flags & VARIANT_TO_NSSTR_BSTR_DEPEND) {
+ nsAString_InitDepend(nsstr, V_BSTR(&strv));
+ break;
+ }
nsAString_Init(nsstr, V_BSTR(&strv));
SysFreeString(V_BSTR(&strv));
break;
@@ -1058,6 +1073,10 @@ HRESULT variant_to_nsstr(VARIANT *v, DWORD flags, nsAString *nsstr)
hres = IDispatch_Invoke(disp, DISPID_VALUE, &IID_NULL, lcid, DISPATCH_PROPERTYGET, NULL, &strv, NULL, NULL);
if(SUCCEEDED(hres)) {
if(V_VT(&strv) == VT_BSTR) {
+ if(flags & VARIANT_TO_NSSTR_BSTR_DEPEND) {
+ nsAString_InitDepend(nsstr, V_BSTR(&strv));
+ break;
+ }
nsAString_Init(nsstr, V_BSTR(&strv));
SysFreeString(V_BSTR(&strv));
break;
--
2.31.1
More information about the wine-devel
mailing list