Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "nsHostObjectURI.h"
8 :
9 : #include "nsIObjectInputStream.h"
10 : #include "nsIObjectOutputStream.h"
11 : #include "nsHostObjectProtocolHandler.h"
12 :
13 : #include "mozilla/ipc/BackgroundUtils.h"
14 : #include "mozilla/ipc/URIUtils.h"
15 :
16 : static NS_DEFINE_CID(kHOSTOBJECTURICID, NS_HOSTOBJECTURI_CID);
17 :
18 : static NS_DEFINE_CID(kThisSimpleURIImplementationCID,
19 : NS_THIS_SIMPLEURI_IMPLEMENTATION_CID);
20 :
21 0 : NS_IMPL_ADDREF_INHERITED(nsHostObjectURI, mozilla::net::nsSimpleURI)
22 0 : NS_IMPL_RELEASE_INHERITED(nsHostObjectURI, mozilla::net::nsSimpleURI)
23 :
24 0 : NS_INTERFACE_MAP_BEGIN(nsHostObjectURI)
25 0 : NS_INTERFACE_MAP_ENTRY(nsIURIWithBlobImpl)
26 0 : NS_INTERFACE_MAP_ENTRY(nsIURIWithPrincipal)
27 0 : NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
28 0 : if (aIID.Equals(kHOSTOBJECTURICID))
29 0 : foundInterface = static_cast<nsIURI*>(this);
30 0 : else if (aIID.Equals(kThisSimpleURIImplementationCID)) {
31 : // Need to return explicitly here, because if we just set foundInterface
32 : // to null the NS_INTERFACE_MAP_END_INHERITING will end up calling into
33 : // nsSimplURI::QueryInterface and finding something for this CID.
34 0 : *aInstancePtr = nullptr;
35 0 : return NS_NOINTERFACE;
36 : }
37 : else
38 0 : NS_INTERFACE_MAP_END_INHERITING(mozilla::net::nsSimpleURI)
39 :
40 : // nsIURIWithBlobImpl methods:
41 :
42 : NS_IMETHODIMP
43 0 : nsHostObjectURI::GetBlobImpl(nsISupports** aBlobImpl)
44 : {
45 0 : RefPtr<mozilla::dom::BlobImpl> blobImpl(mBlobImpl);
46 0 : blobImpl.forget(aBlobImpl);
47 0 : return NS_OK;
48 : }
49 :
50 : // nsIURIWithPrincipal methods:
51 :
52 : NS_IMETHODIMP
53 0 : nsHostObjectURI::GetPrincipal(nsIPrincipal** aPrincipal)
54 : {
55 0 : NS_IF_ADDREF(*aPrincipal = mPrincipal);
56 :
57 0 : return NS_OK;
58 : }
59 :
60 : NS_IMETHODIMP
61 0 : nsHostObjectURI::GetPrincipalUri(nsIURI** aUri)
62 : {
63 0 : if (mPrincipal) {
64 0 : mPrincipal->GetURI(aUri);
65 : }
66 : else {
67 0 : *aUri = nullptr;
68 : }
69 :
70 0 : return NS_OK;
71 : }
72 :
73 : // nsISerializable methods:
74 :
75 : NS_IMETHODIMP
76 0 : nsHostObjectURI::Read(nsIObjectInputStream* aStream)
77 : {
78 0 : nsresult rv = mozilla::net::nsSimpleURI::Read(aStream);
79 0 : NS_ENSURE_SUCCESS(rv, rv);
80 :
81 0 : nsCOMPtr<nsISupports> supports;
82 0 : rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
83 0 : NS_ENSURE_SUCCESS(rv, rv);
84 :
85 0 : mPrincipal = do_QueryInterface(supports, &rv);
86 0 : return rv;
87 : }
88 :
89 : NS_IMETHODIMP
90 0 : nsHostObjectURI::Write(nsIObjectOutputStream* aStream)
91 : {
92 0 : nsresult rv = mozilla::net::nsSimpleURI::Write(aStream);
93 0 : NS_ENSURE_SUCCESS(rv, rv);
94 :
95 : return NS_WriteOptionalCompoundObject(aStream, mPrincipal,
96 : NS_GET_IID(nsIPrincipal),
97 0 : true);
98 : }
99 :
100 : // nsIIPCSerializableURI methods:
101 : void
102 0 : nsHostObjectURI::Serialize(mozilla::ipc::URIParams& aParams)
103 : {
104 : using namespace mozilla::ipc;
105 :
106 0 : HostObjectURIParams hostParams;
107 0 : URIParams simpleParams;
108 :
109 0 : mozilla::net::nsSimpleURI::Serialize(simpleParams);
110 0 : hostParams.simpleParams() = simpleParams;
111 :
112 0 : if (mPrincipal) {
113 0 : PrincipalInfo info;
114 0 : nsresult rv = PrincipalToPrincipalInfo(mPrincipal, &info);
115 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
116 0 : return;
117 : }
118 :
119 0 : hostParams.principal() = info;
120 : } else {
121 0 : hostParams.principal() = mozilla::void_t();
122 : }
123 :
124 0 : aParams = hostParams;
125 : }
126 :
127 : bool
128 0 : nsHostObjectURI::Deserialize(const mozilla::ipc::URIParams& aParams)
129 : {
130 : using namespace mozilla::ipc;
131 :
132 0 : if (aParams.type() != URIParams::THostObjectURIParams) {
133 0 : NS_ERROR("Received unknown parameters from the other process!");
134 0 : return false;
135 : }
136 :
137 0 : const HostObjectURIParams& hostParams = aParams.get_HostObjectURIParams();
138 :
139 0 : if (!mozilla::net::nsSimpleURI::Deserialize(hostParams.simpleParams())) {
140 0 : return false;
141 : }
142 :
143 0 : if (hostParams.principal().type() == OptionalPrincipalInfo::Tvoid_t) {
144 0 : return true;
145 : }
146 :
147 0 : mPrincipal = PrincipalInfoToPrincipal(hostParams.principal().get_PrincipalInfo());
148 0 : if (!mPrincipal) {
149 0 : return false;
150 : }
151 :
152 : // If this fails, we still want to complete the operation. Probably this
153 : // blobURL has been revoked in the meantime.
154 0 : NS_GetBlobForBlobURI(this, getter_AddRefs(mBlobImpl));
155 :
156 0 : return true;
157 : }
158 :
159 : NS_IMETHODIMP
160 0 : nsHostObjectURI::SetScheme(const nsACString& aScheme)
161 : {
162 : // Disallow setting the scheme, since that could cause us to be associated
163 : // with a different protocol handler that doesn't expect us to be carrying
164 : // around a principal with nsIURIWithPrincipal.
165 0 : return NS_ERROR_FAILURE;
166 : }
167 :
168 : // nsIURI methods:
169 : nsresult
170 0 : nsHostObjectURI::CloneInternal(mozilla::net::nsSimpleURI::RefHandlingEnum aRefHandlingMode,
171 : const nsACString& newRef,
172 : nsIURI** aClone)
173 : {
174 0 : nsCOMPtr<nsIURI> simpleClone;
175 : nsresult rv =
176 0 : mozilla::net::nsSimpleURI::CloneInternal(aRefHandlingMode, newRef, getter_AddRefs(simpleClone));
177 0 : NS_ENSURE_SUCCESS(rv, rv);
178 :
179 : #ifdef DEBUG
180 0 : RefPtr<nsHostObjectURI> uriCheck;
181 0 : rv = simpleClone->QueryInterface(kHOSTOBJECTURICID, getter_AddRefs(uriCheck));
182 0 : MOZ_ASSERT(NS_SUCCEEDED(rv) && uriCheck);
183 : #endif
184 :
185 0 : nsHostObjectURI* u = static_cast<nsHostObjectURI*>(simpleClone.get());
186 :
187 0 : u->mPrincipal = mPrincipal;
188 0 : u->mBlobImpl = mBlobImpl;
189 :
190 0 : simpleClone.forget(aClone);
191 0 : return NS_OK;
192 : }
193 :
194 : /* virtual */ nsresult
195 0 : nsHostObjectURI::EqualsInternal(nsIURI* aOther,
196 : mozilla::net::nsSimpleURI::RefHandlingEnum aRefHandlingMode,
197 : bool* aResult)
198 : {
199 0 : if (!aOther) {
200 0 : *aResult = false;
201 0 : return NS_OK;
202 : }
203 :
204 0 : RefPtr<nsHostObjectURI> otherUri;
205 0 : aOther->QueryInterface(kHOSTOBJECTURICID, getter_AddRefs(otherUri));
206 0 : if (!otherUri) {
207 0 : *aResult = false;
208 0 : return NS_OK;
209 : }
210 :
211 : // Compare the member data that our base class knows about.
212 0 : if (!mozilla::net::nsSimpleURI::EqualsInternal(otherUri, aRefHandlingMode)) {
213 0 : *aResult = false;
214 0 : return NS_OK;
215 : }
216 :
217 : // Compare the piece of additional member data that we add to base class,
218 : // but we cannot compare BlobImpl. This should not be a problem, because we
219 : // don't support changing the underlying mBlobImpl.
220 :
221 0 : if (mPrincipal && otherUri->mPrincipal) {
222 : // Both of us have mPrincipals. Compare them.
223 0 : return mPrincipal->Equals(otherUri->mPrincipal, aResult);
224 : }
225 : // else, at least one of us lacks a principal; only equal if *both* lack it.
226 0 : *aResult = (!mPrincipal && !otherUri->mPrincipal);
227 0 : return NS_OK;
228 : }
229 :
230 : // nsIClassInfo methods:
231 : NS_IMETHODIMP
232 0 : nsHostObjectURI::GetInterfaces(uint32_t *count, nsIID * **array)
233 : {
234 0 : *count = 0;
235 0 : *array = nullptr;
236 0 : return NS_OK;
237 : }
238 :
239 : NS_IMETHODIMP
240 0 : nsHostObjectURI::GetScriptableHelper(nsIXPCScriptable **_retval)
241 : {
242 0 : *_retval = nullptr;
243 0 : return NS_OK;
244 : }
245 :
246 : NS_IMETHODIMP
247 0 : nsHostObjectURI::GetContractID(char * *aContractID)
248 : {
249 : // Make sure to modify any subclasses as needed if this ever
250 : // changes.
251 0 : *aContractID = nullptr;
252 0 : return NS_OK;
253 : }
254 :
255 : NS_IMETHODIMP
256 0 : nsHostObjectURI::GetClassDescription(char * *aClassDescription)
257 : {
258 0 : *aClassDescription = nullptr;
259 0 : return NS_OK;
260 : }
261 :
262 : NS_IMETHODIMP
263 0 : nsHostObjectURI::GetClassID(nsCID * *aClassID)
264 : {
265 : // Make sure to modify any subclasses as needed if this ever
266 : // changes to not call the virtual GetClassIDNoAlloc.
267 0 : *aClassID = (nsCID*) moz_xmalloc(sizeof(nsCID));
268 0 : NS_ENSURE_TRUE(*aClassID, NS_ERROR_OUT_OF_MEMORY);
269 :
270 0 : return GetClassIDNoAlloc(*aClassID);
271 : }
272 :
273 : NS_IMETHODIMP
274 0 : nsHostObjectURI::GetFlags(uint32_t *aFlags)
275 : {
276 0 : *aFlags = nsIClassInfo::MAIN_THREAD_ONLY;
277 0 : return NS_OK;
278 : }
279 :
280 : NS_IMETHODIMP
281 0 : nsHostObjectURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
282 : {
283 0 : *aClassIDNoAlloc = kHOSTOBJECTURICID;
284 0 : return NS_OK;
285 : }
286 :
287 : void
288 0 : nsHostObjectURI::ForgetBlobImpl()
289 : {
290 0 : MOZ_ASSERT(mBlobImpl);
291 0 : mBlobImpl = nullptr;
292 0 : }
|