mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
Merge mysql.com:/home/jimw/my/mysql-5.0-10214
into mysql.com:/home/jimw/my/mysql-5.0-clean
This commit is contained in:
@ -866,6 +866,9 @@ extern void add_compiled_collation(CHARSET_INFO *cs);
|
|||||||
extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
|
extern ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
|
||||||
char *to, ulong to_length,
|
char *to, ulong to_length,
|
||||||
const char *from, ulong length);
|
const char *from, ulong length);
|
||||||
|
extern ulong escape_quotes_for_mysql(CHARSET_INFO *charset_info,
|
||||||
|
char *to, ulong to_length,
|
||||||
|
const char *from, ulong length);
|
||||||
|
|
||||||
extern void thd_increment_bytes_sent(ulong length);
|
extern void thd_increment_bytes_sent(ulong length);
|
||||||
extern void thd_increment_bytes_received(ulong length);
|
extern void thd_increment_bytes_received(ulong length);
|
||||||
|
@ -148,6 +148,7 @@ enum enum_server_command
|
|||||||
*/
|
*/
|
||||||
#define SERVER_STATUS_LAST_ROW_SENT 128
|
#define SERVER_STATUS_LAST_ROW_SENT 128
|
||||||
#define SERVER_STATUS_DB_DROPPED 256 /* A database was dropped */
|
#define SERVER_STATUS_DB_DROPPED 256 /* A database was dropped */
|
||||||
|
#define SERVER_STATUS_NO_BACKSLASH_ESCAPES 512
|
||||||
|
|
||||||
#define MYSQL_ERRMSG_SIZE 512
|
#define MYSQL_ERRMSG_SIZE 512
|
||||||
#define NET_READ_TIMEOUT 30 /* Timeout on read */
|
#define NET_READ_TIMEOUT 30 /* Timeout on read */
|
||||||
|
@ -1616,7 +1616,14 @@ ulong STDCALL
|
|||||||
mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
|
mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
|
||||||
ulong length)
|
ulong length)
|
||||||
{
|
{
|
||||||
return escape_string_for_mysql(mysql->charset, to, 0, from, length);
|
if (mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)
|
||||||
|
{
|
||||||
|
return escape_quotes_for_mysql(mysql->charset, to, 0, from, length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return escape_string_for_mysql(mysql->charset, to, 0, from, length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
116
mysys/charset.c
116
mysys/charset.c
@ -561,11 +561,30 @@ CHARSET_INFO *get_charset_by_csname(const char *cs_name,
|
|||||||
DBUG_RETURN(cs);
|
DBUG_RETURN(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Escape string with backslashes (\)
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
escape_string_for_mysql()
|
||||||
|
charset_info Charset of the strings
|
||||||
|
to Buffer for escaped string
|
||||||
|
to_length Length of destination buffer, or 0
|
||||||
|
from The string to escape
|
||||||
|
length The length of the string to escape
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This escapes the contents of a string by adding backslashes before special
|
||||||
|
characters, and turning others into specific escape sequences, such as
|
||||||
|
turning newlines into \n and null bytes into \0.
|
||||||
|
|
||||||
NOTE
|
NOTE
|
||||||
to keep old C API, to_length may be 0 to mean "big enough"
|
To maintain compatibility with the old C API, to_length may be 0 to mean
|
||||||
RETURN
|
"big enough"
|
||||||
the length of the escaped string or ~0 if it did not fit.
|
|
||||||
|
RETURN VALUES
|
||||||
|
~0 The escaped string did not fit in the to buffer
|
||||||
|
>=0 The length of the escaped string
|
||||||
*/
|
*/
|
||||||
ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
|
ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
|
||||||
char *to, ulong to_length,
|
char *to, ulong to_length,
|
||||||
@ -573,20 +592,20 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
|
|||||||
{
|
{
|
||||||
const char *to_start= to;
|
const char *to_start= to;
|
||||||
const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
|
const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
|
||||||
my_bool overflow=0;
|
my_bool overflow= FALSE;
|
||||||
#ifdef USE_MB
|
#ifdef USE_MB
|
||||||
my_bool use_mb_flag= use_mb(charset_info);
|
my_bool use_mb_flag= use_mb(charset_info);
|
||||||
#endif
|
#endif
|
||||||
for (end= from + length; from < end; from++)
|
for (end= from + length; from < end; from++)
|
||||||
{
|
{
|
||||||
char escape=0;
|
char escape= 0;
|
||||||
#ifdef USE_MB
|
#ifdef USE_MB
|
||||||
int tmp_length;
|
int tmp_length;
|
||||||
if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
|
if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
|
||||||
{
|
{
|
||||||
if (to + tmp_length > to_end)
|
if (to + tmp_length > to_end)
|
||||||
{
|
{
|
||||||
overflow=1;
|
overflow= TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while (tmp_length--)
|
while (tmp_length--)
|
||||||
@ -636,7 +655,7 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
|
|||||||
{
|
{
|
||||||
if (to + 2 > to_end)
|
if (to + 2 > to_end)
|
||||||
{
|
{
|
||||||
overflow=1;
|
overflow= TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*to++= '\\';
|
*to++= '\\';
|
||||||
@ -646,7 +665,7 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
|
|||||||
{
|
{
|
||||||
if (to + 1 > to_end)
|
if (to + 1 > to_end)
|
||||||
{
|
{
|
||||||
overflow=1;
|
overflow= TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*to++= *from;
|
*to++= *from;
|
||||||
@ -656,3 +675,84 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info,
|
|||||||
return overflow ? (ulong)~0 : (ulong) (to - to_start);
|
return overflow ? (ulong)~0 : (ulong) (to - to_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Escape apostrophes by doubling them up
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
escape_quotes_for_mysql()
|
||||||
|
charset_info Charset of the strings
|
||||||
|
to Buffer for escaped string
|
||||||
|
to_length Length of destination buffer, or 0
|
||||||
|
from The string to escape
|
||||||
|
length The length of the string to escape
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
This escapes the contents of a string by doubling up any apostrophes that
|
||||||
|
it contains. This is used when the NO_BACKSLASH_ESCAPES SQL_MODE is in
|
||||||
|
effect on the server.
|
||||||
|
|
||||||
|
NOTE
|
||||||
|
To be consistent with escape_string_for_mysql(), to_length may be 0 to
|
||||||
|
mean "big enough"
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
~0 The escaped string did not fit in the to buffer
|
||||||
|
>=0 The length of the escaped string
|
||||||
|
*/
|
||||||
|
ulong escape_quotes_for_mysql(CHARSET_INFO *charset_info,
|
||||||
|
char *to, ulong to_length,
|
||||||
|
const char *from, ulong length)
|
||||||
|
{
|
||||||
|
const char *to_start= to;
|
||||||
|
const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
|
||||||
|
my_bool overflow= FALSE;
|
||||||
|
#ifdef USE_MB
|
||||||
|
my_bool use_mb_flag= use_mb(charset_info);
|
||||||
|
#endif
|
||||||
|
for (end= from + length; from < end; from++)
|
||||||
|
{
|
||||||
|
char escape= 0;
|
||||||
|
#ifdef USE_MB
|
||||||
|
int tmp_length;
|
||||||
|
if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
|
||||||
|
{
|
||||||
|
if (to + tmp_length > to_end)
|
||||||
|
{
|
||||||
|
overflow= TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (tmp_length--)
|
||||||
|
*to++= *from++;
|
||||||
|
from--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
We don't have the same issue here with a non-multi-byte character being
|
||||||
|
turned into a multi-byte character by the addition of an escaping
|
||||||
|
character, because we are only escaping the ' character with itself.
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
if (*from == '\'')
|
||||||
|
{
|
||||||
|
if (to + 2 > to_end)
|
||||||
|
{
|
||||||
|
overflow= TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*to++= '\'';
|
||||||
|
*to++= '\'';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (to + 1 > to_end)
|
||||||
|
{
|
||||||
|
overflow= TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*to++= *from;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*to= 0;
|
||||||
|
return overflow ? (ulong)~0 : (ulong) (to - to_start);
|
||||||
|
}
|
||||||
|
@ -3238,7 +3238,16 @@ void fix_sql_mode_var(THD *thd, enum_var_type type)
|
|||||||
global_system_variables.sql_mode=
|
global_system_variables.sql_mode=
|
||||||
fix_sql_mode(global_system_variables.sql_mode);
|
fix_sql_mode(global_system_variables.sql_mode);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
thd->variables.sql_mode= fix_sql_mode(thd->variables.sql_mode);
|
thd->variables.sql_mode= fix_sql_mode(thd->variables.sql_mode);
|
||||||
|
/*
|
||||||
|
Update thd->server_status
|
||||||
|
*/
|
||||||
|
if (thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
|
||||||
|
thd->server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
|
||||||
|
else
|
||||||
|
thd->server_status&= ~SERVER_STATUS_NO_BACKSLASH_ESCAPES;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map database specific bits to function bits */
|
/* Map database specific bits to function bits */
|
||||||
|
@ -282,6 +282,8 @@ void THD::init(void)
|
|||||||
#endif
|
#endif
|
||||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||||
server_status= SERVER_STATUS_AUTOCOMMIT;
|
server_status= SERVER_STATUS_AUTOCOMMIT;
|
||||||
|
if (variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
|
||||||
|
server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
|
||||||
options= thd_startup_options;
|
options= thd_startup_options;
|
||||||
open_options=ha_open_options;
|
open_options=ha_open_options;
|
||||||
update_lock_default= (variables.low_priority_updates ?
|
update_lock_default= (variables.low_priority_updates ?
|
||||||
|
@ -13332,7 +13332,6 @@ static void test_bug9992()
|
|||||||
mysql_close(mysql1);
|
mysql_close(mysql1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Bug#10736: cursors and subqueries, memroot management */
|
/* Bug#10736: cursors and subqueries, memroot management */
|
||||||
|
|
||||||
static void test_bug10736()
|
static void test_bug10736()
|
||||||
@ -13600,6 +13599,34 @@ static void test_bug11656()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check that the server signals when NO_BACKSLASH_ESCAPES mode is in effect,
|
||||||
|
and mysql_real_escape_string() does the right thing as a result.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void test_bug10214()
|
||||||
|
{
|
||||||
|
MYSQL_RES* res ;
|
||||||
|
int len;
|
||||||
|
char out[8];
|
||||||
|
|
||||||
|
myheader("test_bug10214");
|
||||||
|
|
||||||
|
DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES));
|
||||||
|
|
||||||
|
len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
|
||||||
|
DIE_UNLESS(memcmp(out, "a\\'b\\\\c", len) == 0);
|
||||||
|
|
||||||
|
mysql_query(mysql, "set sql_mode='NO_BACKSLASH_ESCAPES'");
|
||||||
|
DIE_UNLESS(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES);
|
||||||
|
|
||||||
|
len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
|
||||||
|
DIE_UNLESS(memcmp(out, "a''b\\c", len) == 0);
|
||||||
|
|
||||||
|
mysql_query(mysql, "set sql_mode=''");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read and parse arguments and MySQL options from my.cnf
|
Read and parse arguments and MySQL options from my.cnf
|
||||||
*/
|
*/
|
||||||
@ -13839,6 +13866,7 @@ static struct my_tests_st my_tests[]= {
|
|||||||
{ "test_bug10794", test_bug10794 },
|
{ "test_bug10794", test_bug10794 },
|
||||||
{ "test_bug11172", test_bug11172 },
|
{ "test_bug11172", test_bug11172 },
|
||||||
{ "test_bug11656", test_bug11656 },
|
{ "test_bug11656", test_bug11656 },
|
||||||
|
{ "test_bug10214", test_bug10214 },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user