nsresult nsLocation::SetHrefWithBase(const nsAString& aHref, nsIURI* aBase, PRBool aReplace) { nsresult result; nsCOMPtr<nsIURI> newUri; nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell)); nsCAutoString docCharset; if (NS_SUCCEEDED(GetDocumentCharacterSetForURI(aHref, docCharset))) result = NS_NewURI(getter_AddRefs(newUri), aHref, docCharset.get(), aBase); else result = NS_NewURI(getter_AddRefs(newUri), aHref, nsnull, 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 * */ PRBool inScriptTag=PR_FALSE; // Get JSContext from stack. nsCOMPtr<nsIJSContextStack> stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1", &result)); if (stack) { JSContext *cx; result = GetContextFromStack(stack, &cx); if (cx) { nsIScriptContext *scriptContext = nsJSUtils::GetDynamicScriptContext(cx); 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(do_GetInterface(docShell)); inScriptTag = (ourGlobal == scriptContext->GetGlobalObject()); } } } //cx } // stack return SetURI(newUri, aReplace || inScriptTag); } return result; }
nsresult Location::SetHrefWithBase(const nsAString& aHref, nsIURI* aBase, bool aReplace) { nsresult result; nsCOMPtr<nsIURI> newUri; nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell)); nsAutoCString docCharset; if (NS_SUCCEEDED(GetDocumentCharacterSetForURI(aHref, docCharset))) result = NS_NewURI(getter_AddRefs(newUri), aHref, docCharset.get(), 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 = nsGlobalWindow::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 nsLocation::SetHrefWithBase(const nsAString& aHref, nsIURI* aBase, bool aReplace) { nsresult result; nsCOMPtr<nsIURI> newUri; nsAutoCString docCharset; if (NS_SUCCEEDED(GetDocumentCharacterSetForURI(aHref, docCharset))) result = NS_NewURI(getter_AddRefs(newUri), aHref, docCharset.get(), aBase); else result = NS_NewURI(getter_AddRefs(newUri), aHref, nullptr, aBase); if (newUri) { return SetURI(newUri, aReplace); } return result; }