diff options
Diffstat (limited to '')
-rw-r--r-- | toolkit/library/gtest/TestUCRTDepends.cpp | 142 | ||||
-rw-r--r-- | toolkit/library/gtest/moz.build | 26 | ||||
-rw-r--r-- | toolkit/library/gtest/rust/Cargo.toml | 34 | ||||
-rw-r--r-- | toolkit/library/gtest/rust/lib.rs | 16 | ||||
-rw-r--r-- | toolkit/library/gtest/rust/moz.build | 16 |
5 files changed, 234 insertions, 0 deletions
diff --git a/toolkit/library/gtest/TestUCRTDepends.cpp b/toolkit/library/gtest/TestUCRTDepends.cpp new file mode 100644 index 0000000000..a2faaf5ce3 --- /dev/null +++ b/toolkit/library/gtest/TestUCRTDepends.cpp @@ -0,0 +1,142 @@ +/* -*- 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 http://mozilla.org/MPL/2.0/. */ + +#include <windows.h> +#include <stdio.h> +#include <string.h> +#include "gtest/gtest.h" +#include "mozilla/ArrayUtils.h" +#include "mozilla/Unused.h" +#include "mozilla/WindowsVersion.h" +#include "nsDependentString.h" +#include "nsReadableUtils.h" +#include "nsUnicharUtils.h" +#include "nsWindowsHelpers.h" + +using namespace mozilla; + +constexpr const WCHAR pattern[] = L"\\api-*.dll"; + +static LPWSTR GetModuleFileDir(HMODULE module, LPWSTR path, DWORD size) { + DWORD chars = GetModuleFileNameW(module, path, size); + if (chars <= 0 || chars >= MAX_PATH) { + return nullptr; + } + + // Split the base name from the directory. + LPWSTR basename = wcsrchr(path, L'\\'); + if (!basename) { + return nullptr; // at least one path separator must be present + } + *basename++ = L'\0'; + return basename; +} + +// Make sure that Universal CRT forwarder DLLs are not in app directory if it +// is in Api Sets. +TEST(TestUCRTDepends, AppDir) +{ + WCHAR appdir[MAX_PATH]; + ASSERT_TRUE(GetModuleFileDir(nullptr, appdir, MAX_PATH)); + + WCHAR path[MAX_PATH + ArrayLength(pattern)]; + swprintf(path, L"%s%s", appdir, pattern); + + WIN32_FIND_DATAW wfd; + HANDLE hFind = FindFirstFileW(path, &wfd); +#if defined(_M_ARM64) // We do not ship Universal CRT DLLs on aarch64. + if (hFind == INVALID_HANDLE_VALUE) { + EXPECT_EQ(GetLastError(), static_cast<DWORD>(ERROR_FILE_NOT_FOUND)); + return; + } +#else + ASSERT_NE(hFind, INVALID_HANDLE_VALUE); +#endif + do { + nsModuleHandle module(LoadLibraryW(wfd.cFileName)); + EXPECT_TRUE(module); + if (!module) { + continue; + } + + // Get a full path of the loaded module. + LPWSTR basename = GetModuleFileDir(module, path, MAX_PATH); + ASSERT_TRUE(basename); + + // If the module is in Api Sets, GetModuleFileName returns the redirected + // DLL path, so filenames will not match. + bool inApiSets = wcsicmp(wfd.cFileName, basename); + if (IsWin10OrLater()) { + // All files must be in Api Sets on Windows 10. + EXPECT_TRUE(inApiSets); + continue; + } + if (IsWin8OrLater()) { + if (inApiSets) { + continue; // This file is in Api Sets, OK. + } + // Universal CRT files are not in Api Sets on Windows 8. + EXPECT_TRUE(StringBeginsWith(nsDependentString(wfd.cFileName), + u"api-ms-win-crt-"_ns, + nsCaseInsensitiveStringComparator)); + } else { // Windows 7 + // All files must not be in Api Sets on Windows 7. + EXPECT_FALSE(inApiSets); + } + // Files must be loaded from appdir + EXPECT_TRUE(!wcsicmp(path, appdir)); + } while (FindNextFileW(hFind, &wfd)); + EXPECT_EQ(GetLastError(), static_cast<DWORD>(ERROR_NO_MORE_FILES)); + BOOL ret = FindClose(hFind); + EXPECT_TRUE(ret); +} + +// Make sure that we do not depend on Universal CRT forwarder DLLs in the +// system directory. +TEST(TestUCRTDepends, SystemDir) +{ + WCHAR appdir[MAX_PATH]; + ASSERT_TRUE(GetModuleFileDir(nullptr, appdir, MAX_PATH)); + + WCHAR path[MAX_PATH + ArrayLength(pattern)]; + UINT chars = GetSystemDirectoryW(path, MAX_PATH); + ASSERT_TRUE(chars > 0 && chars < MAX_PATH); + wcscat(path, pattern); + + WIN32_FIND_DATAW wfd; + HANDLE hFind = FindFirstFileW(path, &wfd); + if (hFind == INVALID_HANDLE_VALUE) { + EXPECT_EQ(GetLastError(), static_cast<DWORD>(ERROR_FILE_NOT_FOUND)); + EXPECT_TRUE(IsWin8OrLater()); + return; // Not found in the system directory, OK. + } + // Api Sets forwarders must not be present on Windows 10. + EXPECT_FALSE(IsWin10OrLater()); + do { + HMODULE module = GetModuleHandleW(wfd.cFileName); + if (!module) { + continue; // We are not using this file, OK. + } + + // Get a full path of the loaded module. + LPWSTR basename = GetModuleFileDir(module, path, MAX_PATH); + ASSERT_TRUE(basename); + + // If the module is in Api Sets, GetModuleFileName returns the redirected + // DLL path, so filenames will not match. + if (wcsicmp(wfd.cFileName, basename)) { + // If this file is in Api Sets, it must not be present in appdir. + swprintf(path, L"%s\\%s", appdir, wfd.cFileName); + EXPECT_EQ(GetFileAttributesW(path), INVALID_FILE_ATTRIBUTES); + } else { + // If this file is not in Api Sets, it must be loaded from appdir. + EXPECT_TRUE(!wcsicmp(path, appdir)); + } + } while (FindNextFileW(hFind, &wfd)); + EXPECT_EQ(GetLastError(), static_cast<DWORD>(ERROR_NO_MORE_FILES)); + BOOL ret = FindClose(hFind); + EXPECT_TRUE(ret); +} diff --git a/toolkit/library/gtest/moz.build b/toolkit/library/gtest/moz.build new file mode 100644 index 0000000000..1a0f692bc7 --- /dev/null +++ b/toolkit/library/gtest/moz.build @@ -0,0 +1,26 @@ +# -*- 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/. + +FINAL_TARGET = "dist/bin/gtest" + +if CONFIG["ENABLE_TESTS"]: + USE_LIBS += [ + "gkrust-gtest", + ] + + if CONFIG["OS_ARCH"] == "WINNT": + UNIFIED_SOURCES += [ + "TestUCRTDepends.cpp", + ] + +USE_LIBS += [ + "static:xul", +] + +Libxul( + "xul-gtest", + output_category=None if CONFIG["LINK_GTEST_DURING_COMPILE"] else "gtest", +) diff --git a/toolkit/library/gtest/rust/Cargo.toml b/toolkit/library/gtest/rust/Cargo.toml new file mode 100644 index 0000000000..a97956ef7e --- /dev/null +++ b/toolkit/library/gtest/rust/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "gkrust-gtest" +version = "0.1.0" +authors = ["The Mozilla Project Developers"] +license = "MPL-2.0" +description = "Testing code for libgkrust" + +[dependencies] +bench-collections-gtest = { path = "../../../../xpcom/rust/gtest/bench-collections" } +l10nregistry-ffi-gtest = { path = "../../../../intl/l10n/rust/gtest" } +moz_task-gtest = { path = "../../../../xpcom/rust/gtest/moz_task" } +mp4parse-gtest = { path = "../../../../dom/media/gtest" } +nsstring-gtest = { path = "../../../../xpcom/rust/gtest/nsstring" } +xpcom-gtest = { path = "../../../../xpcom/rust/gtest/xpcom" } +gkrust-shared = { path = "../../rust/shared" } +gecko-fuzz-targets = { path = "../../../../tools/fuzzing/rust", optional = true } +fog-gtest = { path = "../../../components/glean/tests/gtest" } +dap_ffi-gtest = { path = "../../../components/telemetry/dap/ffi-gtest" } +dllservices-gtest = { path = "../../../xre/dllservices/tests/gtest/rust" } + +# Workarounds for https://github.com/rust-lang/rust/issues/58393 +mozglue-static = { path = "../../../../mozglue/static/rust" } +swgl = { path = "../../../../gfx/wr/swgl" } +lmdb-rkv-sys = "0.11" + +[lib] +path = "lib.rs" +crate-type = ["staticlib"] +test = false +doctest = false +bench = false +doc = false +plugin = false +harness = false diff --git a/toolkit/library/gtest/rust/lib.rs b/toolkit/library/gtest/rust/lib.rs new file mode 100644 index 0000000000..218353ee2e --- /dev/null +++ b/toolkit/library/gtest/rust/lib.rs @@ -0,0 +1,16 @@ +// 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/. + +extern crate bench_collections_gtest; +extern crate dap_ffi_gtest; +extern crate fog_gtest; +#[cfg(feature = "gecko-fuzz-targets")] +extern crate gecko_fuzz_targets; +extern crate gkrust_shared; +extern crate l10nregistry_ffi_gtest; +extern crate moz_task_gtest; +extern crate mp4parse_gtest; +extern crate nsstring_gtest; +extern crate xpcom_gtest; +extern crate dllservices_gtest; diff --git a/toolkit/library/gtest/rust/moz.build b/toolkit/library/gtest/rust/moz.build new file mode 100644 index 0000000000..8b98fbfda0 --- /dev/null +++ b/toolkit/library/gtest/rust/moz.build @@ -0,0 +1,16 @@ +# -*- Mode: python; c-basic-offset: 4; 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/. + +include("../../rust/gkrust-features.mozbuild") + +if CONFIG["LIBFUZZER"]: + gkrust_features += ["gecko-fuzz-targets"] + +RustLibrary( + "gkrust-gtest", + gkrust_features, + output_category=None if CONFIG["LINK_GTEST_DURING_COMPILE"] else "gtest", +) |