void Location::SetSearch(const nsAString& aSearch, nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) { if (!CallerSubsumes(&aSubjectPrincipal)) { aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); return; } nsCOMPtr<nsIURI> uri; aRv = GetURI(getter_AddRefs(uri)); nsCOMPtr<nsIURL> url(do_QueryInterface(uri)); if (NS_WARN_IF(aRv.Failed()) || !url) { return; } if (nsIDocument* doc = GetEntryDocument()) { aRv = NS_MutateURI(uri) .SetQueryWithEncoding(NS_ConvertUTF16toUTF8(aSearch), doc->GetDocumentCharacterSet()) .Finalize(uri); } else { aRv = NS_MutateURI(uri) .SetQuery(NS_ConvertUTF16toUTF8(aSearch)) .Finalize(uri); } if (NS_WARN_IF(aRv.Failed())) { return; } aRv = SetURI(uri); }
nsresult Location::SetHrefWithBase(const nsAString& aHref, nsIURI* aBase, bool aReplace) { nsresult result; nsCOMPtr<nsIURI> newUri; nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell)); if (nsIDocument* doc = GetEntryDocument()) { result = NS_NewURI(getter_AddRefs(newUri), aHref, doc->GetDocumentCharacterSet(), aBase); } else { result = NS_NewURI(getter_AddRefs(newUri), aHref, nullptr, aBase); } if (newUri) { /* 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<nsIScriptGlobalObject> ourGlobal = docShell ? docShell->GetScriptGlobalObject() : nullptr; inScriptTag = (ourGlobal == scriptContext->GetGlobalObject()); } } return SetURI(newUri, aReplace || inScriptTag); } return result; }
nsresult Location::GetSourceBaseURL(JSContext* cx, nsIURI** sourceURL) { *sourceURL = nullptr; nsIDocument* doc = GetEntryDocument(); // 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 && GetDocShell()) { nsCOMPtr<nsPIDOMWindowOuter> docShellWin = do_QueryInterface(GetDocShell()->GetScriptGlobalObject()); if (docShellWin) { doc = docShellWin->GetDoc(); } } NS_ENSURE_TRUE(doc, NS_OK); *sourceURL = doc->GetBaseURI().take(); return NS_OK; }
already_AddRefed<Promise> ServiceWorkerContainer::Register(const nsAString& aScriptURL, const RegistrationOptions& aOptions, ErrorResult& aRv) { nsCOMPtr<nsISupports> promise; nsCOMPtr<nsIServiceWorkerManager> swm = mozilla::services::GetServiceWorkerManager(); if (!swm) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } nsCOMPtr<nsIURI> baseURI; nsIDocument* doc = GetEntryDocument(); if (doc) { baseURI = doc->GetBaseURI(); } else { // XXXnsm. One of our devtools browser test calls register() from a content // script where there is no valid entry document. Use the window to resolve // the uri in that case. nsCOMPtr<nsPIDOMWindow> window = GetOwner(); nsCOMPtr<nsPIDOMWindow> outerWindow; if (window && (outerWindow = window->GetOuterWindow()) && outerWindow->GetServiceWorkersTestingEnabled()) { baseURI = window->GetDocBaseURI(); } } nsresult rv; nsCOMPtr<nsIURI> scriptURI; rv = NS_NewURI(getter_AddRefs(scriptURI), aScriptURL, nullptr, baseURI); if (NS_WARN_IF(NS_FAILED(rv))) { aRv.ThrowTypeError<MSG_INVALID_URL>(&aScriptURL); return nullptr; } aRv = CheckForSlashEscapedCharsInPath(scriptURI); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } // In ServiceWorkerContainer.register() the scope argument is parsed against // different base URLs depending on whether it was passed or not. nsCOMPtr<nsIURI> scopeURI; // Step 4. If none passed, parse against script's URL if (!aOptions.mScope.WasPassed()) { NS_NAMED_LITERAL_STRING(defaultScope, "./"); rv = NS_NewURI(getter_AddRefs(scopeURI), defaultScope, nullptr, scriptURI); if (NS_WARN_IF(NS_FAILED(rv))) { nsAutoCString spec; scriptURI->GetSpec(spec); NS_ConvertUTF8toUTF16 wSpec(spec); aRv.ThrowTypeError<MSG_INVALID_SCOPE>(&defaultScope, &wSpec); return nullptr; } } else { // Step 5. Parse against entry settings object's base URL. rv = NS_NewURI(getter_AddRefs(scopeURI), aOptions.mScope.Value(), nullptr, baseURI); if (NS_WARN_IF(NS_FAILED(rv))) { nsAutoCString spec; baseURI->GetSpec(spec); NS_ConvertUTF8toUTF16 wSpec(spec); aRv.ThrowTypeError<MSG_INVALID_SCOPE>(&aOptions.mScope.Value(), &wSpec); return nullptr; } aRv = CheckForSlashEscapedCharsInPath(scopeURI); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } } // The spec says that the "client" passed to Register() must be the global // where the ServiceWorkerContainer was retrieved from. aRv = swm->Register(GetOwner(), scopeURI, scriptURI, getter_AddRefs(promise)); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } RefPtr<Promise> ret = static_cast<Promise*>(promise.get()); MOZ_ASSERT(ret); return ret.forget(); }