Added unescape function which takes a charset to uconv,
changed uriloader to use the uconv unescape to handle unescape non Ascii URI correctly. bug 155569, r=ftang, sr=bzbarsky.
This commit is contained in:
Родитель
77d4c4fbee
Коммит
2bc1b24b8e
|
@ -50,4 +50,17 @@ interface nsITextToSubURI : nsISupports
|
|||
{
|
||||
string ConvertAndEscape(in string charset, in wstring text);
|
||||
wstring UnEscapeAndConvert(in string charset, in string text);
|
||||
|
||||
/**
|
||||
* Unescapes the given URI fragment (for UI purpose only)
|
||||
* note: escaping back the result unescaped string is not guaranteed to be
|
||||
* identical to the original escaped string
|
||||
*
|
||||
* @param aCharset the charset to convert from
|
||||
* @param aURIFragment the URI (or URI fragment) to unescape
|
||||
* @return Unescaped aURIFragment converted to unicode
|
||||
* @throws NS_ERROR_UCONV_NOCONV when there is no decoder for aCharset
|
||||
* or error code of nsIUnicodeDecoder in case of covnersion failure
|
||||
*/
|
||||
AString unEscapeURIForUI(in ACString aCharset, in AUTF8String aURIFragment);
|
||||
};
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
#include "nsString.h"
|
||||
#include "nsIUnicodeEncoder.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsICharsetConverterManager2.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsITextToSubURI.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsUConvDll.h"
|
||||
|
@ -157,4 +159,66 @@ NS_IMETHODIMP nsTextToSubURI::UnEscapeAndConvert(
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsTextToSubURI::convertURItoUnicode(const nsAFlatCString &aCharset,
|
||||
const nsAFlatCString &aURI,
|
||||
PRBool aIRI,
|
||||
nsAString &_retval)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (IsASCII(aURI)) {
|
||||
_retval.Assign(NS_ConvertASCIItoUCS2(aURI));
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aIRI) {
|
||||
NS_ConvertUTF8toUCS2 ucs2(aURI);
|
||||
if (aURI.Equals(NS_ConvertUCS2toUTF8(ucs2))) {
|
||||
_retval.Assign(ucs2);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICharsetConverterManager2> charsetConverterManager;
|
||||
|
||||
charsetConverterManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIAtom> charsetAtom;
|
||||
rv = charsetConverterManager->GetCharsetAtom2(aCharset.get(), getter_AddRefs(charsetAtom));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIUnicodeDecoder> unicodeDecoder;
|
||||
rv = charsetConverterManager->GetUnicodeDecoder(charsetAtom,
|
||||
getter_AddRefs(unicodeDecoder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 srcLen = aURI.Length();
|
||||
PRInt32 dstLen;
|
||||
rv = unicodeDecoder->GetMaxLength(aURI.get(), srcLen, &dstLen);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUnichar *ustr = (PRUnichar *) nsMemory::Alloc(dstLen * sizeof(PRUnichar));
|
||||
NS_ENSURE_TRUE(ustr, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
rv = unicodeDecoder->Convert(aURI.get(), &srcLen, ustr, &dstLen);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
_retval.Assign(ustr, dstLen);
|
||||
|
||||
nsMemory::Free(ustr);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTextToSubURI::UnEscapeURIForUI(const nsACString & aCharset,
|
||||
const nsACString &aURIFragment,
|
||||
nsAString &_retval)
|
||||
{
|
||||
nsCAutoString unescapedSpec(aURIFragment);
|
||||
NS_UnescapeURL(unescapedSpec);
|
||||
|
||||
return convertURItoUnicode(PromiseFlatCString(aCharset), unescapedSpec, PR_TRUE, _retval);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -48,6 +48,21 @@ class nsTextToSubURI: public nsITextToSubURI {
|
|||
public:
|
||||
nsTextToSubURI();
|
||||
virtual ~nsTextToSubURI();
|
||||
|
||||
private:
|
||||
// IRI is "Internationalized Resource Identifiers"
|
||||
// http://www.ietf.org/internet-drafts/draft-duerst-iri-01.txt
|
||||
//
|
||||
// if the IRI option is true then we assume that the URI is encoded as UTF-8
|
||||
// note: there is no definite way to distinguish between IRI and a URI encoded
|
||||
// with a non-UTF-8 charset
|
||||
// Use this option carefully -- it may cause dataloss
|
||||
// (recommended to set to true for UI purpose only)
|
||||
//
|
||||
nsresult convertURItoUnicode(const nsAFlatCString &aCharset,
|
||||
const nsAFlatCString &aURI,
|
||||
PRBool aIRI,
|
||||
nsAString &_retval);
|
||||
};
|
||||
|
||||
#endif // nsTextToSubURI_h__
|
||||
|
|
|
@ -40,6 +40,7 @@ REQUIRES = xpcom \
|
|||
rdf \
|
||||
helperAppDlg \
|
||||
dom \
|
||||
uconv \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = nsURILoaderModule.cpp
|
||||
|
|
|
@ -52,6 +52,7 @@ REQUIRES = xpcom \
|
|||
plugin \
|
||||
pref \
|
||||
intl \
|
||||
uconv \
|
||||
windowwatcher \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -80,6 +80,8 @@
|
|||
#include "nsIPromptService.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
|
||||
#include "nsITextToSubURI.h"
|
||||
|
||||
const char *FORCE_ALWAYS_ASK_PREF = "browser.helperApps.alwaysAsk.force";
|
||||
|
||||
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
||||
|
@ -1046,8 +1048,21 @@ nsresult nsExternalAppHandler::SetUpTempFile(nsIChannel * aChannel)
|
|||
url->GetFileName(leafName);
|
||||
if (!leafName.IsEmpty())
|
||||
{
|
||||
NS_UnescapeURL(leafName);
|
||||
mSuggestedFileName = NS_ConvertUTF8toUCS2(leafName); // XXX leafName may not be UTF-8
|
||||
|
||||
nsCOMPtr<nsITextToSubURI> textToSubURI = do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCAutoString originCharset;
|
||||
url->GetOriginCharset(originCharset);
|
||||
rv = textToSubURI->UnEscapeURIForUI(originCharset, leafName,
|
||||
mSuggestedFileName);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
mSuggestedFileName = NS_ConvertUTF8toUCS2(leafName); // use escaped name
|
||||
rv = NS_OK;
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Make sure extension is still correct.
|
||||
|
|
Загрузка…
Ссылка в новой задаче