blob: 2a80007f2fb13c346ec889bdb40fd6ff0e21731a [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <windows.h>
#include <string>
#include "base/functional/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "content/browser/sandbox_support_impl.h"
#include "content/common/sandbox_support.mojom.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/system/functions.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
using LcTypeString = mojom::SandboxSupport::LcTypeString;
using LcTypeStrings = mojom::SandboxSupport::LcTypeStrings;
namespace {
inline constexpr uint32_t kSunday = 0;
// LCIDs - See https://msdn.microsoft.com/en-us/goglobal/bb964664.aspx
inline constexpr uint32_t kEnglishUS = 0x409; // en-us
inline constexpr uint32_t kSpanishMexico = 0x080A; // es-MX
inline constexpr uint32_t kKoreanKorea = 0x0412; // ko-KR
// Test that the mojo interface calls the expected Windows APIs.
class SandboxSupportWinUnitTest : public testing::Test {
public:
SandboxSupportWinUnitTest() {
features_.InitFromCommandLine("WinSboxProxyLocale", "");
impl_.BindReceiver(sandbox_support_.BindNewPipeAndPassReceiver());
}
void SetUp() override {
mojo::SetDefaultProcessErrorHandler(base::BindRepeating(
&SandboxSupportWinUnitTest::OnProcessError, base::Unretained(this)));
}
content::mojom::SandboxSupport& sandbox_support() {
return *sandbox_support_;
}
bool had_error() { return had_error_; }
void OnProcessError(const std::string& error) { had_error_ = true; }
bool had_error_ = false;
base::test::ScopedFeatureList features_;
base::test::TaskEnvironment task_environment_;
mojo::Remote<content::mojom::SandboxSupport> sandbox_support_;
SandboxSupportImpl impl_;
};
} // namespace
TEST_F(SandboxSupportWinUnitTest, BasicEnUs) {
uint32_t lcid;
uint32_t first_day;
EXPECT_TRUE(sandbox_support().LcidAndFirstDayOfWeek(u"en-us", u"en-us", true,
&lcid, &first_day));
EXPECT_EQ(first_day, kSunday);
// This depends on the system configuration.
EXPECT_TRUE(lcid == LOCALE_USER_DEFAULT || lcid == kEnglishUS);
uint32_t digit_sub;
std::u16string digits;
std::u16string decimal;
std::u16string thousand;
std::u16string negative_sign;
uint32_t negnumber;
EXPECT_TRUE(sandbox_support().DigitsAndSigns(lcid, true, &digit_sub, &digits,
&decimal, &thousand,
&negative_sign, &negnumber));
EXPECT_EQ(digit_sub, 1u);
EXPECT_TRUE(digits.empty());
EXPECT_EQ(decimal, u".");
EXPECT_EQ(thousand, u",");
EXPECT_EQ(negative_sign, u"-");
EXPECT_EQ(negnumber, 1u);
std::u16string tmp_string;
EXPECT_TRUE(sandbox_support().LocaleString(
lcid, true, LcTypeString::kYearMonth, &tmp_string));
EXPECT_EQ(tmp_string, u"MMMM yyyy");
std::vector<std::u16string> tmp_strings;
EXPECT_TRUE(sandbox_support().LocaleStrings(lcid, true, LcTypeStrings::kAmPm,
&tmp_strings));
EXPECT_EQ(tmp_strings.size(), 2u);
EXPECT_EQ(tmp_strings.at(1), u"PM");
}
TEST_F(SandboxSupportWinUnitTest, Locales) {
uint32_t lcid;
uint32_t first_day;
EXPECT_TRUE(sandbox_support().LcidAndFirstDayOfWeek(u"es-MX", u"es-MX", true,
&lcid, &first_day));
EXPECT_EQ(lcid, kSpanishMexico);
EXPECT_EQ(first_day, kSunday);
EXPECT_TRUE(sandbox_support().LcidAndFirstDayOfWeek(u"ko-KR", u"ko-KR", true,
&lcid, &first_day));
EXPECT_EQ(lcid, kKoreanKorea);
EXPECT_EQ(first_day, kSunday);
}
TEST_F(SandboxSupportWinUnitTest, NonDefault) {
// Chrome actually calls these with `force_defaults=false`. We cannot test
// return values as the test machine may have custom locales or settings.
uint32_t lcid;
uint32_t first_day;
EXPECT_TRUE(sandbox_support().LcidAndFirstDayOfWeek(u"en-us", u"en-us", false,
&lcid, &first_day));
EXPECT_TRUE(lcid == LOCALE_USER_DEFAULT || lcid == kEnglishUS);
uint32_t digit_sub;
std::u16string digits;
std::u16string decimal;
std::u16string thousand;
std::u16string negative_sign;
uint32_t negnumber;
EXPECT_TRUE(sandbox_support().DigitsAndSigns(lcid, true, &digit_sub, &digits,
&decimal, &thousand,
&negative_sign, &negnumber));
std::u16string tmp_string;
EXPECT_TRUE(sandbox_support().LocaleString(
lcid, true, LcTypeString::kYearMonth, &tmp_string));
EXPECT_EQ(tmp_string, u"MMMM yyyy");
std::vector<std::u16string> tmp_strings;
EXPECT_TRUE(sandbox_support().LocaleStrings(lcid, true, LcTypeStrings::kAmPm,
&tmp_strings));
}
TEST_F(SandboxSupportWinUnitTest, MultiStrings) {
// Collection => expected value of 2nd element. (kAmPm is shortest with two.)
std::vector<std::pair<LcTypeStrings, std::u16string>> expected = {
{LcTypeStrings::kMonths, u"February"},
{LcTypeStrings::kShortMonths, u"Feb"},
{LcTypeStrings::kShortWeekDays, u"Mo"},
{LcTypeStrings::kAmPm, u"PM"}};
uint32_t lcid;
uint32_t first_day;
EXPECT_TRUE(sandbox_support().LcidAndFirstDayOfWeek(u"en-us", u"en-us", false,
&lcid, &first_day));
EXPECT_TRUE(lcid == LOCALE_USER_DEFAULT || lcid == kEnglishUS);
for (const auto& val : expected) {
std::vector<std::u16string> tmp_strings;
EXPECT_TRUE(
sandbox_support().LocaleStrings(lcid, true, val.first, &tmp_strings));
EXPECT_EQ(val.second, tmp_strings.at(1));
}
}
TEST_F(SandboxSupportWinUnitTest, Strings) {
// Collection => expected value of item.
std::vector<std::pair<LcTypeString, std::u16string>> expected = {
{LcTypeString::kShortDate, u"M/d/yyyy"},
{LcTypeString::kYearMonth, u"MMMM yyyy"},
{LcTypeString::kTimeFormat, u"h:mm:ss tt"},
{LcTypeString::kShortTime, u"h:mm tt"}};
uint32_t lcid;
uint32_t first_day;
EXPECT_TRUE(sandbox_support().LcidAndFirstDayOfWeek(u"en-us", u"en-us", false,
&lcid, &first_day));
EXPECT_TRUE(lcid == LOCALE_USER_DEFAULT || lcid == kEnglishUS);
for (const auto& val : expected) {
std::u16string tmp_string;
EXPECT_TRUE(
sandbox_support().LocaleString(lcid, true, val.first, &tmp_string));
EXPECT_EQ(val.second, tmp_string);
}
}
TEST_F(SandboxSupportWinUnitTest, LimitsLanguage) {
uint32_t lcid;
uint32_t first_day;
// https://learn.microsoft.com/en-us/windows/win32/intl/locale-name-constants
// LOCALE_NAME_MAX_LENGTH at time of writing was 85.
static_assert(LOCALE_NAME_MAX_LENGTH <= 85);
EXPECT_FALSE(sandbox_support().LcidAndFirstDayOfWeek(
u"0123456789012345678901234567890123456789"
u"0123456789012345678901234567890123456789tooooooooolong-"
u"toolongtoolong",
u"en-us", false, &lcid, &first_day));
EXPECT_TRUE(had_error());
}
TEST_F(SandboxSupportWinUnitTest, LimitsDefaultLanguage) {
uint32_t lcid;
uint32_t first_day;
// https://learn.microsoft.com/en-us/windows/win32/intl/locale-name-constants
// LOCALE_NAME_MAX_LENGTH at time of writing was 85.
static_assert(LOCALE_NAME_MAX_LENGTH <= 85);
EXPECT_FALSE(sandbox_support().LcidAndFirstDayOfWeek(
u"en-us",
u"0123456789012345678901234567890123456789"
u"0123456789012345678901234567890123456789tooooooooolong-"
u"toolongtoolong",
false, &lcid, &first_day));
EXPECT_TRUE(had_error());
}
} // namespace content