-- v4: mshtml: Remove unused struct mutation_observer_ctor. mshtml: Use designated initializers for the Location dispex data. mshtml: Validate builtin host functions in IE9+ using prototype_id rather mshtml: Store the object_id of the last object in the prototype chain that
From: Gabriel Ivăncescu gabrielopcode@gmail.com
And use it instead of on_prototype boolean.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 1e31cb66db1..80ccc83069f 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -55,7 +55,7 @@ typedef struct { tid_t tid; BSTR name; dispex_hook_invoke_t hook; - BOOLEAN on_prototype; + object_id_t prototype_id; SHORT call_vtbl_off; SHORT put_vtbl_off; SHORT get_vtbl_off; @@ -517,31 +517,32 @@ 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 BOOL find_prototype_member(const dispex_data_t *info, DISPID id) +static object_id_t find_prototype_member(const dispex_data_t *info, DISPID id) { compat_mode_t compat_mode = info->compat_mode; + object_id_t ret = OBJID_NONE;
if(compat_mode < COMPAT_MODE_IE9) - return FALSE; + return ret;
if(!info->is_prototype) { if(!info->desc->id) - return FALSE; + return ret; info = info->desc->prototype_info[compat_mode - COMPAT_MODE_IE9]; }else { if(!info->desc->prototype_id) - return FALSE; + return ret; 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)) - return TRUE; + ret = info->desc->id; if(!info->desc->prototype_id) break; info = object_descriptors[info->desc->prototype_id]->prototype_info[compat_mode - COMPAT_MODE_IE9]; } - return FALSE; + return ret; }
static const char *object_names[] = { @@ -616,11 +617,11 @@ 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(find_prototype_member(data, data->funcs[i].id)) { - data->funcs[i].on_prototype = TRUE; + if(data->funcs[i].prototype_id != OBJID_NONE) continue; - } data->name_table[data->name_cnt++] = data->funcs+i; } qsort(data->name_table, data->name_cnt, sizeof(func_info_t*), func_name_cmp); @@ -2531,7 +2532,7 @@ HRESULT dispex_next_id(DispatchEx *dispex, DISPID id, BOOL enum_all_own_props, D }
while(func < dispex->info->funcs + dispex->info->func_cnt) { - if(enum_all_own_props ? (!func->on_prototype) : (func->func_disp_idx == -1)) { + if(enum_all_own_props ? (func->prototype_id == OBJID_NONE) : (func->func_disp_idx == -1)) { *ret = func->id; return S_OK; }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 12 +++++++----- dlls/mshtml/tests/documentmode.js | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 80ccc83069f..21927315443 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -67,6 +67,8 @@ typedef struct { func_arg_info_t *arg_info; } func_info_t;
+#define CALLFUNC_USE_TID 0x80000000u + struct dispex_data_t { const dispex_static_data_vtbl_t *vtbl; dispex_static_data_t *desc; @@ -1076,7 +1078,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 | CALLFUNC_USE_TID, DISPATCH_METHOD, ¶ms, res, ei, caller);
fail: while(argc--) @@ -1103,7 +1105,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 | CALLFUNC_USE_TID, DISPATCH_METHOD, ¶ms, res, ei, caller); IWineJSDispatchHost_Release(this_iface); return (hres == E_UNEXPECTED) ? CTL_E_ILLEGALFUNCTIONCALL : hres; } @@ -2614,13 +2616,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 +2733,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) || (iid != func->prototype_id && iid != (func->tid | CALLFUNC_USE_TID))) 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() {
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmllocation.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/mshtml/htmllocation.c b/dlls/mshtml/htmllocation.c index b176b56280c..91ca17946f3 100644 --- a/dlls/mshtml/htmllocation.c +++ b/dlls/mshtml/htmllocation.c @@ -605,10 +605,10 @@ static const tid_t HTMLLocation_iface_tids[] = { 0 }; static dispex_static_data_t HTMLLocation_dispex = { - "Location", - &HTMLLocation_dispex_vtbl, - DispHTMLLocation_tid, - HTMLLocation_iface_tids + .name = "Location", + .vtbl = &HTMLLocation_dispex_vtbl, + .disp_tid = DispHTMLLocation_tid, + .iface_tids = HTMLLocation_iface_tids };
HRESULT create_location(HTMLOuterWindow *window, HTMLLocation **ret)
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mutation.c | 4 ---- 1 file changed, 4 deletions(-)
diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index b5ec41136ea..92fc97a03d9 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -1243,10 +1243,6 @@ static HRESULT create_mutation_observer(DispatchEx *owner, IDispatch *callback, return S_OK; }
-struct mutation_observer_ctor { - DispatchEx dispex; -}; - static HRESULT mutation_observer_ctor_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
This merge request was approved by Jacek Caban.