MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Ian Greenhoe Date:December 11 2006 1:10pm
Subject:bk commit into 5.0 tree (igreenhoe:1.2341) BUG#16864
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of greenman. When greenman 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-11 13:09:52-08:00, igreenhoe@stripped +34 -0
  Fix for Bug #16864 : strxmov in code
  
  Updated code to not use strxmov.  Instead it uses strxn0mov, which has the same behavior
  as strxnmov except that it has a guarantee of null termination.  (The maximum number of
  non-null characters written to the string is at most size - 1.)
  
  Update also include several private functions which allowed the use of strxn0mov by
  adding a size parameter.
  
  There are still several locations that cannot use strxn0mov.  These locations are in
  functions which take a pointer to a buffer, do not specify a size constraint, and
  are possibly referenced by code outside of our code base.

  client/mysql.cc@stripped, 2006-12-11 13:09:47-08:00, igreenhoe@stripped +1 -1
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  client/mysqlcheck.c@stripped, 2006-12-11 13:09:47-08:00, igreenhoe@stripped +19 -11
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)
    Added parameter to fix_table_name to support this.

  client/mysqldump.c@stripped, 2006-12-11 13:09:47-08:00, igreenhoe@stripped +45 -31
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)
    Added parameter to add_load_option to support this.

  client/mysqlimport.c@stripped, 2006-12-11 13:09:47-08:00, igreenhoe@stripped +14 -10
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)
    Added parameter to add_load_option to support this.

  client/mysqlshow.c@stripped, 2006-12-11 13:09:47-08:00, igreenhoe@stripped +4 -3
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  client/mysqltest.c@stripped, 2006-12-11 13:09:47-08:00, igreenhoe@stripped +7 -7
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  extra/comp_err.c@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +5 -4
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  include/m_string.h@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +1 -0
    Added definition for strxn0mov

  libmysql/Makefile.shared@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +1 -1
    Added reference to strxn0mov

  libmysqld/libmysqld.def@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +1 -0
    Added reference to strxn0mov

  myisammrg/myrg_create.c@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +3 -2
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  mysys/charset.c@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +2 -1
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  mysys/default.c@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +2 -2
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  mysys/mf_loadpath.c@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +1 -1
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  mysys/my_init.c@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +4 -3
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)
    Added parameter to SetEnvString to support this.

  mysys/raid.cc@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +3 -1
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  sql-common/client.c@stripped, 2006-12-11 13:09:49-08:00, igreenhoe@stripped +4 -3
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  sql/ha_myisam.cc@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +2 -2
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  sql/item.cc@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +6 -6
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  sql/log.cc@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +3 -3
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  sql/log_event.cc@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +7 -4
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  sql/mysqld.cc@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +11 -10
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  sql/sp.cc@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +2 -2
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  sql/sql_acl.cc@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +9 -9
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  sql/sql_base.cc@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +4 -3
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  sql/sql_db.cc@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +12 -11
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  sql/sql_parse.cc@stripped, 2006-12-11 13:09:48-08:00, igreenhoe@stripped +5 -3
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  sql/sql_show.cc@stripped, 2006-12-11 13:09:49-08:00, igreenhoe@stripped +9 -7
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  sql/sql_table.cc@stripped, 2006-12-11 13:09:49-08:00, igreenhoe@stripped +12 -9
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  sql/sql_trigger.cc@stripped, 2006-12-11 13:09:49-08:00, igreenhoe@stripped +5 -3
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  sql/table.cc@stripped, 2006-12-11 13:09:49-08:00, igreenhoe@stripped +6 -6
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

  strings/Makefile.am@stripped, 2006-12-11 13:09:49-08:00, igreenhoe@stripped +3 -3
    Added references to strxn0mov

  strings/strxn0mov.c@stripped, 2006-12-11 13:09:49-08:00, igreenhoe@stripped +64 -0
    Implementation of strxn0mov

  strings/strxn0mov.c@stripped, 2006-12-11 13:09:49-08:00, igreenhoe@stripped +0 -0

  tests/mysql_client_test.c@stripped, 2006-12-11 13:09:49-08:00, igreenhoe@stripped +23 -16
    Updated references strxmov to strxn0mov with appropriate limits.
    (strxn0mov is the same as strxnmov, but with a guarantee of null-termination)

# 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:	igreenhoe
# Host:	ra.greendragongames.com
# Root:	/home/greenman/workspace/mysql/bug-strxmov/my50-bug-strxmov

--- 1.229/client/mysql.cc	2006-12-11 13:10:00 -08:00
+++ 1.230/client/mysql.cc	2006-12-11 13:10:00 -08:00
@@ -2854,7 +2854,7 @@ com_edit(String *buffer,char *line __att
   if (!(editor = (char *)getenv("EDITOR")) &&
       !(editor = (char *)getenv("VISUAL")))
     editor = "vi";
-  strxmov(buff,editor," ",filename,NullS);
+  strxn0mov(buff, sizeof(buff), editor, " ", filename, NullS);
   (void) system(buff);
 
   MY_STAT stat_arg;

--- 1.252/client/mysqldump.c	2006-12-11 13:10:00 -08:00
+++ 1.253/client/mysqldump.c	2006-12-11 13:10:00 -08:00
@@ -77,7 +77,7 @@
 #define IGNORE_DATA 0x01 /* don't dump data for this table */
 #define IGNORE_INSERT_DELAYED 0x02 /* table doesn't support INSERT DELAYED */
 
-static char *add_load_option(char *ptr, const char *object,
+static char *add_load_option(char *ptr, uint ptr_size, const char *object,
                              const char *statement);
 static ulong find_set(TYPELIB *lib, const char *x, uint length,
                       char **err_pos, uint *err_len);
@@ -1455,15 +1455,17 @@ static uint dump_routines_for_db(char *d
                   Allocate memory for new query string: original string
                   from SHOW statement and version-specific comments.
                 */
-                query_str= alloc_query_str(strlen(row[2]) + 23);
+                uint length= strlen(row[2]) + 23;
+                query_str= alloc_query_str(length);
 
                 query_str_tail= strnmov(query_str, row[2],
                                         definer_begin - row[2]);
                 query_str_tail= strmov(query_str_tail, "*/ /*!50020");
                 query_str_tail= strnmov(query_str_tail, definer_begin,
                                         definer_end - definer_begin);
-                query_str_tail= strxmov(query_str_tail, "*/ /*!50003",
-                                        definer_end, NullS);
+                query_str_tail= strxn0mov(query_str_tail,
+                                        query_str + length - query_str_tail,
+                                        "*/ /*!50003", definer_end, NullS);
               }
             }
 
@@ -2099,18 +2101,18 @@ DELIMITER ;;\n");
   DBUG_VOID_RETURN;
 }
 
-static char *add_load_option(char *ptr,const char *object,
+static char *add_load_option(char *ptr, uint ptr_size, const char *object,
                              const char *statement)
 {
   if (object)
   {
     /* Don't escape hex constants */
     if (object[0] == '0' && (object[1] == 'x' || object[1] == 'X'))
-      ptr= strxmov(ptr," ",statement," ",object,NullS);
+      ptr= strxn0mov(ptr, ptr_size, " ", statement, " ", object, NullS);
     else
     {
       /* char constant; escape */
-      ptr= strxmov(ptr," ",statement," '",NullS);
+      ptr= strxn0mov(ptr, ptr_size, " ", statement, " '", NullS);
       ptr= field_escape(ptr,object,(uint) strlen(object));
       *ptr++= '\'';
     }
@@ -2254,11 +2256,16 @@ static void dump_table(char *table, char
 
     if (fields_terminated || enclosed || opt_enclosed || escaped)
       end= strmov(end, " FIELDS");
-    end= add_load_option(end, fields_terminated, " TERMINATED BY");
-    end= add_load_option(end, enclosed, " ENCLOSED BY");
-    end= add_load_option(end, opt_enclosed, " OPTIONALLY ENCLOSED BY");
-    end= add_load_option(end, escaped, " ESCAPED BY");
-    end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
+    end= add_load_option(end, query_buf + sizeof(query_buf) - end,
+                         fields_terminated, " TERMINATED BY");
+    end= add_load_option(end, query_buf + sizeof(query_buf) - end,
+                         enclosed, " ENCLOSED BY");
+    end= add_load_option(end, query_buf + sizeof(query_buf) - end,
+                         opt_enclosed, " OPTIONALLY ENCLOSED BY");
+    end= add_load_option(end, query_buf + sizeof(query_buf) - end,
+                         escaped, " ESCAPED BY");
+    end= add_load_option(end, query_buf + sizeof(query_buf) - end,
+                         lines_terminated, " LINES TERMINATED BY");
     *end= '\0';
 
     my_snprintf(buff, sizeof(buff), " FROM %s", result_table);
@@ -2271,9 +2278,11 @@ static void dump_table(char *table, char
       end= strmov(query, query_buf);
 
       if (where)
-        end= strxmov(end, " WHERE ", where, NullS);
+        end= strxn0mov(end, query_buf + sizeof(query_buf) - end, " WHERE ",
+                       where, NullS);
       if (order_by)
-        end= strxmov(end, " ORDER BY ", order_by, NullS);
+        end= strxn0mov(end, query_buf + sizeof(query_buf) - end, " ORDER BY ",
+                       order_by, NullS);
     }
     if (mysql_real_query(mysql, query, (uint) (end - query)))
     {
@@ -2306,7 +2315,8 @@ static void dump_table(char *table, char
           fprintf(md_result_file, "-- WHERE:  %s\n", where);
           check_io(md_result_file);
         }
-        end= strxmov(end, " WHERE ", where, NullS);
+        end= strxn0mov(end, query_buf + sizeof(query_buf) - end, " WHERE ",
+                       where, NullS);
       }
       if (order_by)
       {
@@ -2316,6 +2326,8 @@ static void dump_table(char *table, char
           check_io(md_result_file);
         }
         end= strxmov(end, " ORDER BY ", order_by, NullS);
+        end= strxn0mov(end, query_buf + sizeof(query_buf) - end, " ORDER BY ",
+                       order_by, NullS);
       }
     }
     if (!opt_xml && !opt_compact)
@@ -3431,8 +3443,9 @@ static char *primary_key_fields(const ch
   if (result_length)
   {
     char *end;
+    uint length= result_length + 10;
     /* result (terminating \0 is already in result_length) */
-    result= my_malloc(result_length + 10, MYF(MY_WME));
+    result= my_malloc(length, MYF(MY_WME));
     if (!result)
     {
       fprintf(stderr, "Error: Not enough memory to store ORDER BY clause\n");
@@ -3445,7 +3458,7 @@ static char *primary_key_fields(const ch
     while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1)
     {
       quoted_field= quote_name(row[4], buff, 0);
-      end= strxmov(end, ",", quoted_field, NullS);
+      end= strxn0mov(end, result + length - end, ",", quoted_field, NullS);
     }
   }
 
@@ -3619,11 +3632,12 @@ static my_bool get_view_structure(char *
     {
 
       ptr= search_buf;
-      search_len= (ulong)(strxmov(ptr, "WITH ", row[0],
+      search_len= (ulong)(strxn0mov(ptr, sizeof(search_buf), "WITH ", row[0],
                                   " CHECK OPTION", NullS) - ptr);
       ptr= replace_buf;
-      replace_len=(ulong)(strxmov(ptr, "*/\n/*!50002 WITH ", row[0],
-                                  " CHECK OPTION", NullS) - ptr);
+      replace_len= (ulong)(strxn0mov(ptr, sizeof(replace_buf),
+                                    "*/\n/*!50002 WITH ", row[0],
+                                    " CHECK OPTION", NullS) - ptr);
       replace(&ds_view, search_buf, search_len, replace_buf, replace_len);
     }
 
@@ -3644,19 +3658,19 @@ static my_bool get_view_structure(char *
 
       ptr= search_buf;
       search_len=
-        (ulong)(strxmov(ptr, "DEFINER=",
-                        quote_name(user_name_str, quoted_user_name_str, FALSE),
-                        "@",
-                        quote_name(host_name_str, quoted_host_name_str, FALSE),
-                        " SQL SECURITY ", row[2], NullS) - ptr);
+        (ulong)(strxn0mov(ptr, sizeof(search_buf), "DEFINER=",
+                         quote_name(user_name_str, quoted_user_name_str, FALSE),
+                         "@",
+                         quote_name(host_name_str, quoted_host_name_str, FALSE),
+                         " SQL SECURITY ", row[2], NullS) - ptr);
       ptr= replace_buf;
       replace_len=
-        (ulong)(strxmov(ptr, "*/\n/*!50013 DEFINER=",
-                        quote_name(user_name_str, quoted_user_name_str, FALSE),
-                        "@",
-                        quote_name(host_name_str, quoted_host_name_str, FALSE),
-                        " SQL SECURITY ", row[2],
-                        " */\n/*!50001", NullS) - ptr);
+        (ulong)(strxn0mov(ptr, sizeof(replace_buf), "*/\n/*!50013 DEFINER=",
+                         quote_name(user_name_str, quoted_user_name_str, FALSE),
+                         "@",
+                         quote_name(host_name_str, quoted_host_name_str, FALSE),
+                         " SQL SECURITY ", row[2],
+                         " */\n/*!50001", NullS) - ptr);
       replace(&ds_view, search_buf, search_len, replace_buf, replace_len);
     }
 

--- 1.60/client/mysqlimport.c	2006-12-11 13:10:00 -08:00
+++ 1.61/client/mysqlimport.c	2006-12-11 13:10:00 -08:00
@@ -33,7 +33,7 @@
 static void db_error_with_table(MYSQL *mysql, char *table);
 static void db_error(MYSQL *mysql);
 static char *field_escape(char *to,const char *from,uint length);
-static char *add_load_option(char *ptr,const char *object,
+static char *add_load_option(char *ptr, uint ptr_size, const char *object,
 			     const char *statement);
 
 static my_bool	verbose=0,lock_tables=0,ignore_errors=0,opt_delete=0,
@@ -316,12 +316,16 @@ static int write_to_table(char *filename
 
   if (fields_terminated || enclosed || opt_enclosed || escaped)
       end= strmov(end, " FIELDS");
-  end= add_load_option(end, fields_terminated, " TERMINATED BY");
-  end= add_load_option(end, enclosed, " ENCLOSED BY");
-  end= add_load_option(end, opt_enclosed,
-		       " OPTIONALLY ENCLOSED BY");
-  end= add_load_option(end, escaped, " ESCAPED BY");
-  end= add_load_option(end, lines_terminated, " LINES TERMINATED BY");
+  end= add_load_option(end, sql_statement + sizeof(sql_statement) - end,
+                       fields_terminated, " TERMINATED BY");
+  end= add_load_option(end, sql_statement + sizeof(sql_statement) - end,
+                       enclosed, " ENCLOSED BY");
+  end= add_load_option(end, sql_statement + sizeof(sql_statement) - end,
+                       opt_enclosed, " OPTIONALLY ENCLOSED BY");
+  end= add_load_option(end, sql_statement + sizeof(sql_statement) - end,
+                       escaped, " ESCAPED BY");
+  end= add_load_option(end, sql_statement + sizeof(sql_statement) - end,
+                       lines_terminated, " LINES TERMINATED BY");
   if (opt_ignore_lines >= 0)
     end= strmov(longlong10_to_str(opt_ignore_lines, 
 				  strmov(end, " IGNORE "),10), " LINES");
@@ -449,18 +453,18 @@ static void db_error(MYSQL *mysql)
 }
 
 
-static char *add_load_option(char *ptr, const char *object,
+static char *add_load_option(char *ptr, uint ptr_size, const char *object,
 			     const char *statement)
 {
   if (object)
   {
     /* Don't escape hex constants */
     if (object[0] == '0' && (object[1] == 'x' || object[1] == 'X'))
-      ptr= strxmov(ptr," ",statement," ",object,NullS);
+      ptr= strxn0mov(ptr, ptr_size, " ", statement, " ", object, NullS);
     else
     {
       /* char constant; escape */
-      ptr= strxmov(ptr," ",statement," '",NullS);
+      ptr= strxn0mov(ptr, ptr_size, " ", statement, " '", NullS);
       ptr= field_escape(ptr,object,(uint) strlen(object));
       *ptr++= '\'';
     }

--- 1.49/client/mysqlshow.c	2006-12-11 13:10:00 -08:00
+++ 1.50/client/mysqlshow.c	2006-12-11 13:10:00 -08:00
@@ -613,9 +613,10 @@ list_table_status(MYSQL *mysql,const cha
   MYSQL_RES *result;
   MYSQL_ROW row;
 
-  end=strxmov(query,"show table status from `",db,"`",NullS);
+  end= strxn0mov(query, sizeof(query), "show table status from `", db, "`",
+                NullS);
   if (wild && wild[0])
-    strxmov(end," like '",wild,"'",NullS);
+    strxn0mov(end, query + sizeof(query) - end, " like '", wild, "'", NullS);
   if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql)))
   {
     fprintf(stderr,"%s: Cannot get status for db: %s, table: %s: %s\n",
@@ -676,7 +677,7 @@ list_fields(MYSQL *mysql,const char *db,
 
   end=strmov(strmov(strmov(query,"show /*!32332 FULL */ columns from `"),table),"`");
   if (wild && wild[0])
-    strxmov(end," like '",wild,"'",NullS);
+    strxn0mov(end, query + sizeof(query) - end, " like '", wild, "'", NullS);
   if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql)))
   {
     fprintf(stderr,"%s: Cannot list columns in db: %s, table: %s: %s\n",

--- 1.24/extra/comp_err.c	2006-12-11 13:10:00 -08:00
+++ 1.25/extra/comp_err.c	2006-12-11 13:10:00 -08:00
@@ -283,11 +283,11 @@ static int create_sys_files(struct langu
       DBUG_RETURN(1);
     }
 
-    outfile_end= strxmov(outfile, DATADIRECTORY, 
+    outfile_end= strxn0mov(outfile, sizeof(outfile), DATADIRECTORY, 
                          tmp_lang->lang_long_name, NullS);
-    if (!my_stat(outfile, &stat_info,MYF(0)))
+    if (!my_stat(outfile, &stat_info, MYF(0)))
     {
-      if (my_mkdir(outfile, 0777,MYF(0)) < 0)
+      if (my_mkdir(outfile, 0777, MYF(0)) < 0)
       {
         fprintf(stderr, "Can't create output directory for %s\n", 
                 outfile);
@@ -295,7 +295,8 @@ static int create_sys_files(struct langu
       }
     }
 
-    strxmov(outfile_end, FN_ROOTDIR, OUTFILE, NullS);
+    strxn0mov(outfile_end, outfile + sizeof(outfile) - outfile_end,
+             FN_ROOTDIR, OUTFILE, NullS);
 
     if (!(to= my_fopen(outfile, O_WRONLY | FILE_BINARY, MYF(MY_WME))))
       DBUG_RETURN(1);

--- 1.38/include/m_string.h	2006-12-11 13:10:00 -08:00
+++ 1.39/include/m_string.h	2006-12-11 13:10:00 -08:00
@@ -184,6 +184,7 @@ extern	char *strxmov _VARARGS((char *dst
 extern	char *strxcpy _VARARGS((char *dst,const char *src, ...));
 extern	char *strxncat _VARARGS((char *dst,uint len, const char *src, ...));
 extern	char *strxnmov _VARARGS((char *dst,uint len, const char *src, ...));
+extern	char *strxn0mov _VARARGS((char *dst,uint len, const char *src, ...));
 extern	char *strxncpy _VARARGS((char *dst,uint len, const char *src, ...));
 
 /* Prototypes of normal stringfunctions (with may ours) */

--- 1.10/myisammrg/myrg_create.c	2006-12-11 13:10:00 -08:00
+++ 1.11/myisammrg/myrg_create.c	2006-12-11 13:10:00 -08:00
@@ -53,8 +53,9 @@ int myrg_create(const char *name, const 
   }
   if (insert_method != MERGE_INSERT_DISABLED)
   {
-    end=strxmov(buff,"#INSERT_METHOD=",
-		get_type(&merge_insert_method,insert_method-1),"\n",NullS);
+    end= strxn0mov(buff, sizeof(buff), "#INSERT_METHOD=",
+                  get_type(&merge_insert_method, insert_method - 1), "\n",
+                  NullS);
     if (my_write(file,buff,(uint) (end-buff),MYF(MY_WME | MY_NABP)))
         goto err;
   }

--- 1.148/mysys/charset.c	2006-12-11 13:10:00 -08:00
+++ 1.149/mysys/charset.c	2006-12-11 13:10:00 -08:00
@@ -487,7 +487,8 @@ static CHARSET_INFO *get_internal_charse
   {
     if (!(cs->state & MY_CS_COMPILED) && !(cs->state & MY_CS_LOADED))
     {
-      strxmov(get_charsets_dir(buf), cs->csname, ".xml", NullS);
+      char *end= get_charsets_dir(buf);
+      strxn0mov(end, buf + sizeof(buf) - end, cs->csname, ".xml", NullS);
       my_read_charset_file(buf,flags);
     }
     cs= (cs->state & MY_CS_AVAILABLE) ? cs : NULL;

--- 1.83/mysys/default.c	2006-12-11 13:10:00 -08:00
+++ 1.84/mysys/default.c	2006-12-11 13:10:00 -08:00
@@ -594,7 +594,7 @@ static int search_default_file_with_ext(
     end=convert_dirname(name, dir, NullS);
     if (dir[0] == FN_HOMELIB)		/* Add . to filenames in home */
       *end++='.';
-    strxmov(end,config_file,ext,NullS);
+    strxn0mov(end, name + sizeof(name) - end, config_file, ext, NullS);
   }
   else
   {
@@ -874,7 +874,7 @@ void my_print_default_files(const char *
 	end= convert_dirname(name, pos, NullS);
 	if (name[0] == FN_HOMELIB)	/* Add . to filenames in home */
 	  *end++='.';
-	strxmov(end, conf_file, *ext, " ", NullS);
+        strxn0mov(end, name + sizeof(name) - end, conf_file, *ext, " ", NullS);
 	fputs(name,stdout);
       }
     }

--- 1.9/mysys/mf_loadpath.c	2006-12-11 13:10:00 -08:00
+++ 1.10/mysys/mf_loadpath.c	2006-12-11 13:10:00 -08:00
@@ -48,7 +48,7 @@ my_string my_load_path(my_string to, con
       VOID(strmov(buff,path));			/* Return org file name */
   }
   else
-    VOID(strxmov(buff,own_path_prefix,path,NullS));
+    VOID(strxn0mov(buff, sizeof(buff), own_path_prefix, path, NullS));
   strmov(to,buff);
   DBUG_PRINT("exit",("to: %s",to));
   DBUG_RETURN(to);

--- 1.46/mysys/my_init.c	2006-12-11 13:10:00 -08:00
+++ 1.47/mysys/my_init.c	2006-12-11 13:10:00 -08:00
@@ -238,10 +238,10 @@ Voluntary context switches %ld, Involunt
 
 /* Crea la stringa d'ambiente */
 
-void setEnvString(char *ret, const char *name, const char *value)
+void setEnvString(char *ret, uint ret_size, const char *name, const char *value)
 {
   DBUG_ENTER("setEnvString");
-  strxmov(ret, name,"=",value,NullS);
+  strxn0mov(ret, ret_size, name, "=", value, NullS);
   DBUG_VOID_RETURN ;
 }
 
@@ -312,7 +312,8 @@ static void my_win_init(void)
   {
     char *my_env;
     /* Crea la stringa d'ambiente */
-    setEnvString(EnvString, NameValueBuffer, DataValueBuffer) ;
+    setEnvString(EnvString, sizeof(EnvString), NameValueBuffer,
+                 DataValueBuffer) ;
 
     /* Inserisce i dati come variabili d'ambiente */
     my_env=strdup(EnvString);  /* variable for putenv must be allocated ! */

--- 1.36/mysys/raid.cc	2006-12-11 13:10:00 -08:00
+++ 1.37/mysys/raid.cc	2006-12-11 13:10:00 -08:00
@@ -370,7 +370,9 @@ extern "C" {
 	  DBUG_RETURN(-1);
 	}
       }
-      strxmov(strend(new_end),"/",new_name+new_length,NullS);
+      strxn0mov(strend(new_end),
+               new_name_buff + sizeof(new_name_buff) - new_end, "/",
+               new_name + new_length, NullS);
       sprintf(old_end,"%02x/%s",i, old_name+old_length);
       if (my_redel(old_name_buff, new_name_buff, MyFlags))
 	error=1;

--- 1.170/sql/ha_myisam.cc	2006-12-11 13:10:00 -08:00
+++ 1.171/sql/ha_myisam.cc	2006-12-11 13:10:00 -08:00
@@ -108,8 +108,8 @@ static void mi_check_print_msg(MI_CHECK 
     my_message(ER_NOT_KEYFILE,msgbuf,MYF(MY_WME));
     return;
   }
-  length=(uint) (strxmov(name, param->db_name,".",param->table_name,NullS) -
-		 name);
+  length=(uint) (strxn0mov(name, sizeof(name), param->db_name, ".",
+                          param->table_name,NullS) - name);
   protocol->prepare_for_resend();
   protocol->store(name, length, system_charset_info);
   protocol->store(param->op_name, system_charset_info);

--- 1.245/sql/item.cc	2006-12-11 13:10:00 -08:00
+++ 1.246/sql/item.cc	2006-12-11 13:10:00 -08:00
@@ -1714,17 +1714,17 @@ const char *Item_ident::full_name() cons
     return field_name ? field_name : name ? name : "tmp_field";
   if (db_name && db_name[0])
   {
-    tmp=(char*) sql_alloc((uint) strlen(db_name)+(uint) strlen(table_name)+
-			  (uint) strlen(field_name)+3);
-    strxmov(tmp,db_name,".",table_name,".",field_name,NullS);
+    uint length= strlen(db_name) + strlen(table_name) + strlen(field_name) + 3;
+    tmp=(char*) sql_alloc(length);
+    strxn0mov(tmp, length, db_name, ".", table_name, ".", field_name, NullS);
   }
   else
   {
     if (table_name[0])
     {
-      tmp= (char*) sql_alloc((uint) strlen(table_name) +
-			     (uint) strlen(field_name) + 2);
-      strxmov(tmp, table_name, ".", field_name, NullS);
+      uint length= strlen(table_name) + strlen(field_name) + 2;
+      tmp= (char*) sql_alloc(length);
+      strxn0mov(tmp, length, table_name, ".", field_name, NullS);
     }
     else
       tmp= (char*) field_name;

--- 1.198/sql/log.cc	2006-12-11 13:10:00 -08:00
+++ 1.199/sql/log.cc	2006-12-11 13:10:00 -08:00
@@ -2030,8 +2030,8 @@ bool MYSQL_LOG::write(THD *thd,const cha
     }
     if (!query)
     {
-      end=strxmov(buff, "# administrator command: ",
-                  command_name[thd->command], NullS);
+      end= strxn0mov(buff, sizeof(buff), "# administrator command: ",
+                    command_name[thd->command], NullS);
       query_length=(ulong) (end-buff);
       query=buff;
     }
@@ -2285,7 +2285,7 @@ bool flush_error_log()
      On Windows is necessary a temporary file for to rename
      the current error file.
     */
-    strxmov(err_temp, err_renamed,"-tmp",NullS);
+    strxn0mov(err_temp, sizeof(err_temp), err_renamed, "-tmp", NullS);
     (void) my_delete(err_temp, MYF(0)); 
     if (freopen(err_temp,"a+",stdout))
     {

--- 1.216/sql/log_event.cc	2006-12-11 13:10:00 -08:00
+++ 1.217/sql/log_event.cc	2006-12-11 13:10:00 -08:00
@@ -3525,6 +3525,7 @@ void User_var_log_event::pack_info(Proto
   char *buf= 0;
   uint val_offset= 4 + name_len;
   uint event_len= val_offset;
+  uint buf_len= 0;
 
   if (is_null)
   {
@@ -3558,7 +3559,8 @@ void User_var_log_event::pack_info(Proto
     } 
     case STRING_RESULT:
       /* 15 is for 'COLLATE' and other chars */
-      buf= my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15, MYF(MY_WME));
+      buf_len= event_len + val_len * 2 + 1 + 2 * MY_CS_NAME_SIZE + 15;
+      buf= my_malloc(buf_len, MYF(MY_WME));
       CHARSET_INFO *cs;
       if (!(cs= get_charset(charset_number, MYF(0))))
       {
@@ -3567,10 +3569,11 @@ void User_var_log_event::pack_info(Proto
       }
       else
       {
-        char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
+        char *p= strxn0mov(buf + val_offset, buf_len - val_offset, "_",
+                          cs->csname, " ", NullS);
         p= str_to_hex(p, val, val_len);
-        p= strxmov(p, " COLLATE ", cs->name, NullS);
-        event_len= p-buf;
+        p= strxn0mov(p, buf + buf_len - p, " COLLATE ", cs->name, NullS);
+        event_len= p - buf;
       }
       break;
     case ROW_RESULT:

--- 1.582/sql/mysqld.cc	2006-12-11 13:10:00 -08:00
+++ 1.583/sql/mysqld.cc	2006-12-11 13:10:00 -08:00
@@ -1924,8 +1924,8 @@ static void getvolumeID(BYTE *volumeName
     NSS admin volumes directory.
   */
 
-  strxmov(path, (const char *) ADMIN_VOL_PATH, (const char *) volumeName,
-          NullS);
+  strxn0mov(path, sizeof(path), (const char *) ADMIN_VOL_PATH,
+           (const char *) volumeName, NullS);
   if ((status= zOpen(rootKey, zNSS_TASK, zNSPACE_LONG|zMODE_UTF8,
                      (BYTE *) path, zRR_READ_ACCESS, &fileKey)) != zOK)
   {
@@ -4320,7 +4320,7 @@ pthread_handler_t handle_connections_sha
       shared_memory_base_name is unique value for each server
       unique_part is unique value for each object (events and file-mapping)
   */
-  suffix_pos= strxmov(tmp,shared_memory_base_name,"_",NullS);
+  suffix_pos= strxn0mov(tmp, sizeof(tmp), shared_memory_base_name, "_", NullS);
   strmov(suffix_pos, "CONNECT_REQUEST");
   if ((smem_event_connect_request= CreateEvent(sa_event,
                                                FALSE, FALSE, tmp)) == 0)
@@ -4379,8 +4379,8 @@ pthread_handler_t handle_connections_sha
 	  unique_part is unique value for each object (events and file-mapping)
 	  number_of_connection is connection-number between server and client
     */
-    suffix_pos= strxmov(tmp,shared_memory_base_name,"_",connect_number_char,
-			 "_",NullS);
+    suffix_pos= strxn0mov(tmp, sizeof(tmp), shared_memory_base_name, "_",
+                         connect_number_char, "_", NullS);
     strmov(suffix_pos, "DATA");
     if ((handle_client_file_map=
          CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
@@ -4469,8 +4469,8 @@ errorconn:
     if (errmsg)
     {
       char buff[180];
-      strxmov(buff, "Can't create shared memory connection: ", errmsg, ".",
-	      NullS);
+      strxn0mov(buff, sizeof(buff), "Can't create shared memory connection: ",
+               errmsg, ".", NullS);
       sql_perror(buff);
     }
     if (handle_client_file_map)
@@ -4495,7 +4495,8 @@ error:
   if (errmsg)
   {
     char buff[180];
-    strxmov(buff, "Can't create shared memory service: ", errmsg, ".", NullS);
+    strxn0mov(buff, sizeof(buff), "Can't create shared memory service: ",
+             errmsg, ".", NullS);
     sql_perror(buff);
   }
   my_security_attr_free(sa_event);
@@ -7287,8 +7288,8 @@ static void get_options(int argc,char **
 
 static void set_server_version(void)
 {
-  char *end= strxmov(server_version, MYSQL_SERVER_VERSION,
-                     MYSQL_SERVER_SUFFIX_STR, NullS);
+  char *end= strxn0mov(server_version, sizeof(server_version),
+                      MYSQL_SERVER_VERSION, MYSQL_SERVER_SUFFIX_STR, NullS);
 #ifdef EMBEDDED_LIBRARY
   end= strmov(end, "-embedded");
 #endif

--- 1.214/sql/sql_acl.cc	2006-12-11 13:10:00 -08:00
+++ 1.215/sql/sql_acl.cc	2006-12-11 13:10:00 -08:00
@@ -2522,7 +2522,7 @@ static int replace_table_table(THD *thd,
   byte user_key[MAX_KEY_LENGTH];
   DBUG_ENTER("replace_table_table");
 
-  strxmov(grantor, thd->security_ctx->user, "@",
+  strxn0mov(grantor, sizeof(grantor), thd->security_ctx->user, "@",
           thd->security_ctx->host_or_ip, NullS);
 
   /*
@@ -2645,7 +2645,7 @@ static int replace_routine_table(THD *th
     DBUG_RETURN(-1);
   }
 
-  strxmov(grantor, thd->security_ctx->user, "@",
+  strxn0mov(grantor, sizeof(grantor), thd->security_ctx->user, "@",
           thd->security_ctx->host_or_ip, NullS);
 
   /*
@@ -3980,7 +3980,7 @@ err:
     char buff[1024];
     const char *command="";
     if (table)
-      strxmov(buff, table->db, ".", table->table_name, NullS);
+      strxn0mov(buff, sizeof(buff), table->db, ".", table->table_name, NullS);
     if (want_access & EXECUTE_ACL)
       command= "execute";
     else if (want_access & ALTER_PROC_ACL)
@@ -4191,8 +4191,8 @@ bool mysql_show_grants(THD *thd,LEX_USER
   List<Item> field_list;
   field->name=buff;
   field->max_length=1024;
-  strxmov(buff,"Grants for ",lex_user->user.str,"@",
-	  lex_user->host.str,NullS);
+  strxn0mov(buff, sizeof(buff), "Grants for ", lex_user->user.str, "@",
+           lex_user->host.str, NullS);
   field_list.push_back(field);
   if (protocol->send_fields(&field_list,
                             Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
@@ -5901,7 +5901,7 @@ int fill_schema_user_privileges(THD *thd
     if (!(want_access & GRANT_ACL))
       is_grantable= "NO";
 
-    strxmov(buff,"'",user,"'@'",host,"'",NullS);
+    strxn0mov(buff, sizeof(buff), "'", user, "'@'", host, "'", NullS);
     if (!(want_access & ~GRANT_ACL))
       update_schema_privilege(table, buff, 0, 0, 0, 0,
                               STRING_WITH_LEN("USAGE"), is_grantable);
@@ -5964,7 +5964,7 @@ int fill_schema_schema_privileges(THD *t
       {
         is_grantable= "NO";
       }
-      strxmov(buff,"'",user,"'@'",host,"'",NullS);
+      strxn0mov(buff, sizeof(buff), "'", user, "'@'", host, "'", NullS);
       if (!(want_access & ~GRANT_ACL))
         update_schema_privilege(table, buff, acl_db->db, 0, 0,
                                 0, STRING_WITH_LEN("USAGE"), is_grantable);
@@ -6030,7 +6030,7 @@ int fill_schema_table_privileges(THD *th
       if (!(table_access & GRANT_ACL))
         is_grantable= "NO";
 
-      strxmov(buff, "'", user, "'@'", host, "'", NullS);
+      strxn0mov(buff, sizeof(buff), "'", user, "'@'", host, "'", NullS);
       if (!test_access)
         update_schema_privilege(table, buff, grant_table->db, grant_table->tname,
                                 0, 0, STRING_WITH_LEN("USAGE"), is_grantable);
@@ -6092,7 +6092,7 @@ int fill_schema_column_privileges(THD *t
         is_grantable= "NO";
 
       ulong test_access= table_access & ~GRANT_ACL;
-      strxmov(buff, "'", user, "'@'", host, "'", NullS);
+      strxn0mov(buff, sizeof(buff), "'", user, "'@'", host, "'", NullS);
       if (!test_access)
         continue;
       else

--- 1.358/sql/sql_base.cc	2006-12-11 13:10:00 -08:00
+++ 1.359/sql/sql_base.cc	2006-12-11 13:10:00 -08:00
@@ -1900,7 +1900,7 @@ static int open_unireg_entry(THD *thd, T
   uint discover_retry_count= 0;
   DBUG_ENTER("open_unireg_entry");
 
-  strxmov(path, mysql_data_home, "/", db, "/", name, NullS);
+  strxn0mov(path, sizeof(path), mysql_data_home, "/", db, "/", name, NullS);
   while ((error= openfrm(thd, path, alias,
 		         (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
 			         HA_GET_INDEX | HA_TRY_READ_ONLY |
@@ -2023,8 +2023,9 @@ static int open_unireg_entry(THD *thd, T
       uint query_buf_size= 20 + 2*NAME_LEN + 1;
       if ((query= (char*)my_malloc(query_buf_size,MYF(MY_WME))))
       {
-        end = strxmov(strmov(query, "DELETE FROM `"),
-                      db,"`.`",name,"`", NullS);
+        end= strmov(query, "DELETE FROM `");
+        end= strxn0mov(end, query + query_buf_size - end, db, "`.`", name, "`",
+                      NullS);
         Query_log_event qinfo(thd, query, (ulong)(end-query), 0, FALSE);
         mysql_bin_log.write(&qinfo);
         my_free(query, MYF(0));

--- 1.133/sql/sql_db.cc	2006-12-11 13:10:00 -08:00
+++ 1.134/sql/sql_db.cc	2006-12-11 13:10:00 -08:00
@@ -453,7 +453,7 @@ bool load_db_opt_by_name(THD *thd, const
 bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
                      bool silent)
 {
-  char	 path[FN_REFLEN+16];
+  char	 path[FN_REFLEN + 16];
   long result= 1;
   int error= 0;
   MY_STAT stat_info;
@@ -489,7 +489,7 @@ bool mysql_create_db(THD *thd, char *db,
   VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
 
   /* Check directory */
-  strxmov(path, mysql_data_home, "/", db, NullS);
+  strxn0mov(path, sizeof(path), mysql_data_home, "/", db, NullS);
   path_len= unpack_dirname(path,path);    // Convert if not unix
   path[path_len-1]= 0;                    // Remove last '/' from path
 
@@ -552,8 +552,8 @@ bool mysql_create_db(THD *thd, char *db,
     if (!thd->query)				// Only in replication
     {
       query= 	     path;
-      query_length= (uint) (strxmov(path,"create database `", db, "`", NullS) -
-			    path);
+      query_length= (uint) (strxn0mov(path, sizeof(path), "create database `",
+                                     db, "`", NullS) - path);
     }
     else
     {
@@ -626,7 +626,8 @@ bool mysql_alter_db(THD *thd, const char
   VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
 
   /* Check directory */
-  strxmov(path, mysql_data_home, "/", db, "/", MY_DB_OPT_FILE, NullS);
+  strxn0mov(path, sizeof(path), mysql_data_home, "/", db, "/", MY_DB_OPT_FILE,
+           NullS);
   fn_format(path, path, "", "", MYF(MY_UNPACK_FILENAME));
   if ((error=write_db_opt(thd, path, create_info)))
     goto exit;
@@ -760,8 +761,8 @@ bool mysql_rm_db(THD *thd,char *db,bool 
     {
       /* The client used the old obsolete mysql_drop_db() call */
       query= path;
-      query_length= (uint) (strxmov(path, "drop database `", db, "`",
-                                     NullS) - path);
+      query_length= (uint) (strxn0mov(path, sizeof(path), "drop database `", db,
+                                     "`", NullS) - path);
     }
     else
     {
@@ -887,7 +888,7 @@ static long mysql_rm_known_files(THD *th
       String *dir;
       uint length;
 
-      strxmov(newpath,org_path,"/",file->name,NullS);
+      strxn0mov(newpath, sizeof(newpath), org_path, "/", file->name, NullS);
       length= unpack_filename(newpath,newpath);
       if ((new_dirp = my_dir(newpath,MYF(MY_DONT_SORT))))
       {
@@ -910,7 +911,7 @@ static long mysql_rm_known_files(THD *th
       /* .frm archive */
       char newpath[FN_REFLEN];
       MY_DIR *new_dirp;
-      strxmov(newpath, org_path, "/", "arc", NullS);
+      strxn0mov(newpath, sizeof(newpath), org_path, "/", "arc", NullS);
       (void) unpack_filename(newpath, newpath);
       if ((new_dirp = my_dir(newpath, MYF(MY_DONT_SORT))))
       {
@@ -949,7 +950,7 @@ static long mysql_rm_known_files(THD *th
     }
     else
     {
-      strxmov(filePath, org_path, "/", file->name, NullS);
+      strxn0mov(filePath, sizeof(filePath), org_path, "/", file->name, NullS);
       if (my_delete_with_symlink(filePath,MYF(MY_WME)))
       {
 	goto err;
@@ -1101,7 +1102,7 @@ static long mysql_rm_arc_files(THD *thd,
       found_other_files++;
       continue;
     }
-    strxmov(filePath, org_path, "/", file->name, NullS);
+    strxn0mov(filePath, sizeof(filePath), org_path, "/", file->name, NullS);
     if (my_delete_with_symlink(filePath,MYF(MY_WME)))
     {
       goto err;

--- 1.594/sql/sql_parse.cc	2006-12-11 13:10:00 -08:00
+++ 1.595/sql/sql_parse.cc	2006-12-11 13:10:00 -08:00
@@ -5754,7 +5754,7 @@ void create_select_for_variable(const ch
   */
   if ((var= get_system_var(thd, OPT_SESSION, tmp, null_lex_string)))
   {
-    end= strxmov(buff, "@@session.", var_name, NullS);
+    end= strxn0mov(buff, sizeof(buff), "@@session.", var_name, NullS);
     var->set_name(buff, end-buff, system_charset_info);
     add_item_to_list(thd, var);
   }
@@ -6895,6 +6895,7 @@ static bool append_file_to_dir(THD *thd,
 			       const char *table_name)
 {
   char buff[FN_REFLEN],*ptr, *end;
+  uint length;
   if (!*filename_ptr)
     return 0;					// nothing to do
 
@@ -6908,10 +6909,11 @@ static bool append_file_to_dir(THD *thd,
   /* Fix is using unix filename format on dos */
   strmov(buff,*filename_ptr);
   end=convert_dirname(buff, *filename_ptr, NullS);
-  if (!(ptr=thd->alloc((uint) (end-buff)+(uint) strlen(table_name)+1)))
+  length= end - buff + strlen(table_name) + 1;
+  if (!(ptr=thd->alloc(length)))
     return 1;					// End of memory
   *filename_ptr=ptr;
-  strxmov(ptr,buff,table_name,NullS);
+  strxn0mov(ptr, length, buff, table_name, NullS);
   return 0;
 }
 

--- 1.333/sql/sql_show.cc	2006-12-11 13:10:00 -08:00
+++ 1.334/sql/sql_show.cc	2006-12-11 13:10:00 -08:00
@@ -2219,7 +2219,8 @@ int get_all_tables(THD *thd, TABLE_LIST 
       }
       else
       {
-        strxmov(path, mysql_data_home, "/", base_name, NullS);
+        strxn0mov(path, sizeof(path), mysql_data_home, "/", base_name,
+                 NullS);
         end= path + (len= unpack_dirname(path,path));
         len= FN_LEN - len;
         find_files_result res= find_files(thd, &files, base_name, 
@@ -2560,9 +2561,9 @@ static int get_schema_tables_record(THD 
     if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
       ptr=strmov(ptr," delay_key_write=1");
     if (share->row_type != ROW_TYPE_DEFAULT)
-      ptr=strxmov(ptr, " row_format=", 
-                  ha_row_type[(uint) share->row_type],
-                  NullS);
+      ptr=strxn0mov(ptr, option_buff + sizeof(option_buff) - ptr,
+                   " row_format=", ha_row_type[(uint) share->row_type],
+                   NullS);
     if (file->raid_type)
     {
       char buff[100];
@@ -2994,7 +2995,7 @@ int fill_schema_proc(THD *thd, TABLE_LIS
   Open_tables_state open_tables_state_backup;
   DBUG_ENTER("fill_schema_proc");
 
-  strxmov(definer, thd->security_ctx->priv_user, "@",
+  strxn0mov(definer, sizeof(definer), thd->security_ctx->priv_user, "@",
           thd->security_ctx->priv_host, NullS);
   /* We use this TABLE_LIST instance only for checking of privileges. */
   bzero((char*) &proc_tables,sizeof(proc_tables));
@@ -3175,8 +3176,9 @@ static int get_schema_views_record(THD *
       table->field[5]->store(STRING_WITH_LEN("YES"), cs);
     else
       table->field[5]->store(STRING_WITH_LEN("NO"), cs);
-    definer_len= (strxmov(definer, tables->definer.user.str, "@",
-                          tables->definer.host.str, NullS) - definer);
+    definer_len= (strxn0mov(definer, sizeof(definer),
+                           tables->definer.user.str, "@",
+                           tables->definer.host.str, NullS) - definer);
     table->field[6]->store(definer, definer_len, cs);
     if (tables->view_suid)
       table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs);

--- 1.328/sql/sql_table.cc	2006-12-11 13:10:00 -08:00
+++ 1.329/sql/sql_table.cc	2006-12-11 13:10:00 -08:00
@@ -2067,7 +2067,8 @@ static int prepare_for_repair(THD* thd, 
   if (!ext[0] || !ext[1])
     goto end;					// No data file
 
-  strxmov(from, table->s->path, ext[1], NullS);	// Name of data file
+  strxn0mov(from, sizeof(from), table->s->path, ext[1], NullS);
+     // Name of data file
   if (!my_stat(from, &stat_info, MYF(0)))
     goto end;				// Can't use USE_FRM flag
 
@@ -2184,7 +2185,7 @@ static bool mysql_admin_table(THD* thd, 
     char* db = table->db;
     bool fatal_error=0;
 
-    strxmov(table_name, db, ".", table->table_name, NullS);
+    strxn0mov(table_name, sizeof(table_name), db, ".", table->table_name, NullS);
     thd->open_options|= extra_open_options;
     table->lock_type= lock_type;
     /* open only one table from local list of command */
@@ -2246,7 +2247,7 @@ static bool mysql_admin_table(THD* thd, 
       if (table->view &&
           view_checksum(thd, table) == HA_ADMIN_WRONG_CHECKSUM)
       {
-        strxmov(buf, err_msg, "; ", ER(ER_VIEW_CHECKSUM), NullS);
+        strxn0mov(buf, sizeof(buf), err_msg, "; ", ER(ER_VIEW_CHECKSUM), NullS);
         err_msg= (const char *)buf;
       }
       protocol->store(err_msg, system_charset_info);
@@ -2715,11 +2716,12 @@ bool mysql_create_like_table(THD* thd, T
     goto err;
 
   if ((tmp_table= find_temporary_table(thd, src_db, src_table)))
-    strxmov(src_path, (*tmp_table)->s->path, reg_ext, NullS);
+    strxn0mov(src_path, sizeof(src_path), (*tmp_table)->s->path, reg_ext,
+             NullS);
   else
   {
-    strxmov(src_path, mysql_data_home, "/", src_db, "/", src_table,
-	    reg_ext, NullS);
+    strxn0mov(src_path, sizeof(src_path), mysql_data_home, "/", src_db,
+             "/", src_table, reg_ext, NullS);
     /* Resolve symlinks (for windows) */
     fn_format(src_path, src_path, "", "", MYF(MY_UNPACK_FILENAME));
     if (lower_case_table_names)
@@ -2759,8 +2761,8 @@ bool mysql_create_like_table(THD* thd, T
   }
   else
   {
-    strxmov(dst_path, mysql_data_home, "/", db, "/", table_name,
-	    reg_ext, NullS);
+    strxn0mov(dst_path, sizeof(dst_path), mysql_data_home, "/", db, "/",
+             table_name, reg_ext, NullS);
     fn_format(dst_path, dst_path, "", "", MYF(MY_UNPACK_FILENAME));
     if (!access(dst_path, F_OK))
       goto table_exists;
@@ -4110,7 +4112,8 @@ bool mysql_checksum_table(THD *thd, TABL
     char table_name[NAME_LEN*2+2];
     TABLE *t;
 
-    strxmov(table_name, table->db ,".", table->table_name, NullS);
+    strxn0mov(table_name, sizeof(table_name), table->db, ".", table->table_name,
+             NullS);
 
     t= table->table= open_ltable(thd, table, TL_READ);
     thd->clear_error();			// these errors shouldn't get client

--- 1.240/sql/table.cc	2006-12-11 13:10:00 -08:00
+++ 1.241/sql/table.cc	2006-12-11 13:10:00 -08:00
@@ -1147,10 +1147,10 @@ ulong make_new_entry(File file, uchar *f
   if (n_length == 1 )
   {						/* First name */
     length++;
-    VOID(strxmov(buff,"/",newname,"/",NullS));
+    VOID(strxn0mov(buff, sizeof(buff), "/", newname, "/", NullS));
   }
   else
-    VOID(strxmov(buff,newname,"/",NullS)); /* purecov: inspected */
+    VOID(strxn0mov(buff, sizeof(buff), newname, "/", NullS)); /* purecov: inspected */
   VOID(my_seek(file,63L+(ulong) n_length,MY_SEEK_SET,MYF(0)));
   if (my_write(file,(byte*) buff,(uint) length+1,MYF(MY_NABP+MY_WME)) ||
       (names && my_write(file,(byte*) (*formnames->type_names+n_length-1),
@@ -1521,10 +1521,10 @@ void update_create_info_from_table(HA_CR
 int
 rename_file_ext(const char * from,const char * to,const char * ext)
 {
-  char from_b[FN_REFLEN],to_b[FN_REFLEN];
-  VOID(strxmov(from_b,from,ext,NullS));
-  VOID(strxmov(to_b,to,ext,NullS));
-  return (my_rename(from_b,to_b,MYF(MY_WME)));
+  char from_b[FN_REFLEN], to_b[FN_REFLEN];
+  VOID(strxn0mov(from_b, sizeof(from_b), from, ext, NullS));
+  VOID(strxn0mov(to_b, sizeof(to_b), to, ext, NullS));
+  return (my_rename(from_b, to_b, MYF(MY_WME)));
 }
 
 

--- 1.51/strings/Makefile.am	2006-12-11 13:10:00 -08:00
+++ 1.52/strings/Makefile.am	2006-12-11 13:10:00 -08:00
@@ -22,19 +22,19 @@ pkglib_LIBRARIES =	libmystrings.a
 # Exact one of ASSEMBLER_X
 if ASSEMBLER_x86
 ASRCS		= strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
-CSRCS		= bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c
+CSRCS		= bfill.c bmove.c bmove512.c bchange.c strxnmov.c strxn0mov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c
 else
 if ASSEMBLER_sparc32
 # These file MUST all be on the same line!! Otherwise automake
 # generats a very broken makefile
 ASRCS		= bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s
-CSRCS		= strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c
+CSRCS		= strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c strxn0mov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c
 else
 #no assembler
 ASRCS		=
 # These file MUST all be on the same line!! Otherwise automake
 # generats a very broken makefile
-CSRCS		= strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c
+CSRCS		= strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c strxn0mov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c
 endif
 endif
 

--- 1.60/sql/sql_trigger.cc	2006-12-11 13:10:00 -08:00
+++ 1.61/sql/sql_trigger.cc	2006-12-11 13:10:00 -08:00
@@ -529,8 +529,9 @@ bool Table_triggers_list::create_trigger
     definer_host= lex->definer->host;
 
     trg_definer->str= trg_definer_holder;
-    trg_definer->length= strxmov(trg_definer->str, definer_user.str, "@",
-                                 definer_host.str, NullS) - trg_definer->str;
+    trg_definer->length= strxn0mov(trg_definer->str, sizeof(trg_definer_holder),
+                                   definer_user.str, "@", definer_host.str,
+                                   NullS) - trg_definer->str;
   }
   else
   {
@@ -956,7 +957,8 @@ bool Table_triggers_list::check_n_load(T
               alloc_root(&table->mem_root, triggers->sroutines_key.length)))
         DBUG_RETURN(1);
       triggers->sroutines_key.str[0]= TYPE_ENUM_TRIGGER;
-      strxmov(triggers->sroutines_key.str+1, db, ".", table_name, NullS);
+      strxn0mov(triggers->sroutines_key.str + 1,
+               triggers->sroutines_key.length - 1, db, ".", table_name, NullS);
 
       /*
         TODO: This could be avoided if there is no triggers

--- 1.106/sql-common/client.c	2006-12-11 13:10:00 -08:00
+++ 1.107/sql-common/client.c	2006-12-11 13:10:00 -08:00
@@ -417,7 +417,8 @@ HANDLE create_shared_memory(MYSQL *mysql
     shared_memory_base_name is unique value for each server
     unique_part is uniquel value for each object (events and file-mapping)
   */
-  suffix_pos = strxmov(tmp,shared_memory_base_name,"_",NullS);
+  suffix_pos= strxn0mov(tmp, sizeof(tmp), shared_memory_base_name, "_",
+                       NullS);
   strmov(suffix_pos, "CONNECT_REQUEST");
   if (!(event_connect_request= OpenEvent(event_access_rights, FALSE, tmp)))
   {
@@ -471,8 +472,8 @@ HANDLE create_shared_memory(MYSQL *mysql
     unique_part is uniquel value for each object (events and file-mapping)
     number_of_connection is number of connection between server and client
   */
-  suffix_pos = strxmov(tmp,shared_memory_base_name,"_",connect_number_char,
-		       "_",NullS);
+  suffix_pos= strxn0mov(tmp, sizeof(tmp), shared_memory_base_name, "_",
+                       connect_number_char, "_", NullS);
   strmov(suffix_pos, "DATA");
   if ((handle_file_map = OpenFileMapping(FILE_MAP_WRITE,FALSE,tmp)) == NULL)
   {
--- New file ---
+++ strings/strxn0mov.c	06/12/11 13:09:49
/* Copyright (C) 2002 MySQL AB
   
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.
   
   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.
   
   You should have received a copy of the GNU Library General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
   MA 02111-1307, USA */

/*  File   : strxn0mov.c
    Author : Richard A. O'Keefe wrote strxnmov, modifed by Ian Greenhoe
    Updated: 27 Nov 2006
    Defines: strxn0mov()

    strxn0mov(dst, len, src1, ..., srcn, NullS)
    moves the first len characters of the concatenation of src1,...,srcn
    to dst.  If there aren't that many characters, a NUL character will
    be added to the end of dst to terminate it properly.  This gives the
    same effect as calling strxcpy(buff, src1, ..., srcn, NullS) with a
    large enough buffer, and then calling strnmov(dst, buff, len).
    It is just like strnmov except that it concatenates multiple sources.
    Beware: the last argument should be the null character pointer.
    Take VERY great care not to omit it!  Also be careful to use NullS
    and NOT to use 0, as on some machines 0 is not the same size as a
    character pointer, or not the same bit pattern as NullS.

	Note: strxn0mov differs from strxnmov in that it gaurantees that
	      a NUL will be written to the end of dst.
*/

#include <my_global.h>
#include "m_string.h"
#include <stdarg.h>

char *strxn0mov(char *dst,uint len, const char *src, ...)
{
  va_list pvar;
  char *end_of_dst=dst+len-1;

  va_start(pvar,src);
  while (src != NullS)
  {
    do
    {
      if (dst == end_of_dst)
        goto end;
    }
    while ((*dst++ = *src++));
    dst--;
    src = va_arg(pvar, char *);
  }
end:
  *dst=0;
  va_end(pvar);
  return dst;
}


--- 1.57/client/mysqlcheck.c	2006-12-11 13:10:00 -08:00
+++ 1.58/client/mysqlcheck.c	2006-12-11 13:10:00 -08:00
@@ -181,7 +181,7 @@ static void dbDisconnect(char *host);
 static void DBerror(MYSQL *mysql, const char *when);
 static void safe_exit(int error);
 static void print_result();
-static char *fix_table_name(char *dest, char *src);
+static char *fix_table_name(char *dest, uint dest_alloc_size, char *src);
 int what_to_do = 0;
 
 #include <help_start.h>
@@ -409,18 +409,21 @@ static int process_selected_tables(char 
     */	  
     char *table_names_comma_sep, *end;
     int i, tot_length = 0;
+    uint length;
 
     for (i = 0; i < tables; i++)
       tot_length += strlen(*(table_names + i)) + 4;
 
+    length= sizeof(char) * tot_length + 4;
     if (!(table_names_comma_sep = (char *)
-	  my_malloc((sizeof(char) * tot_length) + 4, MYF(MY_WME))))
+          my_malloc(length, MYF(MY_WME))))
       return 1;
 
     for (end = table_names_comma_sep + 1; tables > 0;
 	 tables--, table_names++)
     {
-      end= fix_table_name(end, *table_names);
+      end= fix_table_name(end, table_names_comma_sep + length - end,
+                          *table_names);
       *end++= ',';
     }
     *--end = 0;
@@ -434,8 +437,9 @@ static int process_selected_tables(char 
 } /* process_selected_tables */
 
 
-static char *fix_table_name(char *dest, char *src)
+static char *fix_table_name(char *dest, uint dest_alloc_size, char *src)
 {
+  char *start= dest; 
   char *db_sep;
 
   *dest++= '`';
@@ -445,7 +449,7 @@ static char *fix_table_name(char *dest, 
     dest= strmov(dest, "`.`");
     src= db_sep + 1;
   }
-  dest= strxmov(dest, src, "`", NullS);
+  dest= strxn0mov(dest, start + dest_alloc_size - dest, src, "`", NullS);
   return dest;
 }
 
@@ -471,13 +475,15 @@ static int process_all_tables_in_db(char
      */
 
     char *tables, *end;
-    uint tot_length = 0;
+    uint tot_length= 0;
+    uint length;
 
     while ((row = mysql_fetch_row(res)))
       tot_length += strlen(row[0]) + 4;
     mysql_data_seek(res, 0);
 
-    if (!(tables=(char *) my_malloc(sizeof(char)*tot_length+4, MYF(MY_WME))))
+    length= sizeof(char) * tot_length + 4;
+    if (!(tables=(char *) my_malloc(length, MYF(MY_WME))))
     {
       mysql_free_result(res);
       return 1;
@@ -487,7 +493,7 @@ static int process_all_tables_in_db(char
       /* Skip tables with an engine of NULL (probably a view). */
       if (row[1])
       {
-        end= fix_table_name(end, row[0]);
+        end= fix_table_name(end, tables + length - end, row[0]);
         *end++= ',';
       }
     }
@@ -529,6 +535,7 @@ static int handle_request_for_tables(cha
   char *query, *end, options[100], message[100];
   uint query_length= 0;
   const char *op = 0;
+  uint alloc_length;
 
   options[0] = 0;
   end = options;
@@ -556,7 +563,8 @@ static int handle_request_for_tables(cha
     break;
   }
 
-  if (!(query =(char *) my_malloc((sizeof(char)*(length+110)), MYF(MY_WME))))
+  alloc_length= sizeof(char) * (length + 110);
+  if (!(query= (char *) my_malloc(alloc_length, MYF(MY_WME))))
     return 1;
   if (opt_all_in_1)
   {
@@ -569,8 +577,8 @@ static int handle_request_for_tables(cha
     char *ptr;
 
     ptr= strmov(strmov(query, op), " TABLE ");
-    ptr= fix_table_name(ptr, tables);
-    ptr= strxmov(ptr, " ", options, NullS);
+    ptr= fix_table_name(ptr, query + alloc_length - ptr, tables);
+    ptr= strxn0mov(ptr, query + alloc_length - ptr, " ", options, NullS);
     query_length= (uint) (ptr - query);
   }
   if (mysql_real_query(sock, query, query_length))

--- 1.16/libmysqld/libmysqld.def	2006-12-11 13:10:01 -08:00
+++ 1.17/libmysqld/libmysqld.def	2006-12-11 13:10:01 -08:00
@@ -119,6 +119,7 @@ EXPORTS
 	print_defaults
 	find_type
 	strxnmov
+	strxn0mov
 	strend
 	my_fopen
 	my_fclose

--- 1.267/client/mysqltest.c	2006-12-11 13:10:01 -08:00
+++ 1.268/client/mysqltest.c	2006-12-11 13:10:01 -08:00
@@ -941,7 +941,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, c
 
   if (!test_if_hard_path(fname))
   {
-    strxmov(eval_file, opt_basedir, fname, NullS);
+    strxn0mov(eval_file, sizeof(eval_file), opt_basedir, fname, NullS);
     fn_format(eval_file, eval_file, "", "", MY_UNPACK_FILENAME);
   }
   else
@@ -1240,7 +1240,7 @@ void var_set(const char *var_name, const
       v->int_dirty= 0;
       v->str_val_len= strlen(v->str_val);
     }
-    strxmov(buf, v->name, "=", v->str_val, NullS);
+    strxn0mov(buf, sizeof(buf), v->name, "=", v->str_val, NullS);
     if (!(v->env_s= my_strdup(buf, MYF(MY_WME))))
       die("Out of memory");
     putenv(v->env_s);
@@ -1433,7 +1433,7 @@ int open_file(const char *name)
   DBUG_PRINT("enter", ("name: %s", name));
   if (!test_if_hard_path(name))
   {
-    strxmov(buff, opt_basedir, name, NullS);
+    strxn0mov(buff, sizeof(buff), opt_basedir, name, NullS);
     name=buff;
   }
   fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
@@ -4002,7 +4002,7 @@ void read_embedded_server_arguments(cons
 
   if (!test_if_hard_path(name))
   {
-    strxmov(buff, opt_basedir, name, NullS);
+    strxn0mov(buff, sizeof(buff), opt_basedir, name, NullS);
     name=buff;
   }
   fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
@@ -4054,7 +4054,7 @@ get_one_option(int optid, const struct m
     char buff[FN_REFLEN];
     if (!test_if_hard_path(argument))
     {
-      strxmov(buff, opt_basedir, argument, NullS);
+      strxn0mov(buff, sizeof(buff), opt_basedir, argument, NullS);
       argument= buff;
     }
     fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
@@ -4071,7 +4071,7 @@ get_one_option(int optid, const struct m
     static char buff[FN_REFLEN];
     if (!test_if_hard_path(argument))
     {
-      strxmov(buff, opt_basedir, argument, NullS);
+      strxn0mov(buff, sizeof(buff), opt_basedir, argument, NullS);
       argument= buff;
     }
     fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
@@ -4164,7 +4164,7 @@ void str_to_file(const char *fname, char
   char buff[FN_REFLEN];
   if (!test_if_hard_path(fname))
   {
-    strxmov(buff, opt_basedir, fname, NullS);
+    strxn0mov(buff, sizeof(buff), opt_basedir, fname, NullS);
     fname= buff;
   }
   fn_format(buff, fname, "", "", MY_UNPACK_FILENAME);

--- 1.124/sql/sp.cc	2006-12-11 13:10:01 -08:00
+++ 1.125/sql/sp.cc	2006-12-11 13:10:01 -08:00
@@ -505,7 +505,7 @@ db_create_routine(THD *thd, int type, sp
     restore_record(table, s->default_values); // Get default values for fields
 
     /* NOTE: all needed privilege checks have been already done. */
-    strxmov(definer, thd->lex->definer->user.str, "@",
+    strxn0mov(definer, sizeof(definer), thd->lex->definer->user.str, "@",
             thd->lex->definer->host.str, NullS);
 
     if (table->s->fields != MYSQL_PROC_FIELD_COUNT)
@@ -1013,7 +1013,7 @@ sp_find_routine(THD *thd, int type, sp_n
       DBUG_RETURN(0);
     }
 
-    strxmov(definer, sp->m_definer_user.str, "@",
+    strxn0mov(definer, sizeof(definer), sp->m_definer_user.str, "@",
             sp->m_definer_host.str, NullS);
     if (type == TYPE_ENUM_FUNCTION)
     {

--- 1.69/libmysql/Makefile.shared	2006-12-11 13:10:01 -08:00
+++ 1.70/libmysql/Makefile.shared	2006-12-11 13:10:01 -08:00
@@ -35,7 +35,7 @@ target_sources = 	libmysql.c password.c 
 			get_password.c errmsg.c
 
 mystringsobjects =	strmov.lo strxmov.lo strxnmov.lo strnmov.lo \
-			strmake.lo strend.lo strtod.lo \
+			strxn0mov.lo strmake.lo strend.lo strtod.lo \
 			strnlen.lo strfill.lo is_prefix.lo \
 			int2str.lo str2int.lo strinstr.lo strcont.lo \
 			strcend.lo bcmp.lo ctype-latin1.lo \

--- 1.217/tests/mysql_client_test.c	2006-12-11 13:10:01 -08:00
+++ 1.218/tests/mysql_client_test.c	2006-12-11 13:10:01 -08:00
@@ -310,12 +310,13 @@ static void client_connect(ulong flag)
             (ulong) mysql_get_server_version(mysql));
     fprintf(stdout, "\n Creating a test database '%s' ...", current_db);
   }
-  strxmov(query, "CREATE DATABASE IF NOT EXISTS ", current_db, NullS);
+  strxn0mov(query, sizeof(query), "CREATE DATABASE IF NOT EXISTS ",
+           current_db, NullS);
 
   rc= mysql_query(mysql, query);
   myquery(rc);
 
-  strxmov(query, "USE ", current_db, NullS);
+  strxn0mov(query, sizeof(query), "USE ", current_db, NullS);
   rc= mysql_query(mysql, query);
   myquery(rc);
   have_innodb= check_have_innodb(mysql);
@@ -337,7 +338,8 @@ static void client_disconnect()
   {
     if (!opt_silent)
       fprintf(stdout, "\n dropping the test database '%s' ...", current_db);
-    strxmov(query, "DROP DATABASE IF EXISTS ", current_db, NullS);
+    strxn0mov(query, sizeof(query), "DROP DATABASE IF EXISTS ",
+             current_db, NullS);
 
     mysql_query(mysql, query);
     if (!opt_silent)
@@ -669,7 +671,8 @@ static void verify_col_data(const char *
 
   if (table && col)
   {
-    strxmov(query, "SELECT ", col, " FROM ", table, " LIMIT 1", NullS);
+    strxn0mov(query, sizeof(query), "SELECT ", col, " FROM ", table,
+             " LIMIT 1", NullS);
     if (!opt_silent)
       fprintf(stdout, "\n %s", query);
     rc= mysql_query(mysql, query);
@@ -1585,7 +1588,8 @@ static void test_prepare()
   myquery(rc);
 
   /* insert by prepare */
-  strxmov(query, "INSERT INTO my_prepare VALUES(?, ?, ?, ?, ?, ?, ?)", NullS);
+  strxn0mov(query, sizeof(query),
+           "INSERT INTO my_prepare VALUES(?, ?, ?, ?, ?, ?, ?)", NullS);
   stmt= mysql_simple_prepare(mysql, query);
   check_stmt(stmt);
 
@@ -2693,7 +2697,8 @@ static void test_select_show()
   stmt= mysql_simple_prepare(mysql, "show tables from mysql like ?");
   check_stmt_r(stmt);
 
-  strxmov(query, "show tables from ", current_db, " like \'test_show\'", NullS);
+  strxn0mov(query, sizeof(query), "show tables from ", current_db,
+           " like \'test_show\'", NullS);
   stmt= mysql_simple_prepare(mysql, query);
   check_stmt(stmt);
 
@@ -2972,7 +2977,7 @@ static void test_long_data_str()
   verify_col_data("test_long_data_str", "LENGTH(longstr)", data);
   data[0]= '\0';
   while (i--)
-   strxmov(data, data, "MySQL", NullS);
+   strxn0mov(data, sizeof(data), data, "MySQL", NullS);
   verify_col_data("test_long_data_str", "longstr", data);
 
   rc= mysql_query(mysql, "DROP TABLE test_long_data_str");
@@ -7167,9 +7172,9 @@ static void test_prepare_grant()
   rc= mysql_query(mysql, "CREATE TABLE test_grant(a tinyint primary key auto_increment)");
   myquery(rc);
 
-  strxmov(query, "GRANT INSERT, UPDATE, SELECT ON ", current_db,
-                ".test_grant TO 'test_grant'@",
-                opt_host ? opt_host : "'localhost'", NullS);
+  strxn0mov(query, sizeof(query), "GRANT INSERT, UPDATE, SELECT ON ",
+           current_db, ".test_grant TO 'test_grant'@",
+           opt_host ? opt_host : "'localhost'", NullS);
 
   if (mysql_query(mysql, query))
   {
@@ -7298,7 +7303,8 @@ static void test_frm_bug()
   rc= mysql_stmt_fetch(stmt);
   DIE_UNLESS(rc == MYSQL_NO_DATA);
 
-  strxmov(test_frm, data_dir, "/", current_db, "/", "test_frm_bug.frm", NullS);
+  strxn0mov(test_frm, sizeof(test_frm), data_dir, "/", current_db, "/",
+           "test_frm_bug.frm", NullS);
 
   if (!opt_silent)
     fprintf(stdout, "\n test_frm: %s", test_frm);
@@ -7625,7 +7631,7 @@ static void test_drop_temp()
   rc= mysql_query(mysql, "delete from mysql.db where Db='test_drop_temp_db'");
   myquery(rc);
 
-  strxmov(query, "GRANT SELECT, USAGE, DROP ON test_drop_temp_db.* TO test_temp@",
+  strxn0mov(query, sizeof(query), "GRANT SELECT, USAGE, DROP ON test_drop_temp_db.* TO test_temp@",
                 opt_host ? opt_host : "localhost", NullS);
 
   if (mysql_query(mysql, query))
@@ -8411,11 +8417,11 @@ static void test_mem_overun()
   rc= mysql_query(mysql, "drop table if exists t_mem_overun");
   myquery(rc);
 
-  strxmov(buffer, "create table t_mem_overun(", NullS);
+  strxn0mov(buffer, sizeof(buffer), "create table t_mem_overun(", NullS);
   for (i= 0; i < 1000; i++)
   {
     sprintf(field, "c%d int", i);
-    strxmov(buffer, buffer, field, ", ", NullS);
+    strxn0mov(buffer, sizeof(buffer), buffer, field, ", ", NullS);
   }
   length= strlen(buffer);
   buffer[length-2]= ')';
@@ -8424,10 +8430,11 @@ static void test_mem_overun()
   rc= mysql_real_query(mysql, buffer, length);
   myquery(rc);
 
-  strxmov(buffer, "insert into t_mem_overun values(", NullS);
+  strxn0mov(buffer, sizeof(buffer), "insert into t_mem_overun values(",
+           NullS);
   for (i= 0; i < 1000; i++)
   {
-    strxmov(buffer, buffer, "1, ", NullS);
+    strxn0mov(buffer, sizeof(buffer), buffer, "1, ", NullS);
   }
   length= strlen(buffer);
   buffer[length-2]= ')';
Thread
bk commit into 5.0 tree (igreenhoe:1.2341) BUG#16864Ian Greenhoe11 Dec