fixed buffer overrun in resolve_stack_dump

fixes for restore table
test case for backup/restore
parent 7c731257
...@@ -159,7 +159,7 @@ static uchar hex_val(char c) ...@@ -159,7 +159,7 @@ static uchar hex_val(char c)
l = tolower(c); l = tolower(c);
if(l < 'a' || l > 'f') if(l < 'a' || l > 'f')
return HEX_INVALID; return HEX_INVALID;
return 10 + c - 'a'; return (uchar)10 + ((uchar)c - (uchar)'a');
} }
static my_long_addr_t read_addr(char** buf) static my_long_addr_t read_addr(char** buf)
...@@ -189,7 +189,7 @@ static int init_sym_entry(SYM_ENTRY* se, char* buf) ...@@ -189,7 +189,7 @@ static int init_sym_entry(SYM_ENTRY* se, char* buf)
/* empty - skip more space */; /* empty - skip more space */;
--buf; --buf;
/* now we are on the symbol */ /* now we are on the symbol */
for(p = se->symbol, p_end = se->symbol + sizeof(se->symbol); for(p = se->symbol, p_end = se->symbol + sizeof(se->symbol) - 1;
*buf != '\n' && *buf; ++buf,++p ) *buf != '\n' && *buf; ++buf,++p )
{ {
if(p < p_end) if(p < p_end)
...@@ -203,7 +203,7 @@ static int init_sym_entry(SYM_ENTRY* se, char* buf) ...@@ -203,7 +203,7 @@ static int init_sym_entry(SYM_ENTRY* se, char* buf)
static void init_sym_table() static void init_sym_table()
{ {
char buf[256]; char buf[512];
if(init_dynamic_array(&sym_table, sizeof(SYM_ENTRY), INIT_SYM_TABLE, if(init_dynamic_array(&sym_table, sizeof(SYM_ENTRY), INIT_SYM_TABLE,
INC_SYM_TABLE)) INC_SYM_TABLE))
die("Failed in init_dynamic_array() -- looks like out of memory problem"); die("Failed in init_dynamic_array() -- looks like out of memory problem");
...@@ -236,7 +236,7 @@ static void verify_sort() ...@@ -236,7 +236,7 @@ static void verify_sort()
get_dynamic(&sym_table, (gptr)&se, i); get_dynamic(&sym_table, (gptr)&se, i);
if(se.addr < last) if(se.addr < last)
die("sym table does not appear to be sorted, did you forget \ die("sym table does not appear to be sorted, did you forget \
--numeric-sort arg to nm"); --numeric-sort arg to nm? trouble addr = %p, last = %p", se.addr, last);
last = se.addr; last = se.addr;
} }
} }
......
Table Op Msg_type Msg_text
t1 backup error Failed copying .frm file: errno = 2
test.t1 backup status Operation failed
Table Op Msg_type Msg_text
test.t1 backup status OK
Table Op Msg_type Msg_text
test.t1 restore status OK
count(*)
0
Table Op Msg_type Msg_text
test.t1 backup status OK
Table Op Msg_type Msg_text
t1 restore error Failed copying .frm file
Table Op Msg_type Msg_text
test.t1 restore status OK
n
23
45
67
Table Op Msg_type Msg_text
test.t1 backup status OK
test.t2 backup status OK
test.t3 backup status OK
Table Op Msg_type Msg_text
test.t1 restore status OK
test.t2 restore status OK
test.t3 restore status OK
n
23
45
67
m
123
145
167
k
223
245
267
connect (con1,localhost,root,,test,0,mysql-master.sock);
connect (con2,localhost,root,,test,0,mysql-master.sock);
connection con1;
set SQL_LOG_BIN=0;
drop table if exists t1;
create table t1(n int);
backup table t1 to '../bogus';
backup table t1 to '../tmp';
drop table t1;
restore table t1 from '../tmp';
select count(*) from t1;
insert into t1 values (23),(45),(67);
backup table t1 to '../tmp';
drop table t1;
restore table t1 from '../bogus';
restore table t1 from '../tmp';
select n from t1;
create table t2(m int not null primary key);
create table t3(k int not null primary key);
insert into t2 values (123),(145),(167);
insert into t3 values (223),(245),(267);
backup table t1,t2,t3 to '../tmp';
drop table t1,t2,t3;
restore table t1,t2,t3 from '../tmp';
select n from t1;
select m from t2;
select k from t3;
drop table t1,t2,t3;
#restore table t1 from '../tmp';
#connection con2;
#lock tables t1 write;
...@@ -8,7 +8,7 @@ load data infile '../../std_data/words.dat' into table t1; ...@@ -8,7 +8,7 @@ load data infile '../../std_data/words.dat' into table t1;
drop table if exists t2; drop table if exists t2;
create table t2 (word char(20) not null); create table t2 (word char(20) not null);
load data infile '../../std_data/words.dat' into table t2; load data infile '../../std_data/words.dat' into table t2;
create table t3 (word char(20) not null); create table t3 (word char(20) not null primary key);
connection slave; connection slave;
use test; use test;
drop table if exists t1; drop table if exists t1;
......
...@@ -375,6 +375,7 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt) ...@@ -375,6 +375,7 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt)
tmp_check_opt.init(); tmp_check_opt.init();
tmp_check_opt.quick = 1; tmp_check_opt.quick = 1;
tmp_check_opt.flags |= T_VERY_SILENT;
return repair(thd, &tmp_check_opt); return repair(thd, &tmp_check_opt);
err: err:
...@@ -396,24 +397,52 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) ...@@ -396,24 +397,52 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt)
char* backup_dir = thd->lex.backup_dir; char* backup_dir = thd->lex.backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN]; char src_path[FN_REFLEN], dst_path[FN_REFLEN];
char* table_name = table->real_name; char* table_name = table->real_name;
int error = 0;
const char* errmsg = "";
if (!fn_format(dst_path, table_name, backup_dir, reg_ext, 4 + 64)) if (!fn_format(dst_path, table_name, backup_dir, reg_ext, 4 + 64))
return HA_ADMIN_INVALID; {
errmsg = "failed in fn_format() for .frm file: errno=%d";
error = HA_ADMIN_INVALID;
goto err;
}
if (my_copy(fn_format(src_path, table->path,"", reg_ext, 4), if (my_copy(fn_format(src_path, table->path,"", reg_ext, 4),
dst_path, dst_path,
MYF(MY_WME | MY_HOLD_ORIGINAL_MODES ))) MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )))
{ {
return HA_ADMIN_FAILED; error = HA_ADMIN_FAILED;
errmsg = "Failed copying .frm file: errno = %d";
goto err;
} }
if (!fn_format(dst_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64)) if (!fn_format(dst_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64))
return HA_ADMIN_INVALID; {
errmsg = "failed in fn_format() for .MYD file: errno=%d";
error = HA_ADMIN_INVALID;
goto err;
}
if (my_copy(fn_format(src_path, table->path,"", MI_NAME_DEXT, 4), if (my_copy(fn_format(src_path, table->path,"", MI_NAME_DEXT, 4),
dst_path, dst_path,
MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )) ) MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )) )
return HA_ADMIN_FAILED; {
errmsg = "Failed copying .MYD file: errno = %d";
error= HA_ADMIN_FAILED;
goto err;
}
return HA_ADMIN_OK; return HA_ADMIN_OK;
err:
{
MI_CHECK param;
myisamchk_init(&param);
param.thd = thd;
param.op_name = (char*)"backup";
param.table_name = table->table_name;
param.testflag = 0;
mi_check_print_error(&param,errmsg, errno );
return error;
}
} }
......
...@@ -828,6 +828,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table) ...@@ -828,6 +828,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
if(lock_retcode && wait_for_locked_table_names(thd, table)) if(lock_retcode && wait_for_locked_table_names(thd, table))
{ {
unlock_table_name(thd, table);
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_open);
return -1; return -1;
} }
...@@ -838,6 +839,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table) ...@@ -838,6 +839,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
reg_ext, 4), reg_ext, 4),
MYF(MY_WME))) MYF(MY_WME)))
{ {
unlock_table_name(thd, table);
return send_check_errmsg(thd, table, "restore", return send_check_errmsg(thd, table, "restore",
"Failed copying .frm file"); "Failed copying .frm file");
} }
...@@ -848,6 +850,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table) ...@@ -848,6 +850,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table)
if(generate_table(thd, table, 0)) if(generate_table(thd, table, 0))
{ {
unlock_table_name(thd, table);
thd->net.no_send_ok = save_no_send_ok; thd->net.no_send_ok = save_no_send_ok;
return send_check_errmsg(thd, table, "restore", return send_check_errmsg(thd, table, "restore",
"Failed generating table from .frm file"); "Failed generating table from .frm file");
...@@ -906,7 +909,8 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -906,7 +909,8 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
// now we should be able to open the partially restored table // now we should be able to open the partially restored table
// to finish the restore in the handler later on // to finish the restore in the handler later on
table->table = reopen_name_locked_table(thd, table); if(!(table->table = reopen_name_locked_table(thd, table)))
unlock_table_name(thd, table);
} }
if (!table->table) if (!table->table)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment