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 "Location.h"
8 #include "nsIScriptObjectPrincipal.h"
9 #include "nsIScriptContext.h"
10 #include "nsDocShellLoadState.h"
11 #include "nsIWebNavigation.h"
12 #include "nsIOService.h"
13 #include "nsIURL.h"
14 #include "nsIJARURI.h"
15 #include "nsIURIMutator.h"
16 #include "nsNetUtil.h"
17 #include "nsCOMPtr.h"
18 #include "nsEscape.h"
19 #include "nsPresContext.h"
20 #include "nsError.h"
21 #include "nsReadableUtils.h"
22 #include "nsJSUtils.h"
23 #include "nsContentUtils.h"
24 #include "nsDocShell.h"
25 #include "nsGlobalWindow.h"
26 #include "mozilla/Likely.h"
27 #include "nsCycleCollectionParticipant.h"
28 #include "mozilla/Components.h"
29 #include "mozilla/NullPrincipal.h"
30 #include "mozilla/Unused.h"
31 #include "mozilla/dom/Document.h"
32 #include "mozilla/dom/DocumentInlines.h"
33 #include "mozilla/dom/LocationBinding.h"
34 #include "mozilla/dom/ScriptSettings.h"
35 #include "ReferrerInfo.h"
36
37 namespace mozilla {
38 namespace dom {
39
Location(nsPIDOMWindowInner * aWindow,BrowsingContext * aBrowsingContext)40 Location::Location(nsPIDOMWindowInner* aWindow,
41 BrowsingContext* aBrowsingContext)
42 : mInnerWindow(aWindow) {
43 // aBrowsingContext can be null if it gets called after nsDocShell::Destory().
44 if (aBrowsingContext) {
45 mBrowsingContextId = aBrowsingContext->Id();
46 }
47 }
48
49 Location::~Location() = default;
50
51 // QueryInterface implementation for Location
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Location)52 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Location)
53 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
54 NS_INTERFACE_MAP_ENTRY(nsISupports)
55 NS_INTERFACE_MAP_END
56
57 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(Location, mInnerWindow)
58
59 NS_IMPL_CYCLE_COLLECTING_ADDREF(Location)
60 NS_IMPL_CYCLE_COLLECTING_RELEASE(Location)
61
62 BrowsingContext* Location::GetBrowsingContext() {
63 RefPtr<BrowsingContext> bc = BrowsingContext::Get(mBrowsingContextId);
64 return bc.get();
65 }
66
GetDocShell()67 already_AddRefed<nsIDocShell> Location::GetDocShell() {
68 if (RefPtr<BrowsingContext> bc = GetBrowsingContext()) {
69 return do_AddRef(bc->GetDocShell());
70 }
71 return nullptr;
72 }
73
GetURI(nsIURI ** aURI,bool aGetInnermostURI)74 nsresult Location::GetURI(nsIURI** aURI, bool aGetInnermostURI) {
75 *aURI = nullptr;
76
77 nsCOMPtr<nsIDocShell> docShell(GetDocShell());
78 if (!docShell) {
79 return NS_OK;
80 }
81
82 nsresult rv;
83 nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(docShell, &rv));
84 if (NS_FAILED(rv)) {
85 return rv;
86 }
87
88 nsCOMPtr<nsIURI> uri;
89 rv = webNav->GetCurrentURI(getter_AddRefs(uri));
90 NS_ENSURE_SUCCESS(rv, rv);
91
92 // It is valid for docshell to return a null URI. Don't try to fixup
93 // if this happens.
94 if (!uri) {
95 return NS_OK;
96 }
97
98 if (aGetInnermostURI) {
99 nsCOMPtr<nsIJARURI> jarURI(do_QueryInterface(uri));
100 while (jarURI) {
101 jarURI->GetJARFile(getter_AddRefs(uri));
102 jarURI = do_QueryInterface(uri);
103 }
104 }
105
106 NS_ASSERTION(uri, "nsJARURI screwed up?");
107 nsCOMPtr<nsIURI> exposableURI = net::nsIOService::CreateExposableURI(uri);
108 exposableURI.forget(aURI);
109 return NS_OK;
110 }
111
GetHash(nsAString & aHash,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)112 void Location::GetHash(nsAString& aHash, nsIPrincipal& aSubjectPrincipal,
113 ErrorResult& aRv) {
114 if (!CallerSubsumes(&aSubjectPrincipal)) {
115 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
116 return;
117 }
118
119 aHash.SetLength(0);
120
121 nsCOMPtr<nsIURI> uri;
122 aRv = GetURI(getter_AddRefs(uri));
123 if (NS_WARN_IF(aRv.Failed()) || !uri) {
124 return;
125 }
126
127 nsAutoCString ref;
128 nsAutoString unicodeRef;
129
130 aRv = uri->GetRef(ref);
131 if (NS_WARN_IF(aRv.Failed())) {
132 return;
133 }
134
135 if (!ref.IsEmpty()) {
136 aHash.Assign(char16_t('#'));
137 AppendUTF8toUTF16(ref, aHash);
138 }
139
140 if (aHash == mCachedHash) {
141 // Work around ShareThis stupidly polling location.hash every
142 // 5ms all the time by handing out the same exact string buffer
143 // we handed out last time.
144 aHash = mCachedHash;
145 } else {
146 mCachedHash = aHash;
147 }
148 }
149
SetHash(const nsAString & aHash,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)150 void Location::SetHash(const nsAString& aHash, nsIPrincipal& aSubjectPrincipal,
151 ErrorResult& aRv) {
152 if (!CallerSubsumes(&aSubjectPrincipal)) {
153 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
154 return;
155 }
156
157 NS_ConvertUTF16toUTF8 hash(aHash);
158 if (hash.IsEmpty() || hash.First() != char16_t('#')) {
159 hash.Insert(char16_t('#'), 0);
160 }
161
162 nsCOMPtr<nsIURI> uri;
163 aRv = GetURI(getter_AddRefs(uri));
164 if (NS_WARN_IF(aRv.Failed()) || !uri) {
165 return;
166 }
167
168 aRv = NS_MutateURI(uri).SetRef(hash).Finalize(uri);
169 if (NS_WARN_IF(aRv.Failed()) || !uri) {
170 return;
171 }
172
173 SetURI(uri, aSubjectPrincipal, aRv);
174 }
175
GetHost(nsAString & aHost,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)176 void Location::GetHost(nsAString& aHost, nsIPrincipal& aSubjectPrincipal,
177 ErrorResult& aRv) {
178 if (!CallerSubsumes(&aSubjectPrincipal)) {
179 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
180 return;
181 }
182
183 aHost.Truncate();
184
185 nsCOMPtr<nsIURI> uri;
186 nsresult result;
187
188 result = GetURI(getter_AddRefs(uri), true);
189
190 if (uri) {
191 nsAutoCString hostport;
192
193 result = uri->GetHostPort(hostport);
194
195 if (NS_SUCCEEDED(result)) {
196 AppendUTF8toUTF16(hostport, aHost);
197 }
198 }
199 }
200
SetHost(const nsAString & aHost,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)201 void Location::SetHost(const nsAString& aHost, nsIPrincipal& aSubjectPrincipal,
202 ErrorResult& aRv) {
203 if (!CallerSubsumes(&aSubjectPrincipal)) {
204 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
205 return;
206 }
207
208 nsCOMPtr<nsIURI> uri;
209 aRv = GetURI(getter_AddRefs(uri));
210 if (NS_WARN_IF(aRv.Failed()) || !uri) {
211 return;
212 }
213
214 aRv =
215 NS_MutateURI(uri).SetHostPort(NS_ConvertUTF16toUTF8(aHost)).Finalize(uri);
216 if (NS_WARN_IF(aRv.Failed())) {
217 return;
218 }
219
220 SetURI(uri, aSubjectPrincipal, aRv);
221 }
222
GetHostname(nsAString & aHostname,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)223 void Location::GetHostname(nsAString& aHostname,
224 nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) {
225 if (!CallerSubsumes(&aSubjectPrincipal)) {
226 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
227 return;
228 }
229
230 aHostname.Truncate();
231
232 nsCOMPtr<nsIURI> uri;
233 GetURI(getter_AddRefs(uri), true);
234 if (uri) {
235 nsContentUtils::GetHostOrIPv6WithBrackets(uri, aHostname);
236 }
237 }
238
SetHostname(const nsAString & aHostname,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)239 void Location::SetHostname(const nsAString& aHostname,
240 nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) {
241 if (!CallerSubsumes(&aSubjectPrincipal)) {
242 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
243 return;
244 }
245
246 nsCOMPtr<nsIURI> uri;
247 aRv = GetURI(getter_AddRefs(uri));
248 if (NS_WARN_IF(aRv.Failed()) || !uri) {
249 return;
250 }
251
252 aRv =
253 NS_MutateURI(uri).SetHost(NS_ConvertUTF16toUTF8(aHostname)).Finalize(uri);
254 if (NS_WARN_IF(aRv.Failed())) {
255 return;
256 }
257
258 SetURI(uri, aSubjectPrincipal, aRv);
259 }
260
GetHref(nsAString & aHref)261 nsresult Location::GetHref(nsAString& aHref) {
262 aHref.Truncate();
263
264 nsCOMPtr<nsIURI> uri;
265 nsresult rv = GetURI(getter_AddRefs(uri));
266 if (NS_WARN_IF(NS_FAILED(rv)) || !uri) {
267 return rv;
268 }
269
270 nsAutoCString uriString;
271 rv = uri->GetSpec(uriString);
272 if (NS_WARN_IF(NS_FAILED(rv))) {
273 return rv;
274 }
275
276 AppendUTF8toUTF16(uriString, aHref);
277 return NS_OK;
278 }
279
GetOrigin(nsAString & aOrigin,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)280 void Location::GetOrigin(nsAString& aOrigin, nsIPrincipal& aSubjectPrincipal,
281 ErrorResult& aRv) {
282 if (!CallerSubsumes(&aSubjectPrincipal)) {
283 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
284 return;
285 }
286
287 aOrigin.Truncate();
288
289 nsCOMPtr<nsIURI> uri;
290 aRv = GetURI(getter_AddRefs(uri), true);
291 if (NS_WARN_IF(aRv.Failed()) || !uri) {
292 return;
293 }
294
295 nsAutoString origin;
296 aRv = nsContentUtils::GetUTFOrigin(uri, origin);
297 if (NS_WARN_IF(aRv.Failed())) {
298 return;
299 }
300
301 aOrigin = origin;
302 }
303
GetPathname(nsAString & aPathname,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)304 void Location::GetPathname(nsAString& aPathname,
305 nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) {
306 if (!CallerSubsumes(&aSubjectPrincipal)) {
307 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
308 return;
309 }
310
311 aPathname.Truncate();
312
313 nsCOMPtr<nsIURI> uri;
314 aRv = GetURI(getter_AddRefs(uri));
315 if (NS_WARN_IF(aRv.Failed()) || !uri) {
316 return;
317 }
318
319 nsAutoCString file;
320
321 aRv = uri->GetFilePath(file);
322 if (NS_WARN_IF(aRv.Failed())) {
323 return;
324 }
325
326 AppendUTF8toUTF16(file, aPathname);
327 }
328
SetPathname(const nsAString & aPathname,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)329 void Location::SetPathname(const nsAString& aPathname,
330 nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) {
331 if (!CallerSubsumes(&aSubjectPrincipal)) {
332 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
333 return;
334 }
335
336 nsCOMPtr<nsIURI> uri;
337 aRv = GetURI(getter_AddRefs(uri));
338 if (NS_WARN_IF(aRv.Failed()) || !uri) {
339 return;
340 }
341
342 nsresult rv = NS_MutateURI(uri)
343 .SetFilePath(NS_ConvertUTF16toUTF8(aPathname))
344 .Finalize(uri);
345 if (NS_FAILED(rv)) {
346 return;
347 }
348
349 SetURI(uri, aSubjectPrincipal, aRv);
350 }
351
GetPort(nsAString & aPort,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)352 void Location::GetPort(nsAString& aPort, nsIPrincipal& aSubjectPrincipal,
353 ErrorResult& aRv) {
354 if (!CallerSubsumes(&aSubjectPrincipal)) {
355 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
356 return;
357 }
358
359 aPort.SetLength(0);
360
361 nsCOMPtr<nsIURI> uri;
362 aRv = GetURI(getter_AddRefs(uri), true);
363 if (NS_WARN_IF(aRv.Failed()) || !uri) {
364 return;
365 }
366
367 int32_t port;
368 nsresult result = uri->GetPort(&port);
369
370 // Don't propagate this exception to caller
371 if (NS_SUCCEEDED(result) && -1 != port) {
372 nsAutoString portStr;
373 portStr.AppendInt(port);
374 aPort.Append(portStr);
375 }
376 }
377
SetPort(const nsAString & aPort,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)378 void Location::SetPort(const nsAString& aPort, nsIPrincipal& aSubjectPrincipal,
379 ErrorResult& aRv) {
380 if (!CallerSubsumes(&aSubjectPrincipal)) {
381 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
382 return;
383 }
384
385 nsCOMPtr<nsIURI> uri;
386 aRv = GetURI(getter_AddRefs(uri));
387 if (NS_WARN_IF(aRv.Failed() || !uri)) {
388 return;
389 }
390
391 // perhaps use nsReadingIterators at some point?
392 NS_ConvertUTF16toUTF8 portStr(aPort);
393 const char* buf = portStr.get();
394 int32_t port = -1;
395
396 if (!portStr.IsEmpty() && buf) {
397 if (*buf == ':') {
398 port = atol(buf + 1);
399 } else {
400 port = atol(buf);
401 }
402 }
403
404 aRv = NS_MutateURI(uri).SetPort(port).Finalize(uri);
405 if (NS_WARN_IF(aRv.Failed())) {
406 return;
407 }
408
409 SetURI(uri, aSubjectPrincipal, aRv);
410 }
411
GetProtocol(nsAString & aProtocol,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)412 void Location::GetProtocol(nsAString& aProtocol,
413 nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) {
414 if (!CallerSubsumes(&aSubjectPrincipal)) {
415 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
416 return;
417 }
418
419 aProtocol.SetLength(0);
420
421 nsCOMPtr<nsIURI> uri;
422 aRv = GetURI(getter_AddRefs(uri));
423 if (NS_WARN_IF(aRv.Failed()) || !uri) {
424 return;
425 }
426
427 nsAutoCString protocol;
428
429 aRv = uri->GetScheme(protocol);
430 if (NS_WARN_IF(aRv.Failed())) {
431 return;
432 }
433
434 CopyASCIItoUTF16(protocol, aProtocol);
435 aProtocol.Append(char16_t(':'));
436 }
437
SetProtocol(const nsAString & aProtocol,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)438 void Location::SetProtocol(const nsAString& aProtocol,
439 nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) {
440 if (!CallerSubsumes(&aSubjectPrincipal)) {
441 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
442 return;
443 }
444
445 nsCOMPtr<nsIURI> uri;
446 aRv = GetURI(getter_AddRefs(uri));
447 if (NS_WARN_IF(aRv.Failed()) || !uri) {
448 return;
449 }
450
451 nsAString::const_iterator start, end;
452 aProtocol.BeginReading(start);
453 aProtocol.EndReading(end);
454 nsAString::const_iterator iter(start);
455 Unused << FindCharInReadable(':', iter, end);
456
457 nsresult rv = NS_MutateURI(uri)
458 .SetScheme(NS_ConvertUTF16toUTF8(Substring(start, iter)))
459 .Finalize(uri);
460 if (NS_WARN_IF(NS_FAILED(rv))) {
461 // Oh, I wish nsStandardURL returned NS_ERROR_MALFORMED_URI for _all_ the
462 // malformed cases, not just some of them!
463 aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
464 return;
465 }
466
467 nsAutoCString newSpec;
468 aRv = uri->GetSpec(newSpec);
469 if (NS_WARN_IF(aRv.Failed())) {
470 return;
471 }
472 // We may want a new URI class for the new URI, so recreate it:
473 rv = NS_NewURI(getter_AddRefs(uri), newSpec);
474 if (NS_FAILED(rv)) {
475 if (rv == NS_ERROR_MALFORMED_URI) {
476 rv = NS_ERROR_DOM_SYNTAX_ERR;
477 }
478
479 aRv.Throw(rv);
480 return;
481 }
482
483 if (!uri->SchemeIs("http") && !uri->SchemeIs("https")) {
484 // No-op, per spec.
485 return;
486 }
487
488 SetURI(uri, aSubjectPrincipal, aRv);
489 }
490
GetSearch(nsAString & aSearch,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)491 void Location::GetSearch(nsAString& aSearch, nsIPrincipal& aSubjectPrincipal,
492 ErrorResult& aRv) {
493 if (!CallerSubsumes(&aSubjectPrincipal)) {
494 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
495 return;
496 }
497
498 aSearch.SetLength(0);
499
500 nsCOMPtr<nsIURI> uri;
501 nsresult result = NS_OK;
502
503 result = GetURI(getter_AddRefs(uri));
504
505 nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
506
507 if (url) {
508 nsAutoCString search;
509
510 result = url->GetQuery(search);
511
512 if (NS_SUCCEEDED(result) && !search.IsEmpty()) {
513 aSearch.Assign(char16_t('?'));
514 AppendUTF8toUTF16(search, aSearch);
515 }
516 }
517 }
518
SetSearch(const nsAString & aSearch,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)519 void Location::SetSearch(const nsAString& aSearch,
520 nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) {
521 if (!CallerSubsumes(&aSubjectPrincipal)) {
522 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
523 return;
524 }
525
526 nsCOMPtr<nsIURI> uri;
527 aRv = GetURI(getter_AddRefs(uri));
528 nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
529 if (NS_WARN_IF(aRv.Failed()) || !url) {
530 return;
531 }
532
533 if (Document* doc = GetEntryDocument()) {
534 aRv = NS_MutateURI(uri)
535 .SetQueryWithEncoding(NS_ConvertUTF16toUTF8(aSearch),
536 doc->GetDocumentCharacterSet())
537 .Finalize(uri);
538 } else {
539 aRv = NS_MutateURI(uri)
540 .SetQuery(NS_ConvertUTF16toUTF8(aSearch))
541 .Finalize(uri);
542 }
543 if (NS_WARN_IF(aRv.Failed())) {
544 return;
545 }
546
547 SetURI(uri, aSubjectPrincipal, aRv);
548 }
549
Reload(bool aForceget,ErrorResult & aRv)550 void Location::Reload(bool aForceget, ErrorResult& aRv) {
551 nsCOMPtr<nsIDocShell> docShell(GetDocShell());
552 if (!docShell) {
553 return aRv.Throw(NS_ERROR_FAILURE);
554 }
555
556 if (StaticPrefs::dom_block_reload_from_resize_event_handler()) {
557 nsCOMPtr<nsPIDOMWindowOuter> window = docShell->GetWindow();
558 if (window && window->IsHandlingResizeEvent()) {
559 // location.reload() was called on a window that is handling a
560 // resize event. Sites do this since Netscape 4.x needed it, but
561 // we don't, and it's a horrible experience for nothing. In stead
562 // of reloading the page, just clear style data and reflow the
563 // page since some sites may use this trick to work around gecko
564 // reflow bugs, and this should have the same effect.
565 RefPtr<Document> doc = window->GetExtantDoc();
566
567 nsPresContext* pcx;
568 if (doc && (pcx = doc->GetPresContext())) {
569 pcx->RebuildAllStyleData(NS_STYLE_HINT_REFLOW,
570 RestyleHint::RestyleSubtree());
571 }
572 return;
573 }
574 }
575
576 uint32_t reloadFlags = nsIWebNavigation::LOAD_FLAGS_NONE;
577
578 if (aForceget) {
579 reloadFlags = nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE |
580 nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY;
581 }
582
583 nsresult rv = nsDocShell::Cast(docShell)->Reload(reloadFlags);
584 if (NS_FAILED(rv) && rv != NS_BINDING_ABORTED) {
585 // NS_BINDING_ABORTED is returned when we attempt to reload a POST result
586 // and the user says no at the "do you want to reload?" prompt. Don't
587 // propagate this one back to callers.
588 return aRv.Throw(rv);
589 }
590 }
591
Assign(const nsAString & aUrl,nsIPrincipal & aSubjectPrincipal,ErrorResult & aRv)592 void Location::Assign(const nsAString& aUrl, nsIPrincipal& aSubjectPrincipal,
593 ErrorResult& aRv) {
594 if (!CallerSubsumes(&aSubjectPrincipal)) {
595 aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
596 return;
597 }
598
599 DoSetHref(aUrl, aSubjectPrincipal, false, aRv);
600 }
601
CallerSubsumes(nsIPrincipal * aSubjectPrincipal)602 bool Location::CallerSubsumes(nsIPrincipal* aSubjectPrincipal) {
603 MOZ_ASSERT(aSubjectPrincipal);
604
605 RefPtr<BrowsingContext> bc(GetBrowsingContext());
606 if (MOZ_UNLIKELY(!bc) || MOZ_UNLIKELY(bc->IsDiscarded())) {
607 // Per spec, operations on a Location object with a discarded BC are no-ops,
608 // not security errors, so we need to return true from the access check and
609 // let the caller do its own discarded docShell check.
610 return true;
611 }
612 if (MOZ_UNLIKELY(!bc->IsInProcess())) {
613 return false;
614 }
615
616 // Get the principal associated with the location object. Note that this is
617 // the principal of the page which will actually be navigated, not the
618 // principal of the Location object itself. This is why we need this check
619 // even though we only allow limited cross-origin access to Location objects
620 // in general.
621 nsCOMPtr<nsPIDOMWindowOuter> outer = bc->GetDOMWindow();
622 MOZ_DIAGNOSTIC_ASSERT(outer);
623 if (MOZ_UNLIKELY(!outer)) return false;
624
625 nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(outer);
626 bool subsumes = false;
627 nsresult rv = aSubjectPrincipal->SubsumesConsideringDomain(
628 sop->GetPrincipal(), &subsumes);
629 NS_ENSURE_SUCCESS(rv, false);
630 return subsumes;
631 }
632
WrapObject(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)633 JSObject* Location::WrapObject(JSContext* aCx,
634 JS::Handle<JSObject*> aGivenProto) {
635 return Location_Binding::Wrap(aCx, this, aGivenProto);
636 }
637
638 } // namespace dom
639 } // namespace mozilla
640