/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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/. */
// Get security manager.
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); if (NS_WARN_IF(!ssm)) {
aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr;
}
// Check to see if URI is allowed. We're not going to worry about a // window ID here because it's not 100% clear which window's id we // would want, and we're throwing a content-visible exception // anyway.
nsresult rv = ssm->CheckLoadURIWithPrincipal(
&aSubjectPrincipal, aURI, nsIScriptSecurityManager::STANDARD, 0); if (NS_WARN_IF(NS_FAILED(rv))) {
nsAutoCString spec;
aURI->GetSpec(spec);
aRv.ThrowTypeError<MSG_URL_NOT_LOADABLE>(spec); return nullptr;
}
// Make the load's referrer reflect changes to the document's URI caused by // push/replaceState, if possible. First, get the document corresponding to // fp. If the document's original URI (i.e. its URI before // push/replaceState) matches the principal's URI, use the document's // current URI as the referrer. If they don't match, use the principal's // URI. // // The triggering principal for this load should be the principal of the // incumbent document (which matches where the referrer information is // coming from) when there is an incumbent document, and the subject // principal otherwise. Note that the URI in the triggering principal // may not match the referrer URI in various cases, notably including // the cases when the incumbent document's document URI was modified // after the document was loaded.
// Create load info
RefPtr<nsDocShellLoadState> loadState = new nsDocShellLoadState(aURI);
if (!doc) { // No document; just use our subject principal as the triggering principal.
loadState->SetTriggeringPrincipal(&aSubjectPrincipal); return loadState.forget();
}
if (aReplace) {
loadState->SetLoadType(LOAD_STOP_CONTENT_AND_REPLACE);
} else {
loadState->SetLoadType(LOAD_STOP_CONTENT);
}
// Get the incumbent script's browsing context to set as source.
nsCOMPtr<nsPIDOMWindowInner> sourceWindow =
nsContentUtils::IncumbentInnerWindow(); if (sourceWindow) {
WindowContext* context = sourceWindow->GetWindowContext();
loadState->SetSourceBrowsingContext(sourceWindow->GetBrowsingContext());
loadState->SetHasValidUserGestureActivation(
context && context->HasValidTransientUserGestureActivation());
}
rv = bc->LoadURI(loadState); if (NS_WARN_IF(NS_FAILED(rv))) { if (rv == NS_ERROR_DOM_BAD_CROSS_ORIGIN_URI &&
net::SchemeIsJavascript(loadState->URI())) { // Per spec[1], attempting to load a javascript: URI into a cross-origin // BrowsingContext is a no-op, and should not raise an exception. // Technically, Location setters run with exceptions enabled should only // throw an exception[2] when the caller is not allowed to navigate[3] the // target browsing context due to sandboxing flags or not being // closely-related enough, though in practice we currently throw for other // reasons as well. // // [1]: // https://html.spec.whatwg.org/multipage/browsing-the-web.html#javascript-protocol // [2]: // https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigate // [3]: // https://html.spec.whatwg.org/multipage/browsers.html#allowed-to-navigate return;
}
aRv.Throw(rv); return;
}
if (Document* doc = GetEntryDocument()) {
result = NS_NewURI(getter_AddRefs(newUri), aHref,
doc->GetDocumentCharacterSet(), aBase);
} else {
result = NS_NewURI(getter_AddRefs(newUri), aHref, nullptr, aBase);
}
if (NS_FAILED(result) || !newUri) {
aRv.ThrowSyntaxError("'"_ns + aHref + "' is not a valid URL."_ns); return;
}
/* Check with the scriptContext if it is currently processing a script tag. * If so, this must be a <script> tag with a location.href in it. * we want to do a replace load, in such a situation. * In other cases, for example if a event handler or a JS timer * had a location.href in it, we want to do a normal load, * so that the new url will be appended to Session History. * This solution is tricky. Hopefully it isn't going to bite * anywhere else. This is part of solution for bug # 39938, 72197
*/ bool inScriptTag = false;
nsIScriptContext* scriptContext = nullptr;
nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(GetEntryGlobal()); if (win) {
scriptContext = nsGlobalWindowInner::Cast(win)->GetContextInternal();
}
if (scriptContext) { if (scriptContext->GetProcessingScriptTag()) { // Now check to make sure that the script is running in our window, // since we only want to replace if the location is set by a // <script> tag in the same window. See bug 178729.
nsCOMPtr<nsIDocShell> docShell(GetDocShell());
nsCOMPtr<nsIScriptGlobalObject> ourGlobal =
docShell ? docShell->GetScriptGlobalObject() : nullptr;
inScriptTag = (ourGlobal == scriptContext->GetGlobalObject());
}
}
// If there's no entry document, we either have no Script Entry Point or one // that isn't a DOM Window. This doesn't generally happen with the DOM, but // can sometimes happen with extension code in certain IPC configurations. If // this happens, try falling back on the current document associated with the // docshell. If that fails, just return null and hope that the caller passed // an absolute URI. if (!doc) { if (nsCOMPtr<nsIDocShell> docShell = GetDocShell()) {
nsCOMPtr<nsPIDOMWindowOuter> docShellWin =
do_QueryInterface(docShell->GetScriptGlobalObject()); if (docShellWin) {
doc = docShellWin->GetDoc();
}
}
} return doc ? doc->GetBaseURI() : nullptr;
}
} // namespace mozilla::dom
¤ Dauer der Verarbeitung: 0.35 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.