Commit 281c8ec1 authored by bar@mysql.com's avatar bar@mysql.com

Bug#5439 : mysql_server_init() crashes if ShiftJIS path is passed

(important for Adobe).

mf_pack.c, mf_dirname.c, charset.c, my_sys.h:

  - adding fs_character_set() function on Windows
  - ignoring fake slashes which are just multibyte
    parts in several functions in /mysys

Verified by Shu to work on WinXP and Win2k.
Test is not possible, or very hard to do.
parent f18796bc
...@@ -788,6 +788,11 @@ extern my_bool init_compiled_charsets(myf flags); ...@@ -788,6 +788,11 @@ extern my_bool init_compiled_charsets(myf flags);
extern void add_compiled_collation(CHARSET_INFO *cs); extern void add_compiled_collation(CHARSET_INFO *cs);
extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to, extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to,
const char *from, ulong length); const char *from, ulong length);
#ifdef __WIN__
#define BACKSLASH_MBTAIL
/* File system character set */
extern CHARSET_INFO *fs_character_set(void);
#endif
#ifdef __WIN__ #ifdef __WIN__
extern my_bool have_tcpip; /* Is set if tcpip is used */ extern my_bool have_tcpip; /* Is set if tcpip is used */
......
...@@ -637,3 +637,29 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to, ...@@ -637,3 +637,29 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to,
*to= 0; *to= 0;
return (ulong) (to - to_start); return (ulong) (to - to_start);
} }
#ifdef BACKSLASH_MBTAIL
static CHARSET_INFO *fs_cset_cache= NULL;
CHARSET_INFO *fs_character_set()
{
if (!fs_cset_cache)
{
char buf[10]= "cp";
GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE,
buf+2, sizeof(buf)-3);
/*
We cannot call get_charset_by_name here
because fs_character_set() is executed before
LOCK_THD_charset mutex initialization, which
is used inside get_charset_by_name.
As we're now interested in cp932 only,
let's just detect it using strcmp().
*/
fs_cset_cache= !strcmp(buf, "cp932") ?
&my_charset_cp932_japanese_ci : &my_charset_bin;
}
return fs_cset_cache;
}
#endif
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
uint dirname_length(const char *name) uint dirname_length(const char *name)
{ {
register my_string pos,gpos; register my_string pos,gpos;
#ifdef BASKSLASH_MBTAIL
CHARSET_INFO *fs= fs_character_set();
#endif
#ifdef FN_DEVCHAR #ifdef FN_DEVCHAR
if ((pos=(char*)strrchr(name,FN_DEVCHAR)) == 0) if ((pos=(char*)strrchr(name,FN_DEVCHAR)) == 0)
#endif #endif
...@@ -29,12 +32,22 @@ uint dirname_length(const char *name) ...@@ -29,12 +32,22 @@ uint dirname_length(const char *name)
gpos= pos++; gpos= pos++;
for ( ; *pos ; pos++) /* Find last FN_LIBCHAR */ for ( ; *pos ; pos++) /* Find last FN_LIBCHAR */
{
#ifdef BASKSLASH_MBTAIL
uint l;
if (use_mb(fs) && (l= my_ismbchar(fs, pos, pos + 3)))
{
pos+= l - 1;
continue;
}
#endif
if (*pos == FN_LIBCHAR || *pos == '/' if (*pos == FN_LIBCHAR || *pos == '/'
#ifdef FN_C_AFTER_DIR #ifdef FN_C_AFTER_DIR
|| *pos == FN_C_AFTER_DIR || *pos == FN_C_AFTER_DIR_2 || *pos == FN_C_AFTER_DIR || *pos == FN_C_AFTER_DIR_2
#endif #endif
) )
gpos=pos; gpos=pos;
}
return ((uint) (uint) (gpos+1-(char*) name)); return ((uint) (uint) (gpos+1-(char*) name));
} }
...@@ -85,6 +98,9 @@ uint dirname_part(my_string to, const char *name) ...@@ -85,6 +98,9 @@ uint dirname_part(my_string to, const char *name)
char *convert_dirname(char *to, const char *from, const char *from_end) char *convert_dirname(char *to, const char *from, const char *from_end)
{ {
char *to_org=to; char *to_org=to;
#ifdef BACKSLASH_MBTAIL
CHARSET_INFO *fs= fs_character_set();
#endif
/* We use -2 here, becasue we need place for the last FN_LIBCHAR */ /* We use -2 here, becasue we need place for the last FN_LIBCHAR */
if (!from_end || (from_end - from) > FN_REFLEN-2) if (!from_end || (from_end - from) > FN_REFLEN-2)
...@@ -103,7 +119,22 @@ char *convert_dirname(char *to, const char *from, const char *from_end) ...@@ -103,7 +119,22 @@ char *convert_dirname(char *to, const char *from, const char *from_end)
*to++= FN_C_AFTER_DIR; *to++= FN_C_AFTER_DIR;
#endif #endif
else else
*to++= *from; {
#ifdef BACKSLASH_MBTAIL
uint l;
if (use_mb(fs) && (l= my_ismbchar(fs, from, from + 3)))
{
memmove(to, from, l);
to+= l;
from+= l - 1;
to_org= to; /* Don't look inside mbchar */
}
else
#endif
{
*to++= *from;
}
}
} }
*to=0; *to=0;
} }
......
...@@ -124,6 +124,9 @@ uint cleanup_dirname(register my_string to, const char *from) ...@@ -124,6 +124,9 @@ uint cleanup_dirname(register my_string to, const char *from)
reg4 my_string start; reg4 my_string start;
char parent[5], /* for "FN_PARENTDIR" */ char parent[5], /* for "FN_PARENTDIR" */
buff[FN_REFLEN+1],*end_parentdir; buff[FN_REFLEN+1],*end_parentdir;
#ifdef BACKSLASH_MBTAIL
CHARSET_INFO *fs= fs_character_set();
#endif
DBUG_ENTER("cleanup_dirname"); DBUG_ENTER("cleanup_dirname");
DBUG_PRINT("enter",("from: '%s'",from)); DBUG_PRINT("enter",("from: '%s'",from));
...@@ -141,6 +144,15 @@ uint cleanup_dirname(register my_string to, const char *from) ...@@ -141,6 +144,15 @@ uint cleanup_dirname(register my_string to, const char *from)
length=(uint) (strmov(parent+1,FN_PARENTDIR)-parent); length=(uint) (strmov(parent+1,FN_PARENTDIR)-parent);
for (pos=start ; (*pos= *from_ptr++) != 0 ; pos++) for (pos=start ; (*pos= *from_ptr++) != 0 ; pos++)
{ {
#ifdef BACKSLASH_MBTAIL
uint l;
if (use_mb(fs) && (l= my_ismbchar(fs, from_ptr - 1, from_ptr + 2)))
{
for (l-- ; l ; *++pos= *from_ptr++, l--);
start= pos + 1; /* Don't look inside multi-byte char */
continue;
}
#endif
if (*pos == '/') if (*pos == '/')
*pos = FN_LIBCHAR; *pos = FN_LIBCHAR;
if (*pos == FN_LIBCHAR) if (*pos == FN_LIBCHAR)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment