From: Gabriel Ivăncescu gabrielopcode@gmail.com
Also do not use the Uri itself as check for local vs session storage, because sessionStorage will rely on the Uri as well.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstorage.c | 42 +++++++++++++++++++++--------------- dlls/mshtml/htmlwindow.c | 12 +++++------ dlls/mshtml/mshtml_private.h | 2 +- dlls/mshtml/tests/dom.c | 33 ++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 24 deletions(-)
diff --git a/dlls/mshtml/htmlstorage.c b/dlls/mshtml/htmlstorage.c index 1983d87a296..3e0e92fa148 100644 --- a/dlls/mshtml/htmlstorage.c +++ b/dlls/mshtml/htmlstorage.c @@ -548,28 +548,20 @@ static dispex_static_data_t HTMLStorage_dispex = { HTMLStorage_iface_tids };
-static WCHAR *build_filename(IUri *uri) +static WCHAR *build_filename(BSTR hostname) { static const WCHAR store[] = L"\Microsoft\Internet Explorer\DOMStore\"; WCHAR path[MAX_PATH], *ret; - BSTR hostname; - HRESULT hres; int len;
- hres = IUri_GetHost(uri, &hostname); - if(hres != S_OK) - return NULL; - if(!SHGetSpecialFolderPathW(NULL, path, CSIDL_LOCAL_APPDATA, TRUE)) { ERR("Can't get folder path %lu\n", GetLastError()); - SysFreeString(hostname); return NULL; }
len = wcslen(path); if(len + ARRAY_SIZE(store) > ARRAY_SIZE(path)) { ERR("Path too long\n"); - SysFreeString(hostname); return NULL; } memcpy(path + len, store, sizeof(store)); @@ -577,7 +569,6 @@ static WCHAR *build_filename(IUri *uri) len += ARRAY_SIZE(store); ret = heap_alloc((len + wcslen(hostname) + ARRAY_SIZE(L".xml")) * sizeof(WCHAR)); if(!ret) { - SysFreeString(hostname); return NULL; }
@@ -585,7 +576,6 @@ static WCHAR *build_filename(IUri *uri) wcscat(ret, hostname); wcscat(ret, L".xml");
- SysFreeString(hostname); return ret; }
@@ -600,17 +590,33 @@ static WCHAR *build_mutexname(const WCHAR *filename) return ret; }
-HRESULT create_html_storage(compat_mode_t compat_mode, IUri *uri, IHTMLStorage **p) +HRESULT create_html_storage(HTMLInnerWindow *window, BOOL local, IHTMLStorage **p) { + IUri *uri = window->base.outer_window->uri; + HRESULT hres = S_FALSE; HTMLStorage *storage; + BSTR hostname = NULL; + + if(!uri) + return S_FALSE; + + hres = IUri_GetHost(uri, &hostname); + if(hres != S_OK) { + SysFreeString(hostname); + return hres; + }
storage = heap_alloc_zero(sizeof(*storage)); - if(!storage) + if(!storage) { + SysFreeString(hostname); return E_OUTOFMEMORY; + }
- if(uri) { + if(local) { WCHAR *mutexname; - if(!(storage->filename = build_filename(uri))) { + storage->filename = build_filename(hostname); + SysFreeString(hostname); + if(!storage->filename) { heap_free(storage); return E_OUTOFMEMORY; } @@ -627,11 +633,13 @@ HRESULT create_html_storage(compat_mode_t compat_mode, IUri *uri, IHTMLStorage * heap_free(storage); return HRESULT_FROM_WIN32(GetLastError()); } - } + }else + SysFreeString(hostname);
storage->IHTMLStorage_iface.lpVtbl = &HTMLStorageVtbl; storage->ref = 1; - init_dispatch(&storage->dispex, (IUnknown*)&storage->IHTMLStorage_iface, &HTMLStorage_dispex, compat_mode); + init_dispatch(&storage->dispex, (IUnknown*)&storage->IHTMLStorage_iface, &HTMLStorage_dispex, + dispex_compat_mode(&window->event_target.dispex));
*p = &storage->IHTMLStorage_iface; return S_OK; diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 0043fb79731..4cc9852e48f 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -2140,12 +2140,12 @@ static HRESULT WINAPI HTMLWindow6_get_sessionStorage(IHTMLWindow6 *iface, IHTMLS
TRACE("(%p)->(%p)\n", This, p);
+ *p = NULL; if(!This->inner_window->session_storage) { HRESULT hres;
- hres = create_html_storage(dispex_compat_mode(&This->inner_window->event_target.dispex), - NULL, &This->inner_window->session_storage); - if(FAILED(hres)) + hres = create_html_storage(This->inner_window, FALSE, &This->inner_window->session_storage); + if(hres != S_OK) return hres; }
@@ -2160,12 +2160,12 @@ static HRESULT WINAPI HTMLWindow6_get_localStorage(IHTMLWindow6 *iface, IHTMLSto
TRACE("(%p)->(%p)\n", This, p);
+ *p = NULL; if(!This->inner_window->local_storage) { HRESULT hres;
- hres = create_html_storage(dispex_compat_mode(&This->inner_window->event_target.dispex), - This->inner_window->base.outer_window->uri, &This->inner_window->local_storage); - if(FAILED(hres)) + hres = create_html_storage(This->inner_window, TRUE, &This->inner_window->local_storage); + if(hres != S_OK) return hres; }
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 05b37c6b9db..23217ea3308 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -950,7 +950,7 @@ HRESULT create_namespace_collection(compat_mode_t,IHTMLNamespaceCollection**) DE HRESULT create_dom_implementation(HTMLDocumentNode*,IHTMLDOMImplementation**) DECLSPEC_HIDDEN; void detach_dom_implementation(IHTMLDOMImplementation*) DECLSPEC_HIDDEN;
-HRESULT create_html_storage(compat_mode_t,IUri*,IHTMLStorage**) DECLSPEC_HIDDEN; +HRESULT create_html_storage(HTMLInnerWindow*,BOOL,IHTMLStorage**) DECLSPEC_HIDDEN;
void HTMLDocument_Persist_Init(HTMLDocument*) DECLSPEC_HIDDEN; void HTMLDocument_OleCmd_Init(HTMLDocument*) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index e3ac177205c..5e135aa88ff 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -10891,6 +10891,37 @@ static void test_docfrag(IHTMLDocument2 *doc) IHTMLDocument2_Release(frag); }
+static void test_about_blank_storage(IHTMLDocument2 *doc) +{ + IHTMLStorage *storage; + IHTMLWindow6 *window6; + IHTMLWindow2 *window; + HRESULT hres; + + hres = IHTMLDocument2_get_parentWindow(doc, &window); + ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres); + ok(window != NULL, "window == NULL\n"); + + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow6, (void**)&window6); + IHTMLWindow2_Release(window); + if(FAILED(hres)) { + win_skip("IHTMLWindow6 not supported\n"); + return; + } + + storage = (IHTMLStorage*)(INT_PTR)0xdeadbeef; + hres = IHTMLWindow6_get_sessionStorage(window6, &storage); + ok(hres == S_FALSE, "get_sessionStorage failed: %08lx\n", hres); + ok(storage == NULL, "session_storage != NULL\n"); + + storage = (IHTMLStorage*)(INT_PTR)0xdeadbeef; + hres = IHTMLWindow6_get_localStorage(window6, &storage); + ok(hres == S_FALSE, "get_localStorage failed: %08lx\n", hres); + ok(storage == NULL, "local_storage != NULL\n"); + + IHTMLWindow6_Release(window6); +} + static void check_quirks_mode(IHTMLDocument2 *doc) { test_compatmode(doc, L"BackCompat"); @@ -11626,9 +11657,11 @@ START_TEST(dom) run_domtest(elem_test_str, test_elems); run_domtest(elem_test2_str, test_elems2); run_domtest(doc_blank, test_dom_elements); + run_domtest(doc_blank, test_about_blank_storage); if(is_ie9plus) { compat_mode = COMPAT_IE9; run_domtest(doc_blank_ie9, test_dom_elements); + run_domtest(doc_blank_ie9, test_about_blank_storage); compat_mode = COMPAT_NONE; } run_domtest(noscript_str, test_noscript);