Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1581)

Unified Diff: content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc

Issue 2153343002: Implement support for loading font files from outside system directory (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add some more comments Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc
diff --git a/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc b/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc
index 6d572abb06cc5baf33bf05ae816a7bfb4a1b971f..d3c2568c1b05af065410bec99db48abe93e4ca01 100644
--- a/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc
+++ b/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc
@@ -13,6 +13,7 @@
#include <utility>
#include "base/callback_helpers.h"
+#include "base/feature_list.h"
#include "base/i18n/case_conversion.h"
#include "base/logging.h"
#include "base/macros.h"
@@ -110,11 +111,23 @@ base::string16 GetWindowsFontsPath() {
const wchar_t* kLastResortFontNames[] = {L"Sans", L"Arial", L"MS UI Gothic",
L"Microsoft Sans Serif"};
+// Feature to enable loading font files from outside the system font directory.
+const base::Feature kEnableCustomFonts {
+ "DirectWriteCustomFonts", base::FEATURE_ENABLED_BY_DEFAULT
+};
+
+// Feature to force loading font files using the custom font file path. Has no
+// effect if kEnableCustomFonts is disabled.
+const base::Feature kForceCustomFonts {
+ "ForceDirectWriteCustomFonts", base::FEATURE_DISABLED_BY_DEFAULT
+};
+
} // namespace
DWriteFontProxyMessageFilter::DWriteFontProxyMessageFilter()
: BrowserMessageFilter(DWriteFontProxyMsgStart),
- windows_fonts_path_(GetWindowsFontsPath()) {}
+ windows_fonts_path_(GetWindowsFontsPath()),
+ custom_font_file_loading_mode_(ENABLE) {}
DWriteFontProxyMessageFilter::~DWriteFontProxyMessageFilter() = default;
@@ -139,6 +152,11 @@ void DWriteFontProxyMessageFilter::OverrideThreadForMessage(
*thread = BrowserThread::FILE_USER_BLOCKING;
}
+void DWriteFontProxyMessageFilter::SetWindowsFontsPathForTesting(
+ base::string16 path) {
+ windows_fonts_path_.swap(path);
+}
+
void DWriteFontProxyMessageFilter::OnFindFamily(
const base::string16& family_name,
UINT32* family_index) {
@@ -228,7 +246,8 @@ void DWriteFontProxyMessageFilter::OnGetFamilyNames(
void DWriteFontProxyMessageFilter::OnGetFontFiles(
uint32_t family_index,
- std::vector<base::string16>* file_paths) {
+ std::vector<base::string16>* file_paths,
+ std::vector<IPC::PlatformFileForTransit>* file_handles) {
InitializeDirectWrite();
TRACE_EVENT0("dwrite", "FontProxyHost::OnGetFontFiles");
DCHECK(collection_);
@@ -246,6 +265,7 @@ void DWriteFontProxyMessageFilter::OnGetFontFiles(
UINT32 font_count = family->GetFontCount();
std::set<base::string16> path_set;
+ std::set<base::string16> custom_font_path_set;
// Iterate through all the fonts in the family, and all the files for those
// fonts. If anything goes wrong, bail on the entire family to avoid having
// a partially-loaded font family.
@@ -258,12 +278,28 @@ void DWriteFontProxyMessageFilter::OnGetFontFiles(
return;
}
- if (!AddFilesForFont(&path_set, font.Get())) {
+ if (!AddFilesForFont(&path_set, &custom_font_path_set, font.Get())) {
if (IsLastResortFallbackFont(family_index))
LogMessageFilterError(LAST_RESORT_FONT_ADD_FILES_FAILED);
}
}
+ // For files outside the windows fonts directory we pass them to the renderer
+ // as file handles. The renderer would be unable to open the files directly
+ // due to sandbox policy (it would get ERROR_ACCESS_DENIED instead). Passing
+ // handles allows the renderer to bypass the restriction and use the fonts.
+ for (const base::string16& custom_font_path : custom_font_path_set) {
+ // Specify FLAG_EXCLUSIVE_WRITE to prevent base::File from opening the file
+ // with FILE_SHARE_WRITE access. FLAG_EXCLUSIVE_WRITE doesn't actually open
+ // the file for write access.
+ base::File file(base::FilePath(custom_font_path),
+ base::File::FLAG_OPEN | base::File::FLAG_READ |
+ base::File::FLAG_EXCLUSIVE_WRITE);
+ if (file.IsValid()) {
+ file_handles->push_back(IPC::TakePlatformFileForTransit(std::move(file)));
+ }
+ }
+
file_paths->assign(path_set.begin(), path_set.end());
LogLastResortFontFileCount(file_paths->size());
}
@@ -392,6 +428,11 @@ void DWriteFontProxyMessageFilter::InitializeDirectWrite() {
return;
}
+ if (!base::FeatureList::IsEnabled(kEnableCustomFonts))
+ custom_font_file_loading_mode_ = DISABLE;
+ else if (base::FeatureList::IsEnabled(kForceCustomFonts))
+ custom_font_file_loading_mode_ = FORCE;
+
// Temp code to help track down crbug.com/561873
for (size_t font = 0; font < arraysize(kLastResortFontNames); font++) {
uint32_t font_index = 0;
@@ -407,6 +448,7 @@ void DWriteFontProxyMessageFilter::InitializeDirectWrite() {
bool DWriteFontProxyMessageFilter::AddFilesForFont(
std::set<base::string16>* path_set,
+ std::set<base::string16>* custom_font_path_set,
IDWriteFont* font) {
mswr::ComPtr<IDWriteFontFace> font_face;
HRESULT hr;
@@ -457,7 +499,7 @@ bool DWriteFontProxyMessageFilter::AddFilesForFont(
return false;
}
- if (!AddLocalFile(path_set, local_loader.Get(),
+ if (!AddLocalFile(path_set, custom_font_path_set, local_loader.Get(),
font_files[file_index].Get())) {
return false;
}
@@ -467,6 +509,7 @@ bool DWriteFontProxyMessageFilter::AddFilesForFont(
bool DWriteFontProxyMessageFilter::AddLocalFile(
std::set<base::string16>* path_set,
+ std::set<base::string16>* custom_font_path_set,
IDWriteLocalFontFileLoader* local_loader,
IDWriteFontFile* font_file) {
HRESULT hr;
@@ -492,23 +535,6 @@ bool DWriteFontProxyMessageFilter::AddLocalFile(
}
base::string16 file_path = base::i18n::FoldCase(file_path_chars.data());
- if (!base::StartsWith(file_path, windows_fonts_path_,
- base::CompareCase::SENSITIVE)) {
- // Skip loading fonts from outside the system fonts directory, since
- // these families will not be accessible to the renderer process. If
- // this turns out to be a common case, we can either grant the renderer
- // access to these files (not sure if this is actually possible), or
- // load the file data ourselves and hand it to the renderer.
-
- // Really, really, really want to know what families hit this. Current
- // data indicates about 0.09% of families fall into this case. Nothing to
- // worry about if it's random obscure fonts noone has ever heard of, but
- // could be a problem if it's common fonts.
-
- LogLoaderType(FILE_OUTSIDE_SANDBOX);
- NOTREACHED(); // Not yet implemented.
- return false;
- }
// Refer to comments in kFontsToIgnore for this block.
for (const auto& file_to_ignore : kFontsToIgnore) {
@@ -525,8 +551,16 @@ bool DWriteFontProxyMessageFilter::AddLocalFile(
}
}
- LogLoaderType(FILE_SYSTEM_FONT_DIR);
- path_set->insert(file_path);
+ if (!base::StartsWith(file_path, windows_fonts_path_,
+ base::CompareCase::SENSITIVE) ||
+ custom_font_file_loading_mode_ == FORCE) {
+ LogLoaderType(FILE_OUTSIDE_SANDBOX);
+ if (custom_font_file_loading_mode_ != DISABLE)
+ custom_font_path_set->insert(file_path);
+ } else {
+ LogLoaderType(FILE_SYSTEM_FONT_DIR);
+ path_set->insert(file_path);
+ }
return true;
}

Powered by Google App Engine
This is Rietveld 408576698