diff options
Diffstat (limited to 'netwerk')
36 files changed, 311 insertions, 980 deletions
diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp index 42fdea4a1..ede825b8f 100644 --- a/netwerk/base/LoadInfo.cpp +++ b/netwerk/base/LoadInfo.cpp @@ -7,6 +7,7 @@ #include "mozilla/LoadInfo.h" #include "mozilla/Assertions.h" +#include "mozilla/dom/TabChild.h" #include "mozilla/dom/ToJSValue.h" #include "mozIThirdPartyUtil.h" #include "nsFrameLoader.h" @@ -47,12 +48,14 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, aTriggeringPrincipal : mLoadingPrincipal.get()) , mPrincipalToInherit(nullptr) , mLoadingContext(do_GetWeakReference(aLoadingContext)) + , mContextForTopLevelLoad(nullptr) , mSecurityFlags(aSecurityFlags) , mInternalContentPolicyType(aContentPolicyType) , mTainting(LoadTainting::Basic) , mUpgradeInsecureRequests(false) , mVerifySignedContent(false) , mEnforceSRI(false) + , mForceAllowDataURI(false) , mForceInheritPrincipalDropped(false) , mInnerWindowID(0) , mOuterWindowID(0) @@ -63,6 +66,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, , mIsThirdPartyContext(false) , mForcePreflight(false) , mIsPreflight(false) + , mLoadTriggeredFromExternal(false) , mForceHSTSPriming(false) , mMixedContentWouldBlock(false) { @@ -215,16 +219,19 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, */ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow, nsIPrincipal* aTriggeringPrincipal, + nsISupports* aContextForTopLevelLoad, nsSecurityFlags aSecurityFlags) : mLoadingPrincipal(nullptr) , mTriggeringPrincipal(aTriggeringPrincipal) , mPrincipalToInherit(nullptr) + , mContextForTopLevelLoad(do_GetWeakReference(aContextForTopLevelLoad)) , mSecurityFlags(aSecurityFlags) , mInternalContentPolicyType(nsIContentPolicy::TYPE_DOCUMENT) , mTainting(LoadTainting::Basic) , mUpgradeInsecureRequests(false) , mVerifySignedContent(false) , mEnforceSRI(false) + , mForceAllowDataURI(false) , mForceInheritPrincipalDropped(false) , mInnerWindowID(0) , mOuterWindowID(0) @@ -235,6 +242,7 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow, , mIsThirdPartyContext(false) // NB: TYPE_DOCUMENT implies not third-party. , mForcePreflight(false) , mIsPreflight(false) + , mLoadTriggeredFromExternal(false) , mForceHSTSPriming(false) , mMixedContentWouldBlock(false) { @@ -276,12 +284,14 @@ LoadInfo::LoadInfo(const LoadInfo& rhs) , mTriggeringPrincipal(rhs.mTriggeringPrincipal) , mPrincipalToInherit(rhs.mPrincipalToInherit) , mLoadingContext(rhs.mLoadingContext) + , mContextForTopLevelLoad(rhs.mContextForTopLevelLoad) , mSecurityFlags(rhs.mSecurityFlags) , mInternalContentPolicyType(rhs.mInternalContentPolicyType) , mTainting(rhs.mTainting) , mUpgradeInsecureRequests(rhs.mUpgradeInsecureRequests) , mVerifySignedContent(rhs.mVerifySignedContent) , mEnforceSRI(rhs.mEnforceSRI) + , mForceAllowDataURI(rhs.mForceAllowDataURI) , mForceInheritPrincipalDropped(rhs.mForceInheritPrincipalDropped) , mInnerWindowID(rhs.mInnerWindowID) , mOuterWindowID(rhs.mOuterWindowID) @@ -297,6 +307,7 @@ LoadInfo::LoadInfo(const LoadInfo& rhs) , mCorsUnsafeHeaders(rhs.mCorsUnsafeHeaders) , mForcePreflight(rhs.mForcePreflight) , mIsPreflight(rhs.mIsPreflight) + , mLoadTriggeredFromExternal(rhs.mLoadTriggeredFromExternal) , mForceHSTSPriming(rhs.mForceHSTSPriming) , mMixedContentWouldBlock(rhs.mMixedContentWouldBlock) { @@ -311,6 +322,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, bool aUpgradeInsecureRequests, bool aVerifySignedContent, bool aEnforceSRI, + bool aForceAllowDataURI, bool aForceInheritPrincipalDropped, uint64_t aInnerWindowID, uint64_t aOuterWindowID, @@ -325,6 +337,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, const nsTArray<nsCString>& aCorsUnsafeHeaders, bool aForcePreflight, bool aIsPreflight, + bool aLoadTriggeredFromExternal, bool aForceHSTSPriming, bool aMixedContentWouldBlock) : mLoadingPrincipal(aLoadingPrincipal) @@ -336,6 +349,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, , mUpgradeInsecureRequests(aUpgradeInsecureRequests) , mVerifySignedContent(aVerifySignedContent) , mEnforceSRI(aEnforceSRI) + , mForceAllowDataURI(aForceAllowDataURI) , mForceInheritPrincipalDropped(aForceInheritPrincipalDropped) , mInnerWindowID(aInnerWindowID) , mOuterWindowID(aOuterWindowID) @@ -348,6 +362,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, , mCorsUnsafeHeaders(aCorsUnsafeHeaders) , mForcePreflight(aForcePreflight) , mIsPreflight(aIsPreflight) + , mLoadTriggeredFromExternal(aLoadTriggeredFromExternal) , mForceHSTSPriming (aForceHSTSPriming) , mMixedContentWouldBlock(aMixedContentWouldBlock) { @@ -477,6 +492,17 @@ LoadInfo::LoadingNode() return node; } +nsISupports* +LoadInfo::ContextForTopLevelLoad() +{ + // Most likely you want to query LoadingNode() instead of + // ContextForTopLevelLoad() if this assertion fires. + MOZ_ASSERT(mInternalContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT, + "should only query this context for top level document loads"); + nsCOMPtr<nsISupports> context = do_QueryReferent(mContextForTopLevelLoad); + return context; +} + NS_IMETHODIMP LoadInfo::GetSecurityFlags(nsSecurityFlags* aResult) { @@ -648,6 +674,23 @@ LoadInfo::GetEnforceSRI(bool* aResult) } NS_IMETHODIMP +LoadInfo::SetForceAllowDataURI(bool aForceAllowDataURI) +{ + MOZ_ASSERT(!mForceAllowDataURI || + mInternalContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT, + "can only allow data URI navigation for TYPE_DOCUMENT"); + mForceAllowDataURI = aForceAllowDataURI; + return NS_OK; +} + +NS_IMETHODIMP +LoadInfo::GetForceAllowDataURI(bool* aForceAllowDataURI) +{ + *aForceAllowDataURI = mForceAllowDataURI; + return NS_OK; +} + +NS_IMETHODIMP LoadInfo::GetForceInheritPrincipalDropped(bool* aResult) { *aResult = mForceInheritPrincipalDropped; @@ -873,6 +916,23 @@ LoadInfo::GetIsPreflight(bool* aIsPreflight) } NS_IMETHODIMP +LoadInfo::SetLoadTriggeredFromExternal(bool aLoadTriggeredFromExternal) +{ + MOZ_ASSERT(!aLoadTriggeredFromExternal || + mInternalContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT, + "can only set load triggered from external for TYPE_DOCUMENT"); + mLoadTriggeredFromExternal = aLoadTriggeredFromExternal; + return NS_OK; +} + +NS_IMETHODIMP +LoadInfo::GetLoadTriggeredFromExternal(bool* aLoadTriggeredFromExternal) +{ + *aLoadTriggeredFromExternal = mLoadTriggeredFromExternal; + return NS_OK; +} + +NS_IMETHODIMP LoadInfo::GetForceHSTSPriming(bool* aForceHSTSPriming) { *aForceHSTSPriming = mForceHSTSPriming; diff --git a/netwerk/base/LoadInfo.h b/netwerk/base/LoadInfo.h index 3e1b92ff4..0ae6061b3 100644 --- a/netwerk/base/LoadInfo.h +++ b/netwerk/base/LoadInfo.h @@ -59,10 +59,12 @@ public: nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType); - // Constructor used for TYPE_DOCUMENT loads which have no reasonable - // loadingNode or loadingPrincipal + // Constructor used for TYPE_DOCUMENT loads which have a different + // loadingContext than other loads. This ContextForTopLevelLoad is + // only used for content policy checks. LoadInfo(nsPIDOMWindowOuter* aOuterWindow, nsIPrincipal* aTriggeringPrincipal, + nsISupports* aContextForTopLevelLoad, nsSecurityFlags aSecurityFlags); // create an exact copy of the loadinfo @@ -94,6 +96,7 @@ private: bool aUpgradeInsecureRequests, bool aVerifySignedContent, bool aEnforceSRI, + bool aForceAllowDataURI, bool aForceInheritPrincipalDropped, uint64_t aInnerWindowID, uint64_t aOuterWindowID, @@ -108,6 +111,7 @@ private: const nsTArray<nsCString>& aUnsafeHeaders, bool aForcePreflight, bool aIsPreflight, + bool aLoadTriggeredFromExternal, bool aForceHSTSPriming, bool aMixedContentWouldBlock); LoadInfo(const LoadInfo& rhs); @@ -132,12 +136,14 @@ private: nsCOMPtr<nsIPrincipal> mTriggeringPrincipal; nsCOMPtr<nsIPrincipal> mPrincipalToInherit; nsWeakPtr mLoadingContext; + nsWeakPtr mContextForTopLevelLoad; nsSecurityFlags mSecurityFlags; nsContentPolicyType mInternalContentPolicyType; LoadTainting mTainting; bool mUpgradeInsecureRequests; bool mVerifySignedContent; bool mEnforceSRI; + bool mForceAllowDataURI; bool mForceInheritPrincipalDropped; uint64_t mInnerWindowID; uint64_t mOuterWindowID; @@ -152,6 +158,7 @@ private: nsTArray<nsCString> mCorsUnsafeHeaders; bool mForcePreflight; bool mIsPreflight; + bool mLoadTriggeredFromExternal; bool mForceHSTSPriming : 1; bool mMixedContentWouldBlock : 1; diff --git a/netwerk/base/moz.build b/netwerk/base/moz.build index 3b731db10..5de1eea81 100644 --- a/netwerk/base/moz.build +++ b/netwerk/base/moz.build @@ -132,7 +132,6 @@ XPIDL_SOURCES += [ 'nsIURIClassifier.idl', 'nsIURIWithBlobImpl.idl', 'nsIURIWithPrincipal.idl', - 'nsIURIWithQuery.idl', 'nsIURL.idl', 'nsIURLParser.idl', 'nsPILoadGroupInternal.idl', diff --git a/netwerk/base/nsBufferedStreams.h b/netwerk/base/nsBufferedStreams.h index 93a770beb..fee55695a 100644 --- a/netwerk/base/nsBufferedStreams.h +++ b/netwerk/base/nsBufferedStreams.h @@ -88,10 +88,10 @@ protected: //////////////////////////////////////////////////////////////////////////////// -class nsBufferedOutputStream final : public nsBufferedStream, - public nsISafeOutputStream, - public nsIBufferedOutputStream, - public nsIStreamBufferAccess +class nsBufferedOutputStream : public nsBufferedStream, + public nsISafeOutputStream, + public nsIBufferedOutputStream, + public nsIStreamBufferAccess { public: NS_DECL_ISUPPORTS_INHERITED diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl index 78433c8b8..4ec29b972 100644 --- a/netwerk/base/nsILoadInfo.idl +++ b/netwerk/base/nsILoadInfo.idl @@ -324,6 +324,16 @@ interface nsILoadInfo : nsISupports nsINode binaryLoadingNode(); /** + * A C++ friendly version of the loadingContext for toplevel loads. + * Most likely you want to query the ownerDocument or LoadingNode + * and not this context only available for TYPE_DOCUMENT loads. + * Please note that except for loads of TYPE_DOCUMENT, this + * ContextForTopLevelLoad will always return null. + */ + [noscript, notxpcom, nostdcall, binaryname(ContextForTopLevelLoad)] + nsISupports binaryContextForTopLevelLoad(); + + /** * The securityFlags of that channel. */ readonly attribute nsSecurityFlags securityFlags; @@ -470,6 +480,11 @@ interface nsILoadInfo : nsISupports [infallible] attribute boolean enforceSRI; /** + * If true, toplevel data: URI navigation is allowed + */ + [infallible] attribute boolean forceAllowDataURI; + + /** * The SEC_FORCE_INHERIT_PRINCIPAL flag may be dropped when a load info * object is created. Specifically, it will be dropped if the SEC_SANDBOXED * flag is also present. This flag is set if SEC_FORCE_INHERIT_PRINCIPAL was @@ -575,6 +590,13 @@ interface nsILoadInfo : nsISupports [infallible] attribute boolean initialSecurityCheckDone; /** + * Returns true if the load was triggered from an external application + * (e.g. Thunderbird). Please note that this flag will only ever be true + * if the load is of TYPE_DOCUMENT. + */ + [infallible] attribute boolean loadTriggeredFromExternal; + + /** * Whenever a channel gets redirected, append the principal of the * channel [before the channels got redirected] to the loadinfo, * so that at every point this array lets us reason about all the diff --git a/netwerk/base/nsIOService.cpp b/netwerk/base/nsIOService.cpp index 0da79c18a..8b7f31f99 100644 --- a/netwerk/base/nsIOService.cpp +++ b/netwerk/base/nsIOService.cpp @@ -173,6 +173,8 @@ uint32_t nsIOService::gDefaultSegmentCount = 24; bool nsIOService::sTelemetryEnabled = false; +bool nsIOService::sBlockToplevelDataUriNavigations = false; + //////////////////////////////////////////////////////////////////////////////// nsIOService::nsIOService() @@ -251,6 +253,8 @@ nsIOService::Init() NS_WARNING("failed to get observer service"); Preferences::AddBoolVarCache(&sTelemetryEnabled, "toolkit.telemetry.enabled", false); + Preferences::AddBoolVarCache(&sBlockToplevelDataUriNavigations, + "security.data_uri.block_toplevel_data_uri_navigations", false); Preferences::AddBoolVarCache(&mOfflineMirrorsConnectivity, OFFLINE_MIRRORS_CONNECTIVITY, true); gIOService = this; @@ -1876,5 +1880,11 @@ nsIOService::SpeculativeAnonymousConnect2(nsIURI *aURI, return SpeculativeConnectInternal(aURI, aPrincipal, aCallbacks, true); } +/*static*/ bool +nsIOService::BlockToplevelDataUriNavigations() +{ + return sBlockToplevelDataUriNavigations; +} + } // namespace net } // namespace mozilla diff --git a/netwerk/base/nsIOService.h b/netwerk/base/nsIOService.h index 7ac23b791..e592c4d1c 100644 --- a/netwerk/base/nsIOService.h +++ b/netwerk/base/nsIOService.h @@ -95,6 +95,8 @@ public: bool IsLinkUp(); + static bool BlockToplevelDataUriNavigations(); + // Used to trigger a recheck of the captive portal status nsresult RecheckCaptivePortal(); private: @@ -176,6 +178,8 @@ private: static bool sTelemetryEnabled; + static bool sBlockToplevelDataUriNavigations; + // These timestamps are needed for collecting telemetry on PR_Connect, // PR_ConnectContinue and PR_Close blocking time. If we spend very long // time in any of these functions we want to know if and what network diff --git a/netwerk/base/nsIURI.idl b/netwerk/base/nsIURI.idl index 2384c5fd9..ef163813a 100644 --- a/netwerk/base/nsIURI.idl +++ b/netwerk/base/nsIURI.idl @@ -10,18 +10,18 @@ * provides accessors to set and query the most basic components of an URI. * Subclasses, including nsIURL, impose greater structure on the URI. * - * This interface follows Tim Berners-Lee's URI spec (RFC2396) [1], where the + * This interface follows Tim Berners-Lee's URI spec (RFC3986) [1], where the * basic URI components are defined as such: * <pre> - * ftp://username:password@hostname:portnumber/pathname#ref - * \ / \ / \ / \ /\ \ / - * - --------------- ------ -------- | - - * | | | | | | - * | | | | | Ref - * | | | Port \ / - * | | Host / -------- - * | UserPass / | - * Scheme / Path + * ftp://username:password@hostname:portnumber/pathname?query#ref + * \ / \ / \ / \ /\ / \ / \ / + * - --------------- ------ -------- ------- --- - + * | | | | | | | + * | | | | FilePath Query Ref + * | | | Port \ / + * | | Host / ------------ + * | UserPass / | + * Scheme / Path * \ / * -------------------------------- * | @@ -30,13 +30,9 @@ * The definition of the URI components has been extended to allow for * internationalized domain names [2] and the more generic IRI structure [3]. * - * Note also that the RFC defines #-separated fragment identifiers as being - * "not part of the URI". Despite this, we bundle them as part of the URI, for - * convenience. - * - * [1] http://www.ietf.org/rfc/rfc2396.txt - * [2] http://www.ietf.org/internet-drafts/draft-ietf-idn-idna-06.txt - * [3] http://www.ietf.org/internet-drafts/draft-masinter-url-i18n-08.txt + * [1] https://tools.ietf.org/html/rfc3986 + * [2] https://tools.ietf.org/html/rfc5890 + * [3] https://tools.ietf.org/html/rfc3987 */ %{C++ @@ -116,7 +112,7 @@ interface nsIURI : nsISupports /** * The Scheme is the protocol to which this URI refers. The scheme is - * restricted to the US-ASCII charset per RFC2396. Setting this is + * restricted to the US-ASCII charset per RFC3986. Setting this is * highly discouraged outside of a protocol handler implementation, since * that will generally lead to incorrect results. */ @@ -174,6 +170,9 @@ interface nsIURI : nsISupports * empty, depending on the protocol). * * Some characters may be escaped. + * + * This attribute contains query and ref parts for historical reasons. + * Use the 'filePath' attribute if you do not want those parts included. */ attribute AUTF8String path; @@ -281,10 +280,31 @@ interface nsIURI : nsISupports /** * returns a string for the current URI with the ref element cleared. */ - readonly attribute AUTF8String specIgnoringRef; + readonly attribute AUTF8String specIgnoringRef; /** * Returns if there is a reference portion (the part after the "#") of the URI. */ - readonly attribute boolean hasRef; + readonly attribute boolean hasRef; + + /************************************************************************ + * Additional attributes added for .query support: + */ + + /** + * Returns a path including the directory and file portions of a + * URL. For example, the filePath of "http://host/foo/bar.html#baz" + * is "/foo/bar.html". + * + * Some characters may be escaped. + */ + attribute AUTF8String filePath; + + /** + * Returns the query portion (the part after the "?") of the URL. + * If there isn't one, an empty string is returned. + * + * Some characters may be escaped. + */ + attribute AUTF8String query; }; diff --git a/netwerk/base/nsIURIWithQuery.idl b/netwerk/base/nsIURIWithQuery.idl deleted file mode 100644 index 749b2773d..000000000 --- a/netwerk/base/nsIURIWithQuery.idl +++ /dev/null @@ -1,30 +0,0 @@ -/* 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 "nsIURI.idl" - -/** - * nsIURIWithQuery is implemented by URIs which have a query parameter. - * This is useful for the URL API. - */ -[scriptable, uuid(367510ee-8556-435a-8f99-b5fd357e08cc)] -interface nsIURIWithQuery : nsIURI -{ - /** - * Returns a path including the directory and file portions of a - * URL. For example, the filePath of "http://host/foo/bar.html#baz" - * is "/foo/bar.html". - * - * Some characters may be escaped. - */ - attribute AUTF8String filePath; - - /** - * Returns the query portion (the part after the "?") of the URL. - * If there isn't one, an empty string is returned. - * - * Some characters may be escaped. - */ - attribute AUTF8String query; -}; diff --git a/netwerk/base/nsIURL.idl b/netwerk/base/nsIURL.idl index aeaa3f694..9ff6c3dcd 100644 --- a/netwerk/base/nsIURL.idl +++ b/netwerk/base/nsIURL.idl @@ -3,7 +3,7 @@ * 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 "nsIURIWithQuery.idl" +#include "nsIURI.idl" /** * The nsIURL interface provides convenience methods that further @@ -20,7 +20,7 @@ * filePath */ [scriptable, uuid(86adcd89-0b70-47a2-b0fe-5bb2c5f37e31)] -interface nsIURL : nsIURIWithQuery +interface nsIURL : nsIURI { /************************************************************************* * The URL path is broken down into the following principal components: @@ -28,7 +28,7 @@ interface nsIURL : nsIURIWithQuery * attribute AUTF8String filePath; * attribute AUTF8String query; * - * These are inherited from nsIURIWithQuery. + * These are inherited from nsIURI. */ /************************************************************************* diff --git a/netwerk/base/nsSimpleURI.cpp b/netwerk/base/nsSimpleURI.cpp index ae5c51a1e..dbc0dc817 100644 --- a/netwerk/base/nsSimpleURI.cpp +++ b/netwerk/base/nsSimpleURI.cpp @@ -48,7 +48,7 @@ nsSimpleURI::~nsSimpleURI() NS_IMPL_ADDREF(nsSimpleURI) NS_IMPL_RELEASE(nsSimpleURI) NS_INTERFACE_TABLE_HEAD(nsSimpleURI) -NS_INTERFACE_TABLE(nsSimpleURI, nsIURI, nsIURIWithQuery, nsISerializable, +NS_INTERFACE_TABLE(nsSimpleURI, nsIURI, nsISerializable, nsIClassInfo, nsIMutable, nsIIPCSerializableURI) NS_INTERFACE_TABLE_TO_MAP_SEGUE if (aIID.Equals(kThisSimpleURIImplementationCID)) @@ -784,10 +784,6 @@ nsSimpleURI::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); } -//---------------------------------------------------------------------------- -// nsSimpleURI::nsIURIWithQuery -//---------------------------------------------------------------------------- - NS_IMETHODIMP nsSimpleURI::GetFilePath(nsACString& aFilePath) { diff --git a/netwerk/base/nsSimpleURI.h b/netwerk/base/nsSimpleURI.h index 29bc9b313..842136ed6 100644 --- a/netwerk/base/nsSimpleURI.h +++ b/netwerk/base/nsSimpleURI.h @@ -8,7 +8,6 @@ #include "mozilla/MemoryReporting.h" #include "nsIURI.h" -#include "nsIURIWithQuery.h" #include "nsISerializable.h" #include "nsString.h" #include "nsIClassInfo.h" @@ -28,7 +27,7 @@ namespace net { } class nsSimpleURI - : public nsIURIWithQuery + : public nsIURI , public nsISerializable , public nsIClassInfo , public nsIMutable @@ -41,7 +40,6 @@ protected: public: NS_DECL_ISUPPORTS NS_DECL_NSIURI - NS_DECL_NSIURIWITHQUERY NS_DECL_NSISERIALIZABLE NS_DECL_NSICLASSINFO NS_DECL_NSIMUTABLE diff --git a/netwerk/base/nsStandardURL.cpp b/netwerk/base/nsStandardURL.cpp index 922d8a3ba..e2a290e4d 100644 --- a/netwerk/base/nsStandardURL.cpp +++ b/netwerk/base/nsStandardURL.cpp @@ -65,19 +65,6 @@ static LazyLogModule gStandardURLLog("nsStandardURL"); //---------------------------------------------------------------------------- -#ifdef MOZ_RUST_URLPARSE -extern "C" int32_t c_fn_set_size(void * container, size_t size) -{ - ((nsACString *) container)->SetLength(size); - return 0; -} - -extern "C" char * c_fn_get_buffer(void * container) -{ - return ((nsACString *) container)->BeginWriting(); -} -#endif - static nsresult EncodeString(nsIUnicodeEncoder *encoder, const nsAFlatString &str, nsACString &result) { @@ -794,11 +781,13 @@ nsStandardURL::BuildNormalizedSpec(const char *spec) i = AppendSegmentToBuf(buf, i, spec, username, mUsername, &encUsername, useEncUsername, &diff); ShiftFromPassword(diff); - if (password.mLen >= 0) { + if (password.mLen > 0) { buf[i++] = ':'; i = AppendSegmentToBuf(buf, i, spec, password, mPassword, &encPassword, useEncPassword, &diff); ShiftFromHost(diff); + } else { + mPassword.mLen = -1; } buf[i++] = '@'; } @@ -1193,7 +1182,6 @@ NS_IMPL_RELEASE(nsStandardURL) NS_INTERFACE_MAP_BEGIN(nsStandardURL) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStandardURL) NS_INTERFACE_MAP_ENTRY(nsIURI) - NS_INTERFACE_MAP_ENTRY(nsIURIWithQuery) NS_INTERFACE_MAP_ENTRY(nsIURL) NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIFileURL, mSupportsFileURL) NS_INTERFACE_MAP_ENTRY(nsIStandardURL) @@ -1496,6 +1484,11 @@ nsStandardURL::SetSpec(const nsACString &input) rv = BuildNormalizedSpec(spec); } + // Make sure that a URLTYPE_AUTHORITY has a non-empty hostname. + if (mURLType == URLTYPE_AUTHORITY && mHost.mLen == -1) { + rv = NS_ERROR_MALFORMED_URI; + } + if (NS_FAILED(rv)) { Clear(); // If parsing the spec has failed, restore the old URL @@ -1629,7 +1622,7 @@ nsStandardURL::SetUserPass(const nsACString &input) usernameLen), esc_Username | esc_AlwaysCopy, buf, ignoredOut); - if (passwordLen >= 0) { + if (passwordLen > 0) { buf.Append(':'); passwordLen = encoder.EncodeSegmentCount(userpass.get(), URLSegment(passwordPos, @@ -1637,6 +1630,8 @@ nsStandardURL::SetUserPass(const nsACString &input) esc_Password | esc_AlwaysCopy, buf, ignoredOut); + } else { + passwordLen = -1; } if (mUsername.mLen < 0) buf.Append('@'); @@ -1667,8 +1662,10 @@ nsStandardURL::SetUserPass(const nsACString &input) // update positions and lengths mUsername.mLen = usernameLen; mPassword.mLen = passwordLen; - if (passwordLen) + if (passwordLen > 0) { mPassword.mPos = mUsername.mPos + mUsername.mLen + 1; + } + return NS_OK; } @@ -3105,20 +3102,26 @@ nsStandardURL::SetFile(nsIFile *file) rv = net_GetURLSpecFromFile(file, url); if (NS_FAILED(rv)) return rv; - SetSpec(url); + uint32_t oldURLType = mURLType; + uint32_t oldDefaultPort = mDefaultPort; + rv = Init(nsIStandardURL::URLTYPE_NO_AUTHORITY, -1, url, nullptr, nullptr); - rv = Init(mURLType, mDefaultPort, url, nullptr, nullptr); + if (NS_FAILED(rv)) { + // Restore the old url type and default port if the call to Init fails. + mURLType = oldURLType; + mDefaultPort = oldDefaultPort; + return rv; + } // must clone |file| since its value is not guaranteed to remain constant - if (NS_SUCCEEDED(rv)) { - InvalidateCache(); - if (NS_FAILED(file->Clone(getter_AddRefs(mFile)))) { - NS_WARNING("nsIFile::Clone failed"); - // failure to clone is not fatal (GetFile will generate mFile) - mFile = nullptr; - } + InvalidateCache(); + if (NS_FAILED(file->Clone(getter_AddRefs(mFile)))) { + NS_WARNING("nsIFile::Clone failed"); + // failure to clone is not fatal (GetFile will generate mFile) + mFile = nullptr; } - return rv; + + return NS_OK; } //---------------------------------------------------------------------------- @@ -3438,10 +3441,29 @@ ToIPCSegment(const nsStandardURL::URLSegment& aSegment) } inline -nsStandardURL::URLSegment -FromIPCSegment(const ipc::StandardURLSegment& aSegment) +MOZ_MUST_USE bool +FromIPCSegment(const nsACString& aSpec, const ipc::StandardURLSegment& aSegment, nsStandardURL::URLSegment& aTarget) { - return nsStandardURL::URLSegment(aSegment.position(), aSegment.length()); + // This seems to be just an empty segment. + if (aSegment.length() == -1) { + aTarget = nsStandardURL::URLSegment(); + return true; + } + + // A value of -1 means an empty segment, but < -1 is undefined. + if (NS_WARN_IF(aSegment.length() < -1)) { + return false; + } + + // Make sure the segment does not extend beyond the spec. + if (NS_WARN_IF(aSegment.position() + aSegment.length() > aSpec.Length())) { + return false; + } + + aTarget.mPos = aSegment.position(); + aTarget.mLen = aSegment.length(); + + return true; } void @@ -3516,23 +3538,38 @@ nsStandardURL::Deserialize(const URIParams& aParams) mPort = params.port(); mDefaultPort = params.defaultPort(); mSpec = params.spec(); - mScheme = FromIPCSegment(params.scheme()); - mAuthority = FromIPCSegment(params.authority()); - mUsername = FromIPCSegment(params.username()); - mPassword = FromIPCSegment(params.password()); - mHost = FromIPCSegment(params.host()); - mPath = FromIPCSegment(params.path()); - mFilepath = FromIPCSegment(params.filePath()); - mDirectory = FromIPCSegment(params.directory()); - mBasename = FromIPCSegment(params.baseName()); - mExtension = FromIPCSegment(params.extension()); - mQuery = FromIPCSegment(params.query()); - mRef = FromIPCSegment(params.ref()); + + NS_ENSURE_TRUE(mSpec.Length() <= (uint32_t) net_GetURLMaxLength(), false); + NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.scheme(), mScheme), false); + NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.authority(), mAuthority), false); + NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.username(), mUsername), false); + NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.password(), mPassword), false); + NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.host(), mHost), false); + NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.path(), mPath), false); + NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.filePath(), mFilepath), false); + NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.directory(), mDirectory), false); + NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.baseName(), mBasename), false); + NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.extension(), mExtension), false); + NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.query(), mQuery), false); + NS_ENSURE_TRUE(FromIPCSegment(mSpec, params.ref(), mRef), false); + mOriginCharset = params.originCharset(); mMutable = params.isMutable(); mSupportsFileURL = params.supportsFileURL(); mHostEncoding = params.hostEncoding(); + // Some sanity checks + NS_ENSURE_TRUE(mScheme.mPos == 0, false); + NS_ENSURE_TRUE(mScheme.mLen > 0, false); + // Make sure scheme is followed by :// (3 characters) + NS_ENSURE_TRUE(mScheme.mLen < INT32_MAX - 3, false); // avoid overflow + NS_ENSURE_TRUE(mSpec.Length() >= (uint32_t) mScheme.mLen + 3, false); + NS_ENSURE_TRUE(nsDependentCSubstring(mSpec, mScheme.mLen, 3).EqualsLiteral("://"), false); + NS_ENSURE_TRUE(mPath.mLen != -1 && mSpec.CharAt(mPath.mPos) == '/', false); + NS_ENSURE_TRUE(mPath.mPos == mFilepath.mPos, false); + NS_ENSURE_TRUE(mQuery.mLen == -1 || mSpec.CharAt(mQuery.mPos - 1) == '?', false); + NS_ENSURE_TRUE(mRef.mLen == -1 || mSpec.CharAt(mRef.mPos - 1) == '#', false); + // mSpecEncoding and mHostA are just caches that can be recovered as needed. return true; } diff --git a/netwerk/base/nsStandardURL.h b/netwerk/base/nsStandardURL.h index 90f7f7db2..0ca345572 100644 --- a/netwerk/base/nsStandardURL.h +++ b/netwerk/base/nsStandardURL.h @@ -54,7 +54,6 @@ protected: public: NS_DECL_ISUPPORTS NS_DECL_NSIURI - NS_DECL_NSIURIWITHQUERY NS_DECL_NSIURL NS_DECL_NSIFILEURL NS_DECL_NSISTANDARDURL diff --git a/netwerk/base/rust-url-capi/.gitignore b/netwerk/base/rust-url-capi/.gitignore deleted file mode 100644 index 4fffb2f89..000000000 --- a/netwerk/base/rust-url-capi/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target -/Cargo.lock diff --git a/netwerk/base/rust-url-capi/Cargo.toml b/netwerk/base/rust-url-capi/Cargo.toml deleted file mode 100644 index ecdb53058..000000000 --- a/netwerk/base/rust-url-capi/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] - -name = "rust_url_capi" -version = "0.0.1" -authors = ["Valentin Gosu <valentin.gosu@gmail.com>"] - -[profile.dev] -opt-level = 3 -debug = true -rpath = true -lto = true - -[lib] -name = "rust_url_capi" - - -[dependencies] -libc = "0.2.0" -url = "1.2.1" diff --git a/netwerk/base/rust-url-capi/src/error_mapping.rs b/netwerk/base/rust-url-capi/src/error_mapping.rs deleted file mode 100644 index f20afb263..000000000 --- a/netwerk/base/rust-url-capi/src/error_mapping.rs +++ /dev/null @@ -1,68 +0,0 @@ -use url::ParseError; - -pub trait ErrorCode { - fn error_code(&self) -> i32; -} - -impl<T: ErrorCode> ErrorCode for Result<(), T> { - fn error_code(&self) -> i32 { - match *self { - Ok(_) => 0, - Err(ref error) => error.error_code(), - } - } -} - -impl ErrorCode for () { - fn error_code(&self) -> i32 { - return -1; - } -} -impl ErrorCode for ParseError { - fn error_code(&self) -> i32 { - return -1; -// match *self { -// ParseError::EmptyHost => -1, -// ParseError::InvalidScheme => -2, -// ParseError::InvalidPort => -3, -// ParseError::InvalidIpv6Address => -4, -// ParseError::InvalidDomainCharacter => -5, -// ParseError::InvalidCharacter => -6, -// ParseError::InvalidBackslash => -7, -// ParseError::InvalidPercentEncoded => -8, -// ParseError::InvalidAtSymbolInUser => -9, -// ParseError::ExpectedTwoSlashes => -10, -// ParseError::ExpectedInitialSlash => -11, -// ParseError::NonUrlCodePoint => -12, -// ParseError::RelativeUrlWithScheme => -13, -// ParseError::RelativeUrlWithoutBase => -14, -// ParseError::RelativeUrlWithNonRelativeBase => -15, -// ParseError::NonAsciiDomainsNotSupportedYet => -16, -// ParseError::CannotSetJavascriptFragment => -17, -// ParseError::CannotSetPortWithFileLikeScheme => -18, -// ParseError::CannotSetUsernameWithNonRelativeScheme => -19, -// ParseError::CannotSetPasswordWithNonRelativeScheme => -20, -// ParseError::CannotSetHostPortWithNonRelativeScheme => -21, -// ParseError::CannotSetHostWithNonRelativeScheme => -22, -// ParseError::CannotSetPortWithNonRelativeScheme => -23, -// ParseError::CannotSetPathWithNonRelativeScheme => -24, -// } - } -} - -pub enum NSError { - OK, - InvalidArg, - Failure, -} - -impl ErrorCode for NSError { - #[allow(overflowing_literals)] - fn error_code(&self) -> i32 { - match *self { - NSError::OK => 0, - NSError::InvalidArg => 0x80070057, - NSError::Failure => 0x80004005 - } - } -} diff --git a/netwerk/base/rust-url-capi/src/lib.rs b/netwerk/base/rust-url-capi/src/lib.rs deleted file mode 100644 index e2997ce46..000000000 --- a/netwerk/base/rust-url-capi/src/lib.rs +++ /dev/null @@ -1,477 +0,0 @@ -extern crate url; -use url::{Url, ParseError, ParseOptions}; -use url::quirks; -extern crate libc; -use libc::size_t; - - -use std::mem; -use std::str; - -#[allow(non_camel_case_types)] -pub type rusturl_ptr = *const libc::c_void; - -mod string_utils; -pub use string_utils::*; - -mod error_mapping; -use error_mapping::*; - -fn parser<'a>() -> ParseOptions<'a> { - Url::options() -} - -fn default_port(scheme: &str) -> Option<u32> { - match scheme { - "ftp" => Some(21), - "gopher" => Some(70), - "http" => Some(80), - "https" => Some(443), - "ws" => Some(80), - "wss" => Some(443), - "rtsp" => Some(443), - "moz-anno" => Some(443), - "android" => Some(443), - _ => None, - } -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_new(spec: *mut libc::c_char, len: size_t) -> rusturl_ptr { - let slice = std::slice::from_raw_parts(spec as *const libc::c_uchar, len as usize); - let url_spec = match str::from_utf8(slice) { - Ok(spec) => spec, - Err(_) => return 0 as rusturl_ptr - }; - - let url = match parser().parse(url_spec) { - Ok(url) => url, - Err(_) => return 0 as rusturl_ptr - }; - - let url = Box::new(url); - Box::into_raw(url) as rusturl_ptr -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_free(urlptr: rusturl_ptr) { - if urlptr.is_null() { - return (); - } - let url: Box<Url> = Box::from_raw(urlptr as *mut url::Url); - drop(url); -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_get_spec(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let url: &Url = mem::transmute(urlptr); - cont.assign(&url.to_string()) -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_get_scheme(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let url: &Url = mem::transmute(urlptr); - cont.assign(&url.scheme()) -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_get_username(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let url: &Url = mem::transmute(urlptr); - if url.cannot_be_a_base() { - cont.set_size(0) - } else { - cont.assign(url.username()) - } -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_get_password(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let url: &Url = mem::transmute(urlptr); - match url.password() { - Some(p) => cont.assign(&p.to_string()), - None => cont.set_size(0) - } -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_get_host(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let url: &Url = mem::transmute(urlptr); - - match url.host() { - Some(h) => cont.assign(&h.to_string()), - None => cont.set_size(0) - } -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_get_port(urlptr: rusturl_ptr) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let url: &Url = mem::transmute(urlptr); - - match url.port() { - Some(port) => port as i32, - None => -1 - } -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_get_path(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let url: &Url = mem::transmute(urlptr); - if url.cannot_be_a_base() { - cont.set_size(0) - } else { - cont.assign(url.path()) - } -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_get_query(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let url: &Url = mem::transmute(urlptr); - match url.query() { - Some(ref s) => cont.assign(s), - None => cont.set_size(0) - } -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_get_fragment(urlptr: rusturl_ptr, cont: *mut libc::c_void) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let url: &Url = mem::transmute(urlptr); - - match url.fragment() { - Some(ref fragment) => cont.assign(fragment), - None => cont.set_size(0) - } -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_has_fragment(urlptr: rusturl_ptr) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let url: &Url = mem::transmute(urlptr); - - match url.fragment() { - Some(_) => return 1, - None => return 0 - } -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_set_scheme(urlptr: rusturl_ptr, scheme: *mut libc::c_char, len: size_t) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let mut url: &mut Url = mem::transmute(urlptr); - let slice = std::slice::from_raw_parts(scheme as *const libc::c_uchar, len as usize); - - let scheme_ = match str::from_utf8(slice).ok() { - Some(p) => p, - None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed - }; - - quirks::set_protocol(url, scheme_).error_code() -} - - -#[no_mangle] -pub unsafe extern "C" fn rusturl_set_username(urlptr: rusturl_ptr, username: *mut libc::c_char, len: size_t) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let mut url: &mut Url = mem::transmute(urlptr); - let slice = std::slice::from_raw_parts(username as *const libc::c_uchar, len as usize); - - let username_ = match str::from_utf8(slice).ok() { - Some(p) => p, - None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed - }; - - quirks::set_username(url, username_).error_code() -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_set_password(urlptr: rusturl_ptr, password: *mut libc::c_char, len: size_t) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let mut url: &mut Url = mem::transmute(urlptr); - let slice = std::slice::from_raw_parts(password as *const libc::c_uchar, len as usize); - - let password_ = match str::from_utf8(slice).ok() { - Some(p) => p, - None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed - }; - - quirks::set_password(url, password_).error_code() -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_set_host_and_port(urlptr: rusturl_ptr, host_and_port: *mut libc::c_char, len: size_t) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let mut url: &mut Url = mem::transmute(urlptr); - let slice = std::slice::from_raw_parts(host_and_port as *const libc::c_uchar, len as usize); - - let host_and_port_ = match str::from_utf8(slice).ok() { - Some(p) => p, - None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed - }; - - quirks::set_host(url, host_and_port_).error_code() -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_set_host(urlptr: rusturl_ptr, host: *mut libc::c_char, len: size_t) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let mut url: &mut Url = mem::transmute(urlptr); - let slice = std::slice::from_raw_parts(host as *const libc::c_uchar, len as usize); - - let hostname = match str::from_utf8(slice).ok() { - Some(h) => h, - None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed - }; - - quirks::set_hostname(url, hostname).error_code() -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_set_port(urlptr: rusturl_ptr, port: *mut libc::c_char, len: size_t) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let mut url: &mut Url = mem::transmute(urlptr); - let slice = std::slice::from_raw_parts(port as *const libc::c_uchar, len as usize); - - let port_ = match str::from_utf8(slice).ok() { - Some(p) => p, - None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed - }; - - quirks::set_port(url, port_).error_code() -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_set_port_no(urlptr: rusturl_ptr, new_port: i32) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let mut url: &mut Url = mem::transmute(urlptr); - if url.cannot_be_a_base() { - -100 - } else { - if url.scheme() == "file" { - return -100; - } - match default_port(url.scheme()) { - Some(def_port) => if new_port == def_port as i32 { - let _ = url.set_port(None); - return NSError::OK.error_code(); - }, - None => {} - }; - if new_port > std::u16::MAX as i32 || new_port < 0 { - let _ = url.set_port(None); - } else { - let _ = url.set_port(Some(new_port as u16)); - } - NSError::OK.error_code() - } -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_set_path(urlptr: rusturl_ptr, path: *mut libc::c_char, len: size_t) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let mut url: &mut Url = mem::transmute(urlptr); - let slice = std::slice::from_raw_parts(path as *const libc::c_uchar, len as usize); - - let path_ = match str::from_utf8(slice).ok() { - Some(p) => p, - None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed - }; - - quirks::set_pathname(url, path_).error_code() -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_set_query(urlptr: rusturl_ptr, query: *mut libc::c_char, len: size_t) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let mut url: &mut Url = mem::transmute(urlptr); - let slice = std::slice::from_raw_parts(query as *const libc::c_uchar, len as usize); - - let query_ = match str::from_utf8(slice).ok() { - Some(p) => p, - None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed - }; - - quirks::set_search(url, query_).error_code() -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_set_fragment(urlptr: rusturl_ptr, fragment: *mut libc::c_char, len: size_t) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let mut url: &mut Url = mem::transmute(urlptr); - let slice = std::slice::from_raw_parts(fragment as *const libc::c_uchar, len as usize); - - let fragment_ = match str::from_utf8(slice).ok() { - Some(p) => p, - None => return ParseError::InvalidDomainCharacter.error_code() // utf-8 failed - }; - - quirks::set_hash(url, fragment_).error_code() -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_resolve(urlptr: rusturl_ptr, resolve: *mut libc::c_char, len: size_t, cont: *mut libc::c_void) -> i32 { - if urlptr.is_null() { - return NSError::InvalidArg.error_code(); - } - let url: &mut Url = mem::transmute(urlptr); - - let slice = std::slice::from_raw_parts(resolve as *const libc::c_uchar, len as usize); - - let resolve_ = match str::from_utf8(slice).ok() { - Some(p) => p, - None => return NSError::Failure.error_code() - }; - - match parser().base_url(Some(&url)).parse(resolve_).ok() { - Some(u) => cont.assign(&u.to_string()), - None => cont.set_size(0) - } -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_common_base_spec(urlptr1: rusturl_ptr, urlptr2: rusturl_ptr, cont: *mut libc::c_void) -> i32 { - if urlptr1.is_null() || urlptr2.is_null() { - return NSError::InvalidArg.error_code(); - } - let url1: &Url = mem::transmute(urlptr1); - let url2: &Url = mem::transmute(urlptr2); - - if url1 == url2 { - return cont.assign(&url1.to_string()); - } - - if url1.scheme() != url2.scheme() || - url1.host() != url2.host() || - url1.username() != url2.username() || - url1.password() != url2.password() || - url1.port() != url2.port() { - return cont.set_size(0); - } - - let path1 = match url1.path_segments() { - Some(path) => path, - None => return cont.set_size(0) - }; - let path2 = match url2.path_segments() { - Some(path) => path, - None => return cont.set_size(0) - }; - - let mut url = url1.clone(); - url.set_query(None); - let _ = url.set_host(None); - { - let mut new_segments = if let Ok(segments) = url.path_segments_mut() { - segments - } else { - return cont.set_size(0) - }; - - for (p1, p2) in path1.zip(path2) { - if p1 != p2 { - break; - } else { - new_segments.push(p1); - } - } - } - - cont.assign(&url.to_string()) -} - -#[no_mangle] -pub unsafe extern "C" fn rusturl_relative_spec(urlptr1: rusturl_ptr, urlptr2: rusturl_ptr, cont: *mut libc::c_void) -> i32 { - if urlptr1.is_null() || urlptr2.is_null() { - return NSError::InvalidArg.error_code(); - } - let url1: &Url = mem::transmute(urlptr1); - let url2: &Url = mem::transmute(urlptr2); - - if url1 == url2 { - return cont.set_size(0); - } - - if url1.scheme() != url2.scheme() || - url1.host() != url2.host() || - url1.username() != url2.username() || - url1.password() != url2.password() || - url1.port() != url2.port() { - return cont.assign(&url2.to_string()); - } - - let mut path1 = match url1.path_segments() { - Some(path) => path, - None => return cont.assign(&url2.to_string()) - }; - let mut path2 = match url2.path_segments() { - Some(path) => path, - None => return cont.assign(&url2.to_string()) - }; - - // TODO: file:// on WIN? - - // Exhaust the part of the iterators that match - while let (Some(ref p1), Some(ref p2)) = (path1.next(), path2.next()) { - if p1 != p2 { - break; - } - } - - let mut buffer: String = "".to_string(); - for _ in path1 { - buffer = buffer + "../"; - } - for p2 in path2 { - buffer = buffer + p2 + "/"; - } - - return cont.assign(&buffer); -} - diff --git a/netwerk/base/rust-url-capi/src/rust-url-capi.h b/netwerk/base/rust-url-capi/src/rust-url-capi.h deleted file mode 100644 index 8d7a05aed..000000000 --- a/netwerk/base/rust-url-capi/src/rust-url-capi.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __RUST_URL_CAPI -#define __RUST_URL_CAPI -#include <stdlib.h> - -#ifdef __cplusplus -extern "C" { -#endif - -struct rusturl; -typedef struct rusturl* rusturl_ptr; - -rusturl_ptr rusturl_new(const char *spec, size_t src_len); -void rusturl_free(rusturl_ptr url); - -int32_t rusturl_get_spec(rusturl_ptr url, void*); -int32_t rusturl_get_scheme(rusturl_ptr url, void*); -int32_t rusturl_get_username(rusturl_ptr url, void*); -int32_t rusturl_get_password(rusturl_ptr url, void*); -int32_t rusturl_get_host(rusturl_ptr url, void*); -int32_t rusturl_get_port(rusturl_ptr url); // returns port or -1 -int32_t rusturl_get_path(rusturl_ptr url, void*); -int32_t rusturl_get_query(rusturl_ptr url, void*); -int32_t rusturl_get_fragment(rusturl_ptr url, void*); -int32_t rusturl_has_fragment(rusturl_ptr url); // 1 true, 0 false, < 0 error - -int32_t rusturl_set_scheme(rusturl_ptr url, const char *scheme, size_t len); -int32_t rusturl_set_username(rusturl_ptr url, const char *user, size_t len); -int32_t rusturl_set_password(rusturl_ptr url, const char *pass, size_t len); -int32_t rusturl_set_host_and_port(rusturl_ptr url, const char *hostport, size_t len); -int32_t rusturl_set_host(rusturl_ptr url, const char *host, size_t len); -int32_t rusturl_set_port(rusturl_ptr url, const char *port, size_t len); -int32_t rusturl_set_port_no(rusturl_ptr url, const int32_t port); -int32_t rusturl_set_path(rusturl_ptr url, const char *path, size_t len); -int32_t rusturl_set_query(rusturl_ptr url, const char *path, size_t len); -int32_t rusturl_set_fragment(rusturl_ptr url, const char *path, size_t len); - -int32_t rusturl_resolve(rusturl_ptr url, const char *relative, size_t len, void*); -int32_t rusturl_common_base_spec(rusturl_ptr url1, rusturl_ptr url2, void*); -int32_t rusturl_relative_spec(rusturl_ptr url1, rusturl_ptr url2, void*); - -#ifdef __cplusplus -} -#endif - -#endif // __RUST_URL_CAPI
\ No newline at end of file diff --git a/netwerk/base/rust-url-capi/src/string_utils.rs b/netwerk/base/rust-url-capi/src/string_utils.rs deleted file mode 100644 index ae68a60dc..000000000 --- a/netwerk/base/rust-url-capi/src/string_utils.rs +++ /dev/null @@ -1,57 +0,0 @@ -extern crate libc; -use libc::size_t; - -extern crate std; -use std::ptr; - -use error_mapping::*; - -extern "C" { - fn c_fn_set_size(user: *mut libc::c_void, size: size_t) -> i32; - fn c_fn_get_buffer(user: *mut libc::c_void) -> *mut libc::c_char; -} - -pub trait StringContainer { - fn set_size(&self, size_t) -> i32; - fn get_buffer(&self) -> *mut libc::c_char; - fn assign(&self, content: &str) -> i32; -} - -impl StringContainer for *mut libc::c_void { - fn set_size(&self, size: size_t) -> i32 { - if (*self).is_null() { - return NSError::InvalidArg.error_code(); - } - unsafe { - c_fn_set_size(*self, size); - } - - return NSError::OK.error_code(); - } - fn get_buffer(&self) -> *mut libc::c_char { - if (*self).is_null() { - return 0 as *mut libc::c_char; - } - unsafe { - c_fn_get_buffer(*self) - } - } - fn assign(&self, content: &str) -> i32 { - if (*self).is_null() { - return NSError::InvalidArg.error_code(); - } - - unsafe { - let slice = content.as_bytes(); - c_fn_set_size(*self, slice.len()); - let buf = c_fn_get_buffer(*self); - if buf.is_null() { - return NSError::Failure.error_code(); - } - - ptr::copy(slice.as_ptr(), buf as *mut u8, slice.len()); - } - - NSError::OK.error_code() - } -} diff --git a/netwerk/base/rust-url-capi/test/Makefile b/netwerk/base/rust-url-capi/test/Makefile deleted file mode 100644 index a4e2fd0cf..000000000 --- a/netwerk/base/rust-url-capi/test/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -all: - cd .. && cargo build - g++ -Wall -o test test.cpp ../target/debug/librust*.a -ldl -lpthread -lrt -lgcc_s -lpthread -lc -lm -std=c++0x - ./test diff --git a/netwerk/base/rust-url-capi/test/test.cpp b/netwerk/base/rust-url-capi/test/test.cpp deleted file mode 100644 index 6e90ea43b..000000000 --- a/netwerk/base/rust-url-capi/test/test.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include "../src/rust-url-capi.h" - -class StringContainer -{ -public: - StringContainer() - { - mBuffer = nullptr; - mLength = 0; - } - - ~StringContainer() - { - free(mBuffer); - mBuffer = nullptr; - } - - void SetSize(size_t size) - { - mLength = size; - if (mBuffer) { - mBuffer = (char *)realloc(mBuffer, size); - return; - } - mBuffer = (char *)malloc(size); - } - - char * GetBuffer() - { - return mBuffer; - } - - void CheckEquals(const char * ref) { - int32_t refLen = strlen(ref); - printf("CheckEquals: %s (len:%d)\n", ref, refLen); - if (refLen != mLength || strncmp(mBuffer, ref, mLength)) { - printf("\t--- ERROR ---\n"); - printf("Got : "); - fwrite(mBuffer, mLength, 1, stdout); - printf(" (len:%d)\n", mLength); - exit(-1); - } - printf("-> OK\n"); - } -private: - int32_t mLength; - char * mBuffer; -}; - -extern "C" int32_t c_fn_set_size(void * container, size_t size) -{ - ((StringContainer *) container)->SetSize(size); - return 0; -} - -extern "C" char * c_fn_get_buffer(void * container) -{ - return ((StringContainer *) container)->GetBuffer(); -} - -#define TEST_CALL(func, expected) \ -{ \ - int32_t code = func; \ - printf("%s -> code %d\n", #func, code); \ - assert(code == expected); \ - printf("-> OK\n"); \ -} \ - - -int main() { - // Create URL - rusturl_ptr url = rusturl_new("http://example.com/path/some/file.txt", - strlen("http://example.com/path/some/file.txt")); - assert(url); // Check we have a URL - - StringContainer container; - - TEST_CALL(rusturl_get_spec(url, &container), 0); - container.CheckEquals("http://example.com/path/some/file.txt"); - TEST_CALL(rusturl_set_host(url, "test.com", strlen("test.com")), 0); - TEST_CALL(rusturl_get_host(url, &container), 0); - container.CheckEquals("test.com"); - TEST_CALL(rusturl_get_path(url, &container), 0); - container.CheckEquals("/path/some/file.txt"); - TEST_CALL(rusturl_set_path(url, "hello/../else.txt", strlen("hello/../else.txt")), 0); - TEST_CALL(rusturl_get_path(url, &container), 0); - container.CheckEquals("/else.txt"); - TEST_CALL(rusturl_resolve(url, "./bla/file.txt", strlen("./bla/file.txt"), &container), 0); - container.CheckEquals("http://test.com/bla/file.txt"); - TEST_CALL(rusturl_get_scheme(url, &container), 0); - container.CheckEquals("http"); - TEST_CALL(rusturl_set_username(url, "user", strlen("user")), 0); - TEST_CALL(rusturl_get_username(url, &container), 0); - container.CheckEquals("user"); - TEST_CALL(rusturl_get_spec(url, &container), 0); - container.CheckEquals("http://user@test.com/else.txt"); - TEST_CALL(rusturl_set_password(url, "pass", strlen("pass")), 0); - TEST_CALL(rusturl_get_password(url, &container), 0); - container.CheckEquals("pass"); - TEST_CALL(rusturl_get_spec(url, &container), 0); - container.CheckEquals("http://user:pass@test.com/else.txt"); - TEST_CALL(rusturl_set_username(url, "", strlen("")), 0); - TEST_CALL(rusturl_set_password(url, "", strlen("")), 0); - TEST_CALL(rusturl_get_spec(url, &container), 0); - container.CheckEquals("http://test.com/else.txt"); - TEST_CALL(rusturl_set_host_and_port(url, "example.org:1234", strlen("example.org:1234")), 0); - TEST_CALL(rusturl_get_host(url, &container), 0); - container.CheckEquals("example.org"); - assert(rusturl_get_port(url) == 1234); - TEST_CALL(rusturl_set_port(url, "9090", strlen("9090")), 0); - assert(rusturl_get_port(url) == 9090); - TEST_CALL(rusturl_set_query(url, "x=1", strlen("x=1")), 0); - TEST_CALL(rusturl_get_query(url, &container), 0); - container.CheckEquals("x=1"); - TEST_CALL(rusturl_set_fragment(url, "fragment", strlen("fragment")), 0); - TEST_CALL(rusturl_get_fragment(url, &container), 0); - container.CheckEquals("fragment"); - TEST_CALL(rusturl_get_spec(url, &container), 0); - container.CheckEquals("http://example.org:9090/else.txt?x=1#fragment"); - - // Free the URL - rusturl_free(url); - - url = rusturl_new("http://example.com/#", - strlen("http://example.com/#")); - assert(url); // Check we have a URL - - assert(rusturl_has_fragment(url) == 1); - TEST_CALL(rusturl_set_fragment(url, "", 0), 0); - assert(rusturl_has_fragment(url) == 0); - TEST_CALL(rusturl_get_spec(url, &container), 0); - container.CheckEquals("http://example.com/"); - - rusturl_free(url); - - printf("SUCCESS\n"); - return 0; -}
\ No newline at end of file diff --git a/netwerk/base/security-prefs.js b/netwerk/base/security-prefs.js index d1b56ce35..329a4c6b7 100644 --- a/netwerk/base/security-prefs.js +++ b/netwerk/base/security-prefs.js @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ pref("security.tls.version.min", 1); -pref("security.tls.version.max", 4); +pref("security.tls.version.max", 3); pref("security.tls.version.fallback-limit", 3); pref("security.tls.insecure_fallback_hosts", ""); pref("security.tls.unrestricted_rc4_fallback", false); diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh index 9365397d1..4f4dcf6a9 100644 --- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -39,6 +39,7 @@ struct LoadInfoArgs bool upgradeInsecureRequests; bool verifySignedContent; bool enforceSRI; + bool forceAllowDataURI; bool forceInheritPrincipalDropped; uint64_t innerWindowID; uint64_t outerWindowID; @@ -53,6 +54,7 @@ struct LoadInfoArgs nsCString[] corsUnsafeHeaders; bool forcePreflight; bool isPreflight; + bool loadTriggeredFromExternal; bool forceHSTSPriming; bool mixedContentWouldBlock; }; diff --git a/netwerk/ipc/NeckoMessageUtils.h b/netwerk/ipc/NeckoMessageUtils.h index 778691369..1633b82b6 100644 --- a/netwerk/ipc/NeckoMessageUtils.h +++ b/netwerk/ipc/NeckoMessageUtils.h @@ -14,11 +14,6 @@ #include "mozilla/net/DNS.h" #include "TimingStruct.h" -#ifdef MOZ_CRASHREPORTER -#include "nsExceptionHandler.h" -#include "nsPrintfCString.h" -#endif - namespace IPC { // nsIPermissionManager utilities @@ -102,12 +97,6 @@ struct ParamTraits<mozilla::net::NetAddr> aMsg->WriteBytes(aParam.local.path, sizeof(aParam.local.path)); #endif } else { -#ifdef MOZ_CRASHREPORTER - if (XRE_IsParentProcess()) { - nsPrintfCString msg("%d", aParam.raw.family); - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Unknown NetAddr socket family"), msg); - } -#endif NS_RUNTIMEABORT("Unknown socket family"); } } diff --git a/netwerk/protocol/http/Http2Session.cpp b/netwerk/protocol/http/Http2Session.cpp index 55ddbe908..4f350af83 100644 --- a/netwerk/protocol/http/Http2Session.cpp +++ b/netwerk/protocol/http/Http2Session.cpp @@ -1044,6 +1044,15 @@ Http2Session::CleanupStream(Http2Stream *aStream, nsresult aResult, return; } + Http2PushedStream *pushSource = aStream->PushSource(); + if (pushSource) { + // aStream is a synthetic attached to an even push + MOZ_ASSERT(pushSource->GetConsumerStream() == aStream); + MOZ_ASSERT(!aStream->StreamID()); + MOZ_ASSERT(!(pushSource->StreamID() & 0x1)); + aStream->ClearPushSource(); + } + if (aStream->DeferCleanup(aResult)) { LOG3(("Http2Session::CleanupStream 0x%X deferred\n", aStream->StreamID())); return; @@ -1054,15 +1063,6 @@ Http2Session::CleanupStream(Http2Stream *aStream, nsresult aResult, return; } - Http2PushedStream *pushSource = aStream->PushSource(); - if (pushSource) { - // aStream is a synthetic attached to an even push - MOZ_ASSERT(pushSource->GetConsumerStream() == aStream); - MOZ_ASSERT(!aStream->StreamID()); - MOZ_ASSERT(!(pushSource->StreamID() & 0x1)); - pushSource->SetConsumerStream(nullptr); - } - // don't reset a stream that has recevied a fin or rst if (!aStream->RecvdFin() && !aStream->RecvdReset() && aStream->StreamID() && !(mInputFrameFinal && (aStream == mInputFrameDataStream))) { // !(recvdfin with mark pending) diff --git a/netwerk/protocol/http/Http2Stream.cpp b/netwerk/protocol/http/Http2Stream.cpp index f49c1f138..7a8f96855 100644 --- a/netwerk/protocol/http/Http2Stream.cpp +++ b/netwerk/protocol/http/Http2Stream.cpp @@ -103,10 +103,20 @@ Http2Stream::Http2Stream(nsAHttpTransaction *httpTransaction, Http2Stream::~Http2Stream() { + ClearPushSource(); ClearTransactionsBlockedOnTunnel(); mStreamID = Http2Session::kDeadStreamID; } +void +Http2Stream::ClearPushSource() +{ + if (mPushSource) { + mPushSource->SetConsumerStream(nullptr); + mPushSource = nullptr; + } +} + // ReadSegments() is used to write data down the socket. Generally, HTTP // request data is pulled from the approriate transaction and // converted to HTTP/2 data. Sometimes control data like a window-update is @@ -1083,6 +1093,10 @@ Http2Stream::ConvertPushHeaders(Http2Decompressor *decompressor, void Http2Stream::Close(nsresult reason) { + // In case we are connected to a push, make sure the push knows we are closed, + // so it doesn't try to give us any more DATA that comes on it after our close. + ClearPushSource(); + mTransaction->Close(reason); } diff --git a/netwerk/protocol/http/Http2Stream.h b/netwerk/protocol/http/Http2Stream.h index 968461ee4..8783eefed 100644 --- a/netwerk/protocol/http/Http2Stream.h +++ b/netwerk/protocol/http/Http2Stream.h @@ -50,6 +50,7 @@ public: uint32_t StreamID() { return mStreamID; } Http2PushedStream *PushSource() { return mPushSource; } + void ClearPushSource(); stateType HTTPState() { return mState; } void SetHTTPState(stateType val) { mState = val; } diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index 0ff792280..278c94db0 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -2480,9 +2480,9 @@ HttpBaseChannel::GetFetchCacheMode(uint32_t* aFetchCacheMode) *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_RELOAD; } else if (mLoadFlags & VALIDATE_ALWAYS) { *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_CACHE; - } else if (mLoadFlags & (LOAD_FROM_CACHE | nsICachingChannel::LOAD_ONLY_FROM_CACHE)) { + } else if (mLoadFlags & (VALIDATE_NEVER | nsICachingChannel::LOAD_ONLY_FROM_CACHE)) { *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_ONLY_IF_CACHED; - } else if (mLoadFlags & LOAD_FROM_CACHE) { + } else if (mLoadFlags & VALIDATE_NEVER) { *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_FORCE_CACHE; } else { *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_DEFAULT; @@ -2518,7 +2518,7 @@ HttpBaseChannel::SetFetchCacheMode(uint32_t aFetchCacheMode) break; case nsIHttpChannelInternal::FETCH_CACHE_MODE_FORCE_CACHE: // force-cache means don't validate unless if the response would vary. - mLoadFlags |= LOAD_FROM_CACHE; + mLoadFlags |= VALIDATE_NEVER; break; case nsIHttpChannelInternal::FETCH_CACHE_MODE_ONLY_IF_CACHED: // only-if-cached means only from cache, no network, no validation, generate @@ -2527,7 +2527,7 @@ HttpBaseChannel::SetFetchCacheMode(uint32_t aFetchCacheMode) // the user has things in their cache without any network traffic side // effects) are addressed in the Request constructor which enforces/requires // same-origin request mode. - mLoadFlags |= LOAD_FROM_CACHE | nsICachingChannel::LOAD_ONLY_FROM_CACHE; + mLoadFlags |= VALIDATE_NEVER | nsICachingChannel::LOAD_ONLY_FROM_CACHE; break; } diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index fe076a237..5f0859f28 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -1772,8 +1772,8 @@ HttpChannelParent::UpdateAndSerializeSecurityInfo(nsACString& aSerializedSecurit bool HttpChannelParent::DoSendDeleteSelf() { - bool rv = SendDeleteSelf(); mIPCClosed = true; + bool rv = SendDeleteSelf(); return rv; } diff --git a/netwerk/protocol/http/HttpChannelParent.h b/netwerk/protocol/http/HttpChannelParent.h index 51fae5a82..a3b377d49 100644 --- a/netwerk/protocol/http/HttpChannelParent.h +++ b/netwerk/protocol/http/HttpChannelParent.h @@ -209,7 +209,7 @@ private: RefPtr<nsHttpChannel> mChannel; nsCOMPtr<nsICacheEntry> mCacheEntry; nsCOMPtr<nsIAssociatedContentSecurity> mAssociatedContentSecurity; - bool mIPCClosed; // PHttpChannel actor has been Closed() + Atomic<bool> mIPCClosed; // PHttpChannel actor has been Closed() nsCOMPtr<nsIChannel> mRedirectChannel; nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback; diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index ce0f45dab..94b0d9bf9 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -1152,7 +1152,7 @@ ProcessXCTO(nsIURI* aURI, nsHttpResponseHead* aResponseHead, nsILoadInfo* aLoadI } if (aLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_SCRIPT) { - if (nsContentUtils::IsScriptType(contentType)) { + if (nsContentUtils::IsJavascriptMIMEType(NS_ConvertUTF8toUTF16(contentType))) { return NS_OK; } ReportTypeBlocking(aURI, aLoadInfo, "MimeTypeMismatch"); diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h index d51662db9..35b14a511 100644 --- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -489,8 +489,8 @@ private: nsCString mCompatGecko; bool mCompatGeckoEnabled; nsCString mCompatFirefox; - nsCString mCompatFirefoxVersion; bool mCompatFirefoxEnabled; + nsCString mCompatFirefoxVersion; nsXPIDLCString mCompatDevice; nsCString mDeviceModelId; diff --git a/netwerk/sctp/datachannel/DataChannel.cpp b/netwerk/sctp/datachannel/DataChannel.cpp index bf7790f51..d47a9d5ea 100644 --- a/netwerk/sctp/datachannel/DataChannel.cpp +++ b/netwerk/sctp/datachannel/DataChannel.cpp @@ -646,6 +646,7 @@ DataChannelConnection::SctpDtlsInput(TransportFlow *flow, } } // Pass the data to SCTP + MutexAutoLock lock(mLock); usrsctp_conninput(static_cast<void *>(this), data, len, 0); } @@ -1016,7 +1017,7 @@ DataChannelConnection::SendDeferredMessages() bool still_blocked = false; // This may block while something is modifying channels, but should not block for IO - MutexAutoLock lock(mLock); + mLock.AssertCurrentThreadOwns(); // XXX For total fairness, on a still_blocked we'd start next time at the // same index. Sorry, not going to bother for now. @@ -1923,7 +1924,7 @@ DataChannelConnection::ReceiveCallback(struct socket* sock, void *data, size_t d if (!data) { usrsctp_close(sock); // SCTP has finished shutting down } else { - MutexAutoLock lock(mLock); + mLock.AssertCurrentThreadOwns(); if (flags & MSG_NOTIFICATION) { HandleNotification(static_cast<union sctp_notification *>(data), datalen); } else { diff --git a/netwerk/test/unit/test_URIs.js b/netwerk/test/unit/test_URIs.js index b68c4f787..1cad7768f 100644 --- a/netwerk/test/unit/test_URIs.js +++ b/netwerk/test/unit/test_URIs.js @@ -92,18 +92,6 @@ var gTests = [ ref: "", relativeURI: "data/text/plain,2", nsIURL: true, nsINestedURI: false }, - { spec: "ftp://", - scheme: "ftp", - prePath: "ftp://", - path: "/", - ref: "", - nsIURL: true, nsINestedURI: false }, - { spec: "ftp:///", - scheme: "ftp", - prePath: "ftp://", - path: "/", - ref: "", - nsIURL: true, nsINestedURI: false }, { spec: "ftp://ftp.mozilla.org/pub/mozilla.org/README", scheme: "ftp", prePath: "ftp://ftp.mozilla.org", @@ -121,7 +109,7 @@ var gTests = [ nsIURL: true, nsINestedURI: false }, { spec: "ftp://foo:@ftp.mozilla.org:100/pub/mozilla.org/README", scheme: "ftp", - prePath: "ftp://foo:@ftp.mozilla.org:100", + prePath: "ftp://foo@ftp.mozilla.org:100", port: 100, username: "foo", password: "", @@ -135,18 +123,6 @@ var gTests = [ path: "//mozilla.org/", ref: "", nsIURL: false, nsINestedURI: false }, - { spec: "http://", - scheme: "http", - prePath: "http://", - path: "/", - ref: "", - nsIURL: true, nsINestedURI: false }, - { spec: "http:///", - scheme: "http", - prePath: "http://", - path: "/", - ref: "", - nsIURL: true, nsINestedURI: false }, { spec: "http://www.example.com/", scheme: "http", prePath: "http://www.example.com", diff --git a/netwerk/test/unit/test_standardurl.js b/netwerk/test/unit/test_standardurl.js index c4d44f41f..4cc2f393e 100644 --- a/netwerk/test/unit/test_standardurl.js +++ b/netwerk/test/unit/test_standardurl.js @@ -251,6 +251,17 @@ add_test(function test_escapeBrackets() run_next_test(); }); +add_test(function test_escapeQuote() +{ + var url = stringToURL("http://example.com/#'"); + do_check_eq(url.spec, "http://example.com/#'"); + do_check_eq(url.ref, "'"); + url.ref = "test'test"; + do_check_eq(url.spec, "http://example.com/#test'test"); + do_check_eq(url.ref, "test'test"); + run_next_test(); +}); + add_test(function test_apostropheEncoding() { // For now, single quote is escaped everywhere _except_ the path. @@ -335,6 +346,14 @@ add_test(function test_backslashReplacement() run_next_test(); }); +add_test(function test_authority_host() +{ + Assert.throws(() => { stringToURL("http:"); }, "TYPE_AUTHORITY should have host"); + Assert.throws(() => { stringToURL("http:///"); }, "TYPE_AUTHORITY should have host"); + + run_next_test(); +}); + add_test(function test_trim_C0_and_space() { var url = stringToURL("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f http://example.com/ \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f "); @@ -453,3 +472,23 @@ add_test(function test_invalidHostChars() { // hostname separators, so there is no way to set them and fail. run_next_test(); }); + +add_test(function test_emptyPassword() { + var url = stringToURL("http://a:@example.com"); + do_check_eq(url.spec, "http://a@example.com/"); + url.password = "pp"; + do_check_eq(url.spec, "http://a:pp@example.com/"); + url.password = ""; + do_check_eq(url.spec, "http://a@example.com/"); + url.userPass = "xxx:"; + do_check_eq(url.spec, "http://xxx@example.com/"); + url.password = "zzzz"; + do_check_eq(url.spec, "http://xxx:zzzz@example.com/"); + url.userPass = "xxxxx:yyyyyy"; + do_check_eq(url.spec, "http://xxxxx:yyyyyy@example.com/"); + url.userPass = "z:"; + do_check_eq(url.spec, "http://z@example.com/"); + url.password = "ppppppppppp"; + do_check_eq(url.spec, "http://z:ppppppppppp@example.com/"); + run_next_test(); +}); |