Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | // Use "dyld interposing" to hook methods imported from other libraries in the |
michael@0 | 7 | // plugin child process. The basic technique is described at |
michael@0 | 8 | // http://books.google.com/books?id=K8vUkpOXhN4C&pg=PA73&lpg=PA73&dq=__interpose&source=bl&ots=OJnnXZYpZC&sig=o7I3lXvoduUi13SrPfOON7o3do4&hl=en&ei=AoehS9brCYGQNrvsmeUM&sa=X&oi=book_result&ct=result&resnum=6&ved=0CBsQ6AEwBQ#v=onepage&q=__interpose&f=false. |
michael@0 | 9 | // The idea of doing it for the plugin child process comes from Chromium code, |
michael@0 | 10 | // particularly from plugin_carbon_interpose_mac.cc |
michael@0 | 11 | // (http://codesearch.google.com/codesearch/p?hl=en#OAMlx_jo-ck/src/chrome/browser/plugin_carbon_interpose_mac.cc&q=nscursor&exact_package=chromium&d=1&l=168) |
michael@0 | 12 | // and from PluginProcessHost::Init() in plugin_process_host.cc |
michael@0 | 13 | // (http://codesearch.google.com/codesearch/p?hl=en#OAMlx_jo-ck/src/content/browser/plugin_process_host.cc&q=nscursor&exact_package=chromium&d=1&l=222). |
michael@0 | 14 | |
michael@0 | 15 | // These hooks are needed to make certain OS calls work from the child process |
michael@0 | 16 | // (a background process) that would normally only work when called in the |
michael@0 | 17 | // parent process (the foreground process). They allow us to serialize |
michael@0 | 18 | // information from the child process to the parent process, so that the same |
michael@0 | 19 | // (or equivalent) calls can be made from the parent process. |
michael@0 | 20 | |
michael@0 | 21 | // This file lives in a seperate module (libplugin_child_interpose.dylib), |
michael@0 | 22 | // which will get loaded by the OS before any other modules when the plugin |
michael@0 | 23 | // child process is launched (from GeckoChildProcessHost:: |
michael@0 | 24 | // PerformAsyncLaunchInternal()). For this reason it shouldn't link in other |
michael@0 | 25 | // browser modules when loaded. Instead it should use dlsym() to load |
michael@0 | 26 | // pointers to the methods it wants to call in other modules. |
michael@0 | 27 | |
michael@0 | 28 | #if !defined(__LP64__) |
michael@0 | 29 | |
michael@0 | 30 | #include <dlfcn.h> |
michael@0 | 31 | #import <Carbon/Carbon.h> |
michael@0 | 32 | |
michael@0 | 33 | // The header file QuickdrawAPI.h is missing on OS X 10.7 and up (though the |
michael@0 | 34 | // QuickDraw APIs defined in it are still present) -- so we need to supply the |
michael@0 | 35 | // relevant parts of its contents here. It's likely that Apple will eventually |
michael@0 | 36 | // remove the APIs themselves (probably in OS X 10.8), so we need to make them |
michael@0 | 37 | // weak imports, and test for their presence before using them. |
michael@0 | 38 | #if !defined(__QUICKDRAWAPI__) |
michael@0 | 39 | |
michael@0 | 40 | struct Cursor; |
michael@0 | 41 | extern "C" void SetCursor(const Cursor * crsr) __attribute__((weak_import)); |
michael@0 | 42 | |
michael@0 | 43 | #endif /* __QUICKDRAWAPI__ */ |
michael@0 | 44 | |
michael@0 | 45 | BOOL (*OnSetThemeCursorPtr) (ThemeCursor) = NULL; |
michael@0 | 46 | BOOL (*OnSetCursorPtr) (const Cursor*) = NULL; |
michael@0 | 47 | BOOL (*OnHideCursorPtr) () = NULL; |
michael@0 | 48 | BOOL (*OnShowCursorPtr) () = NULL; |
michael@0 | 49 | |
michael@0 | 50 | static BOOL loadXULPtrs() |
michael@0 | 51 | { |
michael@0 | 52 | if (!OnSetThemeCursorPtr) { |
michael@0 | 53 | // mac_plugin_interposing_child_OnSetThemeCursor(ThemeCursor cursor) is in |
michael@0 | 54 | // PluginInterposeOSX.mm |
michael@0 | 55 | OnSetThemeCursorPtr = (BOOL(*)(ThemeCursor)) |
michael@0 | 56 | dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnSetThemeCursor"); |
michael@0 | 57 | } |
michael@0 | 58 | if (!OnSetCursorPtr) { |
michael@0 | 59 | // mac_plugin_interposing_child_OnSetCursor(const Cursor* cursor) is in |
michael@0 | 60 | // PluginInterposeOSX.mm |
michael@0 | 61 | OnSetCursorPtr = (BOOL(*)(const Cursor*)) |
michael@0 | 62 | dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnSetCursor"); |
michael@0 | 63 | } |
michael@0 | 64 | if (!OnHideCursorPtr) { |
michael@0 | 65 | // mac_plugin_interposing_child_OnHideCursor() is in PluginInterposeOSX.mm |
michael@0 | 66 | OnHideCursorPtr = (BOOL(*)()) |
michael@0 | 67 | dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnHideCursor"); |
michael@0 | 68 | } |
michael@0 | 69 | if (!OnShowCursorPtr) { |
michael@0 | 70 | // mac_plugin_interposing_child_OnShowCursor() is in PluginInterposeOSX.mm |
michael@0 | 71 | OnShowCursorPtr = (BOOL(*)()) |
michael@0 | 72 | dlsym(RTLD_DEFAULT, "mac_plugin_interposing_child_OnShowCursor"); |
michael@0 | 73 | } |
michael@0 | 74 | return (OnSetCursorPtr && OnSetThemeCursorPtr && OnHideCursorPtr && OnShowCursorPtr); |
michael@0 | 75 | } |
michael@0 | 76 | |
michael@0 | 77 | static OSStatus MacPluginChildSetThemeCursor(ThemeCursor cursor) |
michael@0 | 78 | { |
michael@0 | 79 | if (loadXULPtrs()) { |
michael@0 | 80 | OnSetThemeCursorPtr(cursor); |
michael@0 | 81 | } |
michael@0 | 82 | return ::SetThemeCursor(cursor); |
michael@0 | 83 | } |
michael@0 | 84 | |
michael@0 | 85 | static void MacPluginChildSetCursor(const Cursor* cursor) |
michael@0 | 86 | { |
michael@0 | 87 | if (::SetCursor) { |
michael@0 | 88 | if (loadXULPtrs()) { |
michael@0 | 89 | OnSetCursorPtr(cursor); |
michael@0 | 90 | } |
michael@0 | 91 | ::SetCursor(cursor); |
michael@0 | 92 | } |
michael@0 | 93 | } |
michael@0 | 94 | |
michael@0 | 95 | static CGError MacPluginChildCGDisplayHideCursor(CGDirectDisplayID display) |
michael@0 | 96 | { |
michael@0 | 97 | if (loadXULPtrs()) { |
michael@0 | 98 | OnHideCursorPtr(); |
michael@0 | 99 | } |
michael@0 | 100 | return ::CGDisplayHideCursor(display); |
michael@0 | 101 | } |
michael@0 | 102 | |
michael@0 | 103 | static CGError MacPluginChildCGDisplayShowCursor(CGDirectDisplayID display) |
michael@0 | 104 | { |
michael@0 | 105 | if (loadXULPtrs()) { |
michael@0 | 106 | OnShowCursorPtr(); |
michael@0 | 107 | } |
michael@0 | 108 | return ::CGDisplayShowCursor(display); |
michael@0 | 109 | } |
michael@0 | 110 | |
michael@0 | 111 | #pragma mark - |
michael@0 | 112 | |
michael@0 | 113 | struct interpose_substitution { |
michael@0 | 114 | const void* replacement; |
michael@0 | 115 | const void* original; |
michael@0 | 116 | }; |
michael@0 | 117 | |
michael@0 | 118 | #define INTERPOSE_FUNCTION(function) \ |
michael@0 | 119 | { reinterpret_cast<const void*>(MacPluginChild##function), \ |
michael@0 | 120 | reinterpret_cast<const void*>(function) } |
michael@0 | 121 | |
michael@0 | 122 | __attribute__((used)) static const interpose_substitution substitutions[] |
michael@0 | 123 | __attribute__((section("__DATA, __interpose"))) = { |
michael@0 | 124 | INTERPOSE_FUNCTION(SetThemeCursor), |
michael@0 | 125 | INTERPOSE_FUNCTION(CGDisplayHideCursor), |
michael@0 | 126 | INTERPOSE_FUNCTION(CGDisplayShowCursor), |
michael@0 | 127 | // SetCursor() and other QuickDraw APIs will probably be removed in OS X |
michael@0 | 128 | // 10.8. But this will make 'SetCursor' NULL, which will just stop the OS |
michael@0 | 129 | // from interposing it (tested using an INTERPOSE_FUNCTION_BROKEN macro |
michael@0 | 130 | // that just sets the second address of each tuple to NULL). |
michael@0 | 131 | INTERPOSE_FUNCTION(SetCursor), |
michael@0 | 132 | }; |
michael@0 | 133 | |
michael@0 | 134 | #endif // !__LP64__ |