summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2005-01-12 03:38:53 +0200
committerunknown <monty@mysql.com>2005-01-12 03:38:53 +0200
commit24a0275722914643a1a6498310bc5a04cea44a3b (patch)
tree6a8b1b01636a63430471b9c070075ba6ecaf9379 /sql
parent0b7895b9b14981926c34fbd833aed0d9235da68a (diff)
downloadmariadb-git-24a0275722914643a1a6498310bc5a04cea44a3b.tar.gz
Fixed memory reference errors found by valgrind
sql/ha_federated.cc: Change mode to -rw-rw-r-- myisam/mi_create.c: Ensure that all referenced memory is reset mysql-test/r/type_timestamp.result: More tests mysql-test/t/func_compress.test: Added comment mysql-test/t/type_timestamp.test: More tests sql/field.h: Count number of varchars in table sql/item_cmpfunc.cc: Safety fix (to avoid warning from valgrind) sql/opt_range.cc: Simple optimzation sql/sql_acl.cc: Safety fix (to avoid warning from valgrind) sql/sql_parse.cc: Safety fix for prepared statements sql/sql_show.cc: Move variable declarations first in function Remove hidden variable (it) Remove accessing freed memory (table_list->table_name) sql/sql_update.cc: Compare records with varchars correctly sql/table.cc: Safety fix when running with purify/valgrind Fix wrong memory reference in case of errors sql/table.h: Added counting of varchar fields strings/ctype-mb.c: Fill max_str properly
Diffstat (limited to 'sql')
-rw-r--r--sql/field.h10
-rw-r--r--[-rwxr-xr-x]sql/ha_federated.cc0
-rw-r--r--sql/item_cmpfunc.cc2
-rw-r--r--sql/opt_range.cc8
-rw-r--r--sql/sql_acl.cc4
-rw-r--r--sql/sql_parse.cc8
-rw-r--r--sql/sql_show.cc45
-rw-r--r--sql/sql_update.cc2
-rw-r--r--sql/table.cc33
-rw-r--r--sql/table.h1
10 files changed, 77 insertions, 36 deletions
diff --git a/sql/field.h b/sql/field.h
index 9e690705801..5e2a3f0e1c0 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -952,14 +952,20 @@ public:
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg, cs),
length_bytes(length_bytes_arg)
- {}
+ {
+ if (table)
+ table->s->varchar_fields++;
+ }
Field_varstring(uint32 len_arg,bool maybe_null_arg,
const char *field_name_arg,
struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, table_arg, cs),
length_bytes(len_arg < 256 ? 1 :2)
- {}
+ {
+ if (table)
+ table->s->varchar_fields++;
+ }
enum_field_types type() const { return MYSQL_TYPE_VARCHAR; }
enum ha_base_keytype key_type() const;
diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc
index abd33f2eaef..abd33f2eaef 100755..100644
--- a/sql/ha_federated.cc
+++ b/sql/ha_federated.cc
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index aa98f1860b6..16a3e86e519 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -2519,7 +2519,7 @@ longlong Item_func_regex::val_int()
regfree(&preg);
regex_compiled=0;
}
- if (regcomp(&preg,res2->c_ptr(),
+ if (regcomp(&preg,res2->c_ptr_safe(),
((cmp_collation.collation->state &
(MY_CS_BINSORT | MY_CS_CSSORT)) ?
REG_EXTENDED | REG_NOSUB :
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 0e46e39960e..e75071a19b5 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -3589,7 +3589,6 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
Item_func::Functype type,Item *value)
{
uint maybe_null=(uint) field->real_maybe_null(), copies;
- uint field_length=field->pack_length()+maybe_null;
bool optimize_range;
SEL_ARG *tree;
char *str, *str2;
@@ -3639,6 +3638,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
char buff1[MAX_FIELD_WIDTH],*min_str,*max_str;
String tmp(buff1,sizeof(buff1),value->collation.collation),*res;
uint length,offset,min_length,max_length;
+ uint field_length= field->pack_length()+maybe_null;
if (!optimize_range)
DBUG_RETURN(0); // Can't optimize this
@@ -3683,21 +3683,23 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
length+=offset;
if (!(min_str= (char*) alloc_root(param->mem_root, length*2)))
DBUG_RETURN(0);
+
max_str=min_str+length;
if (maybe_null)
max_str[0]= min_str[0]=0;
+ field_length-= maybe_null;
like_error= my_like_range(field->charset(),
res->ptr(), res->length(),
((Item_func_like*)(param->cond))->escape,
wild_one, wild_many,
- field_length-maybe_null,
+ field_length,
min_str+offset, max_str+offset,
&min_length, &max_length);
if (like_error) // Can't optimize with LIKE
DBUG_RETURN(0);
- if (offset != maybe_null) // Blob
+ if (offset != maybe_null) // BLOB or VARCHAR
{
int2store(min_str+maybe_null,min_length);
int2store(max_str+maybe_null,max_length);
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index b607f8a7822..e65c214c3a9 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -4800,7 +4800,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
if (result)
- my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr());
+ my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr_safe());
DBUG_RETURN(result);
}
@@ -4905,7 +4905,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
rw_unlock(&LOCK_grant);
close_thread_tables(thd);
if (result)
- my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr());
+ my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe());
DBUG_RETURN(result);
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 4b484500527..a0728f58372 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1911,7 +1911,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
{
DBUG_ENTER("prepare_schema_table");
SELECT_LEX *sel= 0;
- switch(schema_table_idx) {
+ switch (schema_table_idx) {
case SCH_SCHEMATA:
#if defined(DONT_ALLOW_SHOW_COMMANDS)
my_message(ER_NOT_ALLOWED_COMMAND,
@@ -1953,7 +1953,11 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
thd->priv_user, thd->priv_host, db);
DBUG_RETURN(1);
}
- lex->select_lex.db= db;
+ /*
+ We need to do a copy to make this prepared statement safe if this
+ was thd->db
+ */
+ lex->select_lex.db= thd->strdup(db);
break;
}
#endif
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 3aa39e87614..b1fd0cbbccd 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1793,14 +1793,28 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
SELECT_LEX *select_lex= &lex->select_lex;
SELECT_LEX *lsel= tables->schema_select_lex;
ST_SCHEMA_TABLE *schema_table= tables->schema_table;
- DBUG_ENTER("fill_schema_tables");
+ SELECT_LEX sel;
+ INDEX_FIELD_VALUES idx_field_vals;
+ char path[FN_REFLEN], *end, *base_name, *file_name;
+ uint len;
+ bool with_i_schema;
+ enum enum_schema_tables schema_table_idx;
+ thr_lock_type lock_type;
+ List<char> bases;
+ COND *partial_cond;
+ DBUG_ENTER("get_all_tables");
+
+ LINT_INIT(end);
+ LINT_INIT(len);
if (lsel)
{
TABLE *old_open_tables= thd->open_tables;
TABLE_LIST *show_table_list= (TABLE_LIST*) lsel->table_list.first;
+ bool res;
+
lex->all_selects_list= lsel;
- bool res= open_and_lock_tables(thd, show_table_list);
+ res= open_and_lock_tables(thd, show_table_list);
if (schema_table->process_table(thd, show_table_list,
table, res, show_table_list->db,
show_table_list->table_name))
@@ -1813,15 +1827,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
DBUG_RETURN(0);
}
- SELECT_LEX sel;
- INDEX_FIELD_VALUES idx_field_vals;
- char path[FN_REFLEN], *end= 0, *base_name, *file_name;
- uint len= 0;
- bool with_i_schema;
- List<char> bases;
lex->all_selects_list= &sel;
- enum enum_schema_tables schema_table_idx= get_schema_table_idx(schema_table);
- thr_lock_type lock_type= TL_UNLOCK;
+ schema_table_idx= get_schema_table_idx(schema_table);
+ lock_type= TL_UNLOCK;
+
if (schema_table_idx == SCH_TABLES)
lock_type= TL_READ;
get_index_field_values(lex, &idx_field_vals);
@@ -1833,9 +1842,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
if (mysql_find_files(thd, &bases, NullS, mysql_data_home,
idx_field_vals.db_value, 1))
return 1;
+
List_iterator_fast<char> it(bases);
- COND *partial_cond= make_cond_for_info_schema(cond, tables);
- while ((base_name=it++) ||
+ partial_cond= make_cond_for_info_schema(cond, tables);
+ while ((base_name= it++) ||
/*
generate error for non existing database.
(to save old behaviour for SHOW TABLES FROM db)
@@ -1868,8 +1878,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
DBUG_RETURN(1);
}
- List_iterator_fast<char> it(files);
- while ((file_name=it++))
+ List_iterator_fast<char> it_files(files);
+ while ((file_name= it_files++))
{
restore_record(table, s->default_values);
table->field[schema_table->idx_field1]->
@@ -1889,8 +1899,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
else
{
my_snprintf(end, len, "/%s%s", file_name, reg_ext);
- switch (mysql_frm_type(path))
- {
+ switch (mysql_frm_type(path)) {
case FRMTYPE_ERROR:
table->field[3]->store("ERROR", 5, system_charset_info);
break;
@@ -3188,9 +3197,7 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
}
table->s->tmp_table= TMP_TABLE;
table->grant.privilege= SELECT_ACL;
- table->alias_name_used= my_strcasecmp(table_alias_charset,
- table_list->table_name,
- table_list->alias);
+ table->alias_name_used= 0;
table_list->schema_table_name= table_list->table_name;
table_list->table_name= (char*) table->s->table_name;
table_list->table= table;
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index c35df041a39..d2220cd67c3 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -31,7 +31,7 @@ static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields);
static bool compare_record(TABLE *table, ulong query_id)
{
- if (!table->s->blob_fields)
+ if (table->s->blob_fields + table->s->varchar_fields == 0)
return cmp_record(table,record[1]);
/* Compare null bits */
if (memcmp(table->null_flags,
diff --git a/sql/table.cc b/sql/table.cc
index ddcb5117338..97f17ea2417 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -288,7 +288,8 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
records=2;
else
records=1;
- if (prgflag & (READ_ALL+EXTRA_RECORD)) records++;
+ if (prgflag & (READ_ALL+EXTRA_RECORD))
+ records++;
/* QQ: TODO, remove the +1 from below */
rec_buff_length= ALIGN_SIZE(share->reclength + 1 +
outparam->file->extra_rec_buf_length());
@@ -304,12 +305,32 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
MYF(MY_NABP)))
goto err_not_open; /* purecov: inspected */
- outparam->record[0]= record+ rec_buff_length;
- if (records > 2)
- outparam->record[1]= record+ rec_buff_length*2;
+ if (records == 1)
+ {
+ /* We are probably in hard repair, and the buffers should not be used */
+ outparam->record[0]= outparam->record[1]= share->default_values;
+ }
else
- outparam->record[1]= outparam->record[0]; // Safety
+ {
+ outparam->record[0]= record+ rec_buff_length;
+ if (records > 2)
+ outparam->record[1]= record+ rec_buff_length*2;
+ else
+ outparam->record[1]= outparam->record[0]; // Safety
+ }
+#ifdef HAVE_purify
+ /*
+ We need this because when we read var-length rows, we are not updating
+ bytes after end of varchar
+ */
+ if (records > 1)
+ {
+ memcpy(outparam->record[0], share->default_values, rec_buff_length);
+ if (records > 2)
+ memcpy(outparam->record[1], share->default_values, rec_buff_length);
+ }
+#endif
VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0)));
if (my_read(file,(byte*) head,288,MYF(MY_NABP))) goto err_not_open;
if (crypted)
@@ -822,7 +843,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
outparam->file=0; // For easier errorchecking
outparam->db_stat=0;
hash_free(&share->name_hash);
- free_root(&share->mem_root, MYF(0));
+ free_root(&outparam->mem_root, MYF(0));
my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR));
DBUG_RETURN (error);
} /* openfrm */
diff --git a/sql/table.h b/sql/table.h
index c4cb948914e..8240a3445ec 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -137,6 +137,7 @@ typedef struct st_table_share
uint uniques; /* Number of UNIQUE index */
uint null_fields; /* number of null fields */
uint blob_fields; /* number of blob fields */
+ uint varchar_fields; /* number of varchar fields */
uint db_create_options; /* Create options from database */
uint db_options_in_use; /* Options in use */
uint db_record_offset; /* if HA_REC_IN_SEQ */