Proxy GetLocaleInfo() & LocaleNameToLCID()
These functions in Windows may result in calls over the CSRSS ALPC and allocations on CSRSS heaps, both of which are closed as part of CSRSS lockdown, so they cannot be called from renderer processes if this sandboxing mode is enabled. This CL adds mojo support functions that proxy these calls, batching together multiple calls from blink::LocaleWin where this makes sense. The mojom calls are `[Sync]`. This is ok as they replace system calls which themselves required a blocking IPC call, and because each call is only needed to initialize cached members of Locale objects, which are also cached by blink. While initially supporting blink, these functions may support other child processes than renderers so live in //content/browser. As the calls to GetLocaleInfo() and LocaleNameToLCID() now happen in the browser process, the mojom interface limits which properties can be requested. Rather than allowing any LCTYPE the strings that can be queried are restricted to those needed by blink. The mojom implementation is guarded by WinSboxProxyLocale and calls are only proxied if this feature is enabled. Bug: 40408399 Change-Id: Ia34f8eff48d2e23e2c9a60825bbabd2ecd48caac Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6108617 Reviewed-by: Rakina Zata Amni <rakina@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Reviewed-by: Xianzhu Wang <wangxianzhu@chromium.org> Commit-Queue: Alex Gough <ajgo@chromium.org> Cr-Commit-Position: refs/heads/main@{#1403046}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
9341f7b5b7
commit
a5a75196ef
content
browser
BUILD.gnbrowser_child_process_host_impl_receiver_bindings.ccchild_process_sandbox_support_win_unittest.cc
renderer_host
sandbox_support_impl.hsandbox_support_win_impl.ccchild
common
renderer
test
utility
third_party/blink
@ -2942,6 +2942,8 @@ source_set("browser") {
|
||||
"renderer_host/legacy_render_widget_host_win.h",
|
||||
"renderer_host/virtual_keyboard_controller_win.cc",
|
||||
"renderer_host/virtual_keyboard_controller_win.h",
|
||||
"sandbox_support_impl.h",
|
||||
"sandbox_support_win_impl.cc",
|
||||
"screenlock_monitor/screenlock_monitor_device_source_win.cc",
|
||||
"speech/tts_win.cc",
|
||||
"speech/tts_win_utils.cc",
|
||||
|
@ -31,6 +31,8 @@
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
#include "content/browser/renderer_host/dwrite_font_proxy_impl_win.h"
|
||||
#include "content/browser/sandbox_support_impl.h"
|
||||
#include "content/common/sandbox_support.mojom.h"
|
||||
#include "content/public/common/font_cache_dispatcher_win.h"
|
||||
#include "content/public/common/font_cache_win.mojom.h"
|
||||
#endif
|
||||
@ -90,7 +92,11 @@ void BrowserChildProcessHostImpl::BindHostReceiver(
|
||||
FontCacheDispatcher::Create(std::move(r));
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto r = receiver.As<mojom::SandboxSupport>()) {
|
||||
static base::NoDestructor<SandboxSupportImpl> sandbox_support;
|
||||
sandbox_support->BindReceiver(std::move(r));
|
||||
return;
|
||||
}
|
||||
if (auto r = receiver.As<blink::mojom::DWriteFontProxy>()) {
|
||||
base::ThreadPool::CreateSequencedTaskRunner(
|
||||
{base::TaskPriority::USER_BLOCKING, base::MayBlock()})
|
||||
|
205
content/browser/child_process_sandbox_support_win_unittest.cc
Normal file
205
content/browser/child_process_sandbox_support_win_unittest.cc
Normal file
@ -0,0 +1,205 @@
|
||||
// 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
|
@ -66,6 +66,8 @@
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
#include "components/services/font_data/font_data_service_impl.h"
|
||||
#include "content/browser/renderer_host/dwrite_font_proxy_impl_win.h"
|
||||
#include "content/browser/sandbox_support_impl.h"
|
||||
#include "content/common/sandbox_support.mojom.h"
|
||||
#include "content/public/common/font_cache_dispatcher_win.h"
|
||||
#include "content/public/common/font_cache_win.mojom.h"
|
||||
#endif
|
||||
@ -379,7 +381,7 @@ void RenderProcessHostImpl::IOThreadHostImpl::BindHostReceiver(
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
|
||||
if (auto r = receiver.As<mojom::SandboxSupport>()) {
|
||||
static base::NoDestructor<SandboxSupportImpl> sandbox_support;
|
||||
sandbox_support->BindReceiver(std::move(r));
|
||||
|
@ -5,6 +5,8 @@
|
||||
#ifndef CONTENT_BROWSER_SANDBOX_SUPPORT_IMPL_H_
|
||||
#define CONTENT_BROWSER_SANDBOX_SUPPORT_IMPL_H_
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "content/common/content_export.h"
|
||||
#include "content/common/sandbox_support.mojom.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/receiver_set.h"
|
||||
@ -16,7 +18,7 @@ namespace content {
|
||||
// renderer. However all child process types have access to this interface.
|
||||
// This class lives on the IO thread and is owned by the Mojo interface
|
||||
// registry.
|
||||
class SandboxSupportImpl : public mojom::SandboxSupport {
|
||||
class CONTENT_EXPORT SandboxSupportImpl : public mojom::SandboxSupport {
|
||||
public:
|
||||
SandboxSupportImpl();
|
||||
|
||||
@ -28,7 +30,27 @@ class SandboxSupportImpl : public mojom::SandboxSupport {
|
||||
void BindReceiver(mojo::PendingReceiver<mojom::SandboxSupport> receiver);
|
||||
|
||||
// content::mojom::SandboxSupport:
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
void GetSystemColors(GetSystemColorsCallback callback) override;
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
void LcidAndFirstDayOfWeek(const std::u16string& locale,
|
||||
const std::u16string& default_language,
|
||||
bool force_defaults,
|
||||
LcidAndFirstDayOfWeekCallback callback) override;
|
||||
void DigitsAndSigns(uint32_t lcid,
|
||||
bool force_defaults,
|
||||
DigitsAndSignsCallback callback) override;
|
||||
void LocaleStrings(uint32_t lcid,
|
||||
bool force_defaults,
|
||||
LcTypeStrings collection,
|
||||
LocaleStringsCallback callback) override;
|
||||
void LocaleString(uint32_t lcid,
|
||||
bool force_defaults,
|
||||
LcTypeString type,
|
||||
LocaleStringCallback callback) override;
|
||||
#endif // BUILDFLAG(IS_WIN)
|
||||
|
||||
private:
|
||||
mojo::ReceiverSet<mojom::SandboxSupport> receivers_;
|
||||
|
219
content/browser/sandbox_support_win_impl.cc
Normal file
219
content/browser/sandbox_support_win_impl.cc
Normal file
@ -0,0 +1,219 @@
|
||||
// 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 <string_view>
|
||||
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/string_util_win.h"
|
||||
#include "content/browser/sandbox_support_impl.h"
|
||||
|
||||
namespace content {
|
||||
namespace {
|
||||
LCID CallLocaleNameToLCID(std::u16string_view locale) {
|
||||
CHECK(locale.size() < LOCALE_NAME_MAX_LENGTH);
|
||||
return ::LocaleNameToLCID(base::as_wcstr(locale), 0);
|
||||
}
|
||||
|
||||
std::u16string GetLocaleInfoString(LCID lcid,
|
||||
LCTYPE type,
|
||||
bool force_defaults) {
|
||||
if (force_defaults) {
|
||||
type = type | LOCALE_NOUSEROVERRIDE;
|
||||
}
|
||||
int size_with_nul = ::GetLocaleInfo(lcid, type, 0, 0);
|
||||
if (size_with_nul <= 0) {
|
||||
return std::u16string();
|
||||
}
|
||||
std::u16string buffer;
|
||||
// basic_string guarantees that `buffer` can be indexed from
|
||||
// [0, size], with the requirement that buffer[size] is only set
|
||||
// to NUL.
|
||||
buffer.resize(size_with_nul - 1);
|
||||
::GetLocaleInfo(lcid, type, base::as_writable_wcstr(buffer.data()),
|
||||
size_with_nul);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
std::vector<std::u16string> GetLocaleInfoStrings(LCID lcid,
|
||||
base::span<const LCTYPE> types,
|
||||
bool force_defaults,
|
||||
bool allow_empty) {
|
||||
std::vector<std::u16string> strings;
|
||||
for (const auto& type : types) {
|
||||
auto str = GetLocaleInfoString(lcid, type, force_defaults);
|
||||
if (str.empty() && !allow_empty) {
|
||||
return {};
|
||||
}
|
||||
strings.push_back(std::move(str));
|
||||
}
|
||||
return strings;
|
||||
}
|
||||
|
||||
std::optional<DWORD> GetLocaleInfoDWORD(LCID lcid,
|
||||
LCTYPE type,
|
||||
bool force_defaults) {
|
||||
DWORD result = 0;
|
||||
if (force_defaults) {
|
||||
type = type | LOCALE_NOUSEROVERRIDE;
|
||||
}
|
||||
if (::GetLocaleInfo(lcid, type | LOCALE_RETURN_NUMBER,
|
||||
reinterpret_cast<LPWSTR>(&result),
|
||||
sizeof(DWORD) / sizeof(TCHAR)) > 0) {
|
||||
return result;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::u16string_view LanguageCode(const std::u16string_view locale) {
|
||||
size_t dash_pos = locale.find('-');
|
||||
if (dash_pos == std::u16string::npos) {
|
||||
return locale;
|
||||
}
|
||||
return locale.substr(0, dash_pos);
|
||||
}
|
||||
|
||||
LCID LCIDFromLocale(const std::u16string& locale, bool force_defaults) {
|
||||
auto default_language_code = GetLocaleInfoString(
|
||||
LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, force_defaults);
|
||||
auto locale_language_code = LanguageCode(locale);
|
||||
if (base::EqualsCaseInsensitiveASCII(locale_language_code,
|
||||
default_language_code)) {
|
||||
return LOCALE_USER_DEFAULT;
|
||||
}
|
||||
return CallLocaleNameToLCID(locale);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
SandboxSupportImpl::SandboxSupportImpl() = default;
|
||||
SandboxSupportImpl::~SandboxSupportImpl() = default;
|
||||
|
||||
void SandboxSupportImpl::BindReceiver(
|
||||
mojo::PendingReceiver<mojom::SandboxSupport> receiver) {
|
||||
receivers_.Add(this, std::move(receiver));
|
||||
}
|
||||
|
||||
void SandboxSupportImpl::LcidAndFirstDayOfWeek(
|
||||
const std::u16string& locale,
|
||||
const std::u16string& default_language,
|
||||
bool force_defaults,
|
||||
LcidAndFirstDayOfWeekCallback callback) {
|
||||
if (locale.size() > LOCALE_NAME_MAX_LENGTH ||
|
||||
default_language.size() > LOCALE_NAME_MAX_LENGTH) {
|
||||
receivers_.ReportBadMessage("Locale larger than LOCALE_NAME_MAX_LENGTH.");
|
||||
return;
|
||||
}
|
||||
LCID lcid = LCIDFromLocale(locale, force_defaults);
|
||||
if (!lcid) {
|
||||
lcid = LCIDFromLocale(default_language, force_defaults);
|
||||
}
|
||||
auto first_day =
|
||||
GetLocaleInfoDWORD(lcid, LOCALE_IFIRSTDAYOFWEEK, force_defaults);
|
||||
int first_day_of_week = ((first_day.has_value() ? *first_day : 0) + 1) % 7;
|
||||
std::move(callback).Run(lcid, first_day_of_week);
|
||||
}
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/intl/locale-idigitsubstitution
|
||||
constexpr inline DWORD kDigitSubstitution0to9 = 1;
|
||||
// https://learn.microsoft.com/en-us/windows/win32/intl/locale-ineg-constants
|
||||
constexpr inline DWORD kNegNumberSignPrefix = 1;
|
||||
|
||||
void SandboxSupportImpl::DigitsAndSigns(uint32_t lcid,
|
||||
bool force_defaults,
|
||||
DigitsAndSignsCallback callback) {
|
||||
DWORD digit_substitution =
|
||||
GetLocaleInfoDWORD(lcid, LOCALE_IDIGITSUBSTITUTION, force_defaults)
|
||||
.value_or(kDigitSubstitution0to9);
|
||||
std::u16string digits;
|
||||
if (digit_substitution != kDigitSubstitution0to9) {
|
||||
digits = GetLocaleInfoString(lcid, LOCALE_SNATIVEDIGITS, force_defaults);
|
||||
}
|
||||
auto decimal = GetLocaleInfoString(lcid, LOCALE_SDECIMAL, force_defaults);
|
||||
auto thousand = GetLocaleInfoString(lcid, LOCALE_STHOUSAND, force_defaults);
|
||||
auto negative_sign =
|
||||
GetLocaleInfoString(lcid, LOCALE_SNEGATIVESIGN, force_defaults);
|
||||
DWORD negnumber = GetLocaleInfoDWORD(lcid, LOCALE_INEGNUMBER, force_defaults)
|
||||
.value_or(kNegNumberSignPrefix);
|
||||
std::move(callback).Run(digit_substitution, digits, decimal, thousand,
|
||||
negative_sign, negnumber);
|
||||
}
|
||||
|
||||
void SandboxSupportImpl::LocaleStrings(uint32_t lcid,
|
||||
bool force_defaults,
|
||||
LcTypeStrings collection,
|
||||
LocaleStringsCallback callback) {
|
||||
std::vector<std::u16string> result;
|
||||
switch (collection) {
|
||||
case LcTypeStrings::kMonths: {
|
||||
static constexpr LCTYPE kTypes[12] = {
|
||||
LOCALE_SMONTHNAME1, LOCALE_SMONTHNAME2, LOCALE_SMONTHNAME3,
|
||||
LOCALE_SMONTHNAME4, LOCALE_SMONTHNAME5, LOCALE_SMONTHNAME6,
|
||||
LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME8, LOCALE_SMONTHNAME9,
|
||||
LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME11, LOCALE_SMONTHNAME12,
|
||||
};
|
||||
result = GetLocaleInfoStrings(lcid, kTypes, force_defaults, false);
|
||||
break;
|
||||
}
|
||||
case LcTypeStrings::kShortMonths: {
|
||||
static constexpr LCTYPE kTypes[12] = {
|
||||
LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2,
|
||||
LOCALE_SABBREVMONTHNAME3, LOCALE_SABBREVMONTHNAME4,
|
||||
LOCALE_SABBREVMONTHNAME5, LOCALE_SABBREVMONTHNAME6,
|
||||
LOCALE_SABBREVMONTHNAME7, LOCALE_SABBREVMONTHNAME8,
|
||||
LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10,
|
||||
LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12,
|
||||
};
|
||||
result = GetLocaleInfoStrings(lcid, kTypes, force_defaults, false);
|
||||
break;
|
||||
}
|
||||
case LcTypeStrings::kShortWeekDays: {
|
||||
static constexpr LCTYPE kTypes[7] = {
|
||||
// Numbered 1 (Monday) - 7 (Sunday), so do 7, then 1-6
|
||||
LOCALE_SSHORTESTDAYNAME7, LOCALE_SSHORTESTDAYNAME1,
|
||||
LOCALE_SSHORTESTDAYNAME2, LOCALE_SSHORTESTDAYNAME3,
|
||||
LOCALE_SSHORTESTDAYNAME4, LOCALE_SSHORTESTDAYNAME5,
|
||||
LOCALE_SSHORTESTDAYNAME6};
|
||||
result = GetLocaleInfoStrings(lcid, kTypes, force_defaults, false);
|
||||
break;
|
||||
}
|
||||
case LcTypeStrings::kAmPm: {
|
||||
static constexpr LCTYPE kTypes[2] = {
|
||||
LOCALE_S1159,
|
||||
LOCALE_S2359,
|
||||
};
|
||||
result = GetLocaleInfoStrings(lcid, kTypes, force_defaults, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::move(callback).Run(result);
|
||||
}
|
||||
|
||||
void SandboxSupportImpl::LocaleString(uint32_t lcid,
|
||||
bool force_defaults,
|
||||
LcTypeString type,
|
||||
LocaleStringCallback callback) {
|
||||
LCTYPE lctype;
|
||||
switch (type) {
|
||||
case LcTypeString::kShortDate:
|
||||
lctype = LOCALE_SSHORTDATE;
|
||||
break;
|
||||
case LcTypeString::kYearMonth:
|
||||
lctype = LOCALE_SYEARMONTH;
|
||||
break;
|
||||
case LcTypeString::kTimeFormat:
|
||||
lctype = LOCALE_STIMEFORMAT;
|
||||
break;
|
||||
case LcTypeString::kShortTime:
|
||||
lctype = LOCALE_SSHORTTIME;
|
||||
break;
|
||||
}
|
||||
auto result = GetLocaleInfoString(lcid, lctype, force_defaults);
|
||||
std::move(callback).Run(result);
|
||||
}
|
||||
|
||||
} // namespace content
|
@ -136,6 +136,8 @@ target(link_target_type, "child") {
|
||||
|
||||
if (is_win) {
|
||||
sources += [
|
||||
"child_process_sandbox_support_impl_win.cc",
|
||||
"child_process_sandbox_support_impl_win.h",
|
||||
"dwrite_font_proxy/dwrite_font_proxy_init_impl_win.cc",
|
||||
"dwrite_font_proxy/dwrite_font_proxy_init_impl_win.h",
|
||||
"dwrite_font_proxy/dwrite_font_proxy_win.cc",
|
||||
|
135
content/child/child_process_sandbox_support_impl_win.cc
Normal file
135
content/child/child_process_sandbox_support_impl_win.cc
Normal file
@ -0,0 +1,135 @@
|
||||
// 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 "content/child/child_process_sandbox_support_impl_win.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/check_op.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/notreached.h"
|
||||
#include "content/public/child/child_thread.h"
|
||||
|
||||
namespace content {
|
||||
|
||||
WebSandboxSupportWin::WebSandboxSupportWin() {
|
||||
// Not available in some browser tests.
|
||||
auto* child_thread = ChildThread::Get();
|
||||
if (child_thread) {
|
||||
child_thread->BindHostReceiver(
|
||||
sandbox_support_.BindNewPipeAndPassReceiver());
|
||||
}
|
||||
}
|
||||
|
||||
WebSandboxSupportWin::~WebSandboxSupportWin() = default;
|
||||
|
||||
bool WebSandboxSupportWin::IsLocaleProxyEnabled() {
|
||||
return base::FeatureList::IsEnabled(content::mojom::kWinSboxProxyLocale);
|
||||
}
|
||||
|
||||
std::pair<LCID, unsigned> WebSandboxSupportWin::LcidAndFirstDayOfWeek(
|
||||
blink::WebString locale,
|
||||
blink::WebString default_language,
|
||||
bool force_defaults) {
|
||||
uint32_t lcid;
|
||||
uint32_t first_day_of_week;
|
||||
CHECK(sandbox_support_->LcidAndFirstDayOfWeek(
|
||||
locale.Utf16(), default_language.Utf16(), force_defaults, &lcid,
|
||||
&first_day_of_week));
|
||||
return {lcid, first_day_of_week};
|
||||
}
|
||||
|
||||
std::unique_ptr<blink::WebSandboxSupport::LocaleInitData>
|
||||
WebSandboxSupportWin::DigitsAndSigns(LCID lcid, bool force_defaults) {
|
||||
auto init_data = std::make_unique<blink::WebSandboxSupport::LocaleInitData>();
|
||||
uint32_t digit_substitution = 0;
|
||||
std::u16string digits;
|
||||
std::u16string decimal;
|
||||
std::u16string thousand;
|
||||
std::u16string negative_sign;
|
||||
uint32_t negnumber = 0;
|
||||
|
||||
CHECK(sandbox_support_->DigitsAndSigns(
|
||||
lcid, force_defaults, &digit_substitution, &digits, &decimal, &thousand,
|
||||
&negative_sign, &negnumber));
|
||||
init_data->digit_substitution = digit_substitution;
|
||||
init_data->digits = blink::WebString(digits);
|
||||
init_data->decimal = blink::WebString(decimal);
|
||||
init_data->thousand = blink::WebString(thousand);
|
||||
init_data->negative_sign = blink::WebString(negative_sign);
|
||||
init_data->negnumber = negnumber;
|
||||
return init_data;
|
||||
}
|
||||
|
||||
blink::WebVector<blink::WebString> WebSandboxSupportWin::LocaleStrings(
|
||||
LCID lcid,
|
||||
bool force_defaults,
|
||||
mojom::SandboxSupport::LcTypeStrings collection) {
|
||||
std::vector<std::u16string> results;
|
||||
CHECK(sandbox_support_->LocaleStrings(lcid, force_defaults, collection,
|
||||
&results));
|
||||
blink::WebVector<blink::WebString> ret;
|
||||
ret.reserve(results.size());
|
||||
for (const auto& str : results) {
|
||||
ret.push_back(blink::WebString(str));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
blink::WebVector<blink::WebString> WebSandboxSupportWin::MonthLabels(
|
||||
LCID lcid,
|
||||
bool force_defaults) {
|
||||
return LocaleStrings(lcid, force_defaults,
|
||||
mojom::SandboxSupport::LcTypeStrings::kMonths);
|
||||
}
|
||||
|
||||
blink::WebVector<blink::WebString> WebSandboxSupportWin::WeekDayShortLabels(
|
||||
LCID lcid,
|
||||
bool force_defaults) {
|
||||
return LocaleStrings(lcid, force_defaults,
|
||||
mojom::SandboxSupport::LcTypeStrings::kShortWeekDays);
|
||||
}
|
||||
|
||||
blink::WebVector<blink::WebString> WebSandboxSupportWin::ShortMonthLabels(
|
||||
LCID lcid,
|
||||
bool force_defaults) {
|
||||
return LocaleStrings(lcid, force_defaults,
|
||||
mojom::SandboxSupport::LcTypeStrings::kShortMonths);
|
||||
}
|
||||
|
||||
blink::WebVector<blink::WebString> WebSandboxSupportWin::AmPmLabels(
|
||||
LCID lcid,
|
||||
bool force_defaults) {
|
||||
return LocaleStrings(lcid, force_defaults,
|
||||
mojom::SandboxSupport::LcTypeStrings::kAmPm);
|
||||
}
|
||||
|
||||
blink::WebString WebSandboxSupportWin::LocaleString(LCID lcid,
|
||||
LCTYPE type,
|
||||
bool force_defaults) {
|
||||
mojom::SandboxSupport::LcTypeString wanted;
|
||||
switch (type) {
|
||||
case LOCALE_SSHORTDATE:
|
||||
wanted = mojom::SandboxSupport::LcTypeString::kShortDate;
|
||||
break;
|
||||
case LOCALE_SYEARMONTH:
|
||||
wanted = mojom::SandboxSupport::LcTypeString::kYearMonth;
|
||||
break;
|
||||
case LOCALE_STIMEFORMAT:
|
||||
wanted = mojom::SandboxSupport::LcTypeString::kTimeFormat;
|
||||
break;
|
||||
case LOCALE_SSHORTTIME:
|
||||
wanted = mojom::SandboxSupport::LcTypeString::kShortTime;
|
||||
break;
|
||||
default:
|
||||
NOTREACHED();
|
||||
}
|
||||
std::u16string str;
|
||||
CHECK(sandbox_support_->LocaleString(lcid, force_defaults, wanted, &str));
|
||||
return blink::WebString(std::move(str));
|
||||
}
|
||||
|
||||
} // namespace content
|
61
content/child/child_process_sandbox_support_impl_win.h
Normal file
61
content/child/child_process_sandbox_support_impl_win.h
Normal file
@ -0,0 +1,61 @@
|
||||
// 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.
|
||||
|
||||
#ifndef CONTENT_CHILD_CHILD_PROCESS_SANDBOX_SUPPORT_IMPL_WIN_H_
|
||||
#define CONTENT_CHILD_CHILD_PROCESS_SANDBOX_SUPPORT_IMPL_WIN_H_
|
||||
|
||||
#include "content/common/sandbox_support.mojom.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
#include "third_party/blink/public/platform/web_string.h"
|
||||
#include "third_party/blink/public/platform/win/web_sandbox_support.h"
|
||||
|
||||
namespace content {
|
||||
|
||||
// Implementation of the interface used by Blink to upcall to the privileged
|
||||
// process (browser) for handling requests for data that are not allowed within
|
||||
// the sandbox.
|
||||
class WebSandboxSupportWin : public blink::WebSandboxSupport {
|
||||
public:
|
||||
WebSandboxSupportWin();
|
||||
|
||||
WebSandboxSupportWin(const WebSandboxSupportWin&) = delete;
|
||||
WebSandboxSupportWin& operator=(const WebSandboxSupportWin&) = delete;
|
||||
|
||||
~WebSandboxSupportWin() override;
|
||||
|
||||
bool IsLocaleProxyEnabled() override;
|
||||
std::pair<LCID, unsigned> LcidAndFirstDayOfWeek(
|
||||
blink::WebString locale,
|
||||
blink::WebString default_language,
|
||||
bool force_defaults) override;
|
||||
|
||||
std::unique_ptr<blink::WebSandboxSupport::LocaleInitData> DigitsAndSigns(
|
||||
LCID lcid,
|
||||
bool force_defaults) override;
|
||||
|
||||
blink::WebVector<blink::WebString> MonthLabels(LCID lcid,
|
||||
bool force_defaults) override;
|
||||
blink::WebVector<blink::WebString> WeekDayShortLabels(
|
||||
LCID lcid,
|
||||
bool force_defaults) override;
|
||||
blink::WebVector<blink::WebString> ShortMonthLabels(
|
||||
LCID lcid,
|
||||
bool force_defaults) override;
|
||||
blink::WebVector<blink::WebString> AmPmLabels(LCID lcid,
|
||||
bool force_defaults) override;
|
||||
blink::WebString LocaleString(LCID lcid,
|
||||
LCTYPE type,
|
||||
bool force_defaults) override;
|
||||
|
||||
private:
|
||||
blink::WebVector<blink::WebString> LocaleStrings(
|
||||
LCID lcid,
|
||||
bool force_defaults,
|
||||
mojom::SandboxSupport::LcTypeStrings collection);
|
||||
mojo::Remote<mojom::SandboxSupport> sandbox_support_;
|
||||
};
|
||||
|
||||
} // namespace content
|
||||
|
||||
#endif // CONTENT_CHILD_CHILD_PROCESS_SANDBOX_SUPPORT_IMPL_WIN_H_
|
@ -507,6 +507,10 @@ mojom("mojo_bindings") {
|
||||
sources += [ "gin_java_bridge.mojom" ]
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
sources += [ "sandbox_support.mojom" ]
|
||||
}
|
||||
|
||||
enabled_features = []
|
||||
if (enable_ipc_logging) {
|
||||
enabled_features += [ "ipc_logging" ]
|
||||
|
@ -4,12 +4,82 @@
|
||||
|
||||
module content.mojom;
|
||||
|
||||
[EnableIf=is_mac]
|
||||
import "mojo/public/mojom/base/shared_memory.mojom";
|
||||
[EnableIf=is_win]
|
||||
import "mojo/public/mojom/base/string16.mojom";
|
||||
|
||||
[EnableIf=is_win]
|
||||
feature kWinSboxProxyLocale {
|
||||
const string name = "WinSboxProxyLocale";
|
||||
const bool enabled_state = false;
|
||||
};
|
||||
|
||||
// Interface for a sandboxed child process to request services of
|
||||
// the browser.
|
||||
interface SandboxSupport {
|
||||
// Mac:
|
||||
|
||||
// Returns the shared memory region containing system theme color
|
||||
// information.
|
||||
[EnableIf=is_mac]
|
||||
GetSystemColors() => (mojo_base.mojom.ReadOnlySharedMemoryRegion region);
|
||||
|
||||
// Windows: Various GetLocale*() proxies. These replace wrapped syscalls
|
||||
// so have to be [Sync].
|
||||
|
||||
// Returns the LCID and first day of week corresponding to `locale` with a
|
||||
// fallback to `default_language`. If `force_defaults` is true then user
|
||||
// customization is ignored. Both string arguments have a max length of
|
||||
// LOCALE_NAME_MAX_LENGTH.
|
||||
[Sync, EnableIf=is_win, RuntimeFeature=kWinSboxProxyLocale]
|
||||
LcidAndFirstDayOfWeek(mojo_base.mojom.String16 locale,
|
||||
mojo_base.mojom.String16 default_language,
|
||||
bool defaults)
|
||||
=> (uint32 lcid, uint32 first_day_of_week);
|
||||
|
||||
// Returns digit substitutions and negative sign prefix and suffix for `lcid`.
|
||||
// Ignores user customization if `defaults` is true. Backs
|
||||
// InitializeLocaleData(). `digits` are not fetched if `digit_substitution` is
|
||||
// 0to9.
|
||||
[Sync, EnableIf=is_win, RuntimeFeature=kWinSboxProxyLocale]
|
||||
DigitsAndSigns(uint32 lcid, bool defaults)
|
||||
=> (uint32 digit_substitution,
|
||||
mojo_base.mojom.String16 digits,
|
||||
mojo_base.mojom.String16 decimal,
|
||||
mojo_base.mojom.String16 thousand,
|
||||
mojo_base.mojom.String16 negative_sign,
|
||||
uint32 negnumber);
|
||||
|
||||
// Single strings that can be directly requested.
|
||||
[EnableIf=is_win]
|
||||
enum LcTypeString {
|
||||
kShortDate,
|
||||
kYearMonth,
|
||||
kTimeFormat,
|
||||
kShortTime,
|
||||
};
|
||||
|
||||
// Returns a single string, selected by `type`.
|
||||
[Sync, EnableIf=is_win, RuntimeFeature=kWinSboxProxyLocale]
|
||||
LocaleString(uint32 lcid, bool defaults, LcTypeString type)
|
||||
=> (mojo_base.mojom.String16 str);
|
||||
|
||||
// Collections of locale strings.
|
||||
[EnableIf=is_win]
|
||||
enum LcTypeStrings {
|
||||
// MONTHNAME*
|
||||
kMonths,
|
||||
// ABBREVMONTHNAME*
|
||||
kShortMonths,
|
||||
// SHORTESTDAYNAME* - in blink order Sunday - Monday.
|
||||
kShortWeekDays,
|
||||
// 1159,2359
|
||||
kAmPm,
|
||||
};
|
||||
|
||||
// Returns a collection of strings, selected by `collection`.
|
||||
[Sync, EnableIf=is_win, RuntimeFeature=kWinSboxProxyLocale]
|
||||
LocaleStrings(uint32 lcid, bool defaults, LcTypeStrings collection)
|
||||
=> (array<mojo_base.mojom.String16> strings);
|
||||
};
|
||||
|
@ -122,6 +122,7 @@
|
||||
#include "url/origin.h"
|
||||
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
#include "content/child/child_process_sandbox_support_impl_win.h"
|
||||
#include "content/renderer/font_data/font_data_manager.h"
|
||||
#include "skia/ext/font_utils.h"
|
||||
#include "third_party/blink/public/web/win/web_font_rendering.h"
|
||||
@ -224,10 +225,13 @@ RendererBlinkPlatformImpl::RendererBlinkPlatformImpl(
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \
|
||||
BUILDFLAG(IS_WIN)
|
||||
if (sandboxEnabled()) {
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
sandbox_support_ = std::make_unique<WebSandboxSupportMac>();
|
||||
#elif BUILDFLAG(IS_WIN)
|
||||
sandbox_support_ = std::make_unique<WebSandboxSupportWin>();
|
||||
#else
|
||||
sandbox_support_ = std::make_unique<WebSandboxSupportLinux>(font_loader);
|
||||
#endif
|
||||
@ -285,7 +289,8 @@ void RendererBlinkPlatformImpl::SetThreadType(base::PlatformThreadId thread_id,
|
||||
#endif
|
||||
|
||||
blink::WebSandboxSupport* RendererBlinkPlatformImpl::GetSandboxSupport() {
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \
|
||||
BUILDFLAG(IS_WIN)
|
||||
return sandbox_support_.get();
|
||||
#else
|
||||
// These platforms do not require sandbox support.
|
||||
|
@ -256,7 +256,8 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
|
||||
void Collect3DContextInformation(blink::Platform::GraphicsInfo* gl_info,
|
||||
const gpu::GPUInfo& gpu_info) const;
|
||||
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \
|
||||
BUILDFLAG(IS_WIN)
|
||||
std::unique_ptr<blink::WebSandboxSupport> sandbox_support_;
|
||||
#endif
|
||||
|
||||
|
@ -3299,6 +3299,7 @@ test("content_unittests") {
|
||||
}
|
||||
if (is_win) {
|
||||
sources += [
|
||||
"../browser/child_process_sandbox_support_win_unittest.cc",
|
||||
"../browser/device_posture/device_posture_registry_watcher_win_unittest.cc",
|
||||
"../browser/renderer_host/direct_manipulation_test_helper_win.cc",
|
||||
"../browser/renderer_host/direct_manipulation_test_helper_win.h",
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "content/child/child_process_sandbox_support_impl_mac.h"
|
||||
#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
|
||||
#include "content/child/child_process_sandbox_support_impl_linux.h"
|
||||
#elif BUILDFLAG(IS_WIN)
|
||||
#include "content/child/child_process_sandbox_support_impl_win.h"
|
||||
#endif
|
||||
|
||||
namespace content {
|
||||
@ -27,6 +29,8 @@ UtilityBlinkPlatformWithSandboxSupportImpl::
|
||||
sandbox_support_ = std::make_unique<WebSandboxSupportLinux>(font_loader);
|
||||
#elif BUILDFLAG(IS_MAC)
|
||||
sandbox_support_ = std::make_unique<WebSandboxSupportMac>();
|
||||
#elif BUILDFLAG(IS_WIN)
|
||||
sandbox_support_ = std::make_unique<WebSandboxSupportWin>();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -35,7 +39,8 @@ UtilityBlinkPlatformWithSandboxSupportImpl::
|
||||
|
||||
blink::WebSandboxSupport*
|
||||
UtilityBlinkPlatformWithSandboxSupportImpl::GetSandboxSupport() {
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \
|
||||
BUILDFLAG(IS_WIN)
|
||||
return sandbox_support_.get();
|
||||
#else
|
||||
return nullptr;
|
||||
|
@ -33,7 +33,8 @@ class UtilityBlinkPlatformWithSandboxSupportImpl : public blink::Platform {
|
||||
blink::WebSandboxSupport* GetSandboxSupport() override;
|
||||
|
||||
private:
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
|
||||
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \
|
||||
BUILDFLAG(IS_WIN)
|
||||
std::unique_ptr<blink::WebSandboxSupport> sandbox_support_;
|
||||
#endif
|
||||
};
|
||||
|
1
third_party/blink/public/BUILD.gn
vendored
1
third_party/blink/public/BUILD.gn
vendored
@ -411,6 +411,7 @@ source_set("blink_headers") {
|
||||
sources += [
|
||||
"platform/web_font_prewarmer.h",
|
||||
"platform/web_font_rendering_client.h",
|
||||
"platform/win/web_sandbox_support.h",
|
||||
"web/win/web_font_family_names.h",
|
||||
"web/win/web_font_rendering.h",
|
||||
]
|
||||
|
3
third_party/blink/public/platform/win/DEPS
vendored
Normal file
3
third_party/blink/public/platform/win/DEPS
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
include_rules = [
|
||||
"+base/win/windows_types.h",
|
||||
]
|
73
third_party/blink/public/platform/win/web_sandbox_support.h
vendored
Normal file
73
third_party/blink/public/platform/win/web_sandbox_support.h
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
// 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.
|
||||
|
||||
#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WIN_WEB_SANDBOX_SUPPORT_H_
|
||||
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WIN_WEB_SANDBOX_SUPPORT_H_
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "base/win/windows_types.h"
|
||||
#include "third_party/blink/public/platform/web_string.h"
|
||||
#include "third_party/blink/public/platform/web_vector.h"
|
||||
|
||||
// Repeat some Windows typedefs used by the locale functions that
|
||||
// are not in base/win/windows_types.h
|
||||
using LCID = DWORD;
|
||||
using LCTYPE = DWORD;
|
||||
|
||||
namespace blink {
|
||||
|
||||
// Put methods here that are required due to sandbox restrictions.
|
||||
class WebSandboxSupport {
|
||||
public:
|
||||
// Bundles the result of several calls to locale functions.
|
||||
struct LocaleInitData {
|
||||
// LOCALE_IDIGITSUBSTITUTION.
|
||||
DWORD digit_substitution;
|
||||
// LOCALE_SNATIVEDIGITS. Empty if digit_substitution == 1 (0to9).
|
||||
WebString digits;
|
||||
// LOCALE_SDECIMAL.
|
||||
WebString decimal;
|
||||
// LOCALE_STHOUSAND.
|
||||
WebString thousand;
|
||||
// LOCALE_SNEGATIVESIGN.
|
||||
WebString negative_sign;
|
||||
// LOCALE_INEGNUMBER.
|
||||
DWORD negnumber;
|
||||
};
|
||||
|
||||
virtual ~WebSandboxSupport() {}
|
||||
|
||||
// Can locale-related calls be proxied?
|
||||
virtual bool IsLocaleProxyEnabled() = 0;
|
||||
|
||||
// Returns locale information. Fails unless IsLocaleProxyEnabled().
|
||||
virtual std::pair<LCID, unsigned> LcidAndFirstDayOfWeek(
|
||||
WebString locale,
|
||||
WebString default_language,
|
||||
bool force_defaults) = 0;
|
||||
|
||||
// Returns digit symbols and sign prefixes and suffixes. Fails unless
|
||||
// IsLocaleProxyEnabled().
|
||||
virtual std::unique_ptr<LocaleInitData> DigitsAndSigns(
|
||||
LCID lcid,
|
||||
bool force_defaults) = 0;
|
||||
|
||||
virtual WebVector<WebString> MonthLabels(LCID lcid, bool force_defaults) = 0;
|
||||
virtual WebVector<WebString> WeekDayShortLabels(LCID lcid,
|
||||
bool force_defaults) = 0;
|
||||
virtual WebVector<WebString> ShortMonthLabels(LCID lcid,
|
||||
bool force_defaults) = 0;
|
||||
virtual WebVector<WebString> AmPmLabels(LCID lcid, bool force_defaults) = 0;
|
||||
|
||||
// Note: only specified allowed types can be provided for `type`.
|
||||
virtual WebString LocaleString(LCID lcid,
|
||||
LCTYPE type,
|
||||
bool force_defaults) = 0;
|
||||
};
|
||||
|
||||
} // namespace blink
|
||||
|
||||
#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WIN_WEB_SANDBOX_SUPPORT_H_
|
@ -39,6 +39,8 @@
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/ranges/algorithm.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "third_party/blink/public/platform/platform.h"
|
||||
#include "third_party/blink/public/platform/win/web_sandbox_support.h"
|
||||
#include "third_party/blink/renderer/platform/language.h"
|
||||
#include "third_party/blink/renderer/platform/text/date_components.h"
|
||||
#include "third_party/blink/renderer/platform/text/date_time_format.h"
|
||||
@ -151,11 +153,22 @@ LCID LCIDFromLocale(const String& locale, bool defaults_for_locale) {
|
||||
|
||||
std::pair<LCID, unsigned> GetLcidAndFirstDayOfWeek(const String& locale,
|
||||
bool defaults_for_locale) {
|
||||
WebSandboxSupport* proxy = Platform::Current()->GetSandboxSupport();
|
||||
if (proxy && proxy->IsLocaleProxyEnabled()) {
|
||||
return proxy->LcidAndFirstDayOfWeek(locale, DefaultLanguage(),
|
||||
defaults_for_locale);
|
||||
}
|
||||
|
||||
LCID lcid = LCIDFromLocale(locale, defaults_for_locale);
|
||||
return {lcid, GetFirstDayOfWeek(lcid, defaults_for_locale)};
|
||||
}
|
||||
|
||||
Vector<String> GetMonthLabels(LCID lcid, bool defaults_for_locale) {
|
||||
WebSandboxSupport* proxy = Platform::Current()->GetSandboxSupport();
|
||||
if (proxy && proxy->IsLocaleProxyEnabled()) {
|
||||
return Vector<String>(proxy->MonthLabels(lcid, defaults_for_locale));
|
||||
}
|
||||
|
||||
static constexpr LCTYPE kTypes[12] = {
|
||||
LOCALE_SMONTHNAME1, LOCALE_SMONTHNAME2, LOCALE_SMONTHNAME3,
|
||||
LOCALE_SMONTHNAME4, LOCALE_SMONTHNAME5, LOCALE_SMONTHNAME6,
|
||||
@ -166,6 +179,11 @@ Vector<String> GetMonthLabels(LCID lcid, bool defaults_for_locale) {
|
||||
}
|
||||
|
||||
Vector<String> GetWeekDayShortLabels(LCID lcid, bool defaults_for_locale) {
|
||||
WebSandboxSupport* proxy = Platform::Current()->GetSandboxSupport();
|
||||
if (proxy && proxy->IsLocaleProxyEnabled()) {
|
||||
return Vector<String>(proxy->WeekDayShortLabels(lcid, defaults_for_locale));
|
||||
}
|
||||
|
||||
static constexpr LCTYPE kTypes[7] = {
|
||||
// Numbered 1 (Monday) - 7 (Sunday), so do 7, then 1-6
|
||||
LOCALE_SSHORTESTDAYNAME7, LOCALE_SSHORTESTDAYNAME1,
|
||||
@ -176,6 +194,11 @@ Vector<String> GetWeekDayShortLabels(LCID lcid, bool defaults_for_locale) {
|
||||
}
|
||||
|
||||
Vector<String> GetShortMonthLabels(LCID lcid, bool defaults_for_locale) {
|
||||
WebSandboxSupport* proxy = Platform::Current()->GetSandboxSupport();
|
||||
if (proxy && proxy->IsLocaleProxyEnabled()) {
|
||||
return Vector<String>(proxy->ShortMonthLabels(lcid, defaults_for_locale));
|
||||
}
|
||||
|
||||
static constexpr LCTYPE kTypes[12] = {
|
||||
LOCALE_SABBREVMONTHNAME1, LOCALE_SABBREVMONTHNAME2,
|
||||
LOCALE_SABBREVMONTHNAME3, LOCALE_SABBREVMONTHNAME4,
|
||||
@ -188,6 +211,11 @@ Vector<String> GetShortMonthLabels(LCID lcid, bool defaults_for_locale) {
|
||||
}
|
||||
|
||||
Vector<String> GetTimeAMPMLabels(LCID lcid, bool defaults_for_locale) {
|
||||
WebSandboxSupport* proxy = Platform::Current()->GetSandboxSupport();
|
||||
if (proxy && proxy->IsLocaleProxyEnabled()) {
|
||||
return Vector<String>(proxy->AmPmLabels(lcid, defaults_for_locale));
|
||||
}
|
||||
|
||||
static constexpr LCTYPE kTypes[2] = {
|
||||
LOCALE_S1159,
|
||||
LOCALE_S2359,
|
||||
@ -196,18 +224,34 @@ Vector<String> GetTimeAMPMLabels(LCID lcid, bool defaults_for_locale) {
|
||||
}
|
||||
|
||||
String GetShortDate(LCID lcid, bool defaults_for_locale) {
|
||||
WebSandboxSupport* proxy = Platform::Current()->GetSandboxSupport();
|
||||
if (proxy && proxy->IsLocaleProxyEnabled()) {
|
||||
return proxy->LocaleString(lcid, LOCALE_SSHORTDATE, defaults_for_locale);
|
||||
}
|
||||
return GetLocaleInfoString(lcid, LOCALE_SSHORTDATE, defaults_for_locale);
|
||||
}
|
||||
|
||||
String GetYearMonth(LCID lcid, bool defaults_for_locale) {
|
||||
WebSandboxSupport* proxy = Platform::Current()->GetSandboxSupport();
|
||||
if (proxy && proxy->IsLocaleProxyEnabled()) {
|
||||
return proxy->LocaleString(lcid, LOCALE_SYEARMONTH, defaults_for_locale);
|
||||
}
|
||||
return GetLocaleInfoString(lcid, LOCALE_SYEARMONTH, defaults_for_locale);
|
||||
}
|
||||
|
||||
String GetTimeFormat(LCID lcid, bool defaults_for_locale) {
|
||||
WebSandboxSupport* proxy = Platform::Current()->GetSandboxSupport();
|
||||
if (proxy && proxy->IsLocaleProxyEnabled()) {
|
||||
return proxy->LocaleString(lcid, LOCALE_STIMEFORMAT, defaults_for_locale);
|
||||
}
|
||||
return GetLocaleInfoString(lcid, LOCALE_STIMEFORMAT, defaults_for_locale);
|
||||
}
|
||||
|
||||
String GetShortTime(LCID lcid, bool defaults_for_locale) {
|
||||
WebSandboxSupport* proxy = Platform::Current()->GetSandboxSupport();
|
||||
if (proxy && proxy->IsLocaleProxyEnabled()) {
|
||||
return proxy->LocaleString(lcid, LOCALE_SSHORTTIME, defaults_for_locale);
|
||||
}
|
||||
return GetLocaleInfoString(lcid, LOCALE_SSHORTTIME, defaults_for_locale);
|
||||
}
|
||||
|
||||
@ -499,35 +543,56 @@ void LocaleWin::InitializeLocaleData() {
|
||||
kNegativeFormatSpaceSignSuffix = 4,
|
||||
};
|
||||
|
||||
DWORD digit_substitution = CallGetLocaleInfoDWORD(
|
||||
lcid_, LOCALE_IDIGITSUBSTITUTION, kDigitSubstitution0to9);
|
||||
DWORD digit_substitution;
|
||||
String digits;
|
||||
String decimal;
|
||||
String thousand;
|
||||
String negative_sign;
|
||||
DWORD negnumber;
|
||||
|
||||
WebSandboxSupport* proxy = Platform::Current()->GetSandboxSupport();
|
||||
if (proxy && proxy->IsLocaleProxyEnabled()) {
|
||||
auto init_data = proxy->DigitsAndSigns(lcid_, defaults_for_locale_);
|
||||
digit_substitution = init_data->digit_substitution;
|
||||
digits = std::move(init_data->digits);
|
||||
decimal = std::move(init_data->decimal);
|
||||
thousand = std::move(init_data->thousand);
|
||||
negative_sign = std::move(init_data->negative_sign);
|
||||
negnumber = init_data->negnumber;
|
||||
} else {
|
||||
digit_substitution = CallGetLocaleInfoDWORD(
|
||||
lcid_, LOCALE_IDIGITSUBSTITUTION, kDigitSubstitution0to9);
|
||||
if (digit_substitution != kDigitSubstitution0to9) {
|
||||
digits = GetLocaleInfoString(lcid_, LOCALE_SNATIVEDIGITS,
|
||||
defaults_for_locale_);
|
||||
}
|
||||
decimal = GetLocaleInfoString(lcid_, LOCALE_SDECIMAL, defaults_for_locale_);
|
||||
thousand =
|
||||
GetLocaleInfoString(lcid_, LOCALE_STHOUSAND, defaults_for_locale_);
|
||||
negative_sign =
|
||||
GetLocaleInfoString(lcid_, LOCALE_SNEGATIVESIGN, defaults_for_locale_);
|
||||
negnumber = CallGetLocaleInfoDWORD(lcid_, LOCALE_INEGNUMBER,
|
||||
kNegativeFormatSignPrefix);
|
||||
}
|
||||
// No Locale calls after this point.
|
||||
Vector<String, kDecimalSymbolsSize> symbols;
|
||||
if (digit_substitution == kDigitSubstitution0to9) {
|
||||
symbols = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
|
||||
} else {
|
||||
String digits =
|
||||
GetLocaleInfoString(lcid_, LOCALE_SNATIVEDIGITS, defaults_for_locale_);
|
||||
DCHECK_GE(digits.length(), 10u);
|
||||
for (wtf_size_t i = 0; i < 10; ++i) {
|
||||
symbols.push_back(digits.Substring(i, 1));
|
||||
}
|
||||
}
|
||||
DCHECK_EQ(symbols.size(), kDecimalSeparatorIndex);
|
||||
symbols.push_back(
|
||||
GetLocaleInfoString(lcid_, LOCALE_SDECIMAL, defaults_for_locale_));
|
||||
symbols.push_back(decimal);
|
||||
DCHECK_EQ(symbols.size(), kGroupSeparatorIndex);
|
||||
symbols.push_back(
|
||||
GetLocaleInfoString(lcid_, LOCALE_STHOUSAND, defaults_for_locale_));
|
||||
symbols.push_back(thousand);
|
||||
DCHECK_EQ(symbols.size(), kDecimalSymbolsSize);
|
||||
|
||||
String negative_sign =
|
||||
GetLocaleInfoString(lcid_, LOCALE_SNEGATIVESIGN, defaults_for_locale_);
|
||||
DWORD negative_format = CallGetLocaleInfoDWORD(lcid_, LOCALE_INEGNUMBER,
|
||||
kNegativeFormatSignPrefix);
|
||||
String negative_prefix = g_empty_string;
|
||||
String negative_suffix = g_empty_string;
|
||||
switch (negative_format) {
|
||||
switch (negnumber) {
|
||||
case kNegativeFormatParenthesis:
|
||||
negative_prefix = "(";
|
||||
negative_suffix = ")";
|
||||
|
Reference in New Issue
Block a user