зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1774317 - part 2: Make `TSFTextStore` support `GUID_PROP_URL` r=m_kato
`GUID_PROP_URL` is defined here: https://learn.microsoft.com/en-us/windows/win32/tsf/predefined-properties > Contains a BSTR value representing the URL of the text control source, where > applicable. The URL may contain sensitive information, e.g., user name, password, query string. However, they are already leaked via MSAA/UIA. https://searchfox.org/mozilla-central/rev/b1e5f2c7c96be36974262551978d54f457db2cae/accessible/generic/DocAccessible.cpp#350 Therefore, this patch just has prefs to completely prevent to expose the URL for users who don't like this feature. Differential Revision: https://phabricator.services.mozilla.com/D157894
This commit is contained in:
Родитель
b3600e6d25
Коммит
58fa8fca99
|
@ -6844,6 +6844,23 @@
|
|||
value: @IS_NOT_EARLY_BETA_OR_EARLIER@
|
||||
mirror: always
|
||||
|
||||
# If true, TSF and TIP (IME) can retrieve URL of the document containing
|
||||
# the focused element. When this is set to true, Gecko exposes the spec
|
||||
# of the URL.
|
||||
# And Gecko exposes only "http" and "https" URLs. E.g., "data", "blob",
|
||||
# "file" URLs are never exposed.
|
||||
- name: intl.tsf.expose_url.allowed
|
||||
type: bool
|
||||
value: true
|
||||
mirror: always
|
||||
|
||||
# If true, TSF and TIP (IME) can retrieve URL of the document containing
|
||||
# the focused element in the private browsing mode too.
|
||||
- name: intl.tsf.expose_url_in_private_browsing.allowed
|
||||
type: bool
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
#if defined(ENABLE_TESTS)
|
||||
# If true, NS_GetComplexLineBreaks compares the line breaks produced in the
|
||||
# content process using the Uniscribe line breaker, with those from a
|
||||
|
|
|
@ -7,8 +7,10 @@
|
|||
#define TEXTATTRS_INIT_GUID
|
||||
#include "TSFTextStore.h"
|
||||
|
||||
#include <olectl.h>
|
||||
#include <algorithm>
|
||||
#include <comutil.h> // for _bstr_t
|
||||
#include <oleauto.h> // for SysAllocString
|
||||
#include <olectl.h>
|
||||
#include "nscore.h"
|
||||
|
||||
#include "IMMHandler.h"
|
||||
|
@ -26,6 +28,7 @@
|
|||
#include "mozilla/WindowsVersion.h"
|
||||
#include "nsWindow.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsReadableUtils.h" // for VoidString()
|
||||
|
||||
// Workaround for mingw32
|
||||
#ifndef TS_SD_INPUTPANEMANUALDISPLAYENABLE
|
||||
|
@ -38,6 +41,14 @@
|
|||
// Therefore you shouldn't use `LogLevel::Verbose` for logging usual behavior.
|
||||
mozilla::LazyLogModule gIMELog("IMEHandler");
|
||||
|
||||
// TODO: GUID_PROP_URL has not been declared in the SDK yet. We should drop the
|
||||
// `s` prefix after it's released by a new SDK and define it with #if.
|
||||
static const GUID sGUID_PROP_URL = {
|
||||
0xd5138268,
|
||||
0xa1bf,
|
||||
0x4308,
|
||||
{0xbc, 0xbf, 0x2e, 0x73, 0x93, 0x98, 0xe2, 0x34}};
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
|
@ -228,6 +239,7 @@ static nsCString GetGUIDNameStrWithTable(REFGUID aGUID) {
|
|||
}
|
||||
|
||||
RETURN_GUID_NAME(GUID_PROP_INPUTSCOPE)
|
||||
RETURN_GUID_NAME(sGUID_PROP_URL)
|
||||
RETURN_GUID_NAME(TSATTRID_OTHERS)
|
||||
RETURN_GUID_NAME(TSATTRID_Font)
|
||||
RETURN_GUID_NAME(TSATTRID_Font_FaceName)
|
||||
|
@ -1807,22 +1819,7 @@ TSFTextStore::TSFTextStore()
|
|||
mSinkMask(0),
|
||||
mLock(0),
|
||||
mLockQueued(0),
|
||||
mHandlingKeyMessage(0),
|
||||
mRequestedAttrValues(false),
|
||||
mIsRecordingActionsWithoutLock(false),
|
||||
mHasReturnedNoLayoutError(false),
|
||||
mWaitingQueryLayout(false),
|
||||
mPendingDestroy(false),
|
||||
mDeferClearingContentForTSF(false),
|
||||
mDeferNotifyingTSF(false),
|
||||
mDeferCommittingComposition(false),
|
||||
mDeferCancellingComposition(false),
|
||||
mDestroyed(false),
|
||||
mBeingDestroyed(false) {
|
||||
for (int32_t i = 0; i < NUM_OF_SUPPORTED_ATTRS; i++) {
|
||||
mRequestedAttrs[i] = false;
|
||||
}
|
||||
|
||||
mHandlingKeyMessage(0) {
|
||||
// We hope that 5 or more actions don't occur at once.
|
||||
mPendingActions.SetCapacity(5);
|
||||
|
||||
|
@ -1871,8 +1868,16 @@ bool TSFTextStore::Init(nsWindow* aWidget, const InputContext& aContext) {
|
|||
return false;
|
||||
}
|
||||
|
||||
SetInputScope(aContext.mHTMLInputType, aContext.mHTMLInputInputmode,
|
||||
aContext.mInPrivateBrowsing);
|
||||
mInPrivateBrowsing = aContext.mInPrivateBrowsing;
|
||||
SetInputScope(aContext.mHTMLInputType, aContext.mHTMLInputInputmode);
|
||||
|
||||
if (aContext.mURI) {
|
||||
// We don't need the document URL if it fails, let's ignore the error.
|
||||
nsAutoCString spec;
|
||||
if (NS_SUCCEEDED(aContext.mURI->GetSpec(spec))) {
|
||||
CopyUTF8toUTF16(spec, mDocumentURL);
|
||||
}
|
||||
}
|
||||
|
||||
// Create document manager
|
||||
RefPtr<ITfThreadMgr> threadMgr = sThreadMgr;
|
||||
|
@ -2000,6 +2005,7 @@ void TSFTextStore::ReleaseTSFObjects() {
|
|||
MOZ_LOG(gIMELog, LogLevel::Info,
|
||||
("0x%p TSFTextStore::ReleaseTSFObjects()", this));
|
||||
|
||||
mDocumentURL.Truncate();
|
||||
mContext = nullptr;
|
||||
if (mDocumentMgr) {
|
||||
RefPtr<ITfDocumentMgr> documentMgr = mDocumentMgr.forget();
|
||||
|
@ -3911,8 +3917,7 @@ bool TSFTextStore::ShouldSetInputScopeOfURLBarToDefault() {
|
|||
}
|
||||
|
||||
void TSFTextStore::SetInputScope(const nsString& aHTMLInputType,
|
||||
const nsString& aHTMLInputInputMode,
|
||||
bool aInPrivateBrowsing) {
|
||||
const nsString& aHTMLInputInputMode) {
|
||||
mInputScopes.Clear();
|
||||
|
||||
// IME may refer only first input scope, but we will append inputmode's
|
||||
|
@ -3920,7 +3925,7 @@ void TSFTextStore::SetInputScope(const nsString& aHTMLInputType,
|
|||
IMEHandler::AppendInputScopeFromType(aHTMLInputType, mInputScopes);
|
||||
IMEHandler::AppendInputScopeFromInputmode(aHTMLInputInputMode, mInputScopes);
|
||||
|
||||
if (aInPrivateBrowsing) {
|
||||
if (mInPrivateBrowsing) {
|
||||
mInputScopes.AppendElement(IS_PRIVATE);
|
||||
}
|
||||
}
|
||||
|
@ -3929,6 +3934,9 @@ int32_t TSFTextStore::GetRequestedAttrIndex(const TS_ATTRID& aAttrID) {
|
|||
if (IsEqualGUID(aAttrID, GUID_PROP_INPUTSCOPE)) {
|
||||
return eInputScope;
|
||||
}
|
||||
if (IsEqualGUID(aAttrID, sGUID_PROP_URL)) {
|
||||
return eDocumentURL;
|
||||
}
|
||||
if (IsEqualGUID(aAttrID, TSATTRID_Text_VerticalWriting)) {
|
||||
return eTextVerticalWriting;
|
||||
}
|
||||
|
@ -3943,6 +3951,8 @@ TSFTextStore::GetAttrID(int32_t aIndex) {
|
|||
switch (aIndex) {
|
||||
case eInputScope:
|
||||
return GUID_PROP_INPUTSCOPE;
|
||||
case eDocumentURL:
|
||||
return sGUID_PROP_URL;
|
||||
case eTextVerticalWriting:
|
||||
return TSATTRID_Text_VerticalWriting;
|
||||
case eTextOrientation:
|
||||
|
@ -4049,6 +4059,9 @@ TSFTextStore::FindNextAttrTransition(LONG acpStart, LONG acpHalt,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
// To test the document URL result, define this to out put it to the stdout
|
||||
// #define DEBUG_PRINT_DOCUMENT_URL
|
||||
|
||||
STDMETHODIMP
|
||||
TSFTextStore::RetrieveRequestedAttrs(ULONG ulCount, TS_ATTRVAL* paAttrVals,
|
||||
ULONG* pcFetched) {
|
||||
|
@ -4079,6 +4092,32 @@ TSFTextStore::RetrieveRequestedAttrs(ULONG ulCount, TS_ATTRVAL* paAttrVals,
|
|||
"ulCount=%lu, mRequestedAttrValues=%s",
|
||||
this, ulCount, GetBoolName(mRequestedAttrValues)));
|
||||
|
||||
auto GetExposingURL = [&]() -> BSTR {
|
||||
const bool allowed =
|
||||
StaticPrefs::intl_tsf_expose_url_allowed() &&
|
||||
(!mInPrivateBrowsing ||
|
||||
StaticPrefs::intl_tsf_expose_url_in_private_browsing_allowed());
|
||||
if (!allowed) {
|
||||
MOZ_ASSERT(EmptyString().get());
|
||||
return ::SysAllocString(EmptyString().get());
|
||||
}
|
||||
if (mDocumentURL.IsEmpty()) {
|
||||
MOZ_ASSERT(EmptyString().get());
|
||||
return ::SysAllocString(EmptyString().get());
|
||||
}
|
||||
return ::SysAllocString(mDocumentURL.get());
|
||||
};
|
||||
|
||||
#ifdef DEBUG_PRINT_DOCUMENT_URL
|
||||
{
|
||||
BSTR exposingURL = GetExposingURL();
|
||||
printf("TSFTextStore::RetrieveRequestedAttrs: DocumentURL=\"%s\"\n",
|
||||
NS_ConvertUTF16toUTF8(static_cast<char16ptr_t>(_bstr_t(exposingURL)))
|
||||
.get());
|
||||
::SysFreeString(exposingURL);
|
||||
}
|
||||
#endif // #ifdef DEBUG_PRINT_DOCUMENT_URL
|
||||
|
||||
int32_t count = 0;
|
||||
for (int32_t i = 0; i < NUM_OF_SUPPORTED_ATTRS; i++) {
|
||||
if (!mRequestedAttrs[i]) {
|
||||
|
@ -4105,6 +4144,11 @@ TSFTextStore::RetrieveRequestedAttrs(ULONG ulCount, TS_ATTRVAL* paAttrVals,
|
|||
paAttrVals[count].varValue.punkVal = inputScope.forget().take();
|
||||
break;
|
||||
}
|
||||
case eDocumentURL: {
|
||||
paAttrVals[count].varValue.vt = VT_BSTR;
|
||||
paAttrVals[count].varValue.bstrVal = GetExposingURL();
|
||||
break;
|
||||
}
|
||||
case eTextVerticalWriting: {
|
||||
Maybe<Selection>& selectionForTSF = SelectionForTSF();
|
||||
paAttrVals[count].varValue.vt = VT_BOOL;
|
||||
|
@ -4151,6 +4195,8 @@ TSFTextStore::RetrieveRequestedAttrs(ULONG ulCount, TS_ATTRVAL* paAttrVals,
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
#undef DEBUG_PRINT_DOCUMENT_URL
|
||||
|
||||
STDMETHODIMP
|
||||
TSFTextStore::GetEndACP(LONG* pacp) {
|
||||
MOZ_LOG(gIMELog, LogLevel::Info,
|
||||
|
@ -6652,9 +6698,19 @@ void TSFTextStore::SetInputContext(nsWindow* aWidget,
|
|||
"Why is this called when TSF is disabled?");
|
||||
if (sEnabledTextStore) {
|
||||
RefPtr<TSFTextStore> textStore(sEnabledTextStore);
|
||||
textStore->mInPrivateBrowsing = aContext.mInPrivateBrowsing;
|
||||
textStore->SetInputScope(aContext.mHTMLInputType,
|
||||
aContext.mHTMLInputInputmode,
|
||||
aContext.mInPrivateBrowsing);
|
||||
aContext.mHTMLInputInputmode);
|
||||
if (aContext.mURI) {
|
||||
nsAutoCString spec;
|
||||
if (NS_SUCCEEDED(aContext.mURI->GetSpec(spec))) {
|
||||
CopyUTF8toUTF16(spec, textStore->mDocumentURL);
|
||||
} else {
|
||||
textStore->mDocumentURL.Truncate();
|
||||
}
|
||||
} else {
|
||||
textStore->mDocumentURL.Truncate();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -382,8 +382,7 @@ class TSFTextStore final : public ITextStoreACP,
|
|||
HRESULT HandleRequestAttrs(DWORD aFlags, ULONG aFilterCount,
|
||||
const TS_ATTRID* aFilterAttrs);
|
||||
void SetInputScope(const nsString& aHTMLInputType,
|
||||
const nsString& aHTMLInputInputmode,
|
||||
bool aInPrivateBrowsing);
|
||||
const nsString& aHTMLInputInputMode);
|
||||
|
||||
// Creates native caret over our caret. This method only works on desktop
|
||||
// application. Otherwise, this does nothing.
|
||||
|
@ -1018,6 +1017,9 @@ class TSFTextStore final : public ITextStoreACP,
|
|||
// The input scopes for this context, defaults to IS_DEFAULT.
|
||||
nsTArray<InputScope> mInputScopes;
|
||||
|
||||
// The URL cache of the focused document.
|
||||
nsString mDocumentURL;
|
||||
|
||||
// Support retrieving attributes.
|
||||
// TODO: We should support RightToLeft, perhaps.
|
||||
enum {
|
||||
|
@ -1026,56 +1028,59 @@ class TSFTextStore final : public ITextStoreACP,
|
|||
|
||||
// Supported attributes
|
||||
eInputScope = 0,
|
||||
eDocumentURL,
|
||||
eTextVerticalWriting,
|
||||
eTextOrientation,
|
||||
|
||||
// Count of the supported attributes
|
||||
NUM_OF_SUPPORTED_ATTRS
|
||||
};
|
||||
bool mRequestedAttrs[NUM_OF_SUPPORTED_ATTRS];
|
||||
bool mRequestedAttrs[NUM_OF_SUPPORTED_ATTRS]{false};
|
||||
|
||||
int32_t GetRequestedAttrIndex(const TS_ATTRID& aAttrID);
|
||||
TS_ATTRID GetAttrID(int32_t aIndex);
|
||||
|
||||
bool mRequestedAttrValues;
|
||||
bool mRequestedAttrValues = false;
|
||||
|
||||
// If edit actions are being recorded without document lock, this is true.
|
||||
// Otherwise, false.
|
||||
bool mIsRecordingActionsWithoutLock;
|
||||
bool mIsRecordingActionsWithoutLock = false;
|
||||
// If GetTextExt() or GetACPFromPoint() is called and the layout hasn't been
|
||||
// calculated yet, these methods return TS_E_NOLAYOUT. At that time,
|
||||
// mHasReturnedNoLayoutError is set to true.
|
||||
bool mHasReturnedNoLayoutError;
|
||||
bool mHasReturnedNoLayoutError = false;
|
||||
// Before calling ITextStoreACPSink::OnLayoutChange() and
|
||||
// ITfContextOwnerServices::OnLayoutChange(), mWaitingQueryLayout is set to
|
||||
// true. This is set to false when GetTextExt() or GetACPFromPoint() is
|
||||
// called.
|
||||
bool mWaitingQueryLayout;
|
||||
// During the documet is locked, we shouldn't destroy the instance.
|
||||
bool mWaitingQueryLayout = false;
|
||||
// During the document is locked, we shouldn't destroy the instance.
|
||||
// If this is true, the instance will be destroyed after unlocked.
|
||||
bool mPendingDestroy;
|
||||
// If this is false, MaybeFlushPendingNotifications() will clear the
|
||||
// mContentForTSF.
|
||||
bool mDeferClearingContentForTSF;
|
||||
bool mDeferClearingContentForTSF = false;
|
||||
// While the instance is dispatching events, the event may not be handled
|
||||
// synchronously in e10s mode. So, in such case, in strictly speaking,
|
||||
// we shouldn't query layout information. However, TS_E_NOLAYOUT bugs of
|
||||
// ITextStoreAPC::GetTextExt() blocks us to behave ideally.
|
||||
// For preventing it to be called, we should put off notifying TSF of
|
||||
// anything until layout information becomes available.
|
||||
bool mDeferNotifyingTSF;
|
||||
bool mDeferNotifyingTSF = false;
|
||||
// While the document is locked, committing composition always fails since
|
||||
// TSF needs another document lock for modifying the composition, selection
|
||||
// and etc. So, committing composition should be performed after the
|
||||
// document is unlocked.
|
||||
bool mDeferCommittingComposition;
|
||||
bool mDeferCancellingComposition;
|
||||
bool mDeferCommittingComposition = false;
|
||||
bool mDeferCancellingComposition = false;
|
||||
// Immediately after a call of Destroy(), mDestroyed becomes true. If this
|
||||
// is true, the instance shouldn't grant any requests from the TIP anymore.
|
||||
bool mDestroyed;
|
||||
bool mDestroyed = false;
|
||||
// While the instance is being destroyed, this is set to true for avoiding
|
||||
// recursive Destroy() calls.
|
||||
bool mBeingDestroyed;
|
||||
bool mBeingDestroyed = false;
|
||||
// Whether we're in the private browsing mode.
|
||||
bool mInPrivateBrowsing = true;
|
||||
|
||||
// TSF thread manager object for the current application
|
||||
static StaticRefPtr<ITfThreadMgr> sThreadMgr;
|
||||
|
|
Загрузка…
Ссылка в новой задаче