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

Side by Side Diff: content/child/dwrite_font_proxy/dwrite_font_proxy_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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/child/dwrite_font_proxy/dwrite_font_proxy_win.h" 5 #include "content/child/dwrite_font_proxy/dwrite_font_proxy_win.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <utility> 10 #include <utility>
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 // Hence, 44 // Hence,
45 // (a) existing enumerated constants should never be deleted or reordered, and 45 // (a) existing enumerated constants should never be deleted or reordered, and
46 // (b) new constants should only be appended at the end of the enumeration. 46 // (b) new constants should only be appended at the end of the enumeration.
47 enum FontProxyError { 47 enum FontProxyError {
48 FIND_FAMILY_SEND_FAILED = 0, 48 FIND_FAMILY_SEND_FAILED = 0,
49 GET_FAMILY_COUNT_SEND_FAILED = 1, 49 GET_FAMILY_COUNT_SEND_FAILED = 1,
50 COLLECTION_KEY_INVALID = 2, 50 COLLECTION_KEY_INVALID = 2,
51 FAMILY_INDEX_OUT_OF_RANGE = 3, 51 FAMILY_INDEX_OUT_OF_RANGE = 3,
52 GET_FONT_FILES_SEND_FAILED = 4, 52 GET_FONT_FILES_SEND_FAILED = 4,
53 MAPPED_FILE_FAILED = 5, 53 MAPPED_FILE_FAILED = 5,
54 DUPLICATE_HANDLE_FAILED = 6,
54 55
55 FONT_PROXY_ERROR_MAX_VALUE 56 FONT_PROXY_ERROR_MAX_VALUE
56 }; 57 };
57 58
58 const char kFontKeyName[] = "font_key_name"; 59 const char kFontKeyName[] = "font_key_name";
59 60
60 void LogLoadFamilyResult(DirectWriteLoadFamilyResult result) { 61 void LogLoadFamilyResult(DirectWriteLoadFamilyResult result) {
61 UMA_HISTOGRAM_ENUMERATION("DirectWrite.Fonts.Proxy.LoadFamilyResult", result, 62 UMA_HISTOGRAM_ENUMERATION("DirectWrite.Fonts.Proxy.LoadFamilyResult", result,
62 LOAD_FAMILY_MAX_VALUE); 63 LOAD_FAMILY_MAX_VALUE);
63 } 64 }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 186
186 if (*family_index >= GetFontFamilyCount()) { 187 if (*family_index >= GetFontFamilyCount()) {
187 LogFontProxyError(FAMILY_INDEX_OUT_OF_RANGE); 188 LogFontProxyError(FAMILY_INDEX_OUT_OF_RANGE);
188 return E_INVALIDARG; 189 return E_INVALIDARG;
189 } 190 }
190 191
191 // If we already loaded the family we should reuse the existing collection. 192 // If we already loaded the family we should reuse the existing collection.
192 DCHECK(!families_[*family_index]->IsLoaded()); 193 DCHECK(!families_[*family_index]->IsLoaded());
193 194
194 std::vector<base::string16> file_names; 195 std::vector<base::string16> file_names;
195 if (!GetSender()->Send( 196 std::vector<uint32_t> file_handles;
196 new DWriteFontProxyMsg_GetFontFiles(*family_index, &file_names))) { 197 if (!GetSender()->Send(new DWriteFontProxyMsg_GetFontFiles(
198 *family_index, &file_names, &file_handles))) {
197 LogFontProxyError(GET_FONT_FILES_SEND_FAILED); 199 LogFontProxyError(GET_FONT_FILES_SEND_FAILED);
198 return E_FAIL; 200 return E_FAIL;
199 } 201 }
200 202
203 std::vector<HANDLE> handles;
204 file_handles.reserve(file_names.size() + file_handles.size());
205 for (const base::string16& file_name : file_names) {
206 // This leaks the handles, since they are used as the reference key to
207 // CreateFontFileStream, and DirectWrite requires the reference keys to
208 // remain valid for the lifetime of the loader. The loader is the font
209 // collection proxy, which remains alive for the lifetime of the renderer.
210 HANDLE handle =
211 CreateFile(file_name.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL,
212 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
nasko 2016/07/21 21:45:56 Do we allow the renderer process to open font file
Ilya Kulshin 2016/07/22 03:30:37 Since these files are in the system fonts director
213 if (handle != INVALID_HANDLE_VALUE)
214 handles.push_back(handle);
215 }
216 for (uint32_t file_handle : file_handles) {
217 handles.push_back(reinterpret_cast<HANDLE>(file_handle));
218 }
219
201 HRESULT hr = mswr::MakeAndInitialize<FontFileEnumerator>( 220 HRESULT hr = mswr::MakeAndInitialize<FontFileEnumerator>(
202 font_file_enumerator, factory, this, &file_names); 221 font_file_enumerator, factory, this, &handles);
203 222
204 if (!SUCCEEDED(hr)) { 223 if (!SUCCEEDED(hr)) {
205 DCHECK(false); 224 DCHECK(false);
206 return E_FAIL; 225 return E_FAIL;
207 } 226 }
208 227
209 return S_OK; 228 return S_OK;
210 } 229 }
211 230
212 HRESULT DWriteFontCollectionProxy::CreateStreamFromKey( 231 HRESULT DWriteFontCollectionProxy::CreateStreamFromKey(
213 const void* font_file_reference_key, 232 const void* font_file_reference_key,
214 UINT32 font_file_reference_key_size, 233 UINT32 font_file_reference_key_size,
215 IDWriteFontFileStream** font_file_stream) { 234 IDWriteFontFileStream** font_file_stream) {
216 if (!font_file_reference_key) { 235 if (font_file_reference_key_size != sizeof(HANDLE)) {
217 return E_FAIL;
218 }
219
220 const base::char16* file_name =
221 reinterpret_cast<const base::char16*>(font_file_reference_key);
222 DCHECK_EQ(font_file_reference_key_size % sizeof(base::char16), 0u);
223 size_t file_name_size =
224 static_cast<size_t>(font_file_reference_key_size) / sizeof(base::char16);
225
226 if (file_name_size == 0 || file_name[file_name_size - 1] != L'\0') {
227 return E_FAIL; 236 return E_FAIL;
228 } 237 }
229 238
230 TRACE_EVENT0("dwrite", "FontFileEnumerator::CreateStreamFromKey"); 239 TRACE_EVENT0("dwrite", "FontFileEnumerator::CreateStreamFromKey");
231 240
232 mswr::ComPtr<IDWriteFontFileStream> stream; 241 HANDLE file_handle =
233 if (!SUCCEEDED(mswr::MakeAndInitialize<FontFileStream>(&stream, file_name))) { 242 *reinterpret_cast<const HANDLE*>(font_file_reference_key);
243
244 if (file_handle == NULL || file_handle == INVALID_HANDLE_VALUE) {
234 DCHECK(false); 245 DCHECK(false);
235 return E_FAIL; 246 return E_FAIL;
236 } 247 }
248
249 mswr::ComPtr<FontFileStream> stream;
250 if (!SUCCEEDED(
251 mswr::MakeAndInitialize<FontFileStream>(&stream, file_handle))) {
252 DCHECK(false);
253 return E_FAIL;
254 }
237 *font_file_stream = stream.Detach(); 255 *font_file_stream = stream.Detach();
238 return S_OK; 256 return S_OK;
239 } 257 }
240 258
241 HRESULT DWriteFontCollectionProxy::RuntimeClassInitialize( 259 HRESULT DWriteFontCollectionProxy::RuntimeClassInitialize(
242 IDWriteFactory* factory, 260 IDWriteFactory* factory,
243 IPC::Sender* sender_override) { 261 IPC::Sender* sender_override) {
244 DCHECK(factory); 262 DCHECK(factory);
245 263
246 factory_ = factory; 264 factory_ = factory;
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 522
505 return SUCCEEDED(hr); 523 return SUCCEEDED(hr);
506 } 524 }
507 525
508 FontFileEnumerator::FontFileEnumerator() = default; 526 FontFileEnumerator::FontFileEnumerator() = default;
509 527
510 FontFileEnumerator::~FontFileEnumerator() = default; 528 FontFileEnumerator::~FontFileEnumerator() = default;
511 529
512 HRESULT FontFileEnumerator::GetCurrentFontFile(IDWriteFontFile** file) { 530 HRESULT FontFileEnumerator::GetCurrentFontFile(IDWriteFontFile** file) {
513 DCHECK(file); 531 DCHECK(file);
514 if (current_file_ >= file_names_.size()) { 532 if (current_file_ >= files_.size()) {
515 return E_FAIL; 533 return E_FAIL;
516 } 534 }
517 535
518 TRACE_EVENT0("dwrite", "FontFileEnumerator::GetCurrentFontFile"); 536 TRACE_EVENT0("dwrite", "FontFileEnumerator::GetCurrentFontFile");
537
519 // CreateCustomFontFileReference ends up calling 538 // CreateCustomFontFileReference ends up calling
520 // DWriteFontCollectionProxy::CreateStreamFromKey. 539 // DWriteFontCollectionProxy::CreateStreamFromKey.
521 HRESULT hr = factory_->CreateCustomFontFileReference( 540 HRESULT hr = factory_->CreateCustomFontFileReference(
522 reinterpret_cast<const void*>(file_names_[current_file_].c_str()), 541 reinterpret_cast<const void*>(&files_[current_file_]),
523 (file_names_[current_file_].length() + 1) * sizeof(base::char16), 542 sizeof(files_[current_file_]), loader_.Get() /*IDWriteFontFileLoader*/,
524 loader_.Get() /*IDWriteFontFileLoader*/, file); 543 file);
525 DCHECK(SUCCEEDED(hr)); 544 DCHECK(SUCCEEDED(hr));
526 return hr; 545 return hr;
527 } 546 }
528 547
529 HRESULT FontFileEnumerator::MoveNext(BOOL* has_current_file) { 548 HRESULT FontFileEnumerator::MoveNext(BOOL* has_current_file) {
530 DCHECK(has_current_file); 549 DCHECK(has_current_file);
531 550
532 TRACE_EVENT0("dwrite", "FontFileEnumerator::MoveNext"); 551 TRACE_EVENT0("dwrite", "FontFileEnumerator::MoveNext");
533 if (next_file_ >= file_names_.size()) { 552 if (next_file_ >= files_.size()) {
534 *has_current_file = FALSE; 553 *has_current_file = FALSE;
535 current_file_ = UINT_MAX; 554 current_file_ = UINT_MAX;
536 return S_OK; 555 return S_OK;
537 } 556 }
538 557
539 current_file_ = next_file_; 558 current_file_ = next_file_;
540 ++next_file_; 559 ++next_file_;
541 *has_current_file = TRUE; 560 *has_current_file = TRUE;
542 return S_OK; 561 return S_OK;
543 } 562 }
544 563
545 HRESULT FontFileEnumerator::RuntimeClassInitialize( 564 HRESULT FontFileEnumerator::RuntimeClassInitialize(
546 IDWriteFactory* factory, 565 IDWriteFactory* factory,
547 IDWriteFontFileLoader* loader, 566 IDWriteFontFileLoader* loader,
548 std::vector<base::string16>* file_names) { 567 std::vector<HANDLE>* files) {
549 factory_ = factory; 568 factory_ = factory;
550 loader_ = loader; 569 loader_ = loader;
551 file_names_.swap(*file_names); 570 files_.swap(*files);
552 file_streams_.resize(file_names_.size());
553 return S_OK; 571 return S_OK;
554 } 572 }
555 573
556 FontFileStream::FontFileStream() = default; 574 FontFileStream::FontFileStream() = default;
557 575
558 FontFileStream::~FontFileStream() = default; 576 FontFileStream::~FontFileStream() = default;
559 577
560 HRESULT FontFileStream::GetFileSize(UINT64* file_size) { 578 HRESULT FontFileStream::GetFileSize(UINT64* file_size) {
561 *file_size = data_.length(); 579 *file_size = data_.length();
562 return S_OK; 580 return S_OK;
(...skipping 10 matching lines...) Expand all
573 void** fragment_context) { 591 void** fragment_context) {
574 if (fragment_offset + fragment_size < fragment_offset) 592 if (fragment_offset + fragment_size < fragment_offset)
575 return E_FAIL; 593 return E_FAIL;
576 if (fragment_offset + fragment_size > data_.length()) 594 if (fragment_offset + fragment_size > data_.length())
577 return E_FAIL; 595 return E_FAIL;
578 *fragment_start = data_.data() + fragment_offset; 596 *fragment_start = data_.data() + fragment_offset;
579 *fragment_context = nullptr; 597 *fragment_context = nullptr;
580 return S_OK; 598 return S_OK;
581 } 599 }
582 600
583 HRESULT FontFileStream::RuntimeClassInitialize( 601 HRESULT FontFileStream::RuntimeClassInitialize(HANDLE handle) {
584 const base::string16& file_name) { 602 // Duplicate the original handle so we can reopen the file after the memory
585 data_.Initialize(base::FilePath(file_name)); 603 // mapped section closes it.
604 HANDLE duplicate_handle;
605 if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(),
606 &duplicate_handle, 0 /* dwDesiredAccess */,
607 false /* bInheritHandle */, DUPLICATE_SAME_ACCESS)) {
608 LogFontProxyError(DUPLICATE_HANDLE_FAILED);
609 return E_FAIL;
610 }
611
612 data_.Initialize(base::File(duplicate_handle));
586 if (!data_.IsValid()) { 613 if (!data_.IsValid()) {
587 LogFontProxyError(MAPPED_FILE_FAILED); 614 LogFontProxyError(MAPPED_FILE_FAILED);
588 return E_FAIL; 615 return E_FAIL;
589 } 616 }
590 return S_OK; 617 return S_OK;
591 } 618 }
592 619
593 } // namespace content 620 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698