From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 6 +++--- dlls/jscript/function.c | 6 +++--- dlls/jscript/jsdisp.idl | 4 ++-- dlls/mshtml/dispex.c | 34 +++++++++++++++++++++---------- dlls/mshtml/htmldoc.c | 2 +- dlls/mshtml/htmlstorage.c | 2 +- dlls/mshtml/htmlwindow.c | 8 ++++---- dlls/mshtml/pluginhost.c | 2 +- dlls/mshtml/tests/documentmode.js | 14 +++++++++++++ 9 files changed, 52 insertions(+), 26 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index d5ed3adf4fb..98cd608cab0 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -275,7 +275,7 @@ static HRESULT update_external_prop(jsdisp_t *obj, const WCHAR *name, dispex_pro if(desc->name) name = desc->name;
- if(!desc->iid) { + if(!desc->prototype_id) { if(!prop && !(prop = alloc_prop(obj, name, PROP_DELETED, 0))) return E_OUTOFMEMORY; prop->type = PROP_EXTERN; @@ -497,7 +497,7 @@ HRESULT jsdisp_index_lookup(jsdisp_t *obj, const WCHAR *name, unsigned length, s desc->flags |= PROPF_WRITABLE; desc->name = NULL; desc->index = idx; - desc->iid = 0; + desc->prototype_id = 0; return S_OK; }
@@ -512,7 +512,7 @@ HRESULT jsdisp_next_index(jsdisp_t *obj, unsigned length, unsigned id, struct pr desc->flags |= PROPF_WRITABLE; desc->name = NULL; desc->index = desc->id; - desc->iid = 0; + desc->prototype_id = 0; return S_OK; }
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 9f1f53a96ae..a7132e9ab6a 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -67,7 +67,7 @@ typedef struct { FunctionInstance function; const WCHAR *name; UINT32 id; - UINT32 iid; + INT32 prototype_id; UINT32 flags; } HostFunction;
@@ -1023,7 +1023,7 @@ static HRESULT HostFunction_call(script_ctx_t *ctx, FunctionInstance *func, jsva
if(SUCCEEDED(hres)) { V_VT(&retv) = VT_EMPTY; - hres = IWineJSDispatchHost_CallFunction(obj, function->id, function->iid, function->flags, &dp, + hres = IWineJSDispatchHost_CallFunction(obj, function->id, function->prototype_id, function->flags, &dp, r ? &retv : NULL, &ei, &ctx->jscaller->IServiceProvider_iface); if(hres == DISP_E_EXCEPTION) handle_dispatch_exception(ctx, &ei); @@ -1084,7 +1084,7 @@ HRESULT create_host_function(script_ctx_t *ctx, const struct property_info *desc
function->name = desc->name; function->id = desc->id; - function->iid = desc->iid; + function->prototype_id = desc->prototype_id; function->flags = flags; *ret = &function->function.dispex; return S_OK; diff --git a/dlls/jscript/jsdisp.idl b/dlls/jscript/jsdisp.idl index 5f1384bce78..ce1d71bab6a 100644 --- a/dlls/jscript/jsdisp.idl +++ b/dlls/jscript/jsdisp.idl @@ -27,7 +27,7 @@ struct property_info UINT32 flags; const WCHAR *name; UINT32 index; - UINT32 iid; + INT32 prototype_id; };
const unsigned int PROPF_METHOD = 0x0100; @@ -69,7 +69,7 @@ interface IWineJSDispatchHost : IDispatchEx HRESULT SetProperty(DISPID id, LCID lcid, VARIANT *v, EXCEPINFO *ei, IServiceProvider *caller); HRESULT DeleteProperty(DISPID id); HRESULT ConfigureProperty(DISPID id, UINT32 flags); - HRESULT CallFunction(DISPID id, UINT32 iid, DWORD flags, DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller); + HRESULT CallFunction(DISPID id, INT32 prototype_id, DWORD flags, DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller); HRESULT Construct(LCID lcid, DWORD flags, DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller); HRESULT GetOuterDispatch(IWineJSDispatchHost **ret); HRESULT ToString(BSTR *str); diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 7e85d41b4fd..c411cef0c9c 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1075,7 +1075,7 @@ static HRESULT function_apply(func_disp_t *func, DISPPARAMS *dp, LCID lcid, VARI } }
- hres = IWineJSDispatchHost_CallFunction(this_iface, func->info->id, func->info->tid, DISPATCH_METHOD, ¶ms, res, ei, caller); + hres = IWineJSDispatchHost_CallFunction(this_iface, func->info->id, -func->info->tid, DISPATCH_METHOD, ¶ms, res, ei, caller);
fail: while(argc--) @@ -1102,7 +1102,7 @@ static HRESULT function_call(func_disp_t *func, DISPPARAMS *dp, LCID lcid, VARIA if(FAILED(hres)) return CTL_E_ILLEGALFUNCTIONCALL;
- hres = IWineJSDispatchHost_CallFunction(this_iface, func->info->id, func->info->tid, DISPATCH_METHOD, ¶ms, res, ei, caller); + hres = IWineJSDispatchHost_CallFunction(this_iface, func->info->id, -func->info->tid, DISPATCH_METHOD, ¶ms, res, ei, caller); IWineJSDispatchHost_Release(this_iface); return (hres == E_UNEXPECTED) ? CTL_E_ILLEGALFUNCTIONCALL : hres; } @@ -1179,7 +1179,7 @@ static HRESULT function_get_prop_desc(DispatchEx *dispex, DISPID id, struct prop desc->id = id; desc->flags = 0; desc->name = function_props[idx].name; - desc->iid = 0; + desc->prototype_id = 0; return S_OK; }
@@ -2578,7 +2578,7 @@ HRESULT dispex_index_prop_desc(DispatchEx *dispex, DISPID id, struct property_in desc->flags |= PROPF_ENUMERABLE; desc->name = NULL; desc->index = id - MSHTML_DISPID_CUSTOM_MIN; - desc->iid = 0; + desc->prototype_id = 0; return S_OK; }
@@ -2598,18 +2598,18 @@ static HRESULT get_host_property_descriptor(DispatchEx *This, DISPID id, struct desc->flags = PROPF_CONFIGURABLE; desc->name = func->name; if(func->func_disp_idx >= 0) { - desc->iid = func->tid; + desc->prototype_id = This->info->desc->id ? This->info->desc->id : -func->tid; desc->flags |= PROPF_METHOD | PROPF_WRITABLE; }else { if(func->func_disp_idx == -1) desc->flags |= PROPF_ENUMERABLE; if(This->info->is_prototype) { - desc->iid = func->tid; + desc->prototype_id = This->info->desc->id ? This->info->desc->id : -func->tid; if(func->put_vtbl_off) desc->flags |= PROPF_WRITABLE; }else { desc->flags |= PROPF_WRITABLE; - desc->iid = 0; + desc->prototype_id = 0; } } break; @@ -2618,7 +2618,7 @@ static HRESULT get_host_property_descriptor(DispatchEx *This, DISPID id, struct dynamic_prop_t *prop = &This->dynamic_data->props[id - DISPID_DYNPROP_0]; desc->flags = prop->flags & PROPF_PUBLIC_MASK; desc->name = prop->name; - desc->iid = 0; + desc->prototype_id = 0; break; } case DISPEXPROP_CUSTOM: @@ -2705,19 +2705,31 @@ static HRESULT WINAPI JSDispatchHost_ConfigureProperty(IWineJSDispatchHost *ifac return S_OK; }
-static HRESULT WINAPI JSDispatchHost_CallFunction(IWineJSDispatchHost *iface, DISPID id, UINT32 iid, DWORD flags, +static HRESULT WINAPI JSDispatchHost_CallFunction(IWineJSDispatchHost *iface, DISPID id, INT32 prototype_id, DWORD flags, DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller) { DispatchEx *This = impl_from_IWineJSDispatchHost(iface); + dispex_static_data_t *desc = This->info->desc; func_info_t *func; HRESULT hres;
- TRACE("%s (%p)->(%lx %x %lx %p %p %p %p)\n", This->info->name, This, id, iid, flags, dp, ret, ei, caller); + TRACE("%s (%p)->(%lx %d %lx %p %p %p %p)\n", This->info->name, This, id, prototype_id, flags, dp, ret, ei, caller);
hres = get_builtin_func(This->info, id, &func); - if(FAILED(hres) || func->tid != iid) + if(FAILED(hres)) return E_UNEXPECTED;
+ if(prototype_id <= 0) { + if(func->tid != -prototype_id) + return E_UNEXPECTED; + }else if(prototype_id != desc->id) { + while(prototype_id != desc->prototype_id) { + if(!desc->prototype_id) + return E_UNEXPECTED; + desc = object_descriptors[desc->prototype_id]; + } + } + switch(flags) { case DISPATCH_METHOD: assert(func->func_disp_idx >= 0); diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index ffd594291f3..056d6cbacf6 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -5528,7 +5528,7 @@ static HRESULT HTMLDocumentNode_get_prop_desc(DispatchEx *dispex, DISPID id, str desc->name = This->elem_vars[idx]; desc->id = id; desc->flags = PROPF_WRITABLE | PROPF_CONFIGURABLE | PROPF_ENUMERABLE; - desc->iid = 0; + desc->prototype_id = 0; return S_OK; }
diff --git a/dlls/mshtml/htmlstorage.c b/dlls/mshtml/htmlstorage.c index 98c1202e315..263e2479a82 100644 --- a/dlls/mshtml/htmlstorage.c +++ b/dlls/mshtml/htmlstorage.c @@ -1273,7 +1273,7 @@ static HRESULT HTMLStorage_get_prop_desc(DispatchEx *dispex, DISPID id, struct p desc->name = This->props[id - MSHTML_DISPID_CUSTOM_MIN]; desc->id = id; desc->flags = PROPF_WRITABLE | PROPF_CONFIGURABLE | PROPF_ENUMERABLE; - desc->iid = 0; + desc->prototype_id = 0; return S_OK; }
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index ffcaf86a361..fbfa821955e 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3491,13 +3491,13 @@ static HRESULT WINAPI WindowDispEx_ConfigureProperty(IWineJSDispatchHost *iface, return IWineJSDispatchHost_ConfigureProperty(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, id, flags); }
-static HRESULT WINAPI WindowDispEx_CallFunction(IWineJSDispatchHost *iface, DISPID id, UINT32 iid, DWORD flags, DISPPARAMS *dp, - VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller) +static HRESULT WINAPI WindowDispEx_CallFunction(IWineJSDispatchHost *iface, DISPID id, INT32 prototype_id, DWORD flags, + DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller) { HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
return IWineJSDispatchHost_CallFunction(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, - id, iid, flags, dp, ret, ei, caller); + id, prototype_id, flags, dp, ret, ei, caller); }
static HRESULT WINAPI WindowDispEx_Construct(IWineJSDispatchHost *iface, LCID lcid, DWORD flags, DISPPARAMS *dp, VARIANT *ret, @@ -4042,7 +4042,7 @@ HRESULT HTMLWindow_get_prop_desc(DispatchEx *dispex, DISPID id, struct property_ desc->name = prop->name; desc->id = id; desc->flags = PROPF_WRITABLE | PROPF_CONFIGURABLE; - desc->iid = 0; + desc->prototype_id = 0;
switch(prop->type) { case GLOBAL_SCRIPTVAR: { diff --git a/dlls/mshtml/pluginhost.c b/dlls/mshtml/pluginhost.c index c4a580ea4eb..03959266f1f 100644 --- a/dlls/mshtml/pluginhost.c +++ b/dlls/mshtml/pluginhost.c @@ -835,7 +835,7 @@ HRESULT HTMLPluginContainer_get_prop_desc(DispatchEx *dispex, DISPID id, struct desc->id = id; desc->flags = 0; desc->name = plugin_container->props[id - MSHTML_DISPID_CUSTOM_MIN]->name; - desc->iid = 0; + desc->prototype_id = 0; return S_OK; }
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 5bbd8b098f6..d304fbadd62 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3131,6 +3131,13 @@ sync_test("__proto__", function() { ok(e.number === 0xa13b6 - 0x80000000 && e.name === "TypeError", "changing __proto__ on non-extensible object threw exception " + e.number + " (" + e.name + ")"); } + + obj = document.createElement("img"); + obj.__proto__ = ctor.prototype; + document.body.setAttribute.call(obj, "height", "101"); + r = document.body.getAttribute.call(obj, "height"); + ok(r === "101", "getAttribute(height) = " + r); + ok(!("getAttribute" in obj), "getAttribute exposed in obj"); });
sync_test("__defineGetter__", function() { @@ -3750,6 +3757,13 @@ sync_test("prototypes", function() { check(Attr.prototype, Node.prototype, "attr prototype"); check(document.createDocumentFragment(), DocumentFragment.prototype, "fragment"); check(DocumentFragment.prototype, Node.prototype, "fragment prototype"); + + try { + HTMLAreaElement.prototype.toString.call(document.createElement("a")); + ok(false, "Area element's toString on Anchor element didn't fail"); + } catch(e) { + ok(e.number == 0xffff - 0x80000000, "Area element's toString on Anchor element threw exception " + e.number); + } });
sync_test("prototype props", function() {