summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/func_str.result7
-rw-r--r--mysql-test/t/func_str.test11
-rw-r--r--sql/item_strfunc.cc17
-rw-r--r--sql/item_strfunc.h1
-rw-r--r--sql/sql_parse.cc3
-rw-r--r--vio/viosocket.c2
-rw-r--r--vio/viossl.c2
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;