From eb7ab47f855b45286f0e62a643babacfe6af8fa1 Mon Sep 17 00:00:00 2001 From: roytam1 Date: Mon, 1 Mar 2021 10:06:37 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1147722 - Part 2. Remove keyboardMayHaveIME method. r=wmccloskey (c0c7c8e85) - Bug 1120487 - Implement shim before moving security checks into AsyncOpen; adding wrapper (r=sicking,sworkman) (d2eb4b169) - Bug 1120487 - Implement shim before moving security checks into AsyncOpen, ioservice changes (r=sicking,sworkman) (41aca5645) --- netwerk/base/moz.build | 2 + netwerk/base/nsIOService.cpp | 46 +++++----- netwerk/base/nsISecCheckWrapChannel.idl | 24 ++++++ netwerk/base/nsSecCheckWrapChannel.cpp | 108 ++++++++++++++++++++++++ netwerk/base/nsSecCheckWrapChannel.h | 85 +++++++++++++++++++ toolkit/xre/nsAppRunner.cpp | 34 -------- widget/windows/nsTextStore.cpp | 4 +- xpcom/system/nsIXULRuntime.idl | 9 +- 8 files changed, 247 insertions(+), 65 deletions(-) create mode 100644 netwerk/base/nsISecCheckWrapChannel.idl create mode 100644 netwerk/base/nsSecCheckWrapChannel.cpp create mode 100644 netwerk/base/nsSecCheckWrapChannel.h diff --git a/netwerk/base/moz.build b/netwerk/base/moz.build index ab518be901..0246073011 100644 --- a/netwerk/base/moz.build +++ b/netwerk/base/moz.build @@ -92,6 +92,7 @@ XPIDL_SOURCES += [ 'nsIRequestObserverProxy.idl', 'nsIResponseHeadProvider.idl', 'nsIResumableChannel.idl', + 'nsISecCheckWrapChannel.idl', 'nsISecretDecoderRing.idl', 'nsISecureBrowserUI.idl', 'nsISecurityEventSink.idl', @@ -215,6 +216,7 @@ UNIFIED_SOURCES += [ 'nsProtocolProxyService.cpp', 'nsProxyInfo.cpp', 'nsRequestObserverProxy.cpp', + 'nsSecCheckWrapChannel.cpp', 'nsSerializationHelper.cpp', 'nsServerSocket.cpp', 'nsSimpleNestedURI.cpp', diff --git a/netwerk/base/nsIOService.cpp b/netwerk/base/nsIOService.cpp index 241b4657ac..65950ff326 100644 --- a/netwerk/base/nsIOService.cpp +++ b/netwerk/base/nsIOService.cpp @@ -22,6 +22,7 @@ #include "nsEscape.h" #include "nsNetCID.h" #include "nsCRT.h" +#include "nsSecCheckWrapChannel.h" #include "nsSimpleNestedURI.h" #include "nsNetUtil.h" #include "nsTArray.h" @@ -622,43 +623,43 @@ nsIOService::NewChannelFromURIWithProxyFlagsInternal(nsIURI* aURI, // Keep in mind that Addons can implement their own Protocolhandlers, hence // NewChannel2() might *not* be implemented. // We do not want to break those addons, therefore we first try to create a channel - // calling NewChannel2(); if that fails we fall back to creating a channel by calling - // NewChannel(); - - bool newChannel2Succeeded = true; - + // calling NewChannel2(); if that fails: + // * we fall back to creating a channel by calling NewChannel() + // * wrap the addon channel + // * and attach the loadInfo to the channel wrapper + nsCOMPtr channel; nsCOMPtr pph = do_QueryInterface(handler); if (pph) { rv = pph->NewProxiedChannel2(aURI, nullptr, aProxyFlags, aProxyURI, - aLoadInfo, result); + aLoadInfo, getter_AddRefs(channel)); // if calling NewProxiedChannel2() fails we try to fall back to // creating a new proxied channel by calling NewProxiedChannel(). if (NS_FAILED(rv)) { - newChannel2Succeeded = false; rv = pph->NewProxiedChannel(aURI, nullptr, aProxyFlags, aProxyURI, - result); + getter_AddRefs(channel)); + NS_ENSURE_SUCCESS(rv, rv); + // we have to wrap that channel + channel = new nsSecCheckWrapChannel(channel, aLoadInfo); } } else { - rv = handler->NewChannel2(aURI, aLoadInfo, result); + rv = handler->NewChannel2(aURI, aLoadInfo, getter_AddRefs(channel)); // if calling newChannel2() fails we try to fall back to // creating a new channel by calling NewChannel(). if (NS_FAILED(rv)) { - newChannel2Succeeded = false; - rv = handler->NewChannel(aURI, result); + rv = handler->NewChannel(aURI, getter_AddRefs(channel)); + NS_ENSURE_SUCCESS(rv, rv); + // we have to wrap that channel + channel = new nsSecCheckWrapChannel(channel, aLoadInfo); } } - NS_ENSURE_SUCCESS(rv, rv); - if (aLoadInfo && newChannel2Succeeded) { - // Make sure that all the individual protocolhandlers attach - // a loadInfo within it's implementation of ::newChannel2(). - // Once Bug 1087720 lands, we should remove the surrounding - // if-clause here and always assert that we indeed have a - // loadinfo on the newly created channel. - nsCOMPtr loadInfo; - (*result)->GetLoadInfo(getter_AddRefs(loadInfo)); + // Make sure that all the individual protocolhandlers attach a loadInfo. + if (aLoadInfo) { // make sure we have the same instance of loadInfo on the newly created channel + nsCOMPtr loadInfo; + channel->GetLoadInfo(getter_AddRefs(loadInfo)); + if (aLoadInfo != loadInfo) { MOZ_ASSERT(false, "newly created channel must have a loadinfo attached"); return NS_ERROR_UNEXPECTED; @@ -667,7 +668,7 @@ nsIOService::NewChannelFromURIWithProxyFlagsInternal(nsIURI* aURI, // If we're sandboxed, make sure to clear any owner the channel // might already have. if (loadInfo->GetLoadingSandboxed()) { - (*result)->SetOwner(nullptr); + channel->SetOwner(nullptr); } } @@ -679,7 +680,7 @@ nsIOService::NewChannelFromURIWithProxyFlagsInternal(nsIURI* aURI, // implement the new interface. // See bug 529041 if (!gHasWarnedUploadChannel2 && scheme.EqualsLiteral("http")) { - nsCOMPtr uploadChannel2 = do_QueryInterface(*result); + nsCOMPtr uploadChannel2 = do_QueryInterface(channel); if (!uploadChannel2) { nsCOMPtr consoleService = do_GetService(NS_CONSOLESERVICE_CONTRACTID); @@ -692,6 +693,7 @@ nsIOService::NewChannelFromURIWithProxyFlagsInternal(nsIURI* aURI, } } + channel.forget(result); return NS_OK; } diff --git a/netwerk/base/nsISecCheckWrapChannel.idl b/netwerk/base/nsISecCheckWrapChannel.idl new file mode 100644 index 0000000000..21f4d0c290 --- /dev/null +++ b/netwerk/base/nsISecCheckWrapChannel.idl @@ -0,0 +1,24 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +interface nsIChannel; + +/** + * nsISecCheckWrapChannel + * Describes an XPCOM component used to wrap channels for performing + * security checks. Channels wrapped inside this class can use + * this interface to query the wrapped inner channel. + */ + +[scriptable, uuid(9446c5d5-c9fb-4a6e-acf9-ca4fc666efe0)] +interface nsISecCheckWrapChannel : nsISupports +{ + /** + * Returns the wrapped channel inside this class. + */ + readonly attribute nsIChannel innerChannel; + +}; diff --git a/netwerk/base/nsSecCheckWrapChannel.cpp b/netwerk/base/nsSecCheckWrapChannel.cpp new file mode 100644 index 0000000000..09a7f6fce7 --- /dev/null +++ b/netwerk/base/nsSecCheckWrapChannel.cpp @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsSecCheckWrapChannel.h" +#include "nsHttpChannel.h" +#include "nsCOMPtr.h" + +#ifdef PR_LOGGING +static PRLogModuleInfo* +GetChannelWrapperLog() +{ + static PRLogModuleInfo* gChannelWrapperPRLog; + if (!gChannelWrapperPRLog) { + gChannelWrapperPRLog = PR_NewLogModule("ChannelWrapper"); + } + return gChannelWrapperPRLog; +} +#endif + +#define CHANNELWRAPPERLOG(args) PR_LOG(GetChannelWrapperLog(), 4, args) + +NS_IMPL_ADDREF(nsSecCheckWrapChannelBase) +NS_IMPL_RELEASE(nsSecCheckWrapChannelBase) + +NS_INTERFACE_MAP_BEGIN(nsSecCheckWrapChannelBase) + NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel) + NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannelInternal, mHttpChannelInternal) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIHttpChannel) + NS_INTERFACE_MAP_ENTRY(nsIRequest) + NS_INTERFACE_MAP_ENTRY(nsIChannel) + NS_INTERFACE_MAP_ENTRY(nsISecCheckWrapChannel) +NS_INTERFACE_MAP_END + +//--------------------------------------------------------- +// nsSecCheckWrapChannelBase implementation +//--------------------------------------------------------- + +nsSecCheckWrapChannelBase::nsSecCheckWrapChannelBase(nsIChannel* aChannel) + : mChannel(aChannel) + , mHttpChannel(do_QueryInterface(aChannel)) + , mHttpChannelInternal(do_QueryInterface(aChannel)) + , mRequest(do_QueryInterface(aChannel)) +{ + MOZ_ASSERT(mChannel, "can not create a channel wrapper without a channel"); +} + +nsSecCheckWrapChannelBase::~nsSecCheckWrapChannelBase() +{ +} + +//--------------------------------------------------------- +// nsISecCheckWrapChannel implementation +//--------------------------------------------------------- + +NS_IMETHODIMP +nsSecCheckWrapChannelBase::GetInnerChannel(nsIChannel **aInnerChannel) +{ + NS_IF_ADDREF(*aInnerChannel = mChannel); + return NS_OK; +} + +//--------------------------------------------------------- +// nsSecCheckWrapChannel implementation +//--------------------------------------------------------- + +nsSecCheckWrapChannel::nsSecCheckWrapChannel(nsIChannel* aChannel, + nsILoadInfo* aLoadInfo) + : nsSecCheckWrapChannelBase(aChannel) + , mLoadInfo(aLoadInfo) +{ +#ifdef PR_LOGGING + { + nsCOMPtr uri; + mChannel->GetURI(getter_AddRefs(uri)); + nsAutoCString spec; + if (uri) { + uri->GetSpec(spec); + } + CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::nsSecCheckWrapChannel [%p] (%s)",this, spec.get())); + } +#endif +} + +nsSecCheckWrapChannel::~nsSecCheckWrapChannel() +{ +} + +//--------------------------------------------------------- +// nsIChannel implementation +//--------------------------------------------------------- + +NS_IMETHODIMP +nsSecCheckWrapChannel::GetLoadInfo(nsILoadInfo** aLoadInfo) +{ + CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::GetLoadInfo() [%p]",this)); + NS_IF_ADDREF(*aLoadInfo = mLoadInfo); + return NS_OK; +} + +NS_IMETHODIMP +nsSecCheckWrapChannel::SetLoadInfo(nsILoadInfo* aLoadInfo) +{ + CHANNELWRAPPERLOG(("nsSecCheckWrapChannel::SetLoadInfo() [%p]", this)); + mLoadInfo = aLoadInfo; + return NS_OK; +} diff --git a/netwerk/base/nsSecCheckWrapChannel.h b/netwerk/base/nsSecCheckWrapChannel.h new file mode 100644 index 0000000000..9ba164ca61 --- /dev/null +++ b/netwerk/base/nsSecCheckWrapChannel.h @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsSecCheckWrapChannel_h__ +#define nsSecCheckWrapChannel_h__ + +#include "nsIHttpChannel.h" +#include "nsIHttpChannelInternal.h" +#include "nsISecCheckWrapChannel.h" +#include "nsIWyciwygChannel.h" +#include "mozilla/LoadInfo.h" + +/* + * The nsSecCheckWrapChannelBase wraps channels that do *not* + * * provide a newChannel2() implementation + * * provide get/setLoadInfo functions + * + * In order to perform security checks for channels + * a) before opening the channel, and + * b) after redirects + * we are attaching a loadinfo object to every channel which + * provides information about the content-type of the channel, + * who initiated the load, etc. + * + * Addon created channels might *not* provide that loadInfo object for + * some transition time before we mark the NewChannel-API as deprecated. + * We do not want to break those addons hence we wrap such channels + * using the provided wrapper in this class. + * + * Please note that the wrapper only forwards calls for + * * nsIRequest + * * nsIChannel + * * nsIHttpChannel + * * nsIHttpChannelInternal + * + * In case any addon needs to query the inner channel this class + * provides a readonly function to query the wrapped channel. + * + */ + +class nsSecCheckWrapChannelBase : public nsIHttpChannel + , public nsIHttpChannelInternal + , public nsISecCheckWrapChannel +{ +public: + NS_FORWARD_NSIHTTPCHANNEL(mHttpChannel->) + NS_FORWARD_NSIHTTPCHANNELINTERNAL(mHttpChannelInternal->) + NS_FORWARD_NSICHANNEL(mChannel->) + NS_FORWARD_NSIREQUEST(mRequest->) + NS_DECL_NSISECCHECKWRAPCHANNEL + NS_DECL_ISUPPORTS + + explicit nsSecCheckWrapChannelBase(nsIChannel* aChannel); + +protected: + virtual ~nsSecCheckWrapChannelBase(); + + nsCOMPtr mChannel; + // We do a QI in the constructor to set the following pointers. + nsCOMPtr mHttpChannel; + nsCOMPtr mHttpChannelInternal; + nsCOMPtr mRequest; +}; + +/* We define a separate class here to make it clear that we're + * overriding Get/SetLoadInfo, rather that using the forwarded + * implementations provided by NS_FORWARD_NSICHANNEL" + */ +class nsSecCheckWrapChannel : public nsSecCheckWrapChannelBase +{ +public: + NS_IMETHOD GetLoadInfo(nsILoadInfo **aLoadInfo); + NS_IMETHOD SetLoadInfo(nsILoadInfo *aLoadInfo); + + nsSecCheckWrapChannel(nsIChannel* aChannel, nsILoadInfo* aLoadInfo); + +protected: + virtual ~nsSecCheckWrapChannel(); + + nsCOMPtr mLoadInfo; +}; + +#endif // nsSecCheckWrapChannel_h__ diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 3b19c6087d..de23484a7b 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -571,29 +571,6 @@ CanShowProfileManager() return true; } -static bool -KeyboardMayHaveIME() -{ -#ifdef XP_WIN - // http://msdn.microsoft.com/en-us/library/windows/desktop/dd318693%28v=vs.85%29.aspx - HKL locales[10]; - int result = GetKeyboardLayoutList(10, locales); - for (int i = 0; i < result; i++) { - int kb = (uintptr_t)locales[i] & 0xFFFF; - if (kb == 0x0411 || // japanese - kb == 0x0412 || // korean - kb == 0x0C04 || // HK Chinese - kb == 0x0804 || kb == 0x0004 || // Hans Chinese - kb == 0x7C04 || kb == 0x0404) { //Hant Chinese - - return true; - } - } -#endif - - return false; -} - bool gSafeMode = false; /** @@ -866,13 +843,6 @@ nsXULAppInfo::GetAccessibilityEnabled(bool* aResult) return NS_OK; } -NS_IMETHODIMP -nsXULAppInfo::GetKeyboardMayHaveIME(bool* aResult) -{ - *aResult = KeyboardMayHaveIME(); - return NS_OK; -} - NS_IMETHODIMP nsXULAppInfo::GetAccessibilityIsUIA(bool* aResult) { @@ -4100,8 +4070,6 @@ mozilla::BrowserTabsRemoteAutostart() // Nightly builds, update gBrowserTabsRemoteAutostart based on all the // e10s remote relayed prefs we watch. bool disabledForA11y = Preferences::GetBool("browser.tabs.remote.autostart.disabled-because-using-a11y", false); - // Only disable for IME for the automatic pref, not the opt-in one. - bool disabledForIME = trialPref && KeyboardMayHaveIME(); if (prefEnabled) { if (gSafeMode) { @@ -4110,8 +4078,6 @@ mozilla::BrowserTabsRemoteAutostart() } else if (disabledForA11y) { status = kE10sDisabledForAccessibility; LogE10sBlockedReason("An accessibility tool is active"); - } else if (disabledForIME) { - LogE10sBlockedReason("The keyboard being used has activated IME"); } else { gBrowserTabsRemoteAutostart = true; } diff --git a/widget/windows/nsTextStore.cpp b/widget/windows/nsTextStore.cpp index cc1c2f2841..62924a51ce 100644 --- a/widget/windows/nsTextStore.cpp +++ b/widget/windows/nsTextStore.cpp @@ -15,6 +15,7 @@ #include "mozilla/Preferences.h" #include "mozilla/TextEvents.h" #include "mozilla/WindowsVersion.h" +#include "nsIXULRuntime.h" #define INPUTSCOPE_INIT_GUID #define TEXTATTRS_INIT_GUID @@ -4590,7 +4591,8 @@ nsTextStore::Initialize() bool enableTsf = Preferences::GetBool(kPrefNameForceEnableTSF, false) || - (IsVistaOrLater() && Preferences::GetBool(kPrefNameEnableTSF, false)); + (IsVistaOrLater() && Preferences::GetBool(kPrefNameEnableTSF, false) && + !BrowserTabsRemoteAutostart()); PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, ("TSF: nsTextStore::Initialize(), TSF is %s", enableTsf ? "enabled" : "disabled")); diff --git a/xpcom/system/nsIXULRuntime.idl b/xpcom/system/nsIXULRuntime.idl index d000977fb7..00c8df3fb1 100644 --- a/xpcom/system/nsIXULRuntime.idl +++ b/xpcom/system/nsIXULRuntime.idl @@ -23,7 +23,7 @@ bool BrowserTabsRemoteAutostart(); * stable/frozen, please contact Benjamin Smedberg. */ -[scriptable, uuid(5754b56e-f392-426d-aec0-3ba7c49aff32)] +[scriptable, uuid(c4cd11c4-6e8e-49da-85a8-dad3b7605bc3)] interface nsIXULRuntime : nsISupports { /** @@ -96,13 +96,6 @@ interface nsIXULRuntime : nsISupports */ readonly attribute boolean accessibilityEnabled; - /** - * This returns a very rough approximation of whether IME is likely - * to be used for the browser session. DO NOT USE! This is temporary - * and will be removed. - */ - readonly attribute boolean keyboardMayHaveIME; - /** * Indicates if the active accessibility client is UIA. * DO NOT USE! This is temporary and will be removed.