From: Tor Lillqvist Date: Wed, 2 Apr 2008 02:43:45 +0000 (+0000) Subject: Bug 524314 - g_convert() on Win32 implicitly converts full width X-Git-Tag: GLIB_2_17_0~105 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a6bdf9a1af6eaaaefa9342ce54bac6200199ff02;p=platform%2Fupstream%2Fglib.git Bug 524314 - g_convert() on Win32 implicitly converts full width 2008-04-02 Tor Lillqvist Bug 524314 - g_convert() on Win32 implicitly converts full width alphanumerics into half width * glib/win_iconv.c: Update from Yukihiro Nakadaira. Use WC_NO_BEST_FIT_CHARS flag for WideCharToMultiByte() unless the //translit flag was suffixed to the codeset name. * glib/gconvert.c: Include win_iconv.c earlier so that its definition of WINVER before it includes is used. svn path=/trunk/; revision=6808 --- diff --git a/ChangeLog b/ChangeLog index 3c9f91e..d9d230b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2008-04-02 Tor Lillqvist + + Bug 524314 - g_convert() on Win32 implicitly converts full width + alphanumerics into half width + + * glib/win_iconv.c: Update from Yukihiro Nakadaira. Use + WC_NO_BEST_FIT_CHARS flag for WideCharToMultiByte() unless the + //translit flag was suffixed to the codeset name. + + * glib/gconvert.c: Include win_iconv.c earlier so that its + definition of WINVER before it includes is used. + 2008-03-31 Tor Lillqvist * glib/gmain.c (g_poll): Improve fix for #525192 below: Use diff --git a/glib/gconvert.c b/glib/gconvert.c index e6fd8bd..8ba4801 100644 --- a/glib/gconvert.c +++ b/glib/gconvert.c @@ -36,6 +36,10 @@ #include "gthreadprivate.h" #include "gunicode.h" +#ifdef G_OS_WIN32 +#include "win_iconv.c" +#endif + #ifdef G_PLATFORM_WIN32 #define STRICT #include @@ -53,10 +57,6 @@ #include "galias.h" -#ifdef G_OS_WIN32 -#include "win_iconv.c" -#endif - GQuark g_convert_error_quark (void) { diff --git a/glib/win_iconv.c b/glib/win_iconv.c index 7ed272b..2770878 100644 --- a/glib/win_iconv.c +++ b/glib/win_iconv.c @@ -19,6 +19,12 @@ * be used for encoding validation purpose. */ +/* for WC_NO_BEST_FIT_CHARS */ +#ifndef WINVER +# define WINVER 0x0500 +#endif + +#define STRICT #include #include #include @@ -36,10 +42,12 @@ #define MB_CHAR_MAX 16 -#define UNICODE_MODE_BOM_DONE 1 -#define UNICODE_MODE_SWAPPED 2 +#define UNICODE_MODE_BOM_DONE 1 +#define UNICODE_MODE_SWAPPED 2 -#define UNICODE_FLAG_USE_BOM_ENDIAN 1 +#define FLAG_USE_BOM_ENDIAN 1 +#define FLAG_TRANSLIT 2 /* //TRANSLIT */ +#define FLAG_IGNORE 4 /* //IGNORE (not implemented) */ #define return_error(code) \ do { \ @@ -873,6 +881,7 @@ make_csconv(const char *_name) CPINFOEX cpinfoex; csconv_t cv; int use_compat = TRUE; + int flag = 0; char name[128]; char *p; @@ -883,11 +892,15 @@ make_csconv(const char *_name) { if (_stricmp(p + 2, "nocompat") == 0) use_compat = FALSE; + else if (_stricmp(p + 2, "translit") == 0) + flag |= FLAG_TRANSLIT; + else if (_stricmp(p + 2, "ignore") == 0) + flag |= FLAG_IGNORE; *p = 0; } cv.mode = 0; - cv.flags = 0; + cv.flags = flag; cv.mblen = NULL; cv.flush = NULL; cv.compat = NULL; @@ -899,14 +912,14 @@ make_csconv(const char *_name) if (_stricmp(name, "UTF-16") == 0 || _stricmp(name, "UTF16") == 0 || _stricmp(name, "UCS-2") == 0) - cv.flags |= UNICODE_FLAG_USE_BOM_ENDIAN; + cv.flags |= FLAG_USE_BOM_ENDIAN; } else if (cv.codepage == 12000 || cv.codepage == 12001) { cv.mbtowc = utf32_mbtowc; cv.wctomb = utf32_wctomb; if (_stricmp(name, "UTF-32") == 0 || _stricmp(name, "UTF32") == 0) - cv.flags |= UNICODE_FLAG_USE_BOM_ENDIAN; + cv.flags |= FLAG_USE_BOM_ENDIAN; } else if (cv.codepage == 65001) { @@ -1061,7 +1074,7 @@ static void check_utf_bom(rec_iconv_t *cd, ushort *wbuf, int *wbufsize) { /* If we have a BOM, trust it, despite what the caller said */ - if (wbuf[0] == 0xFFFE && (cd->from.flags & UNICODE_FLAG_USE_BOM_ENDIAN)) + if (wbuf[0] == 0xFFFE && (cd->from.flags & FLAG_USE_BOM_ENDIAN)) { /* swap endian: 1200 <-> 1201 or 12000 <-> 12001 */ cd->from.codepage ^= 1; @@ -1345,13 +1358,22 @@ static int kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) { BOOL usedDefaultChar = 0; + BOOL *p = NULL; + int flags = 0; int len; if (bufsize == 0) return_error(E2BIG); - len = WideCharToMultiByte(cv->codepage, 0, - (const wchar_t *)wbuf, wbufsize, (char *)buf, bufsize, NULL, - must_use_null_useddefaultchar(cv->codepage) ? NULL : &usedDefaultChar); + if (!must_use_null_useddefaultchar(cv->codepage)) + { + p = &usedDefaultChar; +#ifdef WC_NO_BEST_FIT_CHARS + if (!(cv->flags & FLAG_TRANSLIT)) + flags |= WC_NO_BEST_FIT_CHARS; +#endif + } + len = WideCharToMultiByte(cv->codepage, flags, + (const wchar_t *)wbuf, wbufsize, (char *)buf, bufsize, NULL, p); if (len == 0) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)