diff options
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r-- | sql/item_strfunc.cc | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 267036e4a3d..be94f19f597 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1629,16 +1629,17 @@ String *Item_func_password::val_str(String *str) return 0; if (res->length() == 0) return &my_empty_string; - make_scrambled_password(tmp_value, res->c_ptr()); + my_make_scrambled_password(tmp_value, res->ptr(), res->length()); str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, res->charset()); return str; } -char *Item_func_password::alloc(THD *thd, const char *password) +char *Item_func_password::alloc(THD *thd, const char *password, + size_t pass_len) { char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1); if (buff) - make_scrambled_password(buff, password); + my_make_scrambled_password(buff, password, pass_len); return buff; } @@ -1652,16 +1653,17 @@ String *Item_func_old_password::val_str(String *str) return 0; if (res->length() == 0) return &my_empty_string; - make_scrambled_password_323(tmp_value, res->c_ptr()); + my_make_scrambled_password_323(tmp_value, res->ptr(), res->length()); str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH_323, res->charset()); return str; } -char *Item_func_old_password::alloc(THD *thd, const char *password) +char *Item_func_old_password::alloc(THD *thd, const char *password, + size_t pass_len) { char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1); if (buff) - make_scrambled_password_323(buff, password); + my_make_scrambled_password_323(buff, password, pass_len); return buff; } @@ -2706,7 +2708,13 @@ String *Item_func_conv_charset::val_str(String *str) DBUG_ASSERT(fixed == 1); if (use_cached_value) return null_value ? 0 : &str_value; - String *arg= args[0]->val_str(str); + /* + Here we don't pass 'str' as a parameter to args[0]->val_str() + as 'str' may point to 'str_value' (e.g. see Item::save_in_field()), + which we use below to convert string. + Use argument's 'str_value' instead. + */ + String *arg= args[0]->val_str(&args[0]->str_value); uint dummy_errors; if (!arg) { @@ -2943,7 +2951,7 @@ String *Item_load_file::val_str(String *str) ) goto err; - (void) fn_format(path, file_name->c_ptr(), mysql_real_data_home, "", + (void) fn_format(path, file_name->c_ptr_safe(), mysql_real_data_home, "", MY_RELATIVE_PATH | MY_UNPACK_FILENAME); /* Read only allowed from within dir specified by secure_file_priv */ @@ -2969,7 +2977,7 @@ String *Item_load_file::val_str(String *str) } if (tmp_value.alloc(stat_info.st_size)) goto err; - if ((file = my_open(file_name->c_ptr(), O_RDONLY, MYF(0))) < 0) + if ((file = my_open(file_name->ptr(), O_RDONLY, MYF(0))) < 0) goto err; if (my_read(file, (uchar*) tmp_value.ptr(), stat_info.st_size, MYF(MY_NABP))) { @@ -3219,7 +3227,21 @@ longlong Item_func_uncompressed_length::val_int() if (res->is_empty()) return 0; /* - res->ptr() using is safe because we have tested that string is not empty, + If length is <= 4 bytes, data is corrupt. This is the best we can do + to detect garbage input without decompressing it. + */ + if (res->length() <= 4) + { + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_ZLIB_Z_DATA_ERROR, + ER(ER_ZLIB_Z_DATA_ERROR)); + null_value= 1; + return 0; + } + + /* + res->ptr() using is safe because we have tested that string is at least + 5 bytes long. res->c_ptr() is not used because: - we do not need \0 terminated string to get first 4 bytes - c_ptr() tests simbol after string end (uninitialiozed memory) which |