mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Reduce usage of strlen()
Changes: - To detect automatic strlen() I removed the methods in String that uses 'const char *' without a length: - String::append(const char*) - Binary_string(const char *str) - String(const char *str, CHARSET_INFO *cs) - append_for_single_quote(const char *) All usage of append(const char*) is changed to either use String::append(char), String::append(const char*, size_t length) or String::append(LEX_CSTRING) - Added STRING_WITH_LEN() around constant string arguments to String::append() - Added overflow argument to escape_string_for_mysql() and escape_quotes_for_mysql() instead of returning (size_t) -1 on overflow. This was needed as most usage of the above functions never tested the result for -1 and would have given wrong results or crashes in case of overflows. - Added Item_func_or_sum::func_name_cstring(), which returns LEX_CSTRING. Changed all Item_func::func_name()'s to func_name_cstring()'s. The old Item_func_or_sum::func_name() is now an inline function that returns func_name_cstring().str. - Changed Item::mode_name() and Item::func_name_ext() to return LEX_CSTRING. - Changed for some functions the name argument from const char * to to const LEX_CSTRING &: - Item::Item_func_fix_attributes() - Item::check_type_...() - Type_std_attributes::agg_item_collations() - Type_std_attributes::agg_item_set_converter() - Type_std_attributes::agg_arg_charsets...() - Type_handler_hybrid_field_type::aggregate_for_result() - Type_handler_geometry::check_type_geom_or_binary() - Type_handler::Item_func_or_sum_illegal_param() - Predicant_to_list_comparator::add_value_skip_null() - Predicant_to_list_comparator::add_value() - cmp_item_row::prepare_comparators() - cmp_item_row::aggregate_row_elements_for_comparison() - Cursor_ref::print_func() - Removes String_space() as it was only used in one cases and that could be simplified to not use String_space(), thanks to the fixed my_vsnprintf(). - Added some const LEX_CSTRING's for common strings: - NULL_clex_str, DATA_clex_str, INDEX_clex_str. - Changed primary_key_name to a LEX_CSTRING - Renamed String::set_quick() to String::set_buffer_if_not_allocated() to clarify what the function really does. - Rename of protocol function: bool store(const char *from, CHARSET_INFO *cs) to bool store_string_or_null(const char *from, CHARSET_INFO *cs). This was done to both clarify the difference between this 'store' function and also to make it easier to find unoptimal usage of store() calls. - Added Protocol::store(const LEX_CSTRING*, CHARSET_INFO*) - Changed some 'const char*' arrays to instead be of type LEX_CSTRING. - class Item_func_units now used LEX_CSTRING for name. Other things: - Fixed a bug in mysql.cc:construct_prompt() where a wrong escape character in the prompt would cause some part of the prompt to be duplicated. - Fixed a lot of instances where the length of the argument to append is known or easily obtain but was not used. - Removed some not needed 'virtual' definition for functions that was inherited from the parent. I added override to these. - Fixed Ordered_key::print() to preallocate needed buffer. Old code could case memory overruns. - Simplified some loops when adding char * to a String with delimiters.
This commit is contained in:
123
client/mysql.cc
123
client/mysql.cc
@@ -2062,13 +2062,14 @@ static int read_and_execute(bool interactive)
|
||||
{
|
||||
status.exit_status= 1;
|
||||
String msg;
|
||||
msg.append("ASCII '\\0' appeared in the statement, but this is not "
|
||||
"allowed unless option --binary-mode is enabled and mysql is "
|
||||
"run in non-interactive mode. Set --binary-mode to 1 if ASCII "
|
||||
"'\\0' is expected. Query: '");
|
||||
msg.append(STRING_WITH_LEN(
|
||||
"ASCII '\\0' appeared in the statement, but this is not "
|
||||
"allowed unless option --binary-mode is enabled and mysql is "
|
||||
"run in non-interactive mode. Set --binary-mode to 1 if ASCII "
|
||||
"'\\0' is expected. Query: '"));
|
||||
msg.append(glob_buffer);
|
||||
msg.append(line);
|
||||
msg.append("'.");
|
||||
msg.append(line, strlen(line));
|
||||
msg.append(STRING_WITH_LEN("'."));
|
||||
put_info(msg.c_ptr(), INFO_ERROR);
|
||||
break;
|
||||
}
|
||||
@@ -2462,8 +2463,9 @@ static bool add_line(String &buffer, char *line, size_t line_length,
|
||||
my_isspace(charset_info, pos[2]))))
|
||||
{
|
||||
// Add trailing single line comments to this statement
|
||||
buffer.append(pos);
|
||||
pos+= strlen(pos);
|
||||
size_t length= strlen(pos);
|
||||
buffer.append(pos, length);
|
||||
pos+= length;
|
||||
}
|
||||
|
||||
pos--;
|
||||
@@ -2509,7 +2511,7 @@ static bool add_line(String &buffer, char *line, size_t line_length,
|
||||
{
|
||||
bool started_with_nothing= !buffer.length();
|
||||
|
||||
buffer.append(pos);
|
||||
buffer.append(pos, strlen(pos));
|
||||
|
||||
/*
|
||||
A single-line comment by itself gets sent immediately so that
|
||||
@@ -2667,7 +2669,7 @@ static void fix_history(String *final_command)
|
||||
not in string, change to space
|
||||
if in string, leave it alone
|
||||
*/
|
||||
fixed_buffer.append(str_char == '\0' ? " " : "\n");
|
||||
fixed_buffer.append(str_char == '\0' ? ' ' : '\n');
|
||||
total_lines++;
|
||||
break;
|
||||
case '\\':
|
||||
@@ -3313,7 +3315,8 @@ com_go(String *buffer,char *line __attribute__((unused)))
|
||||
#ifdef HAVE_READLINE
|
||||
if (status.add_to_history)
|
||||
{
|
||||
buffer->append(vertical ? "\\G" : delimiter);
|
||||
const char *delim= vertical ? "\\G" : delimiter;
|
||||
buffer->append(delim, strlen(delim));
|
||||
/* Append final command onto history */
|
||||
fix_history(buffer);
|
||||
}
|
||||
@@ -5227,20 +5230,27 @@ static const char *construct_prompt()
|
||||
add_int_to_prompt(++prompt_counter);
|
||||
break;
|
||||
case 'v':
|
||||
if (connected)
|
||||
processed_prompt.append(mysql_get_server_info(&mysql));
|
||||
else
|
||||
processed_prompt.append("not_connected");
|
||||
{
|
||||
const char *info= (connected ?
|
||||
mysql_get_server_info(&mysql) :
|
||||
"not_connected");
|
||||
processed_prompt.append(info, strlen(info));
|
||||
break;
|
||||
}
|
||||
case 'd':
|
||||
processed_prompt.append(current_db ? current_db : "(none)");
|
||||
break;
|
||||
case 'N':
|
||||
if (connected)
|
||||
processed_prompt.append(mysql_get_server_name(&mysql));
|
||||
else
|
||||
processed_prompt.append("unknown");
|
||||
{
|
||||
const char *db= current_db ? current_db : "(none)";
|
||||
processed_prompt.append(db, strlen(db));
|
||||
break;
|
||||
}
|
||||
case 'N':
|
||||
{
|
||||
const char *name= (connected ?
|
||||
mysql_get_server_name(&mysql) :
|
||||
"unknown");
|
||||
processed_prompt.append(name, strlen(name));
|
||||
break;
|
||||
}
|
||||
case 'h':
|
||||
case 'H':
|
||||
{
|
||||
@@ -5249,16 +5259,20 @@ static const char *construct_prompt()
|
||||
if (strstr(prompt, "Localhost") || strstr(prompt, "localhost "))
|
||||
{
|
||||
if (*c == 'h')
|
||||
processed_prompt.append("localhost");
|
||||
processed_prompt.append(STRING_WITH_LEN("localhost"));
|
||||
else
|
||||
{
|
||||
static char hostname[FN_REFLEN];
|
||||
if (hostname[0])
|
||||
processed_prompt.append(hostname);
|
||||
static size_t hostname_length;
|
||||
if (hostname_length)
|
||||
processed_prompt.append(hostname, hostname_length);
|
||||
else if (gethostname(hostname, sizeof(hostname)) == 0)
|
||||
processed_prompt.append(hostname);
|
||||
{
|
||||
hostname_length= strlen(hostname);
|
||||
processed_prompt.append(hostname, hostname_length);
|
||||
}
|
||||
else
|
||||
processed_prompt.append("gethostname(2) failed");
|
||||
processed_prompt.append(STRING_WITH_LEN("gethostname(2) failed"));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -5273,38 +5287,47 @@ static const char *construct_prompt()
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
if (!connected)
|
||||
{
|
||||
processed_prompt.append("not_connected");
|
||||
processed_prompt.append(STRING_WITH_LEN("not_connected"));
|
||||
break;
|
||||
}
|
||||
|
||||
const char *host_info = mysql_get_host_info(&mysql);
|
||||
if (strstr(host_info, "memory"))
|
||||
{
|
||||
processed_prompt.append( mysql.host );
|
||||
processed_prompt.append( mysql.host, strlen(mysql.host));
|
||||
}
|
||||
else if (strstr(host_info,"TCP/IP") ||
|
||||
!mysql.unix_socket)
|
||||
add_int_to_prompt(mysql.port);
|
||||
else
|
||||
{
|
||||
char *pos=strrchr(mysql.unix_socket,'/');
|
||||
processed_prompt.append(pos ? pos+1 : mysql.unix_socket);
|
||||
char *pos= strrchr(mysql.unix_socket,'/');
|
||||
const char *tmp= pos ? pos+1 : mysql.unix_socket;
|
||||
processed_prompt.append(tmp, strlen(tmp));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 'U':
|
||||
{
|
||||
const char *name;
|
||||
if (!full_username)
|
||||
init_username();
|
||||
processed_prompt.append(full_username ? full_username :
|
||||
(current_user ? current_user : "(unknown)"));
|
||||
name= (full_username ? full_username :
|
||||
(current_user ? current_user : "(unknown)"));
|
||||
processed_prompt.append(name, strlen(name));
|
||||
break;
|
||||
}
|
||||
case 'u':
|
||||
{
|
||||
const char *name;
|
||||
if (!full_username)
|
||||
init_username();
|
||||
processed_prompt.append(part_username ? part_username :
|
||||
(current_user ? current_user : "(unknown)"));
|
||||
name= (part_username ? part_username :
|
||||
(current_user ? current_user : "(unknown)"));
|
||||
processed_prompt.append(name, strlen(name));
|
||||
break;
|
||||
}
|
||||
case PROMPT_CHAR:
|
||||
processed_prompt.append(PROMPT_CHAR);
|
||||
break;
|
||||
@@ -5345,29 +5368,39 @@ static const char *construct_prompt()
|
||||
add_int_to_prompt(t->tm_year+1900);
|
||||
break;
|
||||
case 'D':
|
||||
{
|
||||
char* dateTime;
|
||||
const char *tmp;
|
||||
dateTime = ctime(&lclock);
|
||||
processed_prompt.append(strtok(dateTime,"\n"));
|
||||
tmp= strtok(dateTime,"\n");
|
||||
processed_prompt.append(tmp, strlen(tmp));
|
||||
break;
|
||||
}
|
||||
case 's':
|
||||
if (t->tm_sec < 10)
|
||||
processed_prompt.append('0');
|
||||
add_int_to_prompt(t->tm_sec);
|
||||
break;
|
||||
case 'w':
|
||||
processed_prompt.append(day_names[t->tm_wday]);
|
||||
break;
|
||||
{
|
||||
const char *name= day_names[t->tm_wday];
|
||||
processed_prompt.append(name, strlen(name));
|
||||
break;
|
||||
}
|
||||
case 'P':
|
||||
processed_prompt.append(t->tm_hour < 12 ? "am" : "pm");
|
||||
processed_prompt.append(t->tm_hour < 12 ? "am" : "pm", 2);
|
||||
break;
|
||||
case 'o':
|
||||
add_int_to_prompt(t->tm_mon+1);
|
||||
break;
|
||||
case 'O':
|
||||
processed_prompt.append(month_names[t->tm_mon]);
|
||||
{
|
||||
const char *name= month_names[t->tm_mon];
|
||||
processed_prompt.append(name, strlen(name));
|
||||
break;
|
||||
}
|
||||
case '\'':
|
||||
processed_prompt.append("'");
|
||||
processed_prompt.append('\'');
|
||||
break;
|
||||
case '"':
|
||||
processed_prompt.append('"');
|
||||
@@ -5379,10 +5412,10 @@ static const char *construct_prompt()
|
||||
processed_prompt.append('\t');
|
||||
break;
|
||||
case 'l':
|
||||
processed_prompt.append(delimiter_str);
|
||||
processed_prompt.append(delimiter_str, strlen(delimiter_str));
|
||||
break;
|
||||
default:
|
||||
processed_prompt.append(c);
|
||||
processed_prompt.append(*c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5394,8 +5427,8 @@ static const char *construct_prompt()
|
||||
static void add_int_to_prompt(int toadd)
|
||||
{
|
||||
char buffer[16];
|
||||
int10_to_str(toadd,buffer,10);
|
||||
processed_prompt.append(buffer);
|
||||
size_t length= (size_t) (int10_to_str(toadd,buffer,10) - buffer);
|
||||
processed_prompt.append(buffer, length);
|
||||
}
|
||||
|
||||
static void init_username()
|
||||
|
Reference in New Issue
Block a user