michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "URIUtils.h" michael@0: michael@0: #include "nsIIPCSerializableURI.h" michael@0: michael@0: #include "mozilla/ArrayUtils.h" michael@0: #include "mozilla/Assertions.h" michael@0: #include "nsComponentManagerUtils.h" michael@0: #include "nsDebug.h" michael@0: #include "nsID.h" michael@0: #include "nsJARURI.h" michael@0: #include "nsNetCID.h" michael@0: #include "nsNetUtil.h" michael@0: #include "nsThreadUtils.h" michael@0: michael@0: using namespace mozilla::ipc; michael@0: using mozilla::ArrayLength; michael@0: michael@0: namespace { michael@0: michael@0: NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID); michael@0: NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID); michael@0: NS_DEFINE_CID(kJARURICID, NS_JARURI_CID); michael@0: michael@0: struct StringWithLengh michael@0: { michael@0: const char* string; michael@0: size_t length; michael@0: }; michael@0: michael@0: #define STRING_WITH_LENGTH(_str) \ michael@0: { _str, ArrayLength(_str) - 1 } michael@0: michael@0: const StringWithLengh kGenericURIAllowedSchemes[] = { michael@0: STRING_WITH_LENGTH("about:"), michael@0: STRING_WITH_LENGTH("javascript:"), michael@0: STRING_WITH_LENGTH("javascript") michael@0: }; michael@0: michael@0: #undef STRING_WITH_LENGTH michael@0: michael@0: } // anonymous namespace michael@0: michael@0: namespace mozilla { michael@0: namespace ipc { michael@0: michael@0: void michael@0: SerializeURI(nsIURI* aURI, michael@0: URIParams& aParams) michael@0: { michael@0: MOZ_ASSERT(NS_IsMainThread()); michael@0: MOZ_ASSERT(aURI); michael@0: michael@0: nsCOMPtr serializable = do_QueryInterface(aURI); michael@0: if (serializable) { michael@0: serializable->Serialize(aParams); michael@0: if (aParams.type() == URIParams::T__None) { michael@0: MOZ_CRASH("Serialize failed!"); michael@0: } michael@0: return; michael@0: } michael@0: michael@0: nsCString scheme; michael@0: if (NS_FAILED(aURI->GetScheme(scheme))) { michael@0: MOZ_CRASH("This must never fail!"); michael@0: } michael@0: michael@0: bool allowed = false; michael@0: michael@0: for (size_t i = 0; i < ArrayLength(kGenericURIAllowedSchemes); i++) { michael@0: const StringWithLengh& entry = kGenericURIAllowedSchemes[i]; michael@0: if (scheme.EqualsASCII(entry.string, entry.length)) { michael@0: allowed = true; michael@0: break; michael@0: } michael@0: } michael@0: michael@0: if (!allowed) { michael@0: MOZ_CRASH("All IPDL URIs must be serializable or an allowed " michael@0: "scheme!"); michael@0: } michael@0: michael@0: GenericURIParams params; michael@0: if (NS_FAILED(aURI->GetSpec(params.spec())) || michael@0: NS_FAILED(aURI->GetOriginCharset(params.charset()))) { michael@0: MOZ_CRASH("This must never fail!"); michael@0: } michael@0: michael@0: aParams = params; michael@0: } michael@0: michael@0: void michael@0: SerializeURI(nsIURI* aURI, michael@0: OptionalURIParams& aParams) michael@0: { michael@0: MOZ_ASSERT(NS_IsMainThread()); michael@0: michael@0: if (aURI) { michael@0: URIParams params; michael@0: SerializeURI(aURI, params); michael@0: aParams = params; michael@0: } michael@0: else { michael@0: aParams = mozilla::void_t(); michael@0: } michael@0: } michael@0: michael@0: already_AddRefed michael@0: DeserializeURI(const URIParams& aParams) michael@0: { michael@0: MOZ_ASSERT(NS_IsMainThread()); michael@0: michael@0: nsCOMPtr uri; michael@0: michael@0: if (aParams.type() != URIParams::TGenericURIParams) { michael@0: nsCOMPtr serializable; michael@0: michael@0: switch (aParams.type()) { michael@0: case URIParams::TSimpleURIParams: michael@0: serializable = do_CreateInstance(kSimpleURICID); michael@0: break; michael@0: michael@0: case URIParams::TStandardURLParams: michael@0: serializable = do_CreateInstance(kStandardURLCID); michael@0: break; michael@0: michael@0: case URIParams::TJARURIParams: michael@0: serializable = do_CreateInstance(kJARURICID); michael@0: break; michael@0: michael@0: default: michael@0: MOZ_CRASH("Unknown params!"); michael@0: } michael@0: michael@0: MOZ_ASSERT(serializable); michael@0: michael@0: if (!serializable->Deserialize(aParams)) { michael@0: MOZ_ASSERT(false, "Deserialize failed!"); michael@0: return nullptr; michael@0: } michael@0: michael@0: uri = do_QueryInterface(serializable); michael@0: MOZ_ASSERT(uri); michael@0: michael@0: return uri.forget(); michael@0: } michael@0: michael@0: MOZ_ASSERT(aParams.type() == URIParams::TGenericURIParams); michael@0: michael@0: const GenericURIParams& params = aParams.get_GenericURIParams(); michael@0: michael@0: if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), params.spec(), michael@0: params.charset().get()))) { michael@0: NS_WARNING("Failed to make new URI!"); michael@0: return nullptr; michael@0: } michael@0: michael@0: nsCString scheme; michael@0: if (NS_FAILED(uri->GetScheme(scheme))) { michael@0: MOZ_CRASH("This must never fail!"); michael@0: } michael@0: michael@0: bool allowed = false; michael@0: michael@0: for (size_t i = 0; i < ArrayLength(kGenericURIAllowedSchemes); i++) { michael@0: const StringWithLengh& entry = kGenericURIAllowedSchemes[i]; michael@0: if (scheme.EqualsASCII(entry.string, entry.length)) { michael@0: allowed = true; michael@0: break; michael@0: } michael@0: } michael@0: michael@0: if (!allowed) { michael@0: MOZ_ASSERT(false, "This type of URI is not allowed!"); michael@0: return nullptr; michael@0: } michael@0: michael@0: return uri.forget(); michael@0: } michael@0: michael@0: already_AddRefed michael@0: DeserializeURI(const OptionalURIParams& aParams) michael@0: { michael@0: MOZ_ASSERT(NS_IsMainThread()); michael@0: michael@0: nsCOMPtr uri; michael@0: michael@0: switch (aParams.type()) { michael@0: case OptionalURIParams::Tvoid_t: michael@0: break; michael@0: michael@0: case OptionalURIParams::TURIParams: michael@0: uri = DeserializeURI(aParams.get_URIParams()); michael@0: break; michael@0: michael@0: default: michael@0: MOZ_CRASH("Unknown params!"); michael@0: } michael@0: michael@0: return uri.forget(); michael@0: } michael@0: michael@0: } // namespace ipc michael@0: } // namespace mozilla