List:Commits« Previous MessageNext Message »
From:tim Date:December 19 2006 10:54pm
Subject:bk commit into 5.0 tree (tsmith:1.2353) BUG#24947
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of tim. When tim does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2006-12-19 15:54:12-07:00, tsmith@stripped +3 -0
  Bug #24947: REPEAT function returns NULL when passed a field as the count parameter
  
  Handling of large signed/unsigned values was not consistent, so some string functions could return bogus results.
  The current fix is to simply patch up the val_str() methods for those string items.
  It would be good clean this code up in general, to make similar problems much harder to make.  This is left as an exercise for the reader.

  mysql-test/r/func_str.result@stripped, 2006-12-19 15:54:09-07:00, tsmith@stripped +12 -0
    Update test results for bug #24947

  mysql-test/t/func_str.test@stripped, 2006-12-19 15:54:09-07:00, tsmith@stripped +8 -0
    Add test case for bug #24947

  sql/item_strfunc.cc@stripped, 2006-12-19 15:54:09-07:00, tsmith@stripped +19 -20
    Adjust some string function Items' val_str() methods to handle large signed/unsigned arguments properly

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	tsmith
# Host:	siva.hindu.god
# Root:	/usr/home/tim/m/bk/50-release

--- 1.290/sql/item_strfunc.cc	2006-12-19 15:54:19 -07:00
+++ 1.291/sql/item_strfunc.cc	2006-12-19 15:54:19 -07:00
@@ -1166,7 +1166,8 @@ String *Item_func_substr::val_str(String
 
   /* if "unsigned_flag" is set, we have a *huge* positive number. */
   /* Assumes that the maximum length of a String is < INT_MAX32. */
-  if ((args[1]->unsigned_flag) || (start < INT_MIN32) || (start > INT_MAX32))
+  if ((!args[1]->unsigned_flag && (start < INT_MIN32 || start > INT_MAX32)) ||
+      (args[1]->unsigned_flag && ((ulonglong) start > INT_MAX32)))
     return &my_empty_string;
 
   start= ((start < 0) ? res->numchars() + start : start - 1);
@@ -2227,25 +2228,23 @@ String *Item_func_repeat::val_str(String
   uint length,tot_length;
   char *to;
   /* must be longlong to avoid truncation */
-  longlong tmp_count= args[1]->val_int();
-  long count= (long) tmp_count;
+  longlong count= args[1]->val_int();
   String *res= args[0]->val_str(str);
 
-  /* Assumes that the maximum length of a String is < INT_MAX32. */
-  /* Bounds check on count:  If this is triggered, we will error. */
-  if ((tmp_count > INT_MAX32) || args[1]->unsigned_flag)
-    count= INT_MAX32;
-
   if (args[0]->null_value || args[1]->null_value)
     goto err;				// string and/or delim are null
   null_value= 0;
-  if ((tmp_count <= 0) && !args[1]->unsigned_flag)	// For nicer SQL code
+  if ((count <= 0) && !args[1]->unsigned_flag)	// For nicer SQL code
     return &my_empty_string;
+  /* Assumes that the maximum length of a String is < INT_MAX32. */
+  /* Bounds check on count:  If this is triggered, we will error. */
+  if ((ulonglong) count > INT_MAX32)
+    count= INT_MAX32;
   if (count == 1)			// To avoid reallocs
     return res;
   length=res->length();
   // Safe length check
-  if (length > current_thd->variables.max_allowed_packet/count)
+  if (length > current_thd->variables.max_allowed_packet / (uint) count)
   {
     push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 			ER_WARN_ALLOWED_PACKET_OVERFLOWED,
@@ -2319,15 +2318,14 @@ String *Item_func_rpad::val_str(String *
   String *res= args[0]->val_str(str);
   String *rpad= args[2]->val_str(&rpad_str);
 
+  if (!res || args[1]->null_value || !rpad || 
+      ((count < 0) && !args[1]->unsigned_flag))
+    goto err;
+  null_value=0;
   /* Assumes that the maximum length of a String is < INT_MAX32. */
   /* Set here so that rest of code sees out-of-bound value as such. */
-  if ((count > INT_MAX32) || args[1]->unsigned_flag)
+  if ((ulonglong) count > INT_MAX32)
     count= INT_MAX32;
-
-  if (!res || args[1]->null_value || !rpad || count < 0)
-    goto err;
-  null_value=0;
-
   if (count <= (res_char_length= res->numchars()))
   {						// String to pad is big enough
     res->length(res->charpos((int) count));     // Shorten result if longer
@@ -2421,14 +2419,15 @@ String *Item_func_lpad::val_str(String *
   String *res= args[0]->val_str(&tmp_value);
   String *pad= args[2]->val_str(&lpad_str);
 
+  if (!res || args[1]->null_value || !pad ||  
+      ((count < 0) && !args[1]->unsigned_flag))
+    goto err;  
+  null_value=0;
   /* Assumes that the maximum length of a String is < INT_MAX32. */
   /* Set here so that rest of code sees out-of-bound value as such. */
-  if ((count > INT_MAX32) || args[1]->unsigned_flag)
+  if ((ulonglong) count > INT_MAX32)
     count= INT_MAX32;
 
-  if (!res || args[1]->null_value || !pad || count < 0)
-    goto err;
-  null_value=0;
   res_char_length= res->numchars();
 
   if (count <= res_char_length)

--- 1.123/mysql-test/r/func_str.result	2006-12-19 15:54:19 -07:00
+++ 1.124/mysql-test/r/func_str.result	2006-12-19 15:54:19 -07:00
@@ -1916,4 +1916,16 @@ CHAR(0xff,0x8f USING utf8) IS NULL
 Warnings:
 Error	1300	Invalid utf8 character string: 'FF8F'
 SET SQL_MODE=@orig_sql_mode;
+select substring('abc', cast(2 as unsigned int));
+substring('abc', cast(2 as unsigned int))
+bc
+select repeat('a', cast(2 as unsigned int));
+repeat('a', cast(2 as unsigned int))
+aa
+select rpad('abc', cast(5 as unsigned integer), 'x');
+rpad('abc', cast(5 as unsigned integer), 'x')
+abcxx
+select lpad('abc', cast(5 as unsigned integer), 'x');
+lpad('abc', cast(5 as unsigned integer), 'x')
+xxabc
 End of 5.0 tests

--- 1.97/mysql-test/t/func_str.test	2006-12-19 15:54:19 -07:00
+++ 1.98/mysql-test/t/func_str.test	2006-12-19 15:54:19 -07:00
@@ -991,5 +991,13 @@ SELECT CHAR(0xff,0x8f USING utf8) IS NUL
 
 SET SQL_MODE=@orig_sql_mode;
 
+#
+# Bug #24947: problem with some string function with unsigned int parameters
+#
+
+select substring('abc', cast(2 as unsigned int));
+select repeat('a', cast(2 as unsigned int));
+select rpad('abc', cast(5 as unsigned integer), 'x');
+select lpad('abc', cast(5 as unsigned integer), 'x');
 
 --echo End of 5.0 tests
Thread
bk commit into 5.0 tree (tsmith:1.2353) BUG#24947tim19 Dec