зеркало из https://github.com/mozilla/pjs.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:
Родитель
706ef91d54
Коммит
e8d65cfa2a
|
@ -61,6 +61,91 @@
|
||||||
#include "nsXPIDLString.h"
|
#include "nsXPIDLString.h"
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
#include "nsDOMClassInfo.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)
|
LocationImpl::LocationImpl(nsIDocShell *aDocShell)
|
||||||
{
|
{
|
||||||
|
@ -416,7 +501,18 @@ LocationImpl::SetHrefWithBase(const nsAReadableString& aHref,
|
||||||
nsresult result;
|
nsresult result;
|
||||||
nsCOMPtr<nsIURI> newUri;
|
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) {
|
if (newUri && mDocShell) {
|
||||||
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
|
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче