List:Commits« Previous MessageNext Message »
From:vasil.dimov Date:December 5 2010 7:22pm
Subject:bzr push into mysql-5.1-innodb branch (vasil.dimov:3664 to 3665)
View as plain text  
 3665 Vasil Dimov	2010-12-05 [merge]
      Merge mysql-5.1-bugteam -> mysql-5.1-innodb

    added:
      mysql-test/suite/federated/federated_bug_35333.result
      mysql-test/suite/federated/federated_bug_35333.test
    modified:
      client/mysqltest.cc
      include/config-netware.h
      include/config-win.h
      include/m_ctype.h
      include/my_global.h
      include/my_stacktrace.h
      mysql-test/r/merge.result
      mysql-test/r/mysql.result
      mysql-test/r/plugin_not_embedded.result
      mysql-test/r/show_check.result
      mysql-test/r/view.result
      mysql-test/t/mysql.test
      mysql-test/t/plugin_not_embedded.test
      mysys/stacktrace.c
      sql/log.cc
      sql/mysqld.cc
      sql/sql_plugin.cc
      sql/sql_plugin.h
      sql/sql_show.cc
      sql/sql_udf.cc
      strings/my_strchr.c
 3664 Marko Mäkelä	2010-12-01
      Bug#58623: Bogus debug assertion failure in i_s_locks_row_validate()
      
      This bogus assertion was introduced in the fix of Bug #57802:
      Empty ASSERTION parameter passed to the HASH_SEARCH macro.

    modified:
      storage/innodb_plugin/trx/trx0i_s.c
=== modified file 'client/mysqltest.cc'
--- a/client/mysqltest.cc	revid:marko.makela@stripped1i
+++ b/client/mysqltest.cc	revid:vasil.dimov@stripped-20101205191613-1i27liitkr9tpa7s
@@ -7782,13 +7782,16 @@ static void dump_backtrace(void)
 {
   struct st_connection *conn= cur_con;
 
-  my_safe_print_str("read_command_buf", read_command_buf,
-                    sizeof(read_command_buf));
+  fprintf(stderr, "read_command_buf (%p): ", read_command_buf);
+  my_safe_print_str(read_command_buf, sizeof(read_command_buf));
+
   if (conn)
   {
-    my_safe_print_str("conn->name", conn->name, conn->name_len);
+    fprintf(stderr, "conn->name (%p): ", conn->name);
+    my_safe_print_str(conn->name, conn->name_len);
 #ifdef EMBEDDED_LIBRARY
-    my_safe_print_str("conn->cur_query", conn->cur_query, conn->cur_query_len);
+    fprintf(stderr, "conn->cur_query (%p): ", conn->cur_query);
+    my_safe_print_str(conn->cur_query, conn->cur_query_len);
 #endif
   }
   fputs("Attempting backtrace...\n", stderr);

=== modified file 'include/config-netware.h'
--- a/include/config-netware.h	revid:marko.makela@stripped01201080353-2i2qyp0iars3nt1i
+++ b/include/config-netware.h	revid:vasil.dimov@stripped9tpa7s
@@ -122,6 +122,7 @@ extern "C" {
 #define CANT_DELETE_OPEN_FILES 1
 
 #define FN_LIBCHAR '\\'
+#define FN_DIRSEP  "/\\"              /* Valid directory separators */
 #define FN_ROOTDIR "\\"
 #define FN_DEVCHAR ':'
 

=== modified file 'include/config-win.h'
--- a/include/config-win.h	revid:marko.makela@strippedyp0iars3nt1i
+++ b/include/config-win.h	revid:vasil.dimov@oracle.com-20101205191613-1i27liitkr9tpa7s
@@ -332,6 +332,7 @@ inline ulonglong double2ulonglong(double
 /* File name handling */
 
 #define FN_LIBCHAR	'\\'
+#define FN_DIRSEP       "/\\"               /* Valid directory separators */
 #define FN_ROOTDIR	"\\"
 #define FN_DEVCHAR	':'
 #define FN_NETWORK_DRIVES	/* Uses \\ to indicate network drives */

=== modified file 'include/m_ctype.h'
--- a/include/m_ctype.h	revid:marko.makela@stripped0353-2i2qyp0iars3nt1i
+++ b/include/m_ctype.h	revid:vasil.dimov@stripped
@@ -464,6 +464,8 @@ extern my_bool my_parse_charset_xml(cons
 				    int (*add)(CHARSET_INFO *cs));
 extern char *my_strchr(CHARSET_INFO *cs, const char *str, const char *end,
                        pchar c);
+extern size_t my_strcspn(CHARSET_INFO *cs, const char *str, const char *end,
+                         const char *accept);
 
 my_bool my_propagate_simple(CHARSET_INFO *cs, const uchar *str, size_t len);
 my_bool my_propagate_complex(CHARSET_INFO *cs, const uchar *str, size_t len);

=== modified file 'include/my_global.h'
--- a/include/my_global.h	revid:marko.makela@stripped
+++ b/include/my_global.h	revid:vasil.dimov@stripped13-1i27liitkr9tpa7s
@@ -758,6 +758,7 @@ typedef SOCKET_SIZE_TYPE size_socket;
 
 #ifndef FN_LIBCHAR
 #define FN_LIBCHAR	'/'
+#define FN_DIRSEP       "/"     /* Valid directory separators */
 #define FN_ROOTDIR	"/"
 #endif
 #define MY_NFILE	64	/* This is only used to save filenames */

=== modified file 'include/my_stacktrace.h'
--- a/include/my_stacktrace.h	revid:marko.makela@stripped80353-2i2qyp0iars3nt1i
+++ b/include/my_stacktrace.h	revid:vasil.dimov@stripped
@@ -47,7 +47,7 @@ C_MODE_START
 #if defined(HAVE_STACKTRACE) || defined(HAVE_BACKTRACE)
 void my_init_stacktrace();
 void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack);
-void my_safe_print_str(const char* name, const char* val, int max_len);
+void my_safe_print_str(const char* val, int max_len);
 void my_write_core(int sig);
 #if BACKTRACE_DEMANGLE
 char *my_demangle(const char *mangled_name, int *status);

=== modified file 'mysql-test/r/merge.result'
--- a/mysql-test/r/merge.result	revid:marko.makela@stripped
+++ b/mysql-test/r/merge.result	revid:vasil.dimov@stripped20101205191613-1i27liitkr9tpa7s
@@ -2024,6 +2024,8 @@ SELECT * FROM INFORMATION_SCHEMA.TABLES 
 TABLE_SCHEMA = 'test' and TABLE_NAME='tm1';
 TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	TABLE_TYPE	ENGINE	VERSION	ROW_FORMAT	TABLE_ROWS	AVG_ROW_LENGTH	DATA_LENGTH	MAX_DATA_LENGTH	INDEX_LENGTH	DATA_FREE	AUTO_INCREMENT	CREATE_TIME	UPDATE_TIME	CHECK_TIME	TABLE_COLLATION	CHECKSUM	CREATE_OPTIONS	TABLE_COMMENT
 NULL	test	tm1	BASE TABLE	NULL	NULL	NULL	#	#	#	#	#	#	#	#	#	#	NULL	#	#	Unable to open underlying table which is differently defined or of non-MyISAM ty
+Warnings:
+Warning	1168	Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
 DROP TABLE tm1;
 CREATE TABLE t1(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM;
 CREATE TABLE t2(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM;

=== modified file 'mysql-test/r/mysql.result'
--- a/mysql-test/r/mysql.result	revid:marko.makela@stripped3nt1i
+++ b/mysql-test/r/mysql.result	revid:vasil.dimov@oracle.com-20101205191613-1i27liitkr9tpa7s
@@ -294,16 +294,14 @@ Tables_in_test
 # Checking --one-database option with non_existent_db 
 # specified with USE command
 #
-SHOW TABLES IN test;
-Tables_in_test
-table_in_test
-DROP DATABASE test;
+CREATE DATABASE connected_db;
+SHOW TABLES IN connected_db;
+Tables_in_connected_db
+table_in_connected_db
 
-CREATE DATABASE test;
-SHOW TABLES IN test;
-Tables_in_test
-table_in_test
-DROP DATABASE test;
-CREATE DATABASE test;
+SHOW TABLES IN connected_db;
+Tables_in_connected_db
+table_in_connected_db
+DROP DATABASE connected_db;
 
 End of tests

=== modified file 'mysql-test/r/plugin_not_embedded.result'
--- a/mysql-test/r/plugin_not_embedded.result	revid:marko.makela@stripped0353-2i2qyp0iars3nt1i
+++ b/mysql-test/r/plugin_not_embedded.result	revid:vasil.dimov@stripped27liitkr9tpa7s
@@ -8,3 +8,5 @@ ERROR 42000: DELETE command denied to us
 GRANT DELETE ON mysql.plugin TO bug51770@localhost;
 UNINSTALL PLUGIN example;
 DROP USER bug51770@localhost;
+INSTALL PLUGIN example SONAME '../ha_example.so';
+ERROR HY000: No paths allowed for shared library

=== modified file 'mysql-test/r/show_check.result'
--- a/mysql-test/r/show_check.result	revid:marko.makela@oracle.com-20101201080353-2i2qyp0iars3nt1i
+++ b/mysql-test/r/show_check.result	revid:vasil.dimov@stripped13-1i27liitkr9tpa7s
@@ -660,6 +660,8 @@ flush tables;
 SHOW TABLE STATUS like 't1';
 Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
 t1	NULL	NULL	NULL	NULL	#	#	#	#	NULL	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Incorrect information in file: './test/t1.frm'
+Warnings:
+Warning	1033	Incorrect information in file: './test/t1.frm'
 show create table t1;
 ERROR HY000: Incorrect information in file: './test/t1.frm'
 drop table if exists t1;

=== modified file 'mysql-test/r/view.result'
--- a/mysql-test/r/view.result	revid:marko.makela@strippedom-20101201080353-2i2qyp0iars3nt1i
+++ b/mysql-test/r/view.result	revid:vasil.dimov@strippedliitkr9tpa7s
@@ -840,6 +840,8 @@ show table status;
 Name	Engine	Version	Row_format	Rows	Avg_row_length	Data_length	Max_data_length	Index_length	Data_free	Auto_increment	Create_time	Update_time	Check_time	Collation	Checksum	Create_options	Comment
 t1	MyISAM	10	Fixed	0	0	0	#	1024	0	NULL	#	#	NULL	latin1_swedish_ci	NULL		
 v1	NULL	NULL	NULL	NULL	NULL	NULL	#	NULL	NULL	NULL	#	#	NULL	NULL	NULL	NULL	View 'test.v1' references invalid table(s) or column(s) or function(s) or define
+Warnings:
+Warning	1356	View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
 drop view v1;
 drop table t1;
 create view v1 as select 99999999999999999999999999999999999999999999999999999 as col1;

=== added file 'mysql-test/suite/federated/federated_bug_35333.result'
--- a/mysql-test/suite/federated/federated_bug_35333.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/federated/federated_bug_35333.result	revid:vasil.dimov@stripped
@@ -0,0 +1,67 @@
+#
+# Bug 35333 "If a Federated table can't connect to the remote hose, can't retrieve metadata"
+#
+# Queries such as SHOW TABLE STATUS and SELECT * FROM INFORMATION_SCHEMA.TABLES fail
+# when encountering a federated table that cannot connect to its remote table.
+#
+# The fix is to store the error text in the TABLE COMMENTS column of I_S.TABLES, clear
+# the remote connection error and push a warning instead. This allows the SELECT operation
+# to complete while still indicating a problem. This fix applies to any non-fatal system
+# error that occurs during a query against I_S.TABLES.de
+CREATE DATABASE federated;
+CREATE DATABASE federated;
+CREATE DATABASE IF NOT EXISTS realdb;
+DROP TABLE IF EXISTS realdb.t0;
+DROP TABLE IF EXISTS federated.t0;
+#
+# Create the base table to be referenced
+#
+CREATE TABLE realdb.t0 (a text, b text) ENGINE=MYISAM;
+#
+# Create a federated table with a bogus port number
+#
+CREATE TABLE federated.t0 (a text, b text) ENGINE=FEDERATED
+CONNECTION='mysql://root@127.0.0.1:63333/realdb/t0';
+#
+# Trigger a federated system error during a INFORMATION_SCHEMA.TABLES query
+#
+SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT
+FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'realdb' or TABLE_SCHEMA = 'federated';
+TABLE_SCHEMA	TABLE_NAME	TABLE_TYPE	ENGINE	ROW_FORMAT	TABLE_ROWS	DATA_LENGTH	TABLE_COMMENT
+federated	t0	BASE TABLE	FEDERATED		NULL	0	Unable to connect to foreign data source: Can't connect to MySQL server on '127.
+realdb	t0	BASE TABLE	MyISAM	Dynamic	0	0	
+Warnings:
+Warning	1429	Unable to connect to foreign data source: Can't connect to MySQL server on '127.0.0.1' (socket errno)
+SHOW WARNINGS;
+Level	Code	Message
+Warning	1429	Unable to connect to foreign data source: Can't connect to MySQL server on '127.0.0.1' (socket errno)
+#
+# Create a MyISAM table then corrupt the file
+#
+USE realdb;
+CREATE TABLE t1 (c1 int) ENGINE=MYISAM;
+#
+# Corrupt the MyISAM table by deleting the base file
+#
+#
+# Trigger a MyISAM system error during an INFORMATION_SCHEMA.TABLES query
+#
+SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT
+FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
+TABLE_SCHEMA	TABLE_NAME	TABLE_TYPE	ENGINE	ROW_FORMAT	TABLE_ROWS	DATA_LENGTH	TABLE_COMMENT
+realdb	t1	BASE TABLE	NULL	NULL	NULL	NULL	Can't find file: 't1' (errno: 2)
+Warnings:
+Warning	1017	Can't find file: 't1' (errno: 2)
+SHOW WARNINGS;
+Level	Code	Message
+Warning	1017	Can't find file: 't1' (errno: 2)
+#
+# Cleanup
+#
+DROP TABLE IF EXISTS realdb.t0;
+DROP TABLE IF EXISTS federated.t0;
+DROP DATABASE realdb;
+DROP TABLE IF EXISTS federated.t1;
+DROP DATABASE federated;
+DROP TABLE IF EXISTS federated.t1;
+DROP DATABASE federated;

=== added file 'mysql-test/suite/federated/federated_bug_35333.test'
--- a/mysql-test/suite/federated/federated_bug_35333.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/federated/federated_bug_35333.test	revid:vasil.dimov@stripped27liitkr9tpa7s
@@ -0,0 +1,74 @@
+--echo #
+--echo # Bug 35333 "If a Federated table can't connect to the remote hose, can't retrieve metadata"
+--echo #
+--echo # Queries such as SHOW TABLE STATUS and SELECT * FROM INFORMATION_SCHEMA.TABLES fail
+--echo # when encountering a federated table that cannot connect to its remote table.
+--echo #
+--echo # The fix is to store the error text in the TABLE COMMENTS column of I_S.TABLES, clear
+--echo # the remote connection error and push a warning instead. This allows the SELECT operation
+--echo # to complete while still indicating a problem. This fix applies to any non-fatal system
+--echo # error that occurs during a query against I_S.TABLES.de
+
+--source federated.inc
+
+--disable_warnings
+CREATE DATABASE IF NOT EXISTS realdb;
+# Federated database exists
+DROP TABLE IF EXISTS realdb.t0;
+DROP TABLE IF EXISTS federated.t0;
+--enable_warnings
+
+--echo #
+--echo # Create the base table to be referenced
+--echo #
+CREATE TABLE realdb.t0 (a text, b text) ENGINE=MYISAM;
+
+--echo #
+--echo # Create a federated table with a bogus port number
+--echo #
+CREATE TABLE federated.t0 (a text, b text) ENGINE=FEDERATED
+    CONNECTION='mysql://root@stripped:63333/realdb/t0';
+
+#--warning ER_CONNECT_TO_FOREIGN_DATA_SOURCE
+
+--echo #
+--echo # Trigger a federated system error during a INFORMATION_SCHEMA.TABLES query
+--echo #
+# Remove O/S-specific socket error
+--replace_regex /\(.*\)/(socket errno)/
+SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT
+       FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'realdb' or TABLE_SCHEMA = 'federated';
+
+# Remove O/S-specific socket error
+--replace_regex /\(.*\)/(socket errno)/
+SHOW WARNINGS;
+
+--echo #
+--echo # Create a MyISAM table then corrupt the file
+--echo #
+USE realdb;
+CREATE TABLE t1 (c1 int) ENGINE=MYISAM;
+--echo #
+--echo # Corrupt the MyISAM table by deleting the base file
+--echo #
+let $MYSQLD_DATADIR= `SELECT @@datadir`;
+--remove_file $MYSQLD_DATADIR/realdb/t1.MYD
+--remove_file $MYSQLD_DATADIR/realdb/t1.MYI
+
+--echo #
+--echo # Trigger a MyISAM system error during an INFORMATION_SCHEMA.TABLES query
+--echo #
+SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, ENGINE, ROW_FORMAT, TABLE_ROWS, DATA_LENGTH, TABLE_COMMENT
+       FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
+
+SHOW WARNINGS;
+--echo #
+--echo # Cleanup
+--echo #
+--disable_warnings
+DROP TABLE IF EXISTS realdb.t0;
+DROP TABLE IF EXISTS federated.t0;
+DROP DATABASE realdb;
+--enable_warnings
+
+--source federated_cleanup.inc

=== modified file 'mysql-test/t/mysql.test'
--- a/mysql-test/t/mysql.test	revid:marko.makela@stripped
+++ b/mysql-test/t/mysql.test	revid:vasil.dimov@strippedm-20101205191613-1i27liitkr9tpa7s
@@ -523,35 +523,34 @@ SHOW TABLES IN test;
 --echo # specified with USE command
 --echo #
 
-# CASE 1 : When 'test' database exists and passed at commandline.
+# CASE 1 : When 'connected_db' database exists and passed at commandline.
 --write_file $MYSQLTEST_VARDIR/tmp/one_db_1.sql
-CREATE TABLE `table_in_test`(i INT);
+CREATE TABLE `table_in_connected_db`(i INT);
 USE non_existent_db;
 # Following statement should be filtered out.
 CREATE TABLE `table_in_non_existent_db`(i INT);
 EOF
 
-# CASE 2 : When 'test' database exists but dropped and recreated in load file.
+# CASE 2 : When 'connected_db' database exists but dropped and recreated in
+# load file.
 --write_file $MYSQLTEST_VARDIR/tmp/one_db_2.sql
-DROP DATABASE test;
-CREATE DATABASE test;
+DROP DATABASE connected_db;
+CREATE DATABASE connected_db;
 USE non_existent_db;
 # Following statements should be filtered out.
 CREATE TABLE `table_in_non_existent_db`(i INT);
-USE test;
+USE connected_db;
 # Following statements should not be filtered out.
-CREATE TABLE `table_in_test`(i INT);
+CREATE TABLE `table_in_connected_db`(i INT);
 EOF
 
---exec $MYSQL --one-database test < $MYSQLTEST_VARDIR/tmp/one_db_1.sql
-SHOW TABLES IN test;
-DROP DATABASE test;
+CREATE DATABASE connected_db;
+--exec $MYSQL --one-database connected_db < $MYSQLTEST_VARDIR/tmp/one_db_1.sql
+SHOW TABLES IN connected_db;
 --echo
-CREATE DATABASE test;
---exec $MYSQL --one-database test < $MYSQLTEST_VARDIR/tmp/one_db_2.sql
-SHOW TABLES IN test;
-DROP DATABASE test;
-CREATE DATABASE test;
+--exec $MYSQL --one-database connected_db < $MYSQLTEST_VARDIR/tmp/one_db_2.sql
+SHOW TABLES IN connected_db;
+DROP DATABASE connected_db;
 
 --remove_file $MYSQLTEST_VARDIR/tmp/one_db_1.sql
 --remove_file $MYSQLTEST_VARDIR/tmp/one_db_2.sql

=== modified file 'mysql-test/t/plugin_not_embedded.test'
--- a/mysql-test/t/plugin_not_embedded.test	revid:marko.makela@strippedom-20101201080353-2i2qyp0iars3nt1i
+++ b/mysql-test/t/plugin_not_embedded.test	revid:vasil.dimov@stripped05191613-1i27liitkr9tpa7s
@@ -18,3 +18,15 @@ UNINSTALL PLUGIN example;
 disconnect con1;
 connection default;
 DROP USER bug51770@localhost;
+
+# 
+# BUG#58246: INSTALL PLUGIN not secure & crashable
+#
+# The bug consisted of not recognizing / on Windows, so checking / on
+# all platforms should cover this case.
+
+let $path = `select CONCAT_WS('/', '..', $HA_EXAMPLE_SO)`;
+--replace_regex /\.dll/.so/
+--error ER_UDF_NO_PATHS
+eval INSTALL PLUGIN example SONAME '$path';
+

=== modified file 'mysys/stacktrace.c'
--- a/mysys/stacktrace.c	revid:marko.makela@strippedm-20101201080353-2i2qyp0iars3nt1i
+++ b/mysys/stacktrace.c	revid:vasil.dimov@strippedtpa7s
@@ -27,6 +27,11 @@
 #include <unistd.h>
 #include <strings.h>
 
+#ifdef __linux__
+#include <ctype.h>          /* isprint */
+#include <sys/syscall.h>    /* SYS_gettid */
+#endif
+
 #if HAVE_EXECINFO_H
 #include <execinfo.h>
 #endif
@@ -46,10 +51,99 @@ void my_init_stacktrace()
 #endif
 }
 
-void my_safe_print_str(const char* name, const char* val, int max_len)
+#ifdef __linux__
+
+static void print_buffer(char *buffer, size_t count)
+{
+  for (; count && *buffer; --count)
+  {
+    int c= (int) *buffer++;
+    fputc(isprint(c) ? c : ' ', stderr);
+  }
+}
+
+/**
+  Access the pages of this process through /proc/self/task/<tid>/mem
+  in order to safely print the contents of a memory address range.
+
+  @param  addr      The address at the start of the memory region.
+  @param  max_len   The length of the memory region.
+
+  @return Zero on success.
+*/
+static int safe_print_str(const char *addr, int max_len)
 {
-  char *heap_end= (char*) sbrk(0);
-  fprintf(stderr, "%s at %p ", name, val);
+  int fd;
+  pid_t tid;
+  off_t offset;
+  ssize_t nbytes= 0;
+  size_t total, count;
+  char buf[256];
+
+  tid= (pid_t) syscall(SYS_gettid);
+
+  sprintf(buf, "/proc/self/task/%d/mem", tid);
+
+  if ((fd= open(buf, O_RDONLY)) < 0)
+    return -1;
+
+  /* Ensure that off_t can hold a pointer. */
+  compile_time_assert(sizeof(off_t) >= sizeof(intptr));
+
+  total= max_len;
+  offset= (intptr) addr;
+
+  /* Read up to the maximum number of bytes. */
+  while (total)
+  {
+    count= min(sizeof(buf), total);
+
+    if ((nbytes= pread(fd, buf, count, offset)) < 0)
+    {
+      /* Just in case... */
+      if (errno == EINTR)
+        continue;
+      else
+        break;
+    }
+
+    /* Advance offset into memory. */
+    total-= nbytes;
+    offset+= nbytes;
+    addr+= nbytes;
+
+    /* Output the printable characters. */
+    print_buffer(buf, nbytes);
+
+    /* Break if less than requested... */
+    if ((count - nbytes))
+      break;
+  }
+
+  /* Output a new line if something was printed. */
+  if (total != (size_t) max_len)
+    fputc('\n', stderr);
+
+  if (nbytes == -1)
+    fprintf(stderr, "Can't read from address %p: %m.\n", addr);
+
+  close(fd);
+
+  return 0;
+}
+
+#endif
+
+void my_safe_print_str(const char* val, int max_len)
+{
+  char *heap_end;
+
+#ifdef __linux__
+  if (!safe_print_str(val, max_len))
+    return;
+#endif
+
+  heap_end= (char*) sbrk(0);
 
   if (!PTR_SANE(val))
   {
@@ -57,7 +151,6 @@ void my_safe_print_str(const char* name,
     return;
   }
 
-  fprintf(stderr, "= ");
   for (; max_len && PTR_SANE(val) && *val; --max_len)
     fputc(*val++, stderr);
   fputc('\n', stderr);
@@ -657,10 +750,9 @@ void my_write_core(int unused)
 }
 
 
-void my_safe_print_str(const char *name, const char *val, int len)
+void my_safe_print_str(const char *val, int len)
 {
-  fprintf(stderr,"%s at %p", name, val);
-  __try 
+  __try
   {
     fprintf(stderr,"=%.*s\n", len, val);
   }

=== modified file 'sql/log.cc'
--- a/sql/log.cc	revid:marko.makela@strippedm-20101201080353-2i2qyp0iars3nt1i
+++ b/sql/log.cc	revid:vasil.dimov@stripped
@@ -3037,7 +3037,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
   }
 
   /* Start logging with a new file */
-  close(LOG_CLOSE_INDEX);
+  close(LOG_CLOSE_INDEX | LOG_CLOSE_TO_BE_OPENED);
   if ((error= my_delete_allow_opened(index_file_name, MYF(0))))	// Reset (open will update)
   {
     if (my_errno == ENOENT) 

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	revid:marko.makela@stripped20101201080353-2i2qyp0iars3nt1i
+++ b/sql/mysqld.cc	revid:vasil.dimov@stripped
@@ -2527,7 +2527,7 @@ the thread stack. Please read http://dev
 
   if (!(test_flags & TEST_NO_STACKTRACE))
   {
-    fprintf(stderr, "thd: 0x%lx\n",(long) thd);
+    fprintf(stderr, "Thread pointer: 0x%lx\n", (long) thd);
     fprintf(stderr, "Attempting backtrace. You can use the following "
                     "information to find out\nwhere mysqld died. If "
                     "you see no messages after this, something went\n"
@@ -2555,11 +2555,13 @@ the thread stack. Please read http://dev
       kreason= "KILLED_NO_VALUE";
       break;
     }
-    fprintf(stderr, "Trying to get some variables.\n\
-Some pointers may be invalid and cause the dump to abort...\n");
-    my_safe_print_str("thd->query", thd->query(), 1024);
-    fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id);
-    fprintf(stderr, "thd->killed=%s\n", kreason);
+    fprintf(stderr, "\nTrying to get some variables.\n"
+                    "Some pointers may be invalid and cause the dump to abort.\n");
+    fprintf(stderr, "Query (%p): ", thd->query());
+    my_safe_print_str(thd->query(), min(1024, thd->query_length()));
+    fprintf(stderr, "Connection ID (thread ID): %lu\n", (ulong) thd->thread_id);
+    fprintf(stderr, "Status: %s\n", kreason);
+    fputc('\n', stderr);
   }
   fprintf(stderr, "\
 The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\

=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc	revid:marko.makela@stripped201080353-2i2qyp0iars3nt1i
+++ b/sql/sql_plugin.cc	revid:vasil.dimov@stripped
@@ -231,6 +231,26 @@ extern bool check_if_table_exists(THD *t
 #endif /* EMBEDDED_LIBRARY */
 
 
+/**
+   Check if the provided path is valid in the sense that it does cause
+   a relative reference outside the directory.
+
+   @note Currently, this function only check if there are any
+   characters in FN_DIRSEP in the string, but it might change in the
+   future.
+
+   @code
+   check_valid_path("../foo.so") -> true
+   check_valid_path("foo.so") -> false
+   @endcode
+ */
+bool check_valid_path(const char *path, size_t len)
+{
+  size_t prefix= my_strcspn(files_charset_info, path, path + len, FN_DIRSEP);
+  return  prefix < len;
+}
+
+
 /****************************************************************************
   Value type thunks, allows the C world to play in the C++ world
 ****************************************************************************/
@@ -354,13 +374,15 @@ static st_plugin_dl *plugin_dl_add(const
   struct st_plugin_dl *tmp, plugin_dl;
   void *sym;
   DBUG_ENTER("plugin_dl_add");
+  DBUG_PRINT("enter", ("dl->str: '%s', dl->length: %d",
+                       dl->str, (int) dl->length));
   plugin_dir_len= strlen(opt_plugin_dir);
   /*
     Ensure that the dll doesn't have a path.
     This is done to ensure that only approved libraries from the
     plugin directory are used (to make this even remotely secure).
   */
-  if (my_strchr(files_charset_info, dl->str, dl->str + dl->length, FN_LIBCHAR) ||
+  if (check_valid_path(dl->str, dl->length) ||
       check_string_char_length((LEX_STRING *) dl, "", NAME_CHAR_LEN,
                                system_charset_info, 1) ||
       plugin_dir_len + dl->length + 1 >= FN_REFLEN)

=== modified file 'sql/sql_plugin.h'
--- a/sql/sql_plugin.h	revid:marko.makela@stripped-20101201080353-2i2qyp0iars3nt1i
+++ b/sql/sql_plugin.h	revid:vasil.dimov@stripped7s
@@ -131,6 +131,7 @@ extern bool mysql_uninstall_plugin(THD *
 extern bool plugin_register_builtin(struct st_mysql_plugin *plugin);
 extern void plugin_thdvar_init(THD *thd);
 extern void plugin_thdvar_cleanup(THD *thd);
+extern bool check_valid_path(const char *path, size_t length);
 
 typedef my_bool (plugin_foreach_func)(THD *thd,
                                       plugin_ref plugin,

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	revid:marko.makela@strippedt1i
+++ b/sql/sql_show.cc	revid:vasil.dimov@stripped101205191613-1i27liitkr9tpa7s
@@ -3636,28 +3636,28 @@ static int get_schema_tables_record(THD 
 {
   const char *tmp_buff;
   MYSQL_TIME time;
+  int info_error= 0;
   CHARSET_INFO *cs= system_charset_info;
   DBUG_ENTER("get_schema_tables_record");
 
   restore_record(table, s->default_values);
   table->field[1]->store(db_name->str, db_name->length, cs);
   table->field[2]->store(table_name->str, table_name->length, cs);
+
   if (res)
   {
-    /*
-      there was errors during opening tables
-    */
-    const char *error= thd->is_error() ? thd->main_da.message() : "";
+    /* There was a table open error, so set the table type and return */
     if (tables->view)
       table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
     else if (tables->schema_table)
       table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
     else
       table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
-    table->field[20]->store(error, strlen(error), cs);
-    thd->clear_error();
+
+    goto err;
   }
-  else if (tables->view)
+
+  if (tables->view)
   {
     table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
     table->field[20]->store(STRING_WITH_LEN("VIEW"), cs);
@@ -3746,9 +3746,14 @@ static int get_schema_tables_record(THD 
     if (share->comment.str)
       table->field[20]->store(share->comment.str, share->comment.length, cs);
 
-    if(file)
+    if (file)
     {
-      file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO);
+      /* If info() fails, then there's nothing else to do */
+      if ((info_error= file->info(HA_STATUS_VARIABLE |
+                                  HA_STATUS_TIME |
+                                  HA_STATUS_AUTO)) != 0)
+        goto err;
+	  
       enum row_type row_type = file->get_row_type();
       switch (row_type) {
       case ROW_TYPE_NOT_USED:
@@ -3826,6 +3831,26 @@ static int get_schema_tables_record(THD 
       }
     }
   }
+
+err:
+  if (res || info_error)
+  {
+    /*
+      If an error was encountered, push a warning, set the TABLE COMMENT
+      column with the error text, and clear the error so that the operation
+      can continue.
+    */
+    const char *error= thd->is_error() ? thd->main_da.message() : "";
+    table->field[20]->store(error, strlen(error), cs);
+
+    if (thd->is_error())
+    {
+      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                   thd->main_da.sql_errno(), thd->main_da.message());
+      thd->clear_error();
+    }
+  }
+  
   DBUG_RETURN(schema_table_store_record(thd, table));
 }
 

=== modified file 'sql/sql_udf.cc'
--- a/sql/sql_udf.cc	revid:marko.makela@oracle.com-20101201080353-2i2qyp0iars3nt1i
+++ b/sql/sql_udf.cc	revid:vasil.dimov@strippeda7s
@@ -173,10 +173,7 @@ void udf_init()
 
       On windows we must check both FN_LIBCHAR and '/'.
     */
-    if (my_strchr(files_charset_info, dl_name,
-                  dl_name + strlen(dl_name), FN_LIBCHAR) ||
-        IF_WIN(my_strchr(files_charset_info, dl_name,
-                         dl_name + strlen(dl_name), '/'), 0) ||
+    if (check_valid_path(dl_name, strlen(dl_name)) ||
         check_string_char_length(&name, "", NAME_CHAR_LEN,
                                  system_charset_info, 1))
     {
@@ -416,13 +413,8 @@ int mysql_create_function(THD *thd,udf_f
     Ensure that the .dll doesn't have a path
     This is done to ensure that only approved dll from the system
     directories are used (to make this even remotely secure).
-
-    On windows we must check both FN_LIBCHAR and '/'.
   */
-  if (my_strchr(files_charset_info, udf->dl,
-                udf->dl + strlen(udf->dl), FN_LIBCHAR) ||
-      IF_WIN(my_strchr(files_charset_info, udf->dl,
-                       udf->dl + strlen(udf->dl), '/'), 0))
+  if (check_valid_path(udf->dl, strlen(udf->dl)))
   {
     my_message(ER_UDF_NO_PATHS, ER(ER_UDF_NO_PATHS), MYF(0));
     DBUG_RETURN(1);

=== modified file 'strings/my_strchr.c'
--- a/strings/my_strchr.c	revid:marko.makela@stripped
+++ b/strings/my_strchr.c	revid:vasil.dimov@stripped05191613-1i27liitkr9tpa7s
@@ -13,6 +13,45 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
+#include <my_global.h>
+#include "m_string.h"
+#include "m_ctype.h"
+
+#define NEQ(A, B) ((A) != (B))
+#define EQU(A, B) ((A) == (B))
+
+/**
+  Macro for the body of the string scanning.
+
+  @param CS  The character set of the string
+  @param STR Pointer to beginning of string
+  @param END Pointer to one-after-end of string
+  @param ACC Pointer to beginning of accept (or reject) string
+  @param LEN Length of accept (or reject) string
+  @param CMP is a function-like for doing the comparison of two characters.
+ */
+
+#define SCAN_STRING(CS, STR, END, ACC, LEN, CMP)                        \
+  do {                                                                  \
+    uint mbl;                                                           \
+    const char *ptr_str, *ptr_acc;                                      \
+    const char *acc_end= (ACC) + (LEN);                                 \
+    for (ptr_str= (STR) ; ptr_str < (END) ; ptr_str+= mbl)              \
+    {                                                                   \
+      mbl= my_mbcharlen((CS), *(uchar*)ptr_str);                        \
+      if (mbl < 2)                                                      \
+      {                                                                 \
+        DBUG_ASSERT(mbl == 1);                                          \
+        for (ptr_acc= (ACC) ; ptr_acc < acc_end ; ++ptr_acc)            \
+          if (CMP(*ptr_acc, *ptr_str))                                  \
+            goto end;                                                   \
+      }                                                                 \
+    }                                                                   \
+end:                                                                    \
+    return (size_t) (ptr_str - (STR));                                  \
+  } while (0)
+
+
 /*
   my_strchr(cs, str, end, c) returns a pointer to the first place in
   str where c (1-byte character) occurs, or NULL if c does not occur
@@ -21,11 +60,6 @@
   frequently.
 */
 
-#include <my_global.h>
-#include "m_string.h"
-#include "m_ctype.h"
-
-
 char *my_strchr(CHARSET_INFO *cs, const char *str, const char *end,
                 pchar c)
 {
@@ -45,3 +79,26 @@ char *my_strchr(CHARSET_INFO *cs, const 
   return(0);
 }
 
+/**
+  Calculate the length of the initial segment of 'str' which consists
+  entirely of characters not in 'reject'.
+
+  @note The reject string points to single-byte characters so it is
+  only possible to find the first occurrence of a single-byte
+  character.  Multi-byte characters in 'str' are treated as not
+  matching any character in the reject string.
+
+  @todo should be moved to CHARSET_INFO if it's going to be called
+  frequently.
+
+  @internal The implementation builds on the assumption that 'str' is long,
+  while 'reject' is short. So it compares each character in string
+  with the characters in 'reject' in a tight loop over the characters
+  in 'reject'.
+*/
+
+size_t my_strcspn(CHARSET_INFO *cs, const char *str, const char *str_end,
+                  const char *reject)
+{
+  SCAN_STRING(cs, str, str_end, reject, strlen(reject), EQU);
+}

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.1-innodb branch (vasil.dimov:3664 to 3665) vasil.dimov5 Dec