From 53253aa6a42f767ab21052419e4e7454144f0aae Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 22 Aug 2017 17:54:54 +0200 Subject: [PATCH] mshtml: Don't allow changing document mode after script insertion or when it's already set. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/mshtml/mshtml_private.h | 4 +++- dlls/mshtml/mutation.c | 16 ++++++++++--- dlls/mshtml/tests/dom.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 1e12a6e7618..2ee34c1052e 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -811,9 +811,11 @@ struct HTMLDocumentNode { LONG ref; - compat_mode_t document_mode; HTMLInnerWindow *window; + compat_mode_t document_mode; + BOOL document_mode_locked; + nsIDOMHTMLDocument *nsdoc; BOOL content_ready; diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index 50e162e4897..cf69b60c19a 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -370,9 +370,17 @@ static nsresult run_insert_script(HTMLDocumentNode *doc, nsISupports *script_ifa return NS_OK; } -static void set_document_mode(HTMLDocumentNode *doc, compat_mode_t document_mode) +static void set_document_mode(HTMLDocumentNode *doc, compat_mode_t document_mode, BOOL lock) { + if(doc->document_mode_locked) { + WARN("attemting to set document mode %d on locked document %p\n", document_mode, doc); + return; + } + TRACE("%p: %d\n", doc, document_mode); + + if(lock) + doc->document_mode_locked = TRUE; doc->document_mode = document_mode; } @@ -444,7 +452,7 @@ static void process_meta_element(HTMLDocumentNode *doc, nsIDOMHTMLMetaElement *m if(!strcmpiW(http_equiv, x_ua_compatibleW)) { compat_mode_t document_mode; if(parse_ua_compatible(content, &document_mode)) - set_document_mode(doc, document_mode); + set_document_mode(doc, document_mode, TRUE); else FIXME("Unsupported document mode %s\n", debugstr_w(content)); } @@ -755,7 +763,7 @@ static void NSAPI nsDocumentObserver_BindToDocument(nsIDocumentObserver *iface, if(NS_SUCCEEDED(nsres)) { TRACE("doctype node\n"); /* FIXME: We should set it to something higher for internet zone. */ - set_document_mode(This, COMPAT_MODE_IE7); + set_document_mode(This, COMPAT_MODE_IE7, FALSE); nsIDOMDocumentType_Release(nsdoctype); } } @@ -814,6 +822,8 @@ static void NSAPI nsDocumentObserver_AttemptToExecuteScript(nsIDocumentObserver if(NS_SUCCEEDED(nsres)) { TRACE("script node\n"); + This->document_mode_locked = TRUE; + add_script_runner(This, run_insert_script, (nsISupports*)nsscript, (nsISupports*)aParser); nsIDOMHTMLScriptElement_Release(nsscript); } diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 5276166b4e5..c6053a6f898 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -10530,12 +10530,65 @@ static void run_domtest(const char *str, domtest_t test) "ref = %d\n", ref); } +static float expected_document_mode; + +static void test_document_mode(IHTMLDocument2 *doc2) +{ + IHTMLDocument6 *doc; + VARIANT v; + HRESULT hres; + + if(expected_document_mode >= 9) { + IHTMLDocument7 *doc7; + hres = IHTMLDocument2_QueryInterface(doc2, &IID_IHTMLDocument7, (void**)&doc7); + if(FAILED(hres)) { + win_skip("IHTMLDocument7 interface not supported: %08x\n", hres); + return; + } + IHTMLDocument7_Release(doc7); + } + + hres = IHTMLDocument2_QueryInterface(doc2, &IID_IHTMLDocument6, (void**)&doc); + ok(hres == S_OK, "Could not get IHTMLDocument6 interface: %08x\n", hres); + + V_VT(&v) = VT_EMPTY; + hres = IHTMLDocument6_get_documentMode(doc, &v); + ok(hres == S_OK, "get_documentMode failed: %08x\n", hres); + ok(V_VT(&v) == VT_R4, "V_VT(documentMode) = %u\n", V_VT(&v)); + ok(V_R4(&v) == expected_document_mode, "documentMode = %f\n", V_R4(&v)); + IHTMLDocument6_Release(doc); +} + static void test_quirks_mode(void) { run_domtest("", check_quirks_mode); run_domtest("\n", check_strict_mode); run_domtest("\n", check_quirks_mode); run_domtest("", test_quirks_mode_offsetHeight); + + expected_document_mode = 5; + run_domtest("", test_document_mode); + + expected_document_mode = 9; + run_domtest("\n" + "" + " " + " " + " " + " " + " " + "", test_document_mode); + + expected_document_mode = 8; + run_domtest("\n" + "" + " " + " " + " " + " " + " " + " " + "", test_document_mode); } START_TEST(dom) -- 2.11.4.GIT