Skip to content

Commit 314cf99

Browse files
author
monty@mysql.com
committed
Fixed memory reference errors found by valgrind
1 parent 10f41d7 commit 314cf99

15 files changed

+90
-39
lines changed

myisam/mi_create.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -630,10 +630,12 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
630630
{
631631
HA_KEYSEG sseg;
632632
sseg.type=SPTYPE;
633-
sseg.language= 7;
633+
sseg.language= 7; /* Binary */
634634
sseg.null_bit=0;
635635
sseg.bit_start=0;
636636
sseg.bit_end=0;
637+
sseg.bit_length= 0;
638+
sseg.bit_pos= 0;
637639
sseg.length=SPLEN;
638640
sseg.null_pos=0;
639641
sseg.start=j*SPLEN;

mysql-test/r/type_timestamp.result

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ UPDATE t1 SET value="my value" WHERE id="myKey";
3535
SELECT stamp FROM t1 WHERE id="myKey";
3636
stamp
3737
1999-04-02 00:00:00
38+
UPDATE t1 SET id="myKey" WHERE value="my value";
39+
SELECT stamp FROM t1 WHERE id="myKey";
40+
stamp
41+
1999-04-02 00:00:00
3842
drop table t1;
3943
create table t1 (a timestamp);
4044
insert into t1 values (now());

mysql-test/t/func_compress.test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#
33
# Test for compress and uncompress functions:
44
#
5+
# Note that this test gives error in the gzip library when running under
6+
# valgrind, but these warnings can be ignored
57

68
select @test_compress_string:='string for test compress function aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ';
79
select length(@test_compress_string);

mysql-test/t/type_timestamp.test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ INSERT INTO t1 VALUES ("my value", "myKey","1999-04-02 00:00:00");
2929
SELECT stamp FROM t1 WHERE id="myKey";
3030
UPDATE t1 SET value="my value" WHERE id="myKey";
3131
SELECT stamp FROM t1 WHERE id="myKey";
32+
UPDATE t1 SET id="myKey" WHERE value="my value";
33+
SELECT stamp FROM t1 WHERE id="myKey";
3234
drop table t1;
3335

3436
create table t1 (a timestamp);

sql/field.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -952,14 +952,20 @@ class Field_varstring :public Field_str {
952952
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
953953
unireg_check_arg, field_name_arg, table_arg, cs),
954954
length_bytes(length_bytes_arg)
955-
{}
955+
{
956+
if (table)
957+
table->s->varchar_fields++;
958+
}
956959
Field_varstring(uint32 len_arg,bool maybe_null_arg,
957960
const char *field_name_arg,
958961
struct st_table *table_arg, CHARSET_INFO *cs)
959962
:Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0,
960963
NONE, field_name_arg, table_arg, cs),
961964
length_bytes(len_arg < 256 ? 1 :2)
962-
{}
965+
{
966+
if (table)
967+
table->s->varchar_fields++;
968+
}
963969

964970
enum_field_types type() const { return MYSQL_TYPE_VARCHAR; }
965971
enum ha_base_keytype key_type() const;

sql/ha_federated.cc

100755100644
File mode changed.

sql/item_cmpfunc.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2519,7 +2519,7 @@ longlong Item_func_regex::val_int()
25192519
regfree(&preg);
25202520
regex_compiled=0;
25212521
}
2522-
if (regcomp(&preg,res2->c_ptr(),
2522+
if (regcomp(&preg,res2->c_ptr_safe(),
25232523
((cmp_collation.collation->state &
25242524
(MY_CS_BINSORT | MY_CS_CSSORT)) ?
25252525
REG_EXTENDED | REG_NOSUB :

sql/opt_range.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3589,7 +3589,6 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
35893589
Item_func::Functype type,Item *value)
35903590
{
35913591
uint maybe_null=(uint) field->real_maybe_null(), copies;
3592-
uint field_length=field->pack_length()+maybe_null;
35933592
bool optimize_range;
35943593
SEL_ARG *tree;
35953594
char *str, *str2;
@@ -3639,6 +3638,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
36393638
char buff1[MAX_FIELD_WIDTH],*min_str,*max_str;
36403639
String tmp(buff1,sizeof(buff1),value->collation.collation),*res;
36413640
uint length,offset,min_length,max_length;
3641+
uint field_length= field->pack_length()+maybe_null;
36423642

36433643
if (!optimize_range)
36443644
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,
36833683
length+=offset;
36843684
if (!(min_str= (char*) alloc_root(param->mem_root, length*2)))
36853685
DBUG_RETURN(0);
3686+
36863687
max_str=min_str+length;
36873688
if (maybe_null)
36883689
max_str[0]= min_str[0]=0;
36893690

3691+
field_length-= maybe_null;
36903692
like_error= my_like_range(field->charset(),
36913693
res->ptr(), res->length(),
36923694
((Item_func_like*)(param->cond))->escape,
36933695
wild_one, wild_many,
3694-
field_length-maybe_null,
3696+
field_length,
36953697
min_str+offset, max_str+offset,
36963698
&min_length, &max_length);
36973699
if (like_error) // Can't optimize with LIKE
36983700
DBUG_RETURN(0);
36993701

3700-
if (offset != maybe_null) // Blob
3702+
if (offset != maybe_null) // BLOB or VARCHAR
37013703
{
37023704
int2store(min_str+maybe_null,min_length);
37033705
int2store(max_str+maybe_null,max_length);

sql/sql_acl.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4800,7 +4800,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
48004800
rw_unlock(&LOCK_grant);
48014801
close_thread_tables(thd);
48024802
if (result)
4803-
my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr());
4803+
my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr_safe());
48044804
DBUG_RETURN(result);
48054805
}
48064806

@@ -4905,7 +4905,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
49054905
rw_unlock(&LOCK_grant);
49064906
close_thread_tables(thd);
49074907
if (result)
4908-
my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr());
4908+
my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe());
49094909
DBUG_RETURN(result);
49104910
}
49114911

sql/sql_parse.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1911,7 +1911,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
19111911
{
19121912
DBUG_ENTER("prepare_schema_table");
19131913
SELECT_LEX *sel= 0;
1914-
switch(schema_table_idx) {
1914+
switch (schema_table_idx) {
19151915
case SCH_SCHEMATA:
19161916
#if defined(DONT_ALLOW_SHOW_COMMANDS)
19171917
my_message(ER_NOT_ALLOWED_COMMAND,
@@ -1953,7 +1953,11 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
19531953
thd->priv_user, thd->priv_host, db);
19541954
DBUG_RETURN(1);
19551955
}
1956-
lex->select_lex.db= db;
1956+
/*
1957+
We need to do a copy to make this prepared statement safe if this
1958+
was thd->db
1959+
*/
1960+
lex->select_lex.db= thd->strdup(db);
19571961
break;
19581962
}
19591963
#endif

sql/sql_show.cc

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,14 +1793,28 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
17931793
SELECT_LEX *select_lex= &lex->select_lex;
17941794
SELECT_LEX *lsel= tables->schema_select_lex;
17951795
ST_SCHEMA_TABLE *schema_table= tables->schema_table;
1796-
DBUG_ENTER("fill_schema_tables");
1796+
SELECT_LEX sel;
1797+
INDEX_FIELD_VALUES idx_field_vals;
1798+
char path[FN_REFLEN], *end, *base_name, *file_name;
1799+
uint len;
1800+
bool with_i_schema;
1801+
enum enum_schema_tables schema_table_idx;
1802+
thr_lock_type lock_type;
1803+
List<char> bases;
1804+
COND *partial_cond;
1805+
DBUG_ENTER("get_all_tables");
1806+
1807+
LINT_INIT(end);
1808+
LINT_INIT(len);
17971809

17981810
if (lsel)
17991811
{
18001812
TABLE *old_open_tables= thd->open_tables;
18011813
TABLE_LIST *show_table_list= (TABLE_LIST*) lsel->table_list.first;
1814+
bool res;
1815+
18021816
lex->all_selects_list= lsel;
1803-
bool res= open_and_lock_tables(thd, show_table_list);
1817+
res= open_and_lock_tables(thd, show_table_list);
18041818
if (schema_table->process_table(thd, show_table_list,
18051819
table, res, show_table_list->db,
18061820
show_table_list->table_name))
@@ -1813,15 +1827,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
18131827
DBUG_RETURN(0);
18141828
}
18151829

1816-
SELECT_LEX sel;
1817-
INDEX_FIELD_VALUES idx_field_vals;
1818-
char path[FN_REFLEN], *end= 0, *base_name, *file_name;
1819-
uint len= 0;
1820-
bool with_i_schema;
1821-
List<char> bases;
18221830
lex->all_selects_list= &sel;
1823-
enum enum_schema_tables schema_table_idx= get_schema_table_idx(schema_table);
1824-
thr_lock_type lock_type= TL_UNLOCK;
1831+
schema_table_idx= get_schema_table_idx(schema_table);
1832+
lock_type= TL_UNLOCK;
1833+
18251834
if (schema_table_idx == SCH_TABLES)
18261835
lock_type= TL_READ;
18271836
get_index_field_values(lex, &idx_field_vals);
@@ -1833,9 +1842,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
18331842
if (mysql_find_files(thd, &bases, NullS, mysql_data_home,
18341843
idx_field_vals.db_value, 1))
18351844
return 1;
1845+
18361846
List_iterator_fast<char> it(bases);
1837-
COND *partial_cond= make_cond_for_info_schema(cond, tables);
1838-
while ((base_name=it++) ||
1847+
partial_cond= make_cond_for_info_schema(cond, tables);
1848+
while ((base_name= it++) ||
18391849
/*
18401850
generate error for non existing database.
18411851
(to save old behaviour for SHOW TABLES FROM db)
@@ -1868,8 +1878,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
18681878
DBUG_RETURN(1);
18691879
}
18701880

1871-
List_iterator_fast<char> it(files);
1872-
while ((file_name=it++))
1881+
List_iterator_fast<char> it_files(files);
1882+
while ((file_name= it_files++))
18731883
{
18741884
restore_record(table, s->default_values);
18751885
table->field[schema_table->idx_field1]->
@@ -1889,8 +1899,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
18891899
else
18901900
{
18911901
my_snprintf(end, len, "/%s%s", file_name, reg_ext);
1892-
switch (mysql_frm_type(path))
1893-
{
1902+
switch (mysql_frm_type(path)) {
18941903
case FRMTYPE_ERROR:
18951904
table->field[3]->store("ERROR", 5, system_charset_info);
18961905
break;
@@ -3188,9 +3197,7 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
31883197
}
31893198
table->s->tmp_table= TMP_TABLE;
31903199
table->grant.privilege= SELECT_ACL;
3191-
table->alias_name_used= my_strcasecmp(table_alias_charset,
3192-
table_list->table_name,
3193-
table_list->alias);
3200+
table->alias_name_used= 0;
31943201
table_list->schema_table_name= table_list->table_name;
31953202
table_list->table_name= (char*) table->s->table_name;
31963203
table_list->table= table;

sql/sql_update.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields);
3131

3232
static bool compare_record(TABLE *table, ulong query_id)
3333
{
34-
if (!table->s->blob_fields)
34+
if (table->s->blob_fields + table->s->varchar_fields == 0)
3535
return cmp_record(table,record[1]);
3636
/* Compare null bits */
3737
if (memcmp(table->null_flags,

sql/table.cc

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,8 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
288288
records=2;
289289
else
290290
records=1;
291-
if (prgflag & (READ_ALL+EXTRA_RECORD)) records++;
291+
if (prgflag & (READ_ALL+EXTRA_RECORD))
292+
records++;
292293
/* QQ: TODO, remove the +1 from below */
293294
rec_buff_length= ALIGN_SIZE(share->reclength + 1 +
294295
outparam->file->extra_rec_buf_length());
@@ -304,12 +305,32 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
304305
MYF(MY_NABP)))
305306
goto err_not_open; /* purecov: inspected */
306307

307-
outparam->record[0]= record+ rec_buff_length;
308-
if (records > 2)
309-
outparam->record[1]= record+ rec_buff_length*2;
308+
if (records == 1)
309+
{
310+
/* We are probably in hard repair, and the buffers should not be used */
311+
outparam->record[0]= outparam->record[1]= share->default_values;
312+
}
310313
else
311-
outparam->record[1]= outparam->record[0]; // Safety
314+
{
315+
outparam->record[0]= record+ rec_buff_length;
316+
if (records > 2)
317+
outparam->record[1]= record+ rec_buff_length*2;
318+
else
319+
outparam->record[1]= outparam->record[0]; // Safety
320+
}
312321

322+
#ifdef HAVE_purify
323+
/*
324+
We need this because when we read var-length rows, we are not updating
325+
bytes after end of varchar
326+
*/
327+
if (records > 1)
328+
{
329+
memcpy(outparam->record[0], share->default_values, rec_buff_length);
330+
if (records > 2)
331+
memcpy(outparam->record[1], share->default_values, rec_buff_length);
332+
}
333+
#endif
313334
VOID(my_seek(file,pos,MY_SEEK_SET,MYF(0)));
314335
if (my_read(file,(byte*) head,288,MYF(MY_NABP))) goto err_not_open;
315336
if (crypted)
@@ -822,7 +843,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
822843
outparam->file=0; // For easier errorchecking
823844
outparam->db_stat=0;
824845
hash_free(&share->name_hash);
825-
free_root(&share->mem_root, MYF(0));
846+
free_root(&outparam->mem_root, MYF(0));
826847
my_free((char*) outparam->alias, MYF(MY_ALLOW_ZERO_PTR));
827848
DBUG_RETURN (error);
828849
} /* openfrm */

sql/table.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ typedef struct st_table_share
137137
uint uniques; /* Number of UNIQUE index */
138138
uint null_fields; /* number of null fields */
139139
uint blob_fields; /* number of blob fields */
140+
uint varchar_fields; /* number of varchar fields */
140141
uint db_create_options; /* Create options from database */
141142
uint db_options_in_use; /* Options in use */
142143
uint db_record_offset; /* if HA_REC_IN_SEQ */

strings/ctype-mb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,9 +561,9 @@ my_bool my_like_range_mb(CHARSET_INFO *cs,
561561
*min_str++= *max_str++ = *ptr;
562562
}
563563

564-
*min_length= *max_length = (uint) (min_str - min_org);
564+
*min_length= *max_length = (uint) (min_str - min_org);
565565
while (min_str != min_end)
566-
*min_str++= *max_str= ' '; /* Because if key compression */
566+
*min_str++= *max_str++= ' '; /* Because if key compression */
567567
return 0;
568568
}
569569

0 commit comments

Comments
 (0)