diff options
-rw-r--r-- | application/palemoon/base/content/aboutDialog.xul | 3 | ||||
-rw-r--r-- | application/palemoon/branding/shared/pref/uaoverrides.inc | 3 | ||||
-rw-r--r-- | dom/canvas/CanvasRenderingContext2D.cpp | 7 | ||||
-rw-r--r-- | dom/canvas/CanvasRenderingContext2D.h | 4 | ||||
-rw-r--r-- | dom/smil/nsSMILAnimationController.cpp | 2 | ||||
-rw-r--r-- | js/public/Value.h | 7 | ||||
-rw-r--r-- | js/src/gc/Nursery.cpp | 1 | ||||
-rw-r--r-- | js/src/gc/Nursery.h | 1 | ||||
-rw-r--r-- | js/src/jsfun.cpp | 58 | ||||
-rw-r--r-- | mfbt/RangedPtr.h | 2 | ||||
-rw-r--r-- | netwerk/protocol/http/TunnelUtils.cpp | 67 | ||||
-rw-r--r-- | netwerk/protocol/http/TunnelUtils.h | 11 | ||||
-rw-r--r-- | netwerk/protocol/http/nsHttpConnection.cpp | 21 | ||||
-rw-r--r-- | netwerk/protocol/http/nsHttpConnection.h | 3 | ||||
-rw-r--r-- | uriloader/exthandler/win/nsOSHelperAppService.cpp | 192 |
15 files changed, 160 insertions, 222 deletions
diff --git a/application/palemoon/base/content/aboutDialog.xul b/application/palemoon/base/content/aboutDialog.xul index a34923a0a..6edfc2155 100644 --- a/application/palemoon/base/content/aboutDialog.xul +++ b/application/palemoon/base/content/aboutDialog.xul @@ -24,9 +24,6 @@ id="PMaboutDialog" windowtype="Browser:About" onload="init(event);" -#ifdef MOZ_UPDATER - onunload="onUnload(event);" -#endif #ifdef XP_MACOSX inwindowmenu="false" #else diff --git a/application/palemoon/branding/shared/pref/uaoverrides.inc b/application/palemoon/branding/shared/pref/uaoverrides.inc index 3e28225f4..36a0ae145 100644 --- a/application/palemoon/branding/shared/pref/uaoverrides.inc +++ b/application/palemoon/branding/shared/pref/uaoverrides.inc @@ -57,6 +57,9 @@ pref("@GUAO_PREF@.www.amazon.com","Mozilla/5.0 (@OS_SLICE@ rv:45.9) @GK_SLICE@ F pref("@GUAO_PREF@.soundcloud.com","Mozilla/5.0 (@OS_SLICE@ rv:@GRE_VERSION@) @GRE_DATE_SLICE@ @PM_SLICE@");
// Daily motion only likes strict Firefox UAs
pref("@GUAO_PREF@.dailymotion.com","Mozilla/5.0 (@OS_SLICE@ rv:52.0) @GK_SLICE@ Firefox/52.0");
+// Financial Times' polyfill.io breaks horribly on a Pale Moon UA. Send a strict Firefox UA instead.
+pref("@GUAO_PREF@.polyfill.io","Mozilla/5.0 (@OS_SLICE@ rv:60.9) @GK_SLICE@ Firefox/60.9");
+
// The following requires native mode. Or it blocks.. "too old firefox", breakage, etc.
pref("@GUAO_PREF@.deviantart.com","Mozilla/5.0 (@OS_SLICE@ rv:@GRE_VERSION@) @GRE_DATE_SLICE@ @PM_SLICE@");
diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index a750c69b0..4849fda57 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -6329,6 +6329,13 @@ CanvasRenderingContext2D::ShouldForceInactiveLayer(LayerManager* aManager) return !aManager->CanUseCanvasLayerForSize(GetSize()); } +void CanvasRenderingContext2D::SetWriteOnly() { + mWriteOnly = true; + if (mCanvasElement) { + mCanvasElement->SetWriteOnly(); + } +} + NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CanvasPath, AddRef) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CanvasPath, Release) diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h index 46758ec88..d4f295a03 100644 --- a/dom/canvas/CanvasRenderingContext2D.h +++ b/dom/canvas/CanvasRenderingContext2D.h @@ -1156,9 +1156,7 @@ protected: // For the origin-clean algorithm (mWriteOnly == !origin-clean) // See https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html - void SetWriteOnly() { - mWriteOnly = true; - } + void SetWriteOnly(); bool IsWriteOnly() const { return mWriteOnly; diff --git a/dom/smil/nsSMILAnimationController.cpp b/dom/smil/nsSMILAnimationController.cpp index 0dd616346..69956203e 100644 --- a/dom/smil/nsSMILAnimationController.cpp +++ b/dom/smil/nsSMILAnimationController.cpp @@ -233,7 +233,7 @@ void nsSMILAnimationController::NotifyRefreshDriverCreated( nsRefreshDriver* aRefreshDriver) { - if (!mPauseState) { + if (!mPauseState && mChildContainerTable.Count()) { MaybeStartSampling(aRefreshDriver); } } diff --git a/js/public/Value.h b/js/public/Value.h index 01666ed4e..7c4f833e3 100644 --- a/js/public/Value.h +++ b/js/public/Value.h @@ -567,8 +567,11 @@ class MOZ_NON_PARAM alignas(8) Value } bool isMagic(JSWhyMagic why) const { - MOZ_ASSERT_IF(isMagic(), data.s.payload.why == why); - return isMagic(); + if (!isMagic()) { + return false; + } + MOZ_RELEASE_ASSERT(data.s.payload.why == why); + return true; } JS::TraceKind traceKind() const { diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index ea4350fb8..93a0eb6a8 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -210,6 +210,7 @@ js::Nursery::disable() return; updateNumChunks(0); currentEnd_ = 0; + position_ = 0; runtime()->gc.storeBuffer.disable(); } diff --git a/js/src/gc/Nursery.h b/js/src/gc/Nursery.h index 0d215d997..a839a4979 100644 --- a/js/src/gc/Nursery.h +++ b/js/src/gc/Nursery.h @@ -245,6 +245,7 @@ class Nursery // Free space remaining, not counting chunk trailers. MOZ_ALWAYS_INLINE size_t freeSpace() const { + MOZ_ASSERT(isEnabled()); MOZ_ASSERT(currentEnd_ - position_ <= NurseryChunkUsableSize); return (currentEnd_ - position_) + (numChunks() - currentChunk_ - 1) * NurseryChunkUsableSize; diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index 863871df9..98311be2f 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -288,6 +288,12 @@ CallerGetterImpl(JSContext* cx, const CallArgs& args) return true; } + if (JS_IsDeadWrapper(callerObj)) { + JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, + JSMSG_DEAD_OBJECT); + return false; + } + JSFunction* callerFun = &callerObj->as<JSFunction>(); MOZ_ASSERT(!callerFun->isBuiltin(), "non-builtin iterator returned a builtin?"); @@ -314,54 +320,14 @@ CallerSetterImpl(JSContext* cx, const CallArgs& args) { MOZ_ASSERT(IsFunction(args.thisv())); - // Beware! This function can be invoked on *any* function! It can't - // assume it'll never be invoked on natives, strict mode functions, bound - // functions, or anything else that ordinarily has immutable .caller - // defined with [[ThrowTypeError]]. - RootedFunction fun(cx, &args.thisv().toObject().as<JSFunction>()); - if (!CallerRestrictions(cx, fun)) - return false; - - // Return |undefined| unless an error must be thrown. - args.rval().setUndefined(); - - // We can almost just return |undefined| here -- but if the caller function - // was strict mode code, we still have to throw a TypeError. This requires - // computing the caller, checking that no security boundaries are crossed, - // and throwing a TypeError if the resulting caller is strict. - - NonBuiltinScriptFrameIter iter(cx); - if (!AdvanceToActiveCallLinear(cx, iter, fun)) - return true; - - ++iter; - while (!iter.done() && iter.isEvalFrame()) - ++iter; - - if (iter.done() || !iter.isFunctionFrame()) - return true; - - RootedObject caller(cx, iter.callee(cx)); - if (!cx->compartment()->wrap(cx, &caller)) { - cx->clearPendingException(); - return true; - } - - // If we don't have full access to the caller, or the caller is not strict, - // return undefined. Otherwise throw a TypeError. - JSObject* callerObj = CheckedUnwrap(caller); - if (!callerObj) - return true; - - JSFunction* callerFun = &callerObj->as<JSFunction>(); - MOZ_ASSERT(!callerFun->isBuiltin(), "non-builtin iterator returned a builtin?"); - - if (callerFun->strict()) { - JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr, - JSMSG_CALLER_IS_STRICT); - return false; + // We just have to return |undefined|, but first we call CallerGetterImpl
+ // because we need the same strict-mode and security checks.
+
+ if (!CallerGetterImpl(cx, args)) { + return false;
} + args.rval().setUndefined(); return true; } diff --git a/mfbt/RangedPtr.h b/mfbt/RangedPtr.h index a07c1f4f8..a3d4ec103 100644 --- a/mfbt/RangedPtr.h +++ b/mfbt/RangedPtr.h @@ -212,7 +212,7 @@ public: return *this; } - T& operator[](int aIndex) const + T& operator[](ptrdiff_t aIndex) const { MOZ_ASSERT(size_t(aIndex > 0 ? aIndex : -aIndex) <= size_t(-1) / sizeof(T)); return *create(mPtr + aIndex); diff --git a/netwerk/protocol/http/TunnelUtils.cpp b/netwerk/protocol/http/TunnelUtils.cpp index 4cc24a07f..6880e0187 100644 --- a/netwerk/protocol/http/TunnelUtils.cpp +++ b/netwerk/protocol/http/TunnelUtils.cpp @@ -23,6 +23,7 @@ #include "nsNetCID.h" #include "nsServiceManagerUtils.h" #include "nsComponentManagerUtils.h" +#include "nsSocketTransport2.h" namespace mozilla { namespace net { @@ -42,6 +43,7 @@ TLSFilterTransaction::TLSFilterTransaction(nsAHttpTransaction *aWrapped, , mSegmentReader(aReader) , mSegmentWriter(aWriter) , mForce(false) + , mReadSegmentReturnValue(NS_OK) , mNudgeCounter(0) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); @@ -130,6 +132,19 @@ TLSFilterTransaction::Close(nsresult aReason) } mTransaction->Close(aReason); mTransaction = nullptr; + + RefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans)); + SpdyConnectTransaction *trans = baseTrans + ? baseTrans->QuerySpdyConnectTransaction() + : nullptr; + + LOG(("TLSFilterTransaction::Close %p aReason=%" PRIx32 " trans=%p\n", + this, static_cast<uint32_t>(aReason), trans)); + + if (trans) { + trans->Close(aReason); + trans = nullptr; + } } nsresult @@ -140,7 +155,7 @@ TLSFilterTransaction::OnReadSegment(const char *aData, LOG(("TLSFilterTransaction %p OnReadSegment %d (buffered %d)\n", this, aCount, mEncryptedTextUsed)); - mReadSegmentBlocked = false; + mReadSegmentReturnValue = NS_OK; MOZ_ASSERT(mSegmentReader); if (!mSecInfo) { return NS_ERROR_FAILURE; @@ -188,10 +203,12 @@ TLSFilterTransaction::OnReadSegment(const char *aData, return NS_OK; } // mTransaction ReadSegments actually obscures this code, so - // keep it in a member var for this::ReadSegments to insepct. Similar + // keep it in a member var for this::ReadSegments to inspect. Similar // to nsHttpConnection::mSocketOutCondition - mReadSegmentBlocked = (PR_GetError() == PR_WOULD_BLOCK_ERROR); - return mReadSegmentBlocked ? NS_BASE_STREAM_WOULD_BLOCK : NS_ERROR_FAILURE; + PRErrorCode code = PR_GetError(); + mReadSegmentReturnValue = ErrorAccordingToNSPR(code); + + return mReadSegmentReturnValue; } aCount -= written; aData += written; @@ -273,10 +290,18 @@ TLSFilterTransaction::OnWriteSegment(char *aData, mFilterReadCode = NS_OK; int32_t bytesRead = PR_Read(mFD, aData, aCount); if (bytesRead == -1) { - if (PR_GetError() == PR_WOULD_BLOCK_ERROR) { + PRErrorCode code = PR_GetError(); + if (code == PR_WOULD_BLOCK_ERROR) { return NS_BASE_STREAM_WOULD_BLOCK; } - return NS_ERROR_FAILURE; + // If reading from the socket succeeded (NS_SUCCEEDED(mFilterReadCode)), + // but the nss layer encountered an error remember the error. + if (NS_SUCCEEDED(mFilterReadCode)) { + mFilterReadCode = ErrorAccordingToNSPR(code); + LOG(("TLSFilterTransaction::OnWriteSegment %p nss error %" PRIx32 ".\n", + this, static_cast<uint32_t>(mFilterReadCode))); + } + return mFilterReadCode; } *outCountRead = bytesRead; @@ -303,7 +328,7 @@ TLSFilterTransaction::FilterInput(char *aBuf, int32_t aAmount) if (NS_SUCCEEDED(mFilterReadCode) && outCountRead) { LOG(("TLSFilterTransaction::FilterInput rv=%x read=%d input from net " "1 layer stripped, 1 still on\n", mFilterReadCode, outCountRead)); - if (mReadSegmentBlocked) { + if (mReadSegmentReturnValue == NS_BASE_STREAM_WOULD_BLOCK) { mNudgeCounter = 0; } } @@ -325,19 +350,18 @@ TLSFilterTransaction::ReadSegments(nsAHttpSegmentReader *aReader, return NS_ERROR_UNEXPECTED; } - mReadSegmentBlocked = false; + mReadSegmentReturnValue = NS_OK; mSegmentReader = aReader; nsresult rv = mTransaction->ReadSegments(this, aCount, outCountRead); LOG(("TLSFilterTransaction %p called trans->ReadSegments rv=%x %d\n", this, rv, *outCountRead)); - if (NS_SUCCEEDED(rv) && mReadSegmentBlocked) { - rv = NS_BASE_STREAM_WOULD_BLOCK; + if (NS_SUCCEEDED(rv) && (mReadSegmentReturnValue == NS_BASE_STREAM_WOULD_BLOCK)) { LOG(("TLSFilterTransaction %p read segment blocked found rv=%x\n", - this, rv)); + this, static_cast<uint32_t>(rv))); Connection()->ForceSend(); } - return rv; + return NS_SUCCEEDED(rv) ? mReadSegmentReturnValue : rv; } nsresult @@ -442,7 +466,10 @@ TLSFilterTransaction::Notify(nsITimer *timer) if (timer != mTimer) { return NS_ERROR_UNEXPECTED; } - StartTimerCallback(); + nsresult rv = StartTimerCallback(); + if (NS_FAILED(rv)) { + Close(rv); + } return NS_OK; } @@ -456,7 +483,7 @@ TLSFilterTransaction::StartTimerCallback() // This class can be called re-entrantly, so cleanup m* before ->on() RefPtr<NudgeTunnelCallback> cb(mNudgeCallback); mNudgeCallback = nullptr; - cb->OnTunnelNudged(this); + return cb->OnTunnelNudged(this); } return NS_OK; } @@ -675,10 +702,12 @@ TLSFilterTransaction::TakeSubTransactions( } nsresult -TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans) +TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans, + nsAHttpTransaction *aSpdyConnectTransaction) { - LOG(("TLSFilterTransaction::SetProxiedTransaction [this=%p] aTrans=%p\n", - this, aTrans)); + LOG(("TLSFilterTransaction::SetProxiedTransaction [this=%p] aTrans=%p, " + "aSpdyConnectTransaction=%p\n", + this, aTrans, aSpdyConnectTransaction)); mTransaction = aTrans; nsCOMPtr<nsIInterfaceRequestor> callbacks; @@ -688,6 +717,8 @@ TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans) secCtrl->SetNotificationCallbacks(callbacks); } + mWeakTrans = do_GetWeakReference(aSpdyConnectTransaction); + return NS_OK; } @@ -1075,7 +1106,7 @@ SpdyConnectTransaction::MapStreamToHttpConnection(nsISocketTransport *aTransport if (mForcePlainText) { mTunneledConn->ForcePlainText(); } else { - mTunneledConn->SetupSecondaryTLS(); + mTunneledConn->SetupSecondaryTLS(this); mTunneledConn->SetInSpdyTunnel(true); } diff --git a/netwerk/protocol/http/TunnelUtils.h b/netwerk/protocol/http/TunnelUtils.h index 20cfaf7ee..4a003082e 100644 --- a/netwerk/protocol/http/TunnelUtils.h +++ b/netwerk/protocol/http/TunnelUtils.h @@ -93,10 +93,11 @@ class TLSFilterTransaction; class NudgeTunnelCallback : public nsISupports { public: - virtual void OnTunnelNudged(TLSFilterTransaction *) = 0; + virtual nsresult OnTunnelNudged(TLSFilterTransaction *) = 0; }; -#define NS_DECL_NUDGETUNNELCALLBACK void OnTunnelNudged(TLSFilterTransaction *) override; +#define NS_DECL_NUDGETUNNELCALLBACK \ + nsresult OnTunnelNudged(TLSFilterTransaction *) override; class TLSFilterTransaction final : public nsAHttpTransaction @@ -121,7 +122,8 @@ public: nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment) override; nsresult GetTransactionSecurityInfo(nsISupports **) override; nsresult NudgeTunnel(NudgeTunnelCallback *callback); - nsresult SetProxiedTransaction(nsAHttpTransaction *aTrans); + MOZ_MUST_USE nsresult SetProxiedTransaction(nsAHttpTransaction *aTrans, + nsAHttpTransaction *aSpdyConnectTransaction = nullptr); void newIODriver(nsIAsyncInputStream *aSocketIn, nsIAsyncOutputStream *aSocketOut, nsIAsyncInputStream **outSocketIn, @@ -153,6 +155,7 @@ private: private: RefPtr<nsAHttpTransaction> mTransaction; + nsWeakPtr mWeakTrans; // SpdyConnectTransaction * nsCOMPtr<nsISupports> mSecInfo; nsCOMPtr<nsITimer> mTimer; RefPtr<NudgeTunnelCallback> mNudgeCallback; @@ -168,7 +171,7 @@ private: nsresult mFilterReadCode; bool mForce; - bool mReadSegmentBlocked; + nsresult mReadSegmentReturnValue; uint32_t mNudgeCounter; }; diff --git a/netwerk/protocol/http/nsHttpConnection.cpp b/netwerk/protocol/http/nsHttpConnection.cpp index 8ccba76e2..505d849c0 100644 --- a/netwerk/protocol/http/nsHttpConnection.cpp +++ b/netwerk/protocol/http/nsHttpConnection.cpp @@ -535,16 +535,16 @@ npnComplete: return true; } -void +nsresult nsHttpConnection::OnTunnelNudged(TLSFilterTransaction *trans) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); LOG(("nsHttpConnection::OnTunnelNudged %p\n", this)); if (trans != mTLSFilter) { - return; + return NS_OK; } LOG(("nsHttpConnection::OnTunnelNudged %p Calling OnSocketWritable\n", this)); - OnSocketWritable(); + return OnSocketWritable(); } // called on the socket thread @@ -639,7 +639,9 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri } if (mTLSFilter) { - mTLSFilter->SetProxiedTransaction(trans); + RefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans)); + rv = mTLSFilter->SetProxiedTransaction(trans, baseTrans); + NS_ENSURE_SUCCESS(rv, rv); mTransaction = mTLSFilter; } @@ -1979,7 +1981,7 @@ nsHttpConnection::OnSocketReadable() // negotiation are known (which is determined from the write path). // If the server speaks SPDY it is likely the readable data here is // a spdy settings frame and without NPN it would be misinterpreted - // as HTTP/* + // as HTTP LOG(("nsHttpConnection::OnSocketReadable %p return due to inactive " "tunnel setup but incomplete NPN state\n", this)); @@ -2019,12 +2021,14 @@ nsHttpConnection::OnSocketReadable() } void -nsHttpConnection::SetupSecondaryTLS() +nsHttpConnection::SetupSecondaryTLS(nsAHttpTransaction *aSpdyConnectTransaction) { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); MOZ_ASSERT(!mTLSFilter); - LOG(("nsHttpConnection %p SetupSecondaryTLS %s %d\n", - this, mConnInfo->Origin(), mConnInfo->OriginPort())); + LOG(("nsHttpConnection %p SetupSecondaryTLS %s %d " + "aSpdyConnectTransaction=%p\n", + this, mConnInfo->Origin(), mConnInfo->OriginPort(), + aSpdyConnectTransaction)); nsHttpConnectionInfo *ci = nullptr; if (mTransaction) { @@ -2041,6 +2045,7 @@ nsHttpConnection::SetupSecondaryTLS() if (mTransaction) { mTransaction = mTLSFilter; } + mWeakTrans = do_GetWeakReference(aSpdyConnectTransaction); } void diff --git a/netwerk/protocol/http/nsHttpConnection.h b/netwerk/protocol/http/nsHttpConnection.h index 08eea1de2..ce7523eb5 100644 --- a/netwerk/protocol/http/nsHttpConnection.h +++ b/netwerk/protocol/http/nsHttpConnection.h @@ -202,7 +202,7 @@ public: static nsresult MakeConnectString(nsAHttpTransaction *trans, nsHttpRequestHead *request, nsACString &result); - void SetupSecondaryTLS(); + void SetupSecondaryTLS(nsAHttpTransaction *aSpdyConnectTransaction = nullptr); void SetInSpdyTunnel(bool arg); // Check active connections for traffic (or not). SPDY connections send a @@ -281,6 +281,7 @@ private: // transaction is open, otherwise it is null. RefPtr<nsAHttpTransaction> mTransaction; RefPtr<TLSFilterTransaction> mTLSFilter; + nsWeakPtr mWeakTrans; // SpdyConnectTransaction * RefPtr<nsHttpHandler> mHttpHandler; // keep gHttpHandler alive diff --git a/uriloader/exthandler/win/nsOSHelperAppService.cpp b/uriloader/exthandler/win/nsOSHelperAppService.cpp index f01f3b49b..48b6f1795 100644 --- a/uriloader/exthandler/win/nsOSHelperAppService.cpp +++ b/uriloader/exthandler/win/nsOSHelperAppService.cpp @@ -29,8 +29,6 @@ #define LOG(args) MOZ_LOG(mLog, mozilla::LogLevel::Debug, args) // helper methods: forward declarations... -static nsresult GetExtensionFrom4xRegistryInfo(const nsACString& aMimeType, - nsString& aFileExtension); static nsresult GetExtensionFromWindowsMimeDatabase(const nsACString& aMimeType, nsString& aFileExtension); @@ -77,79 +75,45 @@ static nsresult GetExtensionFromWindowsMimeDatabase(const nsACString& aMimeType, return NS_OK; } -// We have a serious problem!! I have this content type and the windows registry only gives me -// helper apps based on extension. Right now, we really don't have a good place to go for -// trying to figure out the extension for a particular mime type....One short term hack is to look -// this information in 4.x (it's stored in the windows regsitry). -static nsresult GetExtensionFrom4xRegistryInfo(const nsACString& aMimeType, - nsString& aFileExtension) -{ - nsCOMPtr<nsIWindowsRegKey> regKey = - do_CreateInstance("@mozilla.org/windows-registry-key;1"); - if (!regKey) - return NS_ERROR_NOT_AVAILABLE; - - nsresult rv = regKey-> - Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, - NS_LITERAL_STRING("Software\\Netscape\\Netscape Navigator\\Suffixes"), - nsIWindowsRegKey::ACCESS_QUERY_VALUE); - if (NS_FAILED(rv)) - return NS_ERROR_NOT_AVAILABLE; - - rv = regKey->ReadStringValue(NS_ConvertASCIItoUTF16(aMimeType), - aFileExtension); - if (NS_FAILED(rv)) - return NS_OK; - - aFileExtension.Insert(char16_t('.'), 0); - - // this may be a comma separated list of extensions...just take the - // first one for now... - - int32_t pos = aFileExtension.FindChar(char16_t(',')); - if (pos > 0) { - // we have a comma separated list of types... - // truncate everything after the first comma (including the comma) - aFileExtension.Truncate(pos); - } - - return NS_OK; -} - nsresult nsOSHelperAppService::OSProtocolHandlerExists(const char * aProtocolScheme, bool * aHandlerExists) { // look up the protocol scheme in the windows registry....if we find a match then we have a handler for it... *aHandlerExists = false; if (aProtocolScheme && *aProtocolScheme) { - // Vista: use new application association interface - if (mAppAssoc) { - wchar_t * pResult = nullptr; - NS_ConvertASCIItoUTF16 scheme(aProtocolScheme); - // We are responsible for freeing returned strings. - HRESULT hr = mAppAssoc->QueryCurrentDefault(scheme.get(), - AT_URLPROTOCOL, AL_EFFECTIVE, - &pResult); - if (SUCCEEDED(hr)) { - CoTaskMemFree(pResult); - *aHandlerExists = true; + NS_ENSURE_TRUE(mAppAssoc, NS_ERROR_NOT_AVAILABLE); + wchar_t * pResult = nullptr; + NS_ConvertASCIItoUTF16 scheme(aProtocolScheme); + // We are responsible for freeing returned strings. + HRESULT hr = mAppAssoc->QueryCurrentDefault(scheme.get(), + AT_URLPROTOCOL, AL_EFFECTIVE, + &pResult); + if (SUCCEEDED(hr)) { + CoTaskMemFree(pResult); + // Check the registry to see if it's a valid handler. + nsCOMPtr<nsIWindowsRegKey> regKey = do_CreateInstance("@mozilla.org/windows-registry-key;1"); + if (!regKey) { + return NS_ERROR_NOT_AVAILABLE; + } + + nsresult rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT, + nsDependentString(scheme.get()), + nsIWindowsRegKey::ACCESS_QUERY_VALUE); + if (NS_FAILED(rv)) { + // Open will fail if the registry key path doesn't exist. + return NS_OK; + } + + bool hasValue; + rv = regKey->HasValue(NS_LITERAL_STRING("URL Protocol"), &hasValue); + if (NS_FAILED(rv)) { + return NS_ERROR_FAILURE; + } + if (!hasValue) { + return NS_OK; } - return NS_OK; - } - HKEY hKey; - LONG err = ::RegOpenKeyExW(HKEY_CLASSES_ROOT, - NS_ConvertASCIItoUTF16(aProtocolScheme).get(), - 0, - KEY_QUERY_VALUE, - &hKey); - if (err == ERROR_SUCCESS) - { - err = ::RegQueryValueExW(hKey, L"URL Protocol", - nullptr, nullptr, nullptr, nullptr); - *aHandlerExists = (err == ERROR_SUCCESS); - // close the key - ::RegCloseKey(hKey); + *aHandlerExists = true; } } @@ -180,40 +144,21 @@ NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString& } } - if (mAppAssoc) { - // Vista: use new application association interface - wchar_t * pResult = nullptr; - // We are responsible for freeing returned strings. - HRESULT hr = mAppAssoc->QueryCurrentDefault(buf.get(), - AT_URLPROTOCOL, AL_EFFECTIVE, - &pResult); - if (SUCCEEDED(hr)) { - nsCOMPtr<nsIFile> app; - nsAutoString appInfo(pResult); - CoTaskMemFree(pResult); - if (NS_SUCCEEDED(GetDefaultAppInfo(appInfo, _retval, getter_AddRefs(app)))) - return NS_OK; - } - return NS_ERROR_NOT_AVAILABLE; + NS_ENSURE_TRUE(mAppAssoc, NS_ERROR_NOT_AVAILABLE); + wchar_t * pResult = nullptr; + // We are responsible for freeing returned strings. + HRESULT hr = mAppAssoc->QueryCurrentDefault(buf.get(), + AT_URLPROTOCOL, AL_EFFECTIVE, + &pResult); + if (SUCCEEDED(hr)) { + nsCOMPtr<nsIFile> app; + nsAutoString appInfo(pResult); + CoTaskMemFree(pResult); + if (NS_SUCCEEDED(GetDefaultAppInfo(appInfo, _retval, getter_AddRefs(app)))) + return NS_OK; } - nsCOMPtr<nsIFile> app; - GetDefaultAppInfo(buf, _retval, getter_AddRefs(app)); - - if (!_retval.Equals(buf)) - return NS_OK; - - // Fall back to full path - buf.AppendLiteral("\\shell\\open\\command"); - nsresult rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT, - buf, - nsIWindowsRegKey::ACCESS_QUERY_VALUE); - if (NS_FAILED(rv)) - return NS_ERROR_NOT_AVAILABLE; - - rv = regKey->ReadStringValue(EmptyString(), _retval); - - return NS_SUCCEEDED(rv) ? NS_OK : NS_ERROR_NOT_AVAILABLE; + return NS_ERROR_NOT_AVAILABLE; } // GetMIMEInfoFromRegistry: This function obtains the values of some of the nsIMIMEInfo @@ -421,36 +366,18 @@ already_AddRefed<nsMIMEInfoWin> nsOSHelperAppService::GetByExtension(const nsAFl bool found; // Retrieve the default application for this extension - if (mAppAssoc) { - // Vista: use the new application association COM interfaces - // for resolving helpers. - nsString assocType(fileExtToUse); - wchar_t * pResult = nullptr; - HRESULT hr = mAppAssoc->QueryCurrentDefault(assocType.get(), - AT_FILEEXTENSION, AL_EFFECTIVE, - &pResult); - if (SUCCEEDED(hr)) { - found = true; - appInfo.Assign(pResult); - CoTaskMemFree(pResult); - } - else { - found = false; - } - } - else - { - nsCOMPtr<nsIWindowsRegKey> regKey = - do_CreateInstance("@mozilla.org/windows-registry-key;1"); - if (!regKey) - return nullptr; - nsresult rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT, - fileExtToUse, - nsIWindowsRegKey::ACCESS_QUERY_VALUE); - if (NS_SUCCEEDED(rv)) { - found = NS_SUCCEEDED(regKey->ReadStringValue(EmptyString(), - appInfo)); - } + NS_ENSURE_TRUE(mAppAssoc, nullptr); + nsString assocType(fileExtToUse); + wchar_t * pResult = nullptr; + HRESULT hr = mAppAssoc->QueryCurrentDefault(assocType.get(), + AT_FILEEXTENSION, AL_EFFECTIVE, + &pResult); + if (SUCCEEDED(hr)) { + found = true; + appInfo.Assign(pResult); + CoTaskMemFree(pResult); + } else { + found = false; } // Bug 358297 - ignore the default handler, force the user to choose app @@ -496,14 +423,9 @@ already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(const nsAC * We'll do extension-based lookup for this type later in this function. */ if (!aMIMEType.LowerCaseEqualsLiteral(APPLICATION_OCTET_STREAM)) { - // (1) try to use the windows mime database to see if there is a mapping to a file extension - // (2) try to see if we have some left over 4.x registry info we can peek at... + // try to use the windows mime database to see if there is a mapping to a file extension GetExtensionFromWindowsMimeDatabase(aMIMEType, fileExtension); LOG(("Windows mime database: extension '%s'\n", fileExtension.get())); - if (fileExtension.IsEmpty()) { - GetExtensionFrom4xRegistryInfo(aMIMEType, fileExtension); - LOG(("4.x Registry: extension '%s'\n", fileExtension.get())); - } } // If we found an extension for the type, do the lookup RefPtr<nsMIMEInfoWin> mi; |