Chromium Code Reviews| 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(); |