diff options
-rw-r--r-- | mysql-test/r/func_str.result | 7 | ||||
-rw-r--r-- | mysql-test/t/func_str.test | 11 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 17 | ||||
-rw-r--r-- | sql/item_strfunc.h | 1 | ||||
-rw-r--r-- | sql/sql_parse.cc | 3 | ||||
-rw-r--r-- | vio/viosocket.c | 2 | ||||
-rw-r--r-- | vio/viossl.c | 2 |
7 files changed, 29 insertions, 14 deletions
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 58d66c7f712..a8a7ad0e349 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -697,6 +697,13 @@ quote(ltrim(concat(' ', 'a'))) select quote(trim(concat(' ', 'a'))); quote(trim(concat(' ', 'a'))) 'a' +CREATE TABLE t1 SELECT 1 UNION SELECT 2 UNION SELECT 3; +SELECT QUOTE('A') FROM t1; +QUOTE('A') +'A' +'A' +'A' +DROP TABLE t1; select trim(null from 'kate') as "must_be_null"; must_be_null NULL diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 34bbb2bab0f..2bf130d1538 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -195,6 +195,17 @@ select trim(trailing 'foo' from 'foo'); select trim(leading 'foo' from 'foo'); # +# crashing bug with QUOTE() and LTRIM() or TRIM() fixed +# Bug #7495 +# + +select quote(ltrim(concat(' ', 'a'))); +select quote(trim(concat(' ', 'a'))); + +# Bad results from QUOTE(). Bug #8248 +CREATE TABLE t1 SELECT 1 UNION SELECT 2 UNION SELECT 3; +SELECT QUOTE('A') FROM t1; +DROP TABLE t1; # Test collation and coercibility # diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index cee3316886a..1fb68561374 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2614,18 +2614,13 @@ String *Item_func_quote::val_str(String *str) for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++) new_length+= get_esc_bit(escmask, (uchar) *from); - /* - We have to use realloc() instead of alloc() as we want to keep the - old result in arg - */ - if (arg->realloc(new_length)) + if (tmp_value.alloc(new_length)) goto null; /* - As 'arg' and 'str' may be the same string, we must replace characters - from the end to the beginning + We replace characters from the end to the beginning */ - to= (char*) arg->ptr() + new_length - 1; + to= (char*) tmp_value.ptr() + new_length - 1; *to--= '\''; for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--) { @@ -2653,10 +2648,10 @@ String *Item_func_quote::val_str(String *str) } } *to= '\''; - arg->length(new_length); - str->set_charset(collation.collation); + tmp_value.length(new_length); + tmp_value.set_charset(collation.collation); null_value= 0; - return arg; + return &tmp_value; null: null_value= 1; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 698536a61c7..c1c0969672c 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -588,6 +588,7 @@ public: class Item_func_quote :public Item_str_func { + String tmp_value; public: Item_func_quote(Item *a) :Item_str_func(a) {} const char *func_name() const { return "quote"; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 85cd24c4fbb..e66eeb279d2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -660,6 +660,8 @@ static int check_connection(THD *thd) DBUG_PRINT("info", ("New connection received on %s", vio_description(net->vio))); + vio_in_addr(net->vio,&thd->remote.sin_addr); + if (!thd->host) // If TCP/IP connection { char ip[30]; @@ -704,7 +706,6 @@ static int check_connection(THD *thd) DBUG_PRINT("info",("Host: %s",thd->host)); thd->host_or_ip= thd->host; thd->ip= 0; - bzero((char*) &thd->remote, sizeof(struct sockaddr)); } vio_keepalive(net->vio, TRUE); ulong pkt_len= 0; diff --git a/vio/viosocket.c b/vio/viosocket.c index 202d70b6c26..fee97daa943 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -276,7 +276,7 @@ void vio_in_addr(Vio *vio, struct in_addr *in) { DBUG_ENTER("vio_in_addr"); if (vio->localhost) - bzero((char*) in, sizeof(*in)); /* This should never be executed */ + bzero((char*) in, sizeof(*in)); else *in=vio->remote.sin_addr; DBUG_VOID_RETURN; diff --git a/vio/viossl.c b/vio/viossl.c index a489cb98f98..07713c83763 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -259,7 +259,7 @@ void vio_ssl_in_addr(Vio *vio, struct in_addr *in) { DBUG_ENTER("vio_ssl_in_addr"); if (vio->localhost) - bzero((char*) in, sizeof(*in)); /* This should never be executed */ + bzero((char*) in, sizeof(*in)); else *in=vio->remote.sin_addr; DBUG_VOID_RETURN; |