Bug #307052 --> Spellchecker doesn't display suggestion list for misspelled words in cyrillic based directions.

In addition to fixing the string conversion issue, fix various memory leaks, poor allocation strategies and other problems with this code.

r=mvl
sr=bz
This commit is contained in:
scott%scott-macgregor.org 2006-01-05 19:11:10 +00:00
Родитель b6bc4dc4ed
Коммит a3fcef1b54
3 изменённых файлов: 69 добавлений и 53 удалений

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

@ -286,39 +286,44 @@ NS_IMETHODIMP mozMySpell::GetDictionaryList(PRUnichar ***aDictionaries, PRUint32
return NS_OK; return NS_OK;
} }
nsresult mozMySpell::ConvertCharset(const PRUnichar* aStr, char ** aDst)
{
NS_ENSURE_ARG_POINTER(aDst);
NS_ENSURE_TRUE(mEncoder, NS_ERROR_NULL_POINTER);
PRInt32 outLength;
PRInt32 inLength = nsCRT::strlen(aStr);
nsresult rv = mEncoder->GetMaxLength(aStr, inLength, &outLength);
NS_ENSURE_SUCCESS(rv, rv);
*aDst = (char *) nsMemory::Alloc(sizeof(char) * (outLength+1));
NS_ENSURE_TRUE(*aDst, NS_ERROR_OUT_OF_MEMORY);
rv = mEncoder->Convert(aStr, &inLength, *aDst, &outLength);
if (NS_SUCCEEDED(rv))
(*aDst)[outLength] = '\0';
return rv;
}
/* boolean Check (in wstring word); */ /* boolean Check (in wstring word); */
NS_IMETHODIMP mozMySpell::Check(const PRUnichar *aWord, PRBool *aResult) NS_IMETHODIMP mozMySpell::Check(const PRUnichar *aWord, PRBool *aResult)
{ {
NS_ENSURE_ARG_POINTER(aWord); NS_ENSURE_ARG_POINTER(aWord);
NS_ENSURE_ARG_POINTER(aResult); NS_ENSURE_ARG_POINTER(aResult);
NS_ENSURE_TRUE(mMySpell, NS_ERROR_FAILURE);
if (!mMySpell) nsXPIDLCString charsetWord;
return NS_ERROR_FAILURE; nsresult rv = ConvertCharset(aWord, getter_Copies(charsetWord));
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 inLength = nsCRT::strlen(aWord);
PRInt32 outLength;
nsresult rv = mEncoder->GetMaxLength(aWord, inLength, &outLength);
// NS_ERROR_UENC_NOMAPPING is a NS_SUCCESS, no error.
if (NS_FAILED(rv) || rv == NS_ERROR_UENC_NOMAPPING) {
// not a word in the current charset, so likely not
// a word in the current language
return PR_FALSE;
}
char *charsetWord = (char *) nsMemory::Alloc(sizeof(char) * (outLength+1));
NS_ENSURE_TRUE(charsetWord, NS_ERROR_OUT_OF_MEMORY);
rv = mEncoder->Convert(aWord, &inLength, charsetWord, &outLength);
charsetWord[outLength] = '\0';
*aResult = mMySpell->spell(charsetWord); *aResult = mMySpell->spell(charsetWord);
if (!*aResult && mPersonalDictionary) {
rv = mPersonalDictionary->Check(aWord, mLanguage.get(), aResult);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK; if (!*aResult && mPersonalDictionary)
rv = mPersonalDictionary->Check(aWord, mLanguage.get(), aResult);
return rv;
} }
/* void Suggest (in wstring word, [array, size_is (count)] out wstring suggestions, out PRUint32 count); */ /* void Suggest (in wstring word, [array, size_is (count)] out wstring suggestions, out PRUint32 count); */
@ -326,40 +331,48 @@ NS_IMETHODIMP mozMySpell::Suggest(const PRUnichar *aWord, PRUnichar ***aSuggesti
{ {
NS_ENSURE_ARG_POINTER(aSuggestions); NS_ENSURE_ARG_POINTER(aSuggestions);
NS_ENSURE_ARG_POINTER(aSuggestionCount); NS_ENSURE_ARG_POINTER(aSuggestionCount);
NS_ENSURE_TRUE(mMySpell, NS_ERROR_FAILURE);
if (!mMySpell) nsresult rv;
return NS_ERROR_FAILURE;
*aSuggestionCount = 0; *aSuggestionCount = 0;
nsXPIDLCString charsetWord;
rv = ConvertCharset(aWord, getter_Copies(charsetWord));
NS_ENSURE_SUCCESS(rv, rv);
char ** wlst; char ** wlst;
*aSuggestionCount = mMySpell->suggest(&wlst, NS_LossyConvertUCS2toASCII(aWord).get()); *aSuggestionCount = mMySpell->suggest(&wlst, charsetWord);
if (*aSuggestionCount) { if (*aSuggestionCount) {
PRUnichar **tmpPtr = (PRUnichar **)nsMemory::Alloc(*aSuggestionCount * sizeof(PRUnichar *)); *aSuggestions = (PRUnichar **)nsMemory::Alloc(*aSuggestionCount * sizeof(PRUnichar *));
if (!tmpPtr) if (*aSuggestions) {
return NS_ERROR_OUT_OF_MEMORY; PRUint32 index = 0;
for (index = 0; index < *aSuggestionCount && NS_SUCCEEDED(rv); ++index) {
for (PRUint32 i = 0; i < *aSuggestionCount; ++i) {
// Convert the suggestion to utf16 // Convert the suggestion to utf16
PRInt32 inLength = PL_strlen(wlst[i]); PRInt32 inLength = nsCRT::strlen(wlst[index]);
PRInt32 outLength; PRInt32 outLength;
nsresult rv = mDecoder->GetMaxLength(wlst[i], inLength, &outLength); rv = mDecoder->GetMaxLength(wlst[index], inLength, &outLength);
NS_ENSURE_SUCCESS(rv, rv); if (NS_SUCCEEDED(rv))
PRUnichar *dest = (PRUnichar *)malloc(sizeof(PRUnichar) * (outLength + 1)); {
if (!dest) (*aSuggestions)[index] = (PRUnichar *) nsMemory::Alloc(sizeof(PRUnichar) * (outLength+1));
return NS_ERROR_OUT_OF_MEMORY; if ((*aSuggestions)[index])
rv = mDecoder->Convert(wlst[i], &inLength, dest, &outLength); {
NS_ENSURE_SUCCESS(rv, rv); rv = mDecoder->Convert(wlst[index], &inLength, (*aSuggestions)[index], &outLength);
dest[outLength] = 0; if (NS_SUCCEEDED(rv))
free(wlst[i]); (*aSuggestions)[index][outLength] = 0;
}
// XXX ewwww. else
tmpPtr[i] = ToNewUnicode(nsDependentString(dest)); rv = NS_ERROR_OUT_OF_MEMORY;
free(dest);
} }
*aSuggestions = tmpPtr;
} }
return NS_OK; if (NS_FAILED(rv))
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(index, *aSuggestions); // free the PRUnichar strings up to the point at which the error occurred
}
else // if (*aSuggestions)
rv = NS_ERROR_OUT_OF_MEMORY;
}
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(*aSuggestionCount, wlst);
return rv;
} }

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

@ -79,6 +79,9 @@ public:
mozMySpell(); mozMySpell();
virtual ~mozMySpell(); virtual ~mozMySpell();
// helper method for converting a word to the charset of the dictionary
nsresult ConvertCharset(const PRUnichar* aStr, char ** aDst);
protected: protected:
nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary; nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary;

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

@ -127,14 +127,14 @@ mozSpellChecker::CheckWord(const nsAString &aWord, PRBool *aIsMisspelled, nsStri
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
*aIsMisspelled = PR_FALSE; *aIsMisspelled = PR_FALSE;
result = mSpellCheckingEngine->Check(PromiseFlatString(aWord).get(), &correct); result = mSpellCheckingEngine->Check(PromiseFlatString(aWord).get(), &correct);
if(NS_FAILED(result)) NS_ENSURE_SUCCESS(result, result);
return result;
if(!correct){ if(!correct){
if(aSuggestions){ if(aSuggestions){
PRUint32 count,i; PRUint32 count,i;
PRUnichar **words; PRUnichar **words;
mSpellCheckingEngine->Suggest(PromiseFlatString(aWord).get(), &words, &count); result = mSpellCheckingEngine->Suggest(PromiseFlatString(aWord).get(), &words, &count);
NS_ENSURE_SUCCESS(result, result);
for(i=0;i<count;i++){ for(i=0;i<count;i++){
aSuggestions->AppendString(nsDependentString(words[i])); aSuggestions->AppendString(nsDependentString(words[i]));
} }