Bug 524314 - g_convert() on Win32 implicitly converts full width

2008-04-02  Tor Lillqvist  <tml@novell.com>

	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 <windows.h> is used.


svn path=/trunk/; revision=6808
This commit is contained in:
Tor Lillqvist 2008-04-02 02:43:45 +00:00 committed by Tor Lillqvist
parent 30dd18b335
commit a6bdf9a1af
3 changed files with 48 additions and 14 deletions

View File

@ -1,3 +1,15 @@
2008-04-02 Tor Lillqvist <tml@novell.com>
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 <windows.h> is used.
2008-03-31 Tor Lillqvist <tml@novell.com> 2008-03-31 Tor Lillqvist <tml@novell.com>
* glib/gmain.c (g_poll): Improve fix for #525192 below: Use * glib/gmain.c (g_poll): Improve fix for #525192 below: Use

View File

@ -36,6 +36,10 @@
#include "gthreadprivate.h" #include "gthreadprivate.h"
#include "gunicode.h" #include "gunicode.h"
#ifdef G_OS_WIN32
#include "win_iconv.c"
#endif
#ifdef G_PLATFORM_WIN32 #ifdef G_PLATFORM_WIN32
#define STRICT #define STRICT
#include <windows.h> #include <windows.h>
@ -53,10 +57,6 @@
#include "galias.h" #include "galias.h"
#ifdef G_OS_WIN32
#include "win_iconv.c"
#endif
GQuark GQuark
g_convert_error_quark (void) g_convert_error_quark (void)
{ {

View File

@ -19,6 +19,12 @@
* be used for encoding validation purpose. * be used for encoding validation purpose.
*/ */
/* for WC_NO_BEST_FIT_CHARS */
#ifndef WINVER
# define WINVER 0x0500
#endif
#define STRICT
#include <windows.h> #include <windows.h>
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
@ -36,10 +42,12 @@
#define MB_CHAR_MAX 16 #define MB_CHAR_MAX 16
#define UNICODE_MODE_BOM_DONE 1 #define UNICODE_MODE_BOM_DONE 1
#define UNICODE_MODE_SWAPPED 2 #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) \ #define return_error(code) \
do { \ do { \
@ -873,6 +881,7 @@ make_csconv(const char *_name)
CPINFOEX cpinfoex; CPINFOEX cpinfoex;
csconv_t cv; csconv_t cv;
int use_compat = TRUE; int use_compat = TRUE;
int flag = 0;
char name[128]; char name[128];
char *p; char *p;
@ -883,11 +892,15 @@ make_csconv(const char *_name)
{ {
if (_stricmp(p + 2, "nocompat") == 0) if (_stricmp(p + 2, "nocompat") == 0)
use_compat = FALSE; 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; *p = 0;
} }
cv.mode = 0; cv.mode = 0;
cv.flags = 0; cv.flags = flag;
cv.mblen = NULL; cv.mblen = NULL;
cv.flush = NULL; cv.flush = NULL;
cv.compat = NULL; cv.compat = NULL;
@ -899,14 +912,14 @@ make_csconv(const char *_name)
if (_stricmp(name, "UTF-16") == 0 || if (_stricmp(name, "UTF-16") == 0 ||
_stricmp(name, "UTF16") == 0 || _stricmp(name, "UTF16") == 0 ||
_stricmp(name, "UCS-2") == 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) else if (cv.codepage == 12000 || cv.codepage == 12001)
{ {
cv.mbtowc = utf32_mbtowc; cv.mbtowc = utf32_mbtowc;
cv.wctomb = utf32_wctomb; cv.wctomb = utf32_wctomb;
if (_stricmp(name, "UTF-32") == 0 || _stricmp(name, "UTF32") == 0) 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) else if (cv.codepage == 65001)
{ {
@ -1061,7 +1074,7 @@ static void
check_utf_bom(rec_iconv_t *cd, ushort *wbuf, int *wbufsize) check_utf_bom(rec_iconv_t *cd, ushort *wbuf, int *wbufsize)
{ {
/* If we have a BOM, trust it, despite what the caller said */ /* 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 */ /* swap endian: 1200 <-> 1201 or 12000 <-> 12001 */
cd->from.codepage ^= 1; cd->from.codepage ^= 1;
@ -1345,13 +1358,22 @@ static int
kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
{ {
BOOL usedDefaultChar = 0; BOOL usedDefaultChar = 0;
BOOL *p = NULL;
int flags = 0;
int len; int len;
if (bufsize == 0) if (bufsize == 0)
return_error(E2BIG); return_error(E2BIG);
len = WideCharToMultiByte(cv->codepage, 0, if (!must_use_null_useddefaultchar(cv->codepage))
(const wchar_t *)wbuf, wbufsize, (char *)buf, bufsize, NULL, {
must_use_null_useddefaultchar(cv->codepage) ? NULL : &usedDefaultChar); 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 (len == 0)
{ {
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)