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:
nhotta%netscape.com 2002-08-12 19:23:22 +00:00
Родитель 77d4c4fbee
Коммит 2bc1b24b8e
6 изменённых файлов: 111 добавлений и 2 удалений

Просмотреть файл

@ -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.