From c46e6a71dcd3e70a93c87d9224ee1075ed681343 Mon Sep 17 00:00:00 2001 From: Michal Novotny Date: Fri, 15 Aug 2008 16:56:22 +0200 Subject: [PATCH] =?UTF-8?q?Bug=20427089=20=E2=80=93=20FTP=20shouldn't=20se?= =?UTF-8?q?nd=20URLs=20in=20UTF-8.=20r=3Dcbiesinger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- netwerk/base/src/nsStandardURL.cpp | 9 +-- netwerk/protocol/ftp/src/Makefile.in | 1 + .../ftp/src/nsFtpConnectionThread.cpp | 62 +++++++++++++++++++ .../protocol/ftp/src/nsFtpConnectionThread.h | 1 + 4 files changed, 69 insertions(+), 4 deletions(-) diff --git a/netwerk/base/src/nsStandardURL.cpp b/netwerk/base/src/nsStandardURL.cpp index 77468405576f..77e1ac78fbd8 100644 --- a/netwerk/base/src/nsStandardURL.cpp +++ b/netwerk/base/src/nsStandardURL.cpp @@ -114,13 +114,14 @@ EncodeString(nsIUnicodeEncoder *encoder, const nsAFlatString &str, nsACString &r goto end; } p[maxlen] = 0; - result = p; + result.Assign(p); - rv = encoder->Finish(p, &len); + len = sizeof(buf) - 1; + rv = encoder->Finish(buf, &len); if (NS_FAILED(rv)) goto end; - p[len] = 0; - result += p; + buf[len] = 0; + result.Append(buf); end: encoder->Reset(); diff --git a/netwerk/protocol/ftp/src/Makefile.in b/netwerk/protocol/ftp/src/Makefile.in index 29c75bdb6455..a9f488cfe71f 100644 --- a/netwerk/protocol/ftp/src/Makefile.in +++ b/netwerk/protocol/ftp/src/Makefile.in @@ -52,6 +52,7 @@ REQUIRES = xpcom \ pref \ intl \ nkcache \ + uconv \ $(NULL) CPPSRCS = \ diff --git a/netwerk/protocol/ftp/src/nsFtpConnectionThread.cpp b/netwerk/protocol/ftp/src/nsFtpConnectionThread.cpp index 14a58db48afe..20f8f799f15c 100644 --- a/netwerk/protocol/ftp/src/nsFtpConnectionThread.cpp +++ b/netwerk/protocol/ftp/src/nsFtpConnectionThread.cpp @@ -66,6 +66,7 @@ #include "nsIPrefBranch.h" #include "nsIStringBundle.h" #include "nsAuthInformationHolder.h" +#include "nsICharsetConverterManager.h" #if defined(PR_LOGGING) extern PRLogModuleInfo* gFTPLog; @@ -1612,6 +1613,12 @@ nsFtpState::Init(nsFtpChannel *channel) // now unescape it... %xx reduced inline to resulting character PRInt32 len = NS_UnescapeURL(fwdPtr); mPath.Assign(fwdPtr, len); + if (IsUTF8(mPath)) { + nsCAutoString originCharset; + rv = mChannel->URI()->GetOriginCharset(originCharset); + if (NS_SUCCEEDED(rv) && !originCharset.EqualsLiteral("UTF-8")) + ConvertUTF8PathToCharset(originCharset); + } #ifdef DEBUG if (mPath.FindCharInSet(CRLF) >= 0) @@ -2135,3 +2142,58 @@ nsFtpState::CheckCache() nsresult rv = session->AsyncOpenCacheEntry(key, accessReq, this); return NS_SUCCEEDED(rv); } + +nsresult +nsFtpState::ConvertUTF8PathToCharset(const nsACString &aCharset) +{ + nsresult rv; + NS_ASSERTION(IsUTF8(mPath), "mPath isn't UTF8 string!"); + NS_ConvertUTF8toUTF16 ucsPath(mPath); + nsCAutoString result; + + nsCOMPtr charsetMgr( + do_GetService("@mozilla.org/charset-converter-manager;1", &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr encoder; + rv = charsetMgr->GetUnicodeEncoder(PromiseFlatCString(aCharset).get(), + getter_AddRefs(encoder)); + NS_ENSURE_SUCCESS(rv, rv); + + PRInt32 len = ucsPath.Length(); + PRInt32 maxlen; + + rv = encoder->GetMaxLength(ucsPath.get(), len, &maxlen); + NS_ENSURE_SUCCESS(rv, rv); + + char buf[256], *p = buf; + if (PRUint32(maxlen) > sizeof(buf) - 1) { + p = (char *) malloc(maxlen + 1); + if (!p) + return NS_ERROR_OUT_OF_MEMORY; + } + + rv = encoder->Convert(ucsPath.get(), &len, p, &maxlen); + if (NS_FAILED(rv)) + goto end; + if (rv == NS_ERROR_UENC_NOMAPPING) { + NS_WARNING("unicode conversion failed"); + rv = NS_ERROR_UNEXPECTED; + goto end; + } + p[maxlen] = 0; + result.Assign(p); + + len = sizeof(buf) - 1; + rv = encoder->Finish(buf, &len); + if (NS_FAILED(rv)) + goto end; + buf[len] = 0; + result.Append(buf); + mPath = result; + +end: + if (p != buf) + free(p); + return rv; +} diff --git a/netwerk/protocol/ftp/src/nsFtpConnectionThread.h b/netwerk/protocol/ftp/src/nsFtpConnectionThread.h index 55be541d1bac..ff7197b3aba9 100644 --- a/netwerk/protocol/ftp/src/nsFtpConnectionThread.h +++ b/netwerk/protocol/ftp/src/nsFtpConnectionThread.h @@ -185,6 +185,7 @@ private: void ConvertDirspecFromVMS(nsCString& fileSpec); nsresult BuildStreamConverter(nsIStreamListener** convertStreamListener); nsresult SetContentType(); + nsresult ConvertUTF8PathToCharset(const nsACString &aCharset); /** * This method is called to kick-off the FTP state machine. mState is