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

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: Test patchset to run try job 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..5ebdd9cc594ef2ed8bdca3620186cb5d5210a1ce 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
@@ -139,6 +139,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 +233,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<uint32_t>* file_handles) {
InitializeDirectWrite();
TRACE_EVENT0("dwrite", "FontProxyHost::OnGetFontFiles");
DCHECK(collection_);
@@ -246,6 +252,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 +265,24 @@ 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 (const base::string16& custom_font_path : custom_font_path_set) {
+ HANDLE renderer_file_handle = CreateRendererHandleForPath(custom_font_path);
+ if (renderer_file_handle != INVALID_HANDLE_VALUE) {
+ // Check that the handle is not truncated by downcasting to uint32_t. This
+ // cast should always be valid, according to
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx
nasko 2016/07/21 21:45:55 Can we shorten the link?
Ilya Kulshin 2016/07/22 03:30:37 I removed this code and the comment after switchin
+ uint32_t uint_handle = PtrToLong(renderer_file_handle);
+ CHECK_EQ(reinterpret_cast<HANDLE>(uint_handle), renderer_file_handle);
+ file_handles->push_back(uint_handle);
+ }
+ }
+
file_paths->assign(path_set.begin(), path_set.end());
LogLastResortFontFileCount(file_paths->size());
}
@@ -407,6 +426,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 +477,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 +487,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 +513,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,11 +529,41 @@ bool DWriteFontProxyMessageFilter::AddLocalFile(
}
}
- LogLoaderType(FILE_SYSTEM_FONT_DIR);
- path_set->insert(file_path);
+ if (!base::StartsWith(file_path, windows_fonts_path_,
+ base::CompareCase::SENSITIVE)) {
+ LogLoaderType(FILE_OUTSIDE_SANDBOX);
+ custom_font_path_set->insert(file_path);
+ } else {
+ LogLoaderType(FILE_SYSTEM_FONT_DIR);
+ path_set->insert(file_path);
+ }
return true;
}
+HANDLE DWriteFontProxyMessageFilter::CreateRendererHandleForPath(
+ const base::string16& path) {
+ // 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(path), base::File::FLAG_OPEN |
+ base::File::FLAG_READ |
+ base::File::FLAG_EXCLUSIVE_WRITE);
+ if (!file.IsValid()) {
+ DCHECK(false);
+ return INVALID_HANDLE_VALUE;
+ }
+
+ HANDLE renderer_handle;
+ if (!DuplicateHandle(GetCurrentProcess(), file.GetPlatformFile(),
+ PeerHandle(), &renderer_handle, 0 /* dwDesiredAccess */,
+ FALSE /* bInheritHandle */,
+ DUPLICATE_SAME_ACCESS /* dwOptions */)) {
+ DCHECK(false);
+ return INVALID_HANDLE_VALUE;
+ }
+ return renderer_handle;
+}
+
bool DWriteFontProxyMessageFilter::IsLastResortFallbackFont(
uint32_t font_index) {
for (auto iter = last_resort_fonts_.begin(); iter != last_resort_fonts_.end();

Powered by Google App Engine
This is Rietveld 408576698