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.dimov | 5 Dec |