Module: wine Branch: master Commit: 1e6c1851b0e758707bf387259f92d0d71734382a URL: https://gitlab.winehq.org/wine/wine/-/commit/1e6c1851b0e758707bf387259f92d0d...
Author: Gabriel Ivăncescu gabrielopcode@gmail.com Date: Tue Aug 23 17:31:21 2022 +0300
mshtml: Handle S_FALSE from IUri methods in localStorage and sessionStorage.
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 | 14 ++++++++------ dlls/mshtml/mshtml_private.h | 2 +- dlls/mshtml/tests/dom.c | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 24 deletions(-)
diff --git a/dlls/mshtml/htmlstorage.c b/dlls/mshtml/htmlstorage.c index 1983d87a296..ae63c2b2f53 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; HTMLStorage *storage; + BSTR hostname = NULL; + HRESULT hres; + + 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..7774e0fc92d 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -2143,10 +2143,11 @@ static HRESULT WINAPI HTMLWindow6_get_sessionStorage(IHTMLWindow6 *iface, IHTMLS 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) { + *p = NULL; return hres; + } }
IHTMLStorage_AddRef(This->inner_window->session_storage); @@ -2163,10 +2164,11 @@ static HRESULT WINAPI HTMLWindow6_get_localStorage(IHTMLWindow6 *iface, IHTMLSto 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) { + *p = NULL; return hres; + } }
IHTMLStorage_AddRef(This->inner_window->local_storage); 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);