diff options
author | scottmg <scottmg@chromium.org> | 2015-01-15 13:00:46 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-15 21:01:52 +0000 |
commit | 55a856eb124f941c191c62dab40055b827186395 (patch) | |
tree | d49845c9bf3b24015f9cf0b0f2f0913bfca49c13 | |
parent | 4e37c9fa01a1683bd1e3460864e6813c8ea0313b (diff) | |
download | chromium_src-55a856eb124f941c191c62dab40055b827186395.zip chromium_src-55a856eb124f941c191c62dab40055b827186395.tar.gz chromium_src-55a856eb124f941c191c62dab40055b827186395.tar.bz2 |
Fix font loading in OOP PDF
This does two things
- avoids pdf.dll being loaded into the renderer when OOP PDF is
being used (this was caused by the patching)
- does the patch in PpapiThread when pdf.dll is loaded there for OOP
The IAT patch to GetFontData allows various users of GDI font methods
to succeed when sandboxed.
R=cpu@chromium.org,raymes@chromium.org,ananta@chromium.org
BUG=448473
Review URL: https://codereview.chromium.org/854773002
Cr-Commit-Position: refs/heads/master@{#311730}
-rw-r--r-- | chrome/renderer/chrome_render_process_observer.cc | 20 | ||||
-rw-r--r-- | content/ppapi_plugin/ppapi_thread.cc | 58 |
2 files changed, 70 insertions, 8 deletions
diff --git a/chrome/renderer/chrome_render_process_observer.cc b/chrome/renderer/chrome_render_process_observer.cc index 860dd32..9367b98 100644 --- a/chrome/renderer/chrome_render_process_observer.cc +++ b/chrome/renderer/chrome_render_process_observer.cc @@ -281,14 +281,18 @@ ChromeRenderProcessObserver::ChromeRenderProcessObserver( net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider); #if defined(OS_WIN) - // Need to patch a few functions for font loading to work correctly. - base::FilePath pdf; - if (PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf) && - base::PathExists(pdf)) { - g_iat_patch_createdca.Patch( - pdf.value().c_str(), "gdi32.dll", "CreateDCA", CreateDCAPatch); - g_iat_patch_get_font_data.Patch( - pdf.value().c_str(), "gdi32.dll", "GetFontData", GetFontDataPatch); + // TODO(scottmg): http://crbug.com/448473. This code should be removed once + // PDF is always OOP and/or PDF is made to use Skia instead of GDI directly. + if (!command_line.HasSwitch(switches::kEnableOutOfProcessPdf)) { + // Need to patch a few functions for font loading to work correctly. + base::FilePath pdf; + if (PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf) && + base::PathExists(pdf)) { + g_iat_patch_createdca.Patch(pdf.value().c_str(), "gdi32.dll", "CreateDCA", + CreateDCAPatch); + g_iat_patch_get_font_data.Patch(pdf.value().c_str(), "gdi32.dll", + "GetFontData", GetFontDataPatch); + } } #endif diff --git a/content/ppapi_plugin/ppapi_thread.cc b/content/ppapi_plugin/ppapi_thread.cc index 59edaaf..6d77afe 100644 --- a/content/ppapi_plugin/ppapi_thread.cc +++ b/content/ppapi_plugin/ppapi_thread.cc @@ -42,10 +42,12 @@ #include "ppapi/proxy/plugin_message_filter.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/resource_reply_thread_registrar.h" +#include "ppapi/shared_impl/proxy_lock.h" #include "third_party/WebKit/public/web/WebKit.h" #include "ui/base/ui_base_switches.h" #if defined(OS_WIN) +#include "base/win/iat_patch_function.h" #include "base/win/win_util.h" #include "base/win/windows_version.h" #include "sandbox/win/src/sandbox.h" @@ -91,6 +93,53 @@ static void WarmupWindowsLocales(const ppapi::PpapiPermissions& permissions) { } } } + +// TODO(scottmg): http://crbug.com/448473. This code should be removed from the +// renderer once PDF is always OOP and/or PDF is made to use Skia instead of GDI +// directly. +const wchar_t kPdfFileName[] = L"pdf.dll"; + +static base::win::IATPatchFunction g_iat_patch_createdca; +HDC WINAPI CreateDCAPatch(LPCSTR driver_name, + LPCSTR device_name, + LPCSTR output, + const void* init_data) { + DCHECK(std::string("DISPLAY") == std::string(driver_name)); + DCHECK(!device_name); + DCHECK(!output); + DCHECK(!init_data); + + // CreateDC fails behind the sandbox, but not CreateCompatibleDC. + return CreateCompatibleDC(NULL); +} + +static base::win::IATPatchFunction g_iat_patch_get_font_data; +DWORD WINAPI GetFontDataPatch(HDC hdc, + DWORD table, + DWORD offset, + LPVOID buffer, + DWORD length) { + int rv = GetFontData(hdc, table, offset, buffer, length); + if (rv == GDI_ERROR && hdc) { + HFONT font = static_cast<HFONT>(GetCurrentObject(hdc, OBJ_FONT)); + + LOGFONT logfont; + if (GetObject(font, sizeof(LOGFONT), &logfont)) { + std::vector<char> font_data; + { + ppapi::ProxyAutoLock lock; + // In the sandbox, font loading will fail. We ask the browser to load it + // which causes it to be loaded by the kernel, which then makes the + // subsequent call succeed. + ppapi::proxy::PluginGlobals::Get()->PreCacheFontForFlash( + reinterpret_cast<const void*>(&logfont)); + } + rv = GetFontData(hdc, table, offset, buffer, length); + } + } + return rv; +} + #else extern void* g_target_services; #endif @@ -325,6 +374,15 @@ void PpapiThread::OnLoadPlugin(const base::FilePath& path, // otherwise these would be silent terminations and fly under the radar). base::win::SetAbortBehaviorForCrashReporting(); + // Need to patch a few functions for font loading to work correctly. This can + // be removed once we switch PDF to use Skia. + if (GetModuleHandle(kPdfFileName)) { + g_iat_patch_createdca.Patch(kPdfFileName, "gdi32.dll", "CreateDCA", + CreateDCAPatch); + g_iat_patch_get_font_data.Patch(kPdfFileName, "gdi32.dll", "GetFontData", + GetFontDataPatch); + } + // Once we lower the token the sandbox is locked down and no new modules // can be loaded. TODO(cpu): consider changing to the loading style of // regular plugins. |