GNOME Bugzilla – Bug 333213
Can't specify the encoding as ISO-8859-15 in mail composer on Solaris
Last modified: 2013-09-13 00:52:30 UTC
Please describe the problem: On solaris, after specifying charset encoding as ISO-8859-15, the mail is still in UTF-8 encoding. Steps to reproduce: 1. Switch to 8859-15 locale on Solairs. 2. Compose a new mail, input euro sign and accented characters. 3. Send above email. 4. Select View->Character Encoding->Western European, New (iso8859-15), then receive the mail. Actual results: Euro sign and accented characters appear as garbage. But it's fine if choosing View->Character Encoding->UTF-8. Expected results: Should display Euro sign and accented chars correctly. Does this happen every time? Yes. Other information: It's actually caused by return value iconv().
Looking into the code, this issue is related to the following code. evolution-2.5.9/composer/e-msg-composer.c:line 430 encoding = best_encoding (buf, "US-ASCII"); evolution-2.5.9/composer/e-msg-composer.c: line 378 status = e_iconv (cd, (const char **) &in, &inlen, &out, &outlen); if (status == (size_t) -1) return -1; by invoking e_iconv(), evolution regards euro sign as a valid ASCII char. So specified ISO-8859-15 charset can't be set. There seems to be some problems with deciding the return value of e_iconv(). Currently we only check if it is -1, in fact, positive value also means failure in conversation.
Accoring to below man page of Linux and Solaris. the positive value returned by iconv() should mean failure. For Linux: DESCRIPTION: .......The conversion can stop for four reasons: 1. An invalid multibyte sequence is encountered in the input. In this case it sets errno to EILSEQ and returns (size_t)(-1). *inbuf is left pointing to the beginning of the invalid multibyte sequence. 2. The input byte sequence has been entirely converted, i.e. *inbytesleft has gone down to 0. In this case iconv returns the number of non-reversible conversions performed during this call. RETURN VALUE The iconv function returns the number of characters converted in a non-reversible way during this call; reversible conversions are not counted. In case of error, it sets errno and returns (size_t)(-1). For Solaris: If iconv() encounters a character in the input buffer that is legal, but for which an identical character does not exist in the target code set, iconv() performs an implementation-defined conversion on this character. RETURN VALUES The iconv() function updates the variables pointed to by the arguments to reflect the extent of the conversion and returns the number of non-identical conversions performed. If the entire string in the input buffer is converted, the value pointed to by inbytesleft will be 0. If the input conversion is stopped due to any conditions mentioned above, the value pointed to by inbytesleft will be non-zero and errno is set to indicate the condition. If an error occurs iconv() returns (size_t) -1 and sets errno to indicate the error.
Created attachment 60527 [details] [review] patch Translate non-zero value returned by iconv() to -1.
simon, do you think that bug 249548 is a duplicate of this one here? :-/
Andre, there's a bit difference between #249548 and this. #249548 is about html format, and this is regarding plain text. They're disposed of by two separate ways.
Jeffrey, post the iconv() section in latest POSIX.1 specfication as below. http://www.opengroup.org/onlinepubs/009695399/functions/iconv.html DESCRIPTION .... If iconv() encounters a character in the input buffer that is valid, but for which an identical character does not exist in the target codeset, iconv() shall perform an implementation-defined conversion on this character. RETURN VALUE The iconv() function shall update the variables pointed to by the arguments to reflect the extent of the conversion and return the number of non-identical conversions performed. If the entire string in the input buffer is converted, the value pointed to by inbytesleft shall be 0. If the input conversion is stopped due to any conditions mentioned above, the value pointed to by inbytesleft shall be non-zero and errno shall be set to indicate the condition. If an error occurs, iconv() shall return (size_t)-1 and set errno to indicate the error. ERRORS The iconv() function shall fail if: [EILSEQ] Input conversion stopped due to an input byte that does not belong to the input codeset. [E2BIG] Input conversion stopped due to lack of space in the output buffer. [EINVAL] Input conversion stopped due to an incomplete character or shift sequence at the end of the input buffer. The iconv() function may fail if: [EBADF] The cd argument is not a valid open conversion descriptor.
Created attachment 60813 [details] [review] Updated patch In case of encounting non-identical characters, iconv() returns the number of non-identical conversation performed. So returning positive value means exception as well as -1.
Looks fine. Please commit to both HEAD and stable branch
Committed the patch to CVS HEAD and gnome-2-14 branch, thanks.