зеркало из https://github.com/mozilla/gecko-dev.git
Changed location.href to force escape 8 bit if the href contains 8 bit, bug 40469, r=ftang, sr=jst.
This commit is contained in:
Родитель
6638bbd7cf
Коммит
4637350292
|
@ -61,6 +61,91 @@
|
|||
#include "nsXPIDLString.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsICharsetConverterManager2.h"
|
||||
|
||||
|
||||
static nsresult EscapeNonAsciiInURI(nsAReadableString& aHref, nsAWritableCString& aEscapedHref)
|
||||
{
|
||||
aEscapedHref.Truncate(0);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// Get a document charset, no escaping in case of failure.
|
||||
nsCOMPtr<nsIJSContextStack> stack(do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
JSContext *cx;
|
||||
|
||||
rv = stack->Peek(&cx);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> nativeGlob;
|
||||
nsJSUtils::GetDynamicScriptGlobal(cx, getter_AddRefs(nativeGlob));
|
||||
NS_ENSURE_TRUE(nativeGlob, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(nativeGlob);
|
||||
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
rv = window->GetDocument(getter_AddRefs(domDoc));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!domDoc)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
|
||||
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
|
||||
|
||||
nsAutoString charset;
|
||||
rv = doc->GetDocumentCharacterSet(charset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Convert from Unicode to a document charset.
|
||||
nsCOMPtr <nsICharsetConverterManager2> ccm2 = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr <nsIAtom> charsetAtom;
|
||||
rv = ccm2->GetCharsetAtom(charset.get(), getter_AddRefs(charsetAtom));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIUnicodeEncoder> encoder;
|
||||
rv = ccm2->GetUnicodeEncoder(charsetAtom, getter_AddRefs(encoder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
const nsAFlatString &tmp = PromiseFlatString(aHref);
|
||||
PRInt32 len;
|
||||
|
||||
rv = encoder->GetMaxLength(tmp.get(), tmp.Length(), &len);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 bufferLen = len;
|
||||
char* buffer = (char *) nsMemory::Alloc(bufferLen);
|
||||
NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = encoder->Convert(tmp.get(), &len, buffer, &bufferLen);
|
||||
if (NS_FAILED(rv)) {
|
||||
nsMemory::Free(buffer);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Escape any 8 bit data.
|
||||
const char* hexChars = "0123456789ABCDEF";
|
||||
for (PRUint32 i = 0; i < (PRUint32) len; i++) {
|
||||
unsigned char c = (unsigned char) buffer[i];
|
||||
if (c < 128) {
|
||||
aEscapedHref.Append((char) c);
|
||||
}
|
||||
else {
|
||||
aEscapedHref.Append('%');
|
||||
aEscapedHref.Append(hexChars[c >> 4]); /* high nibble */
|
||||
aEscapedHref.Append(hexChars[c & 0x0f]); /* low nibble */
|
||||
}
|
||||
}
|
||||
|
||||
nsMemory::Free(buffer);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
LocationImpl::LocationImpl(nsIDocShell *aDocShell)
|
||||
{
|
||||
|
@ -416,7 +501,18 @@ LocationImpl::SetHrefWithBase(const nsAReadableString& aHref,
|
|||
nsresult result;
|
||||
nsCOMPtr<nsIURI> newUri;
|
||||
|
||||
result = NS_NewURI(getter_AddRefs(newUri), aHref, aBase);
|
||||
// 'aHref' is supposed to be already escaped by the script
|
||||
// but if it contains 8 bit characters without escaped then force to escape it.
|
||||
// This is for comptibility reason, some of the existing pages do not escape hrefs
|
||||
// and they are working on 4.x.
|
||||
nsCAutoString escapedHref;
|
||||
if (!nsCRT::IsAscii(PromiseFlatString(aHref).get()))
|
||||
(void) EscapeNonAsciiInURI(aHref, escapedHref);
|
||||
|
||||
if (escapedHref.IsEmpty())
|
||||
result = NS_NewURI(getter_AddRefs(newUri), aHref, aBase);
|
||||
else
|
||||
result = NS_NewURI(getter_AddRefs(newUri), escapedHref.get(), aBase);
|
||||
|
||||
if (newUri && mDocShell) {
|
||||
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
|
||||
|
|
Загрузка…
Ссылка в новой задаче