diff --git a/mozilla/xpfe/components/search/src/nsInternetSearchService.cpp b/mozilla/xpfe/components/search/src/nsInternetSearchService.cpp index e0df516f946..35c7688e074 100755 --- a/mozilla/xpfe/components/search/src/nsInternetSearchService.cpp +++ b/mozilla/xpfe/components/search/src/nsInternetSearchService.cpp @@ -64,6 +64,7 @@ #include "nsEnumeratorUtils.h" #include "nsIRDFRemoteDataSource.h" #include "nsICharsetConverterManager.h" +#include "nsICharsetConverterManager2.h" #include "nsICharsetAlias.h" #include "nsITextToSubURI.h" #include "nsEscape.h" @@ -3216,7 +3217,43 @@ InternetSearchDataSource::FindData(nsIRDFResource *engine, nsIRDFLiteral **dataL return(rv); } +nsresult +InternetSearchDataSource::DecodeData(const PRUnichar *aCharset, const PRUnichar *aInString, PRUnichar **aOutString) +{ + nsresult rv; + + nsCOMPtr charsetConv = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr charsetAtom; + rv = charsetConv->GetCharsetAtom(aCharset, getter_AddRefs(charsetAtom)); + // Use the sherlock default charset in case of failure + if (NS_FAILED(rv)) + rv = charsetConv->GetCharsetAtom(NS_LITERAL_STRING("x-mac-roman").get(), getter_AddRefs(charsetAtom)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr unicodeDecoder; + rv = charsetConv->GetUnicodeDecoder(charsetAtom, getter_AddRefs(unicodeDecoder)); + NS_ENSURE_SUCCESS(rv, rv); + + // This fixes the corruption occured in InternetSearchDataSource::ReadFileContents() + // (eg. aValue contains "0x0082 0x00a1" for "0x82 0xa1" shift_jis double-byte char) + NS_LossyConvertUCS2toASCII value(aInString); + + PRInt32 srcLength = value.Length(); + PRInt32 outUnicodeLen; + rv = unicodeDecoder->GetMaxLength(value.get(), srcLength, &outUnicodeLen); + NS_ENSURE_SUCCESS(rv, rv); + + *aOutString = NS_REINTERPRET_CAST(PRUnichar*, nsMemory::Alloc((outUnicodeLen + 1) * sizeof(PRUnichar))); + NS_ENSURE_TRUE(*aOutString, NS_ERROR_OUT_OF_MEMORY); + + rv = unicodeDecoder->Convert(value.get(), &srcLength, *aOutString, &outUnicodeLen); + NS_ENSURE_SUCCESS(rv, rv); + (*aOutString)[outUnicodeLen] = (PRUnichar)'\0'; + + return rv; +} nsresult InternetSearchDataSource::updateDataHintsInGraph(nsIRDFResource *engine, const PRUnichar *dataUni) @@ -3231,12 +3268,27 @@ InternetSearchDataSource::updateDataHintsInGraph(nsIRDFResource *engine, const P } // save/update name of search engine (as specified in file) + nsAutoString scriptCodeValue; + const PRUnichar *charsetName = MapScriptCodeToCharsetName(0); + nsXPIDLString decodedValue; + + if (NS_SUCCEEDED(rv = GetData(dataUni, "search", 0, "sourceTextEncoding", scriptCodeValue)) && + !scriptCodeValue.IsEmpty()) + { + PRInt32 err; + PRInt32 scriptCode = scriptCodeValue.ToInteger(&err); + if (NS_SUCCEEDED(err)) + charsetName = MapScriptCodeToCharsetName(scriptCode); + } + nsAutoString nameValue; if (NS_SUCCEEDED(rv = GetData(dataUni, "search", 0, "name", nameValue))) { + rv = DecodeData(charsetName, nameValue.get(), getter_Copies(decodedValue)); nsCOMPtr nameLiteral; - if (NS_SUCCEEDED(rv = gRDFService->GetLiteral(nameValue.get(), - getter_AddRefs(nameLiteral)))) + if (NS_SUCCEEDED(rv) && + NS_SUCCEEDED(rv = gRDFService->GetLiteral(decodedValue.get(), + getter_AddRefs(nameLiteral)))) { rv = updateAtom(mInner, engine, kNC_Name, nameLiteral, nsnull); } @@ -3246,9 +3298,11 @@ InternetSearchDataSource::updateDataHintsInGraph(nsIRDFResource *engine, const P nsAutoString descValue; if (NS_SUCCEEDED(rv = GetData(dataUni, "search", 0, "description", descValue))) { + rv = DecodeData(charsetName, descValue.get(), getter_Copies(decodedValue)); nsCOMPtr descLiteral; - if (NS_SUCCEEDED(rv = gRDFService->GetLiteral(descValue.get(), - getter_AddRefs(descLiteral)))) + if (NS_SUCCEEDED(rv) && + NS_SUCCEEDED(rv = gRDFService->GetLiteral(decodedValue.get(), + getter_AddRefs(descLiteral)))) { rv = updateAtom(mInner, engine, kNC_Description, descLiteral, nsnull); } @@ -3490,6 +3544,74 @@ InternetSearchDataSource::MapEncoding(const nsString &numericEncoding, nsString return(NS_OK); } +struct scripts +{ + PRInt32 scriptCode; + PRUnichar charsetName[22]; +}; + + +const PRUnichar * +InternetSearchDataSource::MapScriptCodeToCharsetName(PRInt32 aScriptCode) +{ + // Script codes listed here are taken from Inside Macintosh Text. + // Used TECGetTextEncodingInternetName to map script code to charset name. + // Some are edited to match with standard name (e.g. "x-mac-japanese" -> "Shift_JIS"). + // In case no converter can be found for a charset name, + // the default sherlock charset "x-mac-roman" should be used. + // + static struct scripts scriptList[] = + { + { 0, {'x','-','m','a','c','-','r','o','m','a','n','\0'} }, + { 1, {'S','h','i','f','t','_','J','I','S','\0'} }, + { 2, {'B','i','g','5','\0'} }, + { 3, {'E','U','C','-','K','R','\0'} }, + { 4, {'X','-','M','A','C','-','A','R','A','B','I','C','\0'} }, + { 5, {'X','-','M','A','C','-','H','E','B','R','E','W','\0'} }, + { 6, {'X','-','M','A','C','-','G','R','E','E','K','\0'} }, + { 7, {'X','-','M','A','C','-','C','Y','R','I','L','L','I','C','\0'} }, + { 9, {'X','-','M','A','C','-','D','E','V','A','N','A','G','A','R','I','\0'} }, + { 10, {'X','-','M','A','C','-','G','U','R','M','U','K','H','I','\0'} }, + { 11, {'X','-','M','A','C','-','G','U','J','A','R','A','T','I','\0'} }, + { 12, {'X','-','M','A','C','-','O','R','I','Y','A','\0'} }, + { 13, {'X','-','M','A','C','-','B','E','N','G','A','L','I','\0'} }, + { 14, {'X','-','M','A','C','-','T','A','M','I','L','\0'} }, + { 15, {'X','-','M','A','C','-','T','E','L','U','G','U','\0'} }, + { 16, {'X','-','M','A','C','-','K','A','N','N','A','D','A','\0'} }, + { 17, {'X','-','M','A','C','-','M','A','L','A','Y','A','L','A','M','\0'} }, + { 18, {'X','-','M','A','C','-','S','I','N','H','A','L','E','S','E','\0'} }, + { 19, {'X','-','M','A','C','-','B','U','R','M','E','S','E','\0'} }, + { 20, {'X','-','M','A','C','-','K','H','M','E','R','\0'} }, + { 21, {'X','-','M','A','C','-','T','H','A','I','\0'} }, + { 22, {'X','-','M','A','C','-','L','A','O','T','I','A','N','\0'} }, + { 23, {'X','-','M','A','C','-','G','E','O','R','G','I','A','N','\0'} }, + { 24, {'X','-','M','A','C','-','A','R','M','E','N','I','A','N','\0'} }, + { 25, {'G','B','2','3','1','2','\0'} }, + { 26, {'X','-','M','A','C','-','T','I','B','E','T','A','N','\0'} }, + { 27, {'X','-','M','A','C','-','M','O','N','G','O','L','I','A','N','\0'} }, + { 28, {'X','-','M','A','C','-','E','T','H','I','O','P','I','C','\0'} }, + { 29, {'X','-','M','A','C','-','C','E','N','T','R','A','L','E','U','R','R','O','M','A','N','\0'} }, + { 30, {'X','-','M','A','C','-','V','I','E','T','N','A','M','E','S','E','\0'} }, + { 31, {'X','-','M','A','C','-','E','X','T','A','R','A','B','I','C','\0'} }, + + { -1, {0} } + }; + + const PRUnichar *charsetName = nsnull; + for (PRUint32 i = 0; scriptList[i].scriptCode >= 0; i++) + { + if (scriptList[i].scriptCode == aScriptCode) + { + charsetName = scriptList[i].charsetName; + break; + } + } + + if (!charsetName) + charsetName = scriptList[0].charsetName; // "x-mac-roman" + + return charsetName; +} nsresult diff --git a/mozilla/xpfe/components/search/src/nsInternetSearchService.h b/mozilla/xpfe/components/search/src/nsInternetSearchService.h index 3088e554d54..d0ca1188506 100644 --- a/mozilla/xpfe/components/search/src/nsInternetSearchService.h +++ b/mozilla/xpfe/components/search/src/nsInternetSearchService.h @@ -148,11 +148,13 @@ friend int PR_CALLBACK searchModePrefCallback(const char *pref, void *aClosur nsresult validateEngine(nsIRDFResource *engine); nsresult DoSearch(nsIRDFResource *source, nsIRDFResource *engine, const nsString &fullURL, const nsString &text); nsresult MapEncoding(const nsString &numericEncoding, nsString &stringEncoding); + const PRUnichar * MapScriptCodeToCharsetName(PRInt32 aScriptCode); nsresult SaveEngineInfoIntoGraph(nsIFile *file, nsIFile *icon, const PRUnichar *hint, const PRUnichar *data, PRBool isSystemSearchFile, PRBool checkMacFileType); nsresult GetSearchEngineList(nsIFile *spec, PRBool isSystemSearchFile, PRBool checkMacFileType); nsresult GetCategoryList(); nsresult GetSearchFolder(nsIFile **spec); nsresult ReadFileContents(const nsFileSpec &baseFilename, nsString & sourceContents); + nsresult DecodeData(const PRUnichar *aCharset, const PRUnichar *aInString, PRUnichar **aOutString); nsresult GetData(const PRUnichar *data, const char *sectionToFind, PRUint32 sectionNum, const char *attribToFind, nsString &value); nsresult GetNumInterpretSections(const PRUnichar *data, PRUint32 &numInterpretSections); nsresult GetInputs(const PRUnichar *data, nsString &userVar, const nsString &text, nsString &input, PRInt16 direction, PRUint16 pageNumber, PRUint16 *whichButtons);