summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <sergefp@mysql.com>2005-02-04 09:14:22 +0300
committerunknown <sergefp@mysql.com>2005-02-04 09:14:22 +0300
commitebda548d0d26f49a05d424f186e0b1d92c90925e (patch)
treedf20fcb468895423bb135dd8c9ec93140e32963b
parentbd556f0d709a324f7d33e2ae561164a90b0f04c9 (diff)
downloadmariadb-git-ebda548d0d26f49a05d424f186e0b1d92c90925e.tar.gz
Fix for BUG#7716: in in_string::set() take into account that the value returned
by item->val_str() may be a substring of the passed string. Disallow string=its_substring assignment in String::operator=(). mysql-test/r/func_misc.result: Testcase for BUG#7716 mysql-test/t/func_misc.test: Testcase for BUG#7716 sql/item_cmpfunc.cc: Fix for BUG#7716: in in_string::set() take into account that the string returned by item->val_str(S) may be not S but use the buffer owned by S. sql/sql_string.h: * Added assert: String& String::operator=(const String&) may not be used to do assignments like str = string_that_uses_buffer_owned_by_str * Added String::uses_buffer_owned_by().
-rw-r--r--mysql-test/r/func_misc.result21
-rw-r--r--mysql-test/t/func_misc.test15
-rw-r--r--sql/item_cmpfunc.cc4
-rw-r--r--sql/sql_string.h10
4 files changed, 50 insertions, 0 deletions
diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result
index 5a9f0f68228..2d464c891bf 100644
--- a/mysql-test/r/func_misc.result
+++ b/mysql-test/r/func_misc.result
@@ -28,3 +28,24 @@ length(format('nan', 2)) > 0
select concat("$",format(2500,2));
concat("$",format(2500,2))
$2,500.00
+create table t1 ( a timestamp );
+insert into t1 values ( '2004-01-06 12:34' );
+select a from t1 where left(a+0,6) in ( left(20040106,6) );
+a
+2004-01-06 12:34:00
+select a from t1 where left(a+0,6) = ( left(20040106,6) );
+a
+2004-01-06 12:34:00
+select a from t1 where right(a+0,6) in ( right(20040106123400,6) );
+a
+2004-01-06 12:34:00
+select a from t1 where right(a+0,6) = ( right(20040106123400,6) );
+a
+2004-01-06 12:34:00
+select a from t1 where mid(a+0,6,3) in ( mid(20040106123400,6,3) );
+a
+2004-01-06 12:34:00
+select a from t1 where mid(a+0,6,3) = ( mid(20040106123400,6,3) );
+a
+2004-01-06 12:34:00
+drop table t1;
diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test
index e73f2a1b26c..89aba7ee583 100644
--- a/mysql-test/t/func_misc.test
+++ b/mysql-test/t/func_misc.test
@@ -23,3 +23,18 @@ select length(format('nan', 2)) > 0;
# Test for bug #628
#
select concat("$",format(2500,2));
+
+# Test for BUG#7716
+create table t1 ( a timestamp );
+insert into t1 values ( '2004-01-06 12:34' );
+select a from t1 where left(a+0,6) in ( left(20040106,6) );
+select a from t1 where left(a+0,6) = ( left(20040106,6) );
+
+select a from t1 where right(a+0,6) in ( right(20040106123400,6) );
+select a from t1 where right(a+0,6) = ( right(20040106123400,6) );
+
+select a from t1 where mid(a+0,6,3) in ( mid(20040106123400,6,3) );
+select a from t1 where mid(a+0,6,3) = ( mid(20040106123400,6,3) );
+
+drop table t1;
+
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index c5e6d520ab7..46ef3281dd1 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1503,7 +1503,11 @@ void in_string::set(uint pos,Item *item)
String *str=((String*) base)+pos;
String *res=item->val_str(str);
if (res && res != str)
+ {
+ if (res->uses_buffer_owned_by(str))
+ res->copy();
*str= *res;
+ }
if (!str->charset())
{
CHARSET_INFO *cs;
diff --git a/sql/sql_string.h b/sql/sql_string.h
index a8fb9574c0b..9136dddbbf2 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -182,6 +182,11 @@ public:
{
if (&s != this)
{
+ /*
+ It is forbidden to do assignments like
+ some_string = substring_of_that_string
+ */
+ DBUG_ASSERT(!s.uses_buffer_owned_by(this));
free();
Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length;
alloced=0;
@@ -313,4 +318,9 @@ public:
/* Swap two string objects. Efficient way to exchange data without memcpy. */
void swap(String &s);
+
+ inline bool uses_buffer_owned_by(const String *s) const
+ {
+ return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length);
+ }
};