diff options
Diffstat (limited to 'widget/windows/tests')
-rw-r--r-- | widget/windows/tests/TestUriValidation.cpp | 135 | ||||
-rw-r--r-- | widget/windows/tests/TestUrisToValidate.h | 471 | ||||
-rw-r--r-- | widget/windows/tests/TestWinDND.cpp | 696 | ||||
-rw-r--r-- | widget/windows/tests/moz.build | 28 |
4 files changed, 1330 insertions, 0 deletions
diff --git a/widget/windows/tests/TestUriValidation.cpp b/widget/windows/tests/TestUriValidation.cpp new file mode 100644 index 0000000000..d8a0ca09ce --- /dev/null +++ b/widget/windows/tests/TestUriValidation.cpp @@ -0,0 +1,135 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#define MOZ_USE_LAUNCHER_ERROR + +#define UNICODE +#include "mozilla/UrlmonHeaderOnlyUtils.h" +#include "TestUrisToValidate.h" + +#include <urlmon.h> + +using namespace mozilla; + +static LauncherResult<_bstr_t> ShellValidateUri(const wchar_t* aUri) { + LauncherResult<UniqueAbsolutePidl> pidlResult = ShellParseDisplayName(aUri); + if (pidlResult.isErr()) { + return pidlResult.propagateErr(); + } + UniqueAbsolutePidl pidl = pidlResult.unwrap(); + + // |pidl| is an absolute path. IShellFolder::GetDisplayNameOf requires a + // valid child ID, so the first thing we need to resolve is the IShellFolder + // for |pidl|'s parent, as well as the childId that represents |pidl|. + // Fortunately SHBindToParent does exactly that! + PCUITEMID_CHILD childId = nullptr; + RefPtr<IShellFolder> parentFolder; + HRESULT hr = SHBindToParent(pidl.get(), IID_IShellFolder, + getter_AddRefs(parentFolder), &childId); + if (FAILED(hr)) { + return LAUNCHER_ERROR_FROM_HRESULT(hr); + } + + // Now we retrieve the display name of |childId|, telling the shell that we + // plan to have the string parsed. + STRRET strret; + hr = parentFolder->GetDisplayNameOf(childId, SHGDN_FORPARSING, &strret); + if (FAILED(hr)) { + return LAUNCHER_ERROR_FROM_HRESULT(hr); + } + + // StrRetToBSTR automatically takes care of freeing any dynamically + // allocated memory in |strret|. + _bstr_t bstrUri; + hr = StrRetToBSTR(&strret, nullptr, bstrUri.GetAddress()); + if (FAILED(hr)) { + return LAUNCHER_ERROR_FROM_HRESULT(hr); + } + + return bstrUri; +} + +static LauncherResult<_bstr_t> GetFragment(const wchar_t* aUri) { + constexpr DWORD flags = + Uri_CREATE_NO_DECODE_EXTRA_INFO | Uri_CREATE_CANONICALIZE | + Uri_CREATE_CRACK_UNKNOWN_SCHEMES | Uri_CREATE_PRE_PROCESS_HTML_URI | + Uri_CREATE_IE_SETTINGS; + RefPtr<IUri> uri; + HRESULT hr = CreateUri(aUri, flags, 0, getter_AddRefs(uri)); + if (FAILED(hr)) { + return LAUNCHER_ERROR_FROM_HRESULT(hr); + } + + _bstr_t bstrFragment; + hr = uri->GetFragment(bstrFragment.GetAddress()); + if (FAILED(hr)) { + return LAUNCHER_ERROR_FROM_HRESULT(hr); + } + return bstrFragment; +} + +static bool RunSingleTest(const wchar_t* aUri) { + LauncherResult<_bstr_t> uriOld = ShellValidateUri(aUri), + uriNew = UrlmonValidateUri(aUri); + if (uriOld.isErr() != uriNew.isErr()) { + printf("TEST-FAILED | UriValidation | Validation result mismatch on %S\n", + aUri); + return false; + } + + if (uriOld.isErr()) { + if (uriOld.unwrapErr().mError != uriNew.unwrapErr().mError) { + printf("TEST-FAILED | UriValidation | Error code mismatch on %S\n", aUri); + return false; + } + return true; + } + + LauncherResult<_bstr_t> bstrFragment = GetFragment(aUri); + if (bstrFragment.isErr()) { + printf("TEST-FAILED | UriValidation | Failed to get a fragment from %S\n", + aUri); + return false; + } + + // We validate a uri with two logics: the current one UrlmonValidateUri and + // the older one ShellValidateUri, to make sure the same validation result. + // We introduced UrlmonValidateUri because ShellValidateUri drops a fragment + // in a uri due to the design of Windows. To bypass the fragment issue, we + // extract a fragment and appends it into the validated string, and compare. + _bstr_t bstrUriOldCorrected = uriOld.unwrap() + bstrFragment.unwrap(); + const _bstr_t& bstrUriNew = uriNew.unwrap(); + if (bstrUriOldCorrected != bstrUriNew) { + printf("TEST-FAILED | UriValidation | %S %S %S\n", aUri, + static_cast<const wchar_t*>(bstrUriOldCorrected), + static_cast<const wchar_t*>(bstrUriNew)); + return false; + } + + return true; +} + +int wmain(int argc, wchar_t* argv[]) { + HRESULT hr = CoInitialize(nullptr); + if (FAILED(hr)) { + return 1; + } + + bool isOk = true; + + if (argc == 2) { + isOk = RunSingleTest(argv[1]); + } else { + for (const wchar_t*& testUri : kTestUris) { + if (!RunSingleTest(testUri)) { + isOk = false; + } + } + } + + CoUninitialize(); + return isOk ? 0 : 1; +} diff --git a/widget/windows/tests/TestUrisToValidate.h b/widget/windows/tests/TestUrisToValidate.h new file mode 100644 index 0000000000..cb00366d1e --- /dev/null +++ b/widget/windows/tests/TestUrisToValidate.h @@ -0,0 +1,471 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_TestUrisToValidate_h
+#define mozilla_TestUrisToValidate_h
+
+const wchar_t* kTestUris[] = {
+ L"callto:%.txt",
+ L"callto:%00.txt",
+ L"callto:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"fdaction:%.txt",
+ L"fdaction:%00.txt",
+ L"fdaction:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"feed:%.txt",
+ L"feed:%00.txt",
+ L"feed:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"feeds:%.txt",
+ L"feeds:%00.txt",
+ L"feeds:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"file:///%.txt",
+ L"file:///%00.txt",
+ L"file:///%41%2D%31%5Ftest%22ing?%41%31%00.txt",
+ L"firefox.url:%.txt",
+ L"firefox.url:%00.txt",
+ L"firefox.url:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"firefoxurl:%.txt",
+ L"firefoxurl:%00.txt",
+ L"firefoxurl:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"ftp:%.txt",
+ L"ftp:%00.txt",
+ L"ftp:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"gopher:%.txt",
+ L"gopher:%00.txt",
+ L"gopher:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"gtalk:%.txt",
+ L"gtalk:%00.txt",
+ L"gtalk:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"HTTP:%.txt",
+ L"HTTP:%00.txt",
+ L"HTTP:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"http:%.txt",
+ L"http:%00.txt",
+ L"http:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"https://bug389580.bmoattachments.org/%.txt",
+ L"https://bug389580.bmoattachments.org/%00.txt",
+ L"https://bug389580.bmoattachments.org/"
+ L"%41%2D%31%5Ftest%22ing?%41%31%00.txt",
+ L"ie.ftp:%.txt",
+ L"ie.ftp:%00.txt",
+ L"ie.ftp:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"ie.http:%.txt",
+ L"ie.http:%00.txt",
+ L"ie.http:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"ie.https:%.txt",
+ L"ie.https:%00.txt",
+ L"ie.https:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"irc:%.txt",
+ L"irc:%00.txt",
+ L"irc:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"ircs:%.txt",
+ L"ircs:%00.txt",
+ L"ircs:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"itms:%.txt",
+ L"itms:%00.txt",
+ L"itms:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"itmss:%.txt",
+ L"itmss:%00.txt",
+ L"itmss:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"itpc:%.txt",
+ L"itpc:%00.txt",
+ L"itpc:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"itunes.assocprotocol.itms:%.txt",
+ L"itunes.assocprotocol.itms:%00.txt",
+ L"itunes.assocprotocol.itms:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"itunes.assocprotocol.itmss:%.txt",
+ L"itunes.assocprotocol.itmss:%00.txt",
+ L"itunes.assocprotocol.itmss:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"itunes.assocprotocol.itpc:%.txt",
+ L"itunes.assocprotocol.itpc:%00.txt",
+ L"itunes.assocprotocol.itpc:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"ldap:%.txt",
+ L"ldap:%00.txt",
+ L"ldap:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"mailto:%.txt",
+ L"mailto:%00.txt",
+ L"mailto:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"mms:%.txt",
+ L"mms:%00.txt",
+ L"mms:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"mmst:%.txt",
+ L"mmst:%00.txt",
+ L"mmst:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"mmst:%.txt",
+ L"mmst:%00.txt",
+ L"mmst:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"mmsu:%.txt",
+ L"mmsu:%00.txt",
+ L"mmsu:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"mmsu:%.txt",
+ L"mmsu:%00.txt",
+ L"mmsu:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"https://bug389580.bmoattachments.org/"
+ L"Mozilla%20Thunderbird.Url.Mailto:%.txt",
+ L"https://bug389580.bmoattachments.org/"
+ L"Mozilla%20Thunderbird.Url.Mailto:%00.txt",
+ L"https://bug389580.bmoattachments.org/"
+ L"Mozilla%20Thunderbird.Url.Mailto:%41%2D%31%5Ftest%22ing?%41%31%00.txt",
+ L"navigatorurl:%.txt",
+ L"navigatorurl:%00.txt",
+ L"navigatorurl:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"news:%.txt",
+ L"news:%00.txt",
+ L"news:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"nntp:%.txt",
+ L"nntp:%00.txt",
+ L"nntp:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"oms:%.txt",
+ L"oms:%00.txt",
+ L"oms:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"outlook:%.txt",
+ L"outlook:%00.txt",
+ L"outlook:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"outlook.url.feed:%.txt",
+ L"outlook.url.feed:%00.txt",
+ L"outlook.url.feed:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"outlook.url.mailto:%.txt",
+ L"outlook.url.mailto:%00.txt",
+ L"outlook.url.mailto:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"outlook.url.webcal:%.txt",
+ L"outlook.url.webcal:%00.txt",
+ L"outlook.url.webcal:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"outlookfeed:%.txt",
+ L"outlookfeed:%00.txt",
+ L"outlookfeed:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"outlookfeeds:%.txt",
+ L"outlookfeeds:%00.txt",
+ L"outlookfeeds:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"pnm:%.txt",
+ L"pnm:%00.txt",
+ L"pnm:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"prls.intappfile.ftp:%.txt",
+ L"prls.intappfile.ftp:%00.txt",
+ L"prls.intappfile.ftp:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"prls.intappfile.http:%.txt",
+ L"prls.intappfile.http:%00.txt",
+ L"prls.intappfile.http:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"prls.intappfile.https:%.txt",
+ L"prls.intappfile.https:%00.txt",
+ L"prls.intappfile.https:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"prls.intappfile.mailto:%.txt",
+ L"prls.intappfile.mailto:%00.txt",
+ L"prls.intappfile.mailto:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"rlogin:%.txt",
+ L"rlogin:%00.txt",
+ L"rlogin:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"rtsp:%.txt",
+ L"rtsp:%00.txt",
+ L"rtsp:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"scp:%.txt",
+ L"scp:%00.txt",
+ L"scp:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"sftp:%.txt",
+ L"sftp:%00.txt",
+ L"sftp:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"sip:%.txt",
+ L"sip:%00.txt",
+ L"sip:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"skype:%.txt",
+ L"skype:%00.txt",
+ L"skype:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"snews:%.txt",
+ L"snews:%00.txt",
+ L"snews:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"telnet:%.txt",
+ L"telnet:%00.txt",
+ L"telnet:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"thunderbird.url.mailto:%.txt",
+ L"thunderbird.url.mailto:%00.txt",
+ L"thunderbird.url.mailto:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"thunderbird.url.news:%.txt",
+ L"thunderbird.url.news:%00.txt",
+ L"thunderbird.url.news:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"tn3270:%.txt",
+ L"tn3270:%00.txt",
+ L"tn3270:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"tscrec4:%.txt",
+ L"tscrec4:%00.txt",
+ L"tscrec4:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"webcal:%.txt",
+ L"webcal:%00.txt",
+ L"webcal:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"webcal:%.txt",
+ L"webcal:%00.txt",
+ L"webcal:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"webcals:%.txt",
+ L"webcals:%00.txt",
+ L"webcals:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"windowscalendar.urlwebcal.1:%.txt",
+ L"windowscalendar.urlwebcal.1:%00.txt",
+ L"windowscalendar.urlwebcal.1:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"windowsmail.url.mailto:%.txt",
+ L"windowsmail.url.mailto:%00.txt",
+ L"windowsmail.url.mailto:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"windowsmail.url.news:%.txt",
+ L"windowsmail.url.news:%00.txt",
+ L"windowsmail.url.news:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"windowsmail.url.nntp:%.txt",
+ L"windowsmail.url.nntp:%00.txt",
+ L"windowsmail.url.nntp:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"windowsmail.url.snews:%.txt",
+ L"windowsmail.url.snews:%00.txt",
+ L"windowsmail.url.snews:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"wmp11.assocprotocol.mms:%.txt",
+ L"wmp11.assocprotocol.mms:%00.txt",
+ L"wmp11.assocprotocol.mms:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"wpc:%.txt",
+ L"wpc:%00.txt",
+ L"wpc:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"ymsgr:%.txt",
+ L"ymsgr:%00.txt",
+ L"ymsgr:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"acrobat:%.txt",
+ L"acrobat:%00.txt",
+ L"acrobat:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"acsui:%.txt",
+ L"acsui:%00.txt",
+ L"acsui:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"aim:%.txt",
+ L"aim:%00.txt",
+ L"aim:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"aim:%.txt",
+ L"aim:%00.txt",
+ L"aim:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"allc8.commands.2:%.txt",
+ L"allc8.commands.2:%00.txt",
+ L"allc8.commands.2:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"allholdem.commands.2:%.txt",
+ L"allholdem.commands.2:%00.txt",
+ L"allholdem.commands.2:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"allpoker.commands.2:%.txt",
+ L"allpoker.commands.2:%00.txt",
+ L"allpoker.commands.2:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"aolautofix:%.txt",
+ L"aolautofix:%00.txt",
+ L"aolautofix:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"aolds:%.txt",
+ L"aolds:%00.txt",
+ L"aolds:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"bc:%.txt",
+ L"bc:%00.txt",
+ L"bc:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"bctp:%.txt",
+ L"bctp:%00.txt",
+ L"bctp:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"bittorrent:%.txt",
+ L"bittorrent:%00.txt",
+ L"bittorrent:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"camfrog:%.txt",
+ L"camfrog:%00.txt",
+ L"camfrog:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"csi:%.txt",
+ L"csi:%00.txt",
+ L"csi:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"cvs:%.txt",
+ L"cvs:%00.txt",
+ L"cvs:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"daap:%.txt",
+ L"daap:%00.txt",
+ L"daap:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"ed2k:%.txt",
+ L"ed2k:%00.txt",
+ L"ed2k:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"explorer.assocprotocol.search-ms:%.txt",
+ L"explorer.assocprotocol.search-ms:%00.txt",
+ L"explorer.assocprotocol.search-ms:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"gizmoproject:%.txt",
+ L"gizmoproject:%00.txt",
+ L"gizmoproject:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"gnet:%.txt",
+ L"gnet:%00.txt",
+ L"gnet:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"gnutella:%.txt",
+ L"gnutella:%00.txt",
+ L"gnutella:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"gsarcade:%.txt",
+ L"gsarcade:%00.txt",
+ L"gsarcade:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"hcp:%.txt",
+ L"hcp:%00.txt",
+ L"hcp:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"icquser:%.txt",
+ L"icquser:%00.txt",
+ L"icquser:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"icy:%.txt",
+ L"icy:%00.txt",
+ L"icy:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"imesync:%.txt",
+ L"imesync:%00.txt",
+ L"imesync:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"itunes.assocprotocol.daap:%.txt",
+ L"itunes.assocprotocol.daap:%00.txt",
+ L"itunes.assocprotocol.daap:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"itunes.assocprotocol.pcast:%.txt",
+ L"itunes.assocprotocol.pcast:%00.txt",
+ L"itunes.assocprotocol.pcast:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"joost:%.txt",
+ L"joost:%00.txt",
+ L"joost:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"m4macdrive:%.txt",
+ L"m4macdrive:%00.txt",
+ L"m4macdrive:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"magnet:%.txt",
+ L"magnet:%00.txt",
+ L"magnet:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"mapi:%.txt",
+ L"mapi:%00.txt",
+ L"mapi:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"mc12:%.txt",
+ L"mc12:%00.txt",
+ L"mc12:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"mediajukebox:%.txt",
+ L"mediajukebox:%00.txt",
+ L"mediajukebox:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"morpheus:%.txt",
+ L"morpheus:%00.txt",
+ L"morpheus:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"mp2p:%.txt",
+ L"mp2p:%00.txt",
+ L"mp2p:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"mpodcast:%.txt",
+ L"mpodcast:%00.txt",
+ L"mpodcast:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"msbd:%.txt",
+ L"msbd:%00.txt",
+ L"msbd:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"msbd:%.txt",
+ L"msbd:%00.txt",
+ L"msbd:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"msdigitallocker:%.txt",
+ L"msdigitallocker:%00.txt",
+ L"msdigitallocker:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"outlook.url.stssync:%.txt",
+ L"outlook.url.stssync:%00.txt",
+ L"outlook.url.stssync:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"p2p:%.txt",
+ L"p2p:%00.txt",
+ L"p2p:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"pando:%.txt",
+ L"pando:%00.txt",
+ L"pando:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"pcast:%.txt",
+ L"pcast:%00.txt",
+ L"pcast:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"picasa:%.txt",
+ L"picasa:%00.txt",
+ L"picasa:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"plaxo:%.txt",
+ L"plaxo:%00.txt",
+ L"plaxo:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"play:%.txt",
+ L"play:%00.txt",
+ L"play:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"podcast:%.txt",
+ L"podcast:%00.txt",
+ L"podcast:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"ppmate:%.txt",
+ L"ppmate:%00.txt",
+ L"ppmate:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"ppmates:%.txt",
+ L"ppmates:%00.txt",
+ L"ppmates:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"ppstream:%.txt",
+ L"ppstream:%00.txt",
+ L"ppstream:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"quicktime:%.txt",
+ L"quicktime:%00.txt",
+ L"quicktime:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"realplayer.autoplay.6:%.txt",
+ L"realplayer.autoplay.6:%00.txt",
+ L"realplayer.autoplay.6:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"realplayer.cdburn.6:%.txt",
+ L"realplayer.cdburn.6:%00.txt",
+ L"realplayer.cdburn.6:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"rhap:%.txt",
+ L"rhap:%00.txt",
+ L"rhap:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"sc:%.txt",
+ L"sc:%00.txt",
+ L"sc:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"search-ms:%.txt",
+ L"search-ms:%00.txt",
+ L"search-ms:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"shareaza:%.txt",
+ L"shareaza:%00.txt",
+ L"shareaza:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"shell:%.txt",
+ L"shell:%00.txt",
+ L"shell:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"shout:%.txt",
+ L"shout:%00.txt",
+ L"shout:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"sig2dat:%.txt",
+ L"sig2dat:%00.txt",
+ L"sig2dat:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"sop:%.txt",
+ L"sop:%00.txt",
+ L"sop:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"steam:%.txt",
+ L"steam:%00.txt",
+ L"steam:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"stssync:%.txt",
+ L"stssync:%00.txt",
+ L"stssync:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"svn:%.txt",
+ L"svn:%00.txt",
+ L"svn:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"svn+ssh:%.txt",
+ L"svn+ssh:%00.txt",
+ L"svn+ssh:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"synacast:%.txt",
+ L"synacast:%00.txt",
+ L"synacast:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"torrent:%.txt",
+ L"torrent:%00.txt",
+ L"torrent:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"tsvn:%.txt",
+ L"tsvn:%00.txt",
+ L"tsvn:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"tvants:%.txt",
+ L"tvants:%00.txt",
+ L"tvants:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"tvu:%.txt",
+ L"tvu:%00.txt",
+ L"tvu:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"unsv:%.txt",
+ L"unsv:%00.txt",
+ L"unsv:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"uvox:%.txt",
+ L"uvox:%00.txt",
+ L"uvox:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"ventrilo:%.txt",
+ L"ventrilo:%00.txt",
+ L"ventrilo:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"vs:%.txt",
+ L"vs:%00.txt",
+ L"vs:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"zune:%.txt",
+ L"zune:%00.txt",
+ L"zune:%41%2D%31%5Ftest"ing?%41%31%00.txt",
+ L"https://example.com/?a=123&b=456",
+ L"https://example.com/#123?a=123&b=456",
+ L"https://example.com/?#123a=123&b=456",
+ L"https://example.com/?a=123&b=456#123",
+ L"mailto:%41%42%23%31",
+ L"mailto:%41%42%23%31#fragment",
+ L"news:%41%42%23%31",
+ L"news:%41%42%23%31#fragment",
+ L"microsoft-edge:%41%42%23%31",
+ L"microsoft-edge:%41%42%23%31#fragment",
+ L"microsoft-edge:%41%42%23%31#fragment#",
+ L"microsoft-edge:%41%42%23%31####",
+ L"something-unknown:",
+ L"something-unknown:x=123",
+ L"something-unknown:?=123",
+ L"something-unknown:#code=0123456789%200123456789&x=01234567890123456789",
+};
+
+#endif // mozilla_TestUrisToValidate_h
diff --git a/widget/windows/tests/TestWinDND.cpp b/widget/windows/tests/TestWinDND.cpp new file mode 100644 index 0000000000..51e43cf19e --- /dev/null +++ b/widget/windows/tests/TestWinDND.cpp @@ -0,0 +1,696 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#define MOZILLA_INTERNAL_API + +#include <ole2.h> +#include <shlobj.h> + +#include "TestHarness.h" +#include "nsArray.h" +#include "nsIFile.h" +#include "nsNetUtil.h" +#include "nsISupportsPrimitives.h" +#include "nsITransferable.h" +#include "nsClipboard.h" +#include "nsDataObjCollection.h" + +nsIFile* xferFile; + +nsresult CheckValidHDROP(STGMEDIUM* pSTG) { + if (pSTG->tymed != TYMED_HGLOBAL) { + fail("Received data is not in an HGLOBAL"); + return NS_ERROR_UNEXPECTED; + } + + HGLOBAL hGlobal = pSTG->hGlobal; + DROPFILES* pDropFiles; + pDropFiles = (DROPFILES*)GlobalLock(hGlobal); + if (!pDropFiles) { + fail("There is no data at the given HGLOBAL"); + return NS_ERROR_UNEXPECTED; + } + + if (pDropFiles->pFiles != sizeof(DROPFILES)) + fail("DROPFILES struct has wrong size"); + + if (pDropFiles->fWide != true) { + fail("Received data is not Unicode"); + return NS_ERROR_UNEXPECTED; + } + nsString s; + unsigned long offset = 0; + while (1) { + s = (char16_t*)((char*)pDropFiles + pDropFiles->pFiles + offset); + if (s.IsEmpty()) break; + nsresult rv; + nsCOMPtr<nsIFile> localFile( + do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv)); + rv = localFile->InitWithPath(s); + if (NS_FAILED(rv)) { + fail("File could not be opened"); + return NS_ERROR_UNEXPECTED; + } + offset += sizeof(char16_t) * (s.Length() + 1); + } + return NS_OK; +} + +nsresult CheckValidTEXT(STGMEDIUM* pSTG) { + if (pSTG->tymed != TYMED_HGLOBAL) { + fail("Received data is not in an HGLOBAL"); + return NS_ERROR_UNEXPECTED; + } + + HGLOBAL hGlobal = pSTG->hGlobal; + char* pText; + pText = (char*)GlobalLock(hGlobal); + if (!pText) { + fail("There is no data at the given HGLOBAL"); + return NS_ERROR_UNEXPECTED; + } + + nsCString string; + string = pText; + + if (!string.EqualsLiteral("Mozilla can drag and drop")) { + fail("Text passed through drop object wrong"); + return NS_ERROR_UNEXPECTED; + } + return NS_OK; +} + +nsresult CheckValidTEXTTwo(STGMEDIUM* pSTG) { + if (pSTG->tymed != TYMED_HGLOBAL) { + fail("Received data is not in an HGLOBAL"); + return NS_ERROR_UNEXPECTED; + } + + HGLOBAL hGlobal = pSTG->hGlobal; + char* pText; + pText = (char*)GlobalLock(hGlobal); + if (!pText) { + fail("There is no data at the given HGLOBAL"); + return NS_ERROR_UNEXPECTED; + } + + nsCString string; + string = pText; + + if (!string.EqualsLiteral("Mozilla can drag and drop twice over")) { + fail("Text passed through drop object wrong"); + return NS_ERROR_UNEXPECTED; + } + return NS_OK; +} + +nsresult CheckValidUNICODE(STGMEDIUM* pSTG) { + if (pSTG->tymed != TYMED_HGLOBAL) { + fail("Received data is not in an HGLOBAL"); + return NS_ERROR_UNEXPECTED; + } + + HGLOBAL hGlobal = pSTG->hGlobal; + char16_t* pText; + pText = (char16_t*)GlobalLock(hGlobal); + if (!pText) { + fail("There is no data at the given HGLOBAL"); + return NS_ERROR_UNEXPECTED; + } + + nsString string; + string = pText; + + if (!string.EqualsLiteral("Mozilla can drag and drop")) { + fail("Text passed through drop object wrong"); + return NS_ERROR_UNEXPECTED; + } + return NS_OK; +} + +nsresult CheckValidUNICODETwo(STGMEDIUM* pSTG) { + if (pSTG->tymed != TYMED_HGLOBAL) { + fail("Received data is not in an HGLOBAL"); + return NS_ERROR_UNEXPECTED; + } + + HGLOBAL hGlobal = pSTG->hGlobal; + char16_t* pText; + pText = (char16_t*)GlobalLock(hGlobal); + if (!pText) { + fail("There is no data at the given HGLOBAL"); + return NS_ERROR_UNEXPECTED; + } + + nsString string; + string = pText; + + if (!string.EqualsLiteral("Mozilla can drag and drop twice over")) { + fail("Text passed through drop object wrong"); + return NS_ERROR_UNEXPECTED; + } + return NS_OK; +} + +nsresult GetTransferableFile(nsCOMPtr<nsITransferable>& pTransferable) { + nsresult rv; + + nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferFile); + + pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1"); + pTransferable->Init(nullptr); + rv = pTransferable->SetTransferData("application/x-moz-file", genericWrapper, + 0); + return rv; +} + +nsresult GetTransferableText(nsCOMPtr<nsITransferable>& pTransferable) { + nsresult rv; + constexpr auto mozString = u"Mozilla can drag and drop"_ns; + nsCOMPtr<nsISupportsString> xferString = + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); + rv = xferString->SetData(mozString); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferString); + + pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1"); + pTransferable->Init(nullptr); + rv = pTransferable->SetTransferData("text/unicode", genericWrapper, + mozString.Length() * sizeof(char16_t)); + return rv; +} + +nsresult GetTransferableTextTwo(nsCOMPtr<nsITransferable>& pTransferable) { + nsresult rv; + constexpr auto mozString = u" twice over"_ns; + nsCOMPtr<nsISupportsString> xferString = + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); + rv = xferString->SetData(mozString); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferString); + + pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1"); + pTransferable->Init(nullptr); + rv = pTransferable->SetTransferData("text/unicode", genericWrapper, + mozString.Length() * sizeof(char16_t)); + return rv; +} + +nsresult GetTransferableURI(nsCOMPtr<nsITransferable>& pTransferable) { + nsresult rv; + + nsCOMPtr<nsIURI> xferURI; + + rv = NS_NewURI(getter_AddRefs(xferURI), "http://www.mozilla.org"); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferURI); + + pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1"); + pTransferable->Init(nullptr); + rv = pTransferable->SetTransferData("text/x-moz-url", genericWrapper, 0); + return rv; +} + +nsresult MakeDataObject(nsIArray* transferableArray, + RefPtr<IDataObject>& itemToDrag) { + nsresult rv; + uint32_t itemCount = 0; + + nsCOMPtr<nsIURI> uri; + rv = NS_NewURI(getter_AddRefs(uri), "http://www.mozilla.org"); + NS_ENSURE_SUCCESS(rv, rv); + + rv = transferableArray->GetLength(&itemCount); + NS_ENSURE_SUCCESS(rv, rv); + + // Copied more or less exactly from nsDragService::InvokeDragSession + // This is what lets us play fake Drag Service for the test + if (itemCount > 1) { + nsDataObjCollection* dataObjCollection = new nsDataObjCollection(); + if (!dataObjCollection) return NS_ERROR_OUT_OF_MEMORY; + itemToDrag = dataObjCollection; + for (uint32_t i = 0; i < itemCount; ++i) { + nsCOMPtr<nsITransferable> trans = do_QueryElementAt(transferableArray, i); + if (trans) { + RefPtr<IDataObject> dataObj; + rv = nsClipboard::CreateNativeDataObject(trans, getter_AddRefs(dataObj), + uri); + NS_ENSURE_SUCCESS(rv, rv); + // Add the flavors to the collection object too + rv = nsClipboard::SetupNativeDataObject(trans, dataObjCollection); + NS_ENSURE_SUCCESS(rv, rv); + + dataObjCollection->AddDataObject(dataObj); + } + } + } // if dragging multiple items + else { + nsCOMPtr<nsITransferable> trans = do_QueryElementAt(transferableArray, 0); + if (trans) { + rv = nsClipboard::CreateNativeDataObject(trans, + getter_AddRefs(itemToDrag), uri); + NS_ENSURE_SUCCESS(rv, rv); + } + } // else dragging a single object + return rv; +} + +nsresult Do_CheckOneFile() { + nsresult rv; + nsCOMPtr<nsITransferable> transferable; + nsCOMPtr<nsIMutableArray> transferableArray = nsArray::Create(); + nsCOMPtr<nsISupports> genericWrapper; + RefPtr<IDataObject> dataObj; + + rv = GetTransferableFile(transferable); + if (NS_FAILED(rv)) { + fail("Could not create the proper nsITransferable!"); + return rv; + } + genericWrapper = do_QueryInterface(transferable); + rv = transferableArray->AppendElement(genericWrapper); + if (NS_FAILED(rv)) { + fail("Could not append element to transferable array"); + return rv; + } + + rv = MakeDataObject(transferableArray, dataObj); + if (NS_FAILED(rv)) { + fail("Could not create data object"); + return rv; + } + + FORMATETC fe; + SET_FORMATETC(fe, CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); + if (dataObj->QueryGetData(&fe) != S_OK) { + fail("File data object does not support the file data type!"); + return NS_ERROR_UNEXPECTED; + } + + STGMEDIUM* stg; + stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM)); + if (dataObj->GetData(&fe, stg) != S_OK) { + fail("File data object did not provide data on request"); + return NS_ERROR_UNEXPECTED; + } + + rv = CheckValidHDROP(stg); + if (NS_FAILED(rv)) { + fail("HDROP was invalid"); + return rv; + } + + ReleaseStgMedium(stg); + + return NS_OK; +} + +nsresult Do_CheckTwoFiles() { + nsresult rv; + nsCOMPtr<nsITransferable> transferable; + nsCOMPtr<nsIMutableArray> transferableArray = nsArray::Create(); + nsCOMPtr<nsISupports> genericWrapper; + RefPtr<IDataObject> dataObj; + + rv = GetTransferableFile(transferable); + if (NS_FAILED(rv)) { + fail("Could not create the proper nsITransferable!"); + return rv; + } + genericWrapper = do_QueryInterface(transferable); + rv = transferableArray->AppendElement(genericWrapper); + if (NS_FAILED(rv)) { + fail("Could not append element to transferable array"); + return rv; + } + + rv = GetTransferableFile(transferable); + if (NS_FAILED(rv)) { + fail("Could not create the proper nsITransferable!"); + return rv; + } + genericWrapper = do_QueryInterface(transferable); + rv = transferableArray->AppendElement(genericWrapper); + if (NS_FAILED(rv)) { + fail("Could not append element to transferable array"); + return rv; + } + + rv = MakeDataObject(transferableArray, dataObj); + if (NS_FAILED(rv)) { + fail("Could not create data object"); + return rv; + } + + FORMATETC fe; + SET_FORMATETC(fe, CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); + if (dataObj->QueryGetData(&fe) != S_OK) { + fail("File data object does not support the file data type!"); + return NS_ERROR_UNEXPECTED; + } + + STGMEDIUM* stg; + stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM)); + if (dataObj->GetData(&fe, stg) != S_OK) { + fail("File data object did not provide data on request"); + return NS_ERROR_UNEXPECTED; + } + + rv = CheckValidHDROP(stg); + if (NS_FAILED(rv)) { + fail("HDROP was invalid"); + return rv; + } + + ReleaseStgMedium(stg); + + return NS_OK; +} + +nsresult Do_CheckOneString() { + nsresult rv; + nsCOMPtr<nsITransferable> transferable; + nsCOMPtr<nsIMutableArray> transferableArray = nsArray::Create(); + nsCOMPtr<nsISupports> genericWrapper; + RefPtr<IDataObject> dataObj; + + rv = GetTransferableText(transferable); + if (NS_FAILED(rv)) { + fail("Could not create the proper nsITransferable!"); + return rv; + } + genericWrapper = do_QueryInterface(transferable); + rv = transferableArray->AppendElement(genericWrapper); + if (NS_FAILED(rv)) { + fail("Could not append element to transferable array"); + return rv; + } + + rv = MakeDataObject(transferableArray, dataObj); + if (NS_FAILED(rv)) { + fail("Could not create data object"); + return rv; + } + + FORMATETC fe; + SET_FORMATETC(fe, CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); + if (dataObj->QueryGetData(&fe) != S_OK) { + fail("String data object does not support the ASCII text data type!"); + return NS_ERROR_UNEXPECTED; + } + + STGMEDIUM* stg; + stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM)); + if (dataObj->GetData(&fe, stg) != S_OK) { + fail("String data object did not provide ASCII data on request"); + return NS_ERROR_UNEXPECTED; + } + + rv = CheckValidTEXT(stg); + if (NS_FAILED(rv)) { + fail("TEXT was invalid"); + return rv; + } + + ReleaseStgMedium(stg); + + SET_FORMATETC(fe, CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); + if (dataObj->QueryGetData(&fe) != S_OK) { + fail("String data object does not support the wide text data type!"); + return NS_ERROR_UNEXPECTED; + } + + if (dataObj->GetData(&fe, stg) != S_OK) { + fail("String data object did not provide wide data on request"); + return NS_ERROR_UNEXPECTED; + } + + rv = CheckValidUNICODE(stg); + if (NS_FAILED(rv)) { + fail("UNICODE was invalid"); + return rv; + } + + return NS_OK; +} + +nsresult Do_CheckTwoStrings() { + nsresult rv; + nsCOMPtr<nsITransferable> transferable; + nsCOMPtr<nsIMutableArray> transferableArray = nsArray::Create(); + nsCOMPtr<nsISupports> genericWrapper; + RefPtr<IDataObject> dataObj; + + rv = GetTransferableText(transferable); + if (NS_FAILED(rv)) { + fail("Could not create the proper nsITransferable!"); + return rv; + } + genericWrapper = do_QueryInterface(transferable); + rv = transferableArray->AppendElement(genericWrapper); + if (NS_FAILED(rv)) { + fail("Could not append element to transferable array"); + return rv; + } + + rv = GetTransferableTextTwo(transferable); + if (NS_FAILED(rv)) { + fail("Could not create the proper nsITransferable!"); + return rv; + } + genericWrapper = do_QueryInterface(transferable); + rv = transferableArray->AppendElement(genericWrapper); + if (NS_FAILED(rv)) { + fail("Could not append element to transferable array"); + return rv; + } + + rv = MakeDataObject(transferableArray, dataObj); + if (NS_FAILED(rv)) { + fail("Could not create data object"); + return rv; + } + + FORMATETC fe; + SET_FORMATETC(fe, CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); + if (dataObj->QueryGetData(&fe) != S_OK) { + fail("String data object does not support the ASCII text data type!"); + return NS_ERROR_UNEXPECTED; + } + + STGMEDIUM* stg; + stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM)); + if (dataObj->GetData(&fe, stg) != S_OK) { + fail("String data object did not provide ASCII data on request"); + return NS_ERROR_UNEXPECTED; + } + + rv = CheckValidTEXTTwo(stg); + if (NS_FAILED(rv)) { + fail("TEXT was invalid"); + return rv; + } + + ReleaseStgMedium(stg); + + SET_FORMATETC(fe, CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); + if (dataObj->QueryGetData(&fe) != S_OK) { + fail("String data object does not support the wide text data type!"); + return NS_ERROR_UNEXPECTED; + } + + if (dataObj->GetData(&fe, stg) != S_OK) { + fail("String data object did not provide wide data on request"); + return NS_ERROR_UNEXPECTED; + } + + rv = CheckValidUNICODETwo(stg); + if (NS_FAILED(rv)) { + fail("UNICODE was invalid"); + return rv; + } + + return NS_OK; +} + +nsresult Do_CheckSetArbitraryData(bool aMultiple) { + nsresult rv; + nsCOMPtr<nsITransferable> transferable; + nsCOMPtr<nsIMutableArray> transferableArray = nsArray::Create(); + nsCOMPtr<nsISupports> genericWrapper; + RefPtr<IDataObject> dataObj; + + rv = GetTransferableText(transferable); + if (NS_FAILED(rv)) { + fail("Could not create the proper nsITransferable!"); + return rv; + } + genericWrapper = do_QueryInterface(transferable); + rv = transferableArray->AppendElement(genericWrapper); + if (NS_FAILED(rv)) { + fail("Could not append element to transferable array"); + return rv; + } + + if (aMultiple) { + rv = GetTransferableText(transferable); + if (NS_FAILED(rv)) { + fail("Could not create the proper nsITransferable!"); + return rv; + } + genericWrapper = do_QueryInterface(transferable); + rv = transferableArray->AppendElement(genericWrapper); + if (NS_FAILED(rv)) { + fail("Could not append element to transferable array"); + return rv; + } + } + + rv = MakeDataObject(transferableArray, dataObj); + if (NS_FAILED(rv)) { + fail("Could not create data object"); + return rv; + } + + static CLIPFORMAT mozArbitraryFormat = + ::RegisterClipboardFormatW(L"MozillaTestFormat"); + FORMATETC fe; + STGMEDIUM stg; + SET_FORMATETC(fe, mozArbitraryFormat, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); + + HGLOBAL hg = GlobalAlloc(GPTR, 1024); + stg.tymed = TYMED_HGLOBAL; + stg.hGlobal = hg; + stg.pUnkForRelease = nullptr; + + if (dataObj->SetData(&fe, &stg, true) != S_OK) { + if (aMultiple) { + fail("Unable to set arbitrary data type on data object collection!"); + } else { + fail("Unable to set arbitrary data type on data object!"); + } + return NS_ERROR_UNEXPECTED; + } + + if (dataObj->QueryGetData(&fe) != S_OK) { + fail("Arbitrary data set on data object is not advertised!"); + return NS_ERROR_UNEXPECTED; + } + + STGMEDIUM* stg2; + stg2 = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM)); + if (dataObj->GetData(&fe, stg2) != S_OK) { + fail("Data object did not provide arbitrary data upon request!"); + return NS_ERROR_UNEXPECTED; + } + + if (stg2->hGlobal != hg) { + fail("Arbitrary data was not returned properly!"); + return rv; + } + ReleaseStgMedium(stg2); + + return NS_OK; +} + +// This function performs basic drop tests, testing a data object consisting +// of one transferable +nsresult Do_Test1() { + nsresult rv = NS_OK; + nsresult workingrv; + + workingrv = Do_CheckOneFile(); + if (NS_FAILED(workingrv)) { + fail("Drag object tests failed on a single file"); + rv = NS_ERROR_UNEXPECTED; + } else { + passed("Successfully created a working file drag object!"); + } + + workingrv = Do_CheckOneString(); + if (NS_FAILED(workingrv)) { + fail("Drag object tests failed on a single string"); + rv = NS_ERROR_UNEXPECTED; + } else { + passed("Successfully created a working string drag object!"); + } + + workingrv = Do_CheckSetArbitraryData(false); + if (NS_FAILED(workingrv)) { + fail("Drag object tests failed on setting arbitrary data"); + rv = NS_ERROR_UNEXPECTED; + } else { + passed("Successfully set arbitrary data on a drag object"); + } + + return rv; +} + +// This function performs basic drop tests, testing a data object consisting of +// two transferables. +nsresult Do_Test2() { + nsresult rv = NS_OK; + nsresult workingrv; + + workingrv = Do_CheckTwoFiles(); + if (NS_FAILED(workingrv)) { + fail("Drag object tests failed on multiple files"); + rv = NS_ERROR_UNEXPECTED; + } else { + passed("Successfully created a working multiple file drag object!"); + } + + workingrv = Do_CheckTwoStrings(); + if (NS_FAILED(workingrv)) { + fail("Drag object tests failed on multiple strings"); + rv = NS_ERROR_UNEXPECTED; + } else { + passed("Successfully created a working multiple string drag object!"); + } + + workingrv = Do_CheckSetArbitraryData(true); + if (NS_FAILED(workingrv)) { + fail("Drag object tests failed on setting arbitrary data"); + rv = NS_ERROR_UNEXPECTED; + } else { + passed("Successfully set arbitrary data on a drag object"); + } + + return rv; +} + +// This function performs advanced drag and drop tests, testing a data object +// consisting of multiple transferables that have different data types +nsresult Do_Test3() { + nsresult rv = NS_OK; + nsresult workingrv; + + // XXX TODO Write more advanced tests in Bug 535860 + return rv; +} + +int main(int argc, char** argv) { + ScopedXPCOM xpcom("Test Windows Drag and Drop"); + + nsCOMPtr<nsIFile> file; + file = xpcom.GetProfileDirectory(); + xferFile = file; + + if (NS_SUCCEEDED(Do_Test1())) + passed( + "Basic Drag and Drop data type tests (single transferable) succeeded!"); + + if (NS_SUCCEEDED(Do_Test2())) + passed( + "Basic Drag and Drop data type tests (multiple transferables) " + "succeeded!"); + + // if (NS_SUCCEEDED(Do_Test3())) + // passed("Advanced Drag and Drop data type tests succeeded!"); + + return gFailCount; +} diff --git a/widget/windows/tests/moz.build b/widget/windows/tests/moz.build new file mode 100644 index 0000000000..8d6c88c5e2 --- /dev/null +++ b/widget/windows/tests/moz.build @@ -0,0 +1,28 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +GeckoCppUnitTests( + [ + "TestUriValidation", + ], + linkage=None, +) + +LOCAL_INCLUDES += [] + +OS_LIBS += [ + "oleaut32", + "ole32", + "shell32", + "shlwapi", + "urlmon", +] + +if CONFIG["OS_TARGET"] == "WINNT" and CONFIG["CC_TYPE"] in ("gcc", "clang"): + # This allows us to use wmain as the entry point on mingw + LDFLAGS += [ + "-municode", + ] |