From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 30 +++++++++++++++--------------- dlls/mshtml/tests/documentmode.js | 14 ++++++++++++++ 2 files changed, 29 insertions(+), 15 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 80ccc83069f..68f74534488 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -517,32 +517,34 @@ static int __cdecl func_name_cmp(const void *p1, const void *p2) return wcsicmp((*(func_info_t* const*)p1)->name, (*(func_info_t* const*)p2)->name); }
-static object_id_t find_prototype_member(const dispex_data_t *info, DISPID id) +static BOOL find_prototype_member(const dispex_data_t *info, func_info_t *func) { compat_mode_t compat_mode = info->compat_mode; - object_id_t ret = OBJID_NONE;
- if(compat_mode < COMPAT_MODE_IE9) - return ret; + if(compat_mode < COMPAT_MODE_IE9) { + func->prototype_id = (object_id_t)func->tid; /* use the tid for calling on arbitrary 'this' via apply/call */ + return FALSE; + }
+ func->prototype_id = OBJID_NONE; if(!info->is_prototype) { if(!info->desc->id) - return ret; + return FALSE; info = info->desc->prototype_info[compat_mode - COMPAT_MODE_IE9]; }else { if(!info->desc->prototype_id) - return ret; + return FALSE; info = object_descriptors[info->desc->prototype_id]->prototype_info[compat_mode - COMPAT_MODE_IE9]; }
for(;;) { - if(bsearch(&id, info->funcs, info->func_cnt, sizeof(info->funcs[0]), dispid_cmp)) - ret = info->desc->id; + if(bsearch(&func->id, info->funcs, info->func_cnt, sizeof(info->funcs[0]), dispid_cmp)) + func->prototype_id = info->desc->id; if(!info->desc->prototype_id) break; info = object_descriptors[info->desc->prototype_id]->prototype_info[compat_mode - COMPAT_MODE_IE9]; } - return ret; + return (func->prototype_id != OBJID_NONE); }
static const char *object_names[] = { @@ -617,10 +619,8 @@ static dispex_data_t *preprocess_dispex_data(dispex_static_data_t *desc, compat_
data->name_table = malloc(data->func_cnt * sizeof(func_info_t*)); for(i=0; i < data->func_cnt; i++) { - data->funcs[i].prototype_id = find_prototype_member(data, data->funcs[i].id); - /* Don't expose properties that are exposed by object's prototype */ - if(data->funcs[i].prototype_id != OBJID_NONE) + if(find_prototype_member(data, &data->funcs[i])) continue; data->name_table[data->name_cnt++] = data->funcs+i; } @@ -2614,13 +2614,13 @@ 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->iid = This->info->desc->id; 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->iid = This->info->desc->id; if(func->put_vtbl_off) desc->flags |= PROPF_WRITABLE; }else { @@ -2731,7 +2731,7 @@ static HRESULT WINAPI JSDispatchHost_CallFunction(IWineJSDispatchHost *iface, DI TRACE("%s (%p)->(%lx %x %lx %p %p %p %p)\n", This->info->name, This, id, iid, flags, dp, ret, ei, caller);
hres = get_builtin_func(This->info, id, &func); - if(FAILED(hres) || func->tid != iid) + if(FAILED(hres) || func->prototype_id != iid) return E_UNEXPECTED;
switch(flags) { diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index f9967e8a6bd..634f4ad3420 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3146,6 +3146,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() { @@ -3765,6 +3772,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() {