Commit da3c5c3c authored by Jacob Mathew's avatar Jacob Mathew

MDEV-15698: Spider ignores syntax errors in connection string in COMMENT field

When a comma separator is missing between COMMENT fields, Spider ignores the
parameter values that are beyond the last expected parameter value.  There are
also some error messages that Spider does generate on COMMENT fields that are
incorrectly formed.

I have introduced additional infrastructure in Spider to fix these problems.

Author:
  Jacob Mathew.

Reviewer:
  Kentoku Shiba.

Cherry-Picked:
  Commit c10da98b on branch bb-10.3-MDEV-15698
parent 8fdeb079
......@@ -85,13 +85,12 @@ int spider_udf_set_copy_tables_param_default(
if (!copy_tables->param_name) \
{ \
if ((copy_tables->param_name = spider_get_string_between_quote( \
start_ptr, TRUE))) \
start_ptr, TRUE, &param_string_parse))) \
copy_tables->SPIDER_PARAM_STR_LEN(param_name) = \
strlen(copy_tables->param_name); \
else { \
error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM; \
my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR, \
MYF(0), tmp_ptr); \
else \
{ \
error_num = param_string_parse.print_param_error(); \
goto error; \
} \
DBUG_PRINT("info",("spider " title_name "=%s", copy_tables->param_name)); \
......@@ -111,9 +110,7 @@ int spider_udf_set_copy_tables_param_default(
{ \
if (hint_num < 0 || hint_num >= max_size) \
{ \
error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM; \
my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR, \
MYF(0), tmp_ptr); \
error_num = param_string_parse.print_param_error(); \
goto error; \
} else if (copy_tables->param_name[hint_num] != -1) \
break; \
......@@ -126,17 +123,13 @@ int spider_udf_set_copy_tables_param_default(
else if (copy_tables->param_name[hint_num] > max_val) \
copy_tables->param_name[hint_num] = max_val; \
} else { \
error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM; \
my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR, \
MYF(0), tmp_ptr); \
error_num = param_string_parse.print_param_error(); \
goto error; \
} \
DBUG_PRINT("info",("spider " title_name "[%d]=%d", hint_num, \
copy_tables->param_name[hint_num])); \
} else { \
error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM; \
my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR, \
MYF(0), tmp_ptr); \
error_num = param_string_parse.print_param_error(); \
goto error; \
} \
break; \
......@@ -155,10 +148,11 @@ int spider_udf_set_copy_tables_param_default(
copy_tables->param_name = min_val; \
else if (copy_tables->param_name > max_val) \
copy_tables->param_name = max_val; \
param_string_parse.set_param_value(tmp_ptr2, \
tmp_ptr2 + \
strlen(tmp_ptr2) + 1); \
} else { \
error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM; \
my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR, \
MYF(0), tmp_ptr); \
error_num = param_string_parse.print_param_error(); \
goto error; \
} \
DBUG_PRINT("info",("spider " title_name "=%d", copy_tables->param_name)); \
......@@ -177,10 +171,11 @@ int spider_udf_set_copy_tables_param_default(
copy_tables->param_name = atoi(tmp_ptr2); \
if (copy_tables->param_name < min_val) \
copy_tables->param_name = min_val; \
param_string_parse.set_param_value(tmp_ptr2, \
tmp_ptr2 + \
strlen(tmp_ptr2) + 1); \
} else { \
error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM; \
my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR, \
MYF(0), tmp_ptr); \
error_num = param_string_parse.print_param_error(); \
goto error; \
} \
DBUG_PRINT("info",("spider " title_name "=%d", copy_tables->param_name)); \
......@@ -200,10 +195,11 @@ int spider_udf_set_copy_tables_param_default(
my_strtoll10(tmp_ptr2, (char**) NULL, &error_num); \
if (copy_tables->param_name < min_val) \
copy_tables->param_name = min_val; \
param_string_parse.set_param_value(tmp_ptr2, \
tmp_ptr2 + \
strlen(tmp_ptr2) + 1); \
} else { \
error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM; \
my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR, \
MYF(0), tmp_ptr); \
error_num = param_string_parse.print_param_error(); \
goto error; \
} \
DBUG_PRINT("info",("spider " title_name "=%lld", \
......@@ -222,6 +218,7 @@ int spider_udf_parse_copy_tables_param(
char *sprit_ptr[2];
char *tmp_ptr, *tmp_ptr2, *start_ptr;
int title_length;
SPIDER_PARAM_STRING_PARSE param_string_parse;
DBUG_ENTER("spider_udf_parse_copy_tables_param");
copy_tables->bulk_insert_interval = -1;
copy_tables->bulk_insert_rows = -1;
......@@ -246,6 +243,7 @@ int spider_udf_parse_copy_tables_param(
DBUG_PRINT("info",("spider param_string=%s", param_string));
sprit_ptr[0] = param_string;
param_string_parse.init(param_string, ER_SPIDER_INVALID_UDF_PARAM_NUM);
while (sprit_ptr[0])
{
if ((sprit_ptr[1] = strchr(sprit_ptr[0], ',')))
......@@ -272,10 +270,14 @@ int spider_udf_parse_copy_tables_param(
title_length++;
start_ptr++;
}
param_string_parse.set_param_title(tmp_ptr, tmp_ptr + title_length);
switch (title_length)
{
case 0:
error_num = param_string_parse.print_param_error();
if (error_num)
goto error;
continue;
case 3:
#ifndef WITHOUT_SPIDER_BG_SEARCH
......@@ -286,55 +288,43 @@ int spider_udf_parse_copy_tables_param(
SPIDER_PARAM_STR("dtb", database);
SPIDER_PARAM_INT_WITH_MAX("utc", use_table_charset, 0, 1);
SPIDER_PARAM_INT_WITH_MAX("utr", use_transaction, 0, 1);
error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM;
my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR,
MYF(0), tmp_ptr);
error_num = param_string_parse.print_param_error();
goto error;
#ifndef WITHOUT_SPIDER_BG_SEARCH
case 7:
SPIDER_PARAM_INT_WITH_MAX("bg_mode", bg_mode, 0, 1);
error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM;
my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR,
MYF(0), tmp_ptr);
error_num = param_string_parse.print_param_error();
goto error;
#endif
case 8:
SPIDER_PARAM_STR("database", database);
error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM;
my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR,
MYF(0), tmp_ptr);
error_num = param_string_parse.print_param_error();
goto error;
case 15:
SPIDER_PARAM_INT_WITH_MAX("use_transaction", use_transaction, 0, 1);
error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM;
my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR,
MYF(0), tmp_ptr);
error_num = param_string_parse.print_param_error();
goto error;
case 16:
SPIDER_PARAM_LONGLONG("bulk_insert_rows", bulk_insert_rows, 1);
error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM;
my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR,
MYF(0), tmp_ptr);
error_num = param_string_parse.print_param_error();
goto error;
case 17:
SPIDER_PARAM_INT_WITH_MAX(
"use_table_charset", use_table_charset, 0, 1);
error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM;
my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR,
MYF(0), tmp_ptr);
error_num = param_string_parse.print_param_error();
goto error;
case 20:
SPIDER_PARAM_INT("bulk_insert_interval", bulk_insert_interval, 0);
error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM;
my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR,
MYF(0), tmp_ptr);
error_num = param_string_parse.print_param_error();
goto error;
default:
error_num = ER_SPIDER_INVALID_UDF_PARAM_NUM;
my_printf_error(error_num, ER_SPIDER_INVALID_UDF_PARAM_STR,
MYF(0), tmp_ptr);
error_num = param_string_parse.print_param_error();
goto error;
}
/* Verify that the remainder of the parameter value is whitespace */
if ((error_num = param_string_parse.has_extra_parameter_values()))
goto error;
}
set_default:
......
This diff is collapsed.
This diff is collapsed.
......@@ -13,6 +13,210 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
/*
Structure used to manage Spider parameter string parsing. Types of
parameters include:
- connection strings
- UDF parameters
A parameter string consists of one or more parameter definitions using
the following syntax:
<parameter title> <parameter value>
A comma is the separator character between multiple parameter definitions.
Parameter titles must not be quoted. Parameter values must be quoted with
single or double quotes.
*/
typedef struct st_spider_param_string_parse
{
char *start_ptr; /* Pointer to the start of the parameter string */
char *end_ptr; /* Pointer to the end of the parameter string */
char *start_title_ptr; /* Pointer to the start of the current parameter
title */
char *end_title_ptr; /* Pointer to the end of the current parameter
title */
char *start_value_ptr; /* Pointer to the start of the current parameter
value */
char *end_value_ptr; /* Pointer to the end of the current parameter
value */
int error_num; /* Error code of the error message to print when
an error is detected */
uint delim_title_len; /* Length of the paramater title's delimiter */
uint delim_value_len; /* Length of the paramater value's delimiter */
char delim_title; /* Current parameter title's delimiter character */
char delim_value; /* Current parameter value's delimiter character */
/**
Initialize the parameter string parse information.
@param param_string Pointer to the parameter string being parsed.
@param error_code Error code of the error message to print when
an error is detected.
*/
inline void init(char *param_string, int error_code)
{
start_ptr = param_string;
end_ptr = start_ptr + strlen(start_ptr);
init_param_title();
init_param_value();
error_num = error_code;
}
/**
Initialize the current parameter title.
*/
inline void init_param_title()
{
start_title_ptr = end_title_ptr = NULL;
delim_title_len = 0;
delim_title = '\0';
}
/**
Save pointers to the start and end positions of the current parameter
title in the parameter string. Also save the parameter title's
delimiter character.
@param start_value Pointer to the start position of the current
parameter title.
@param end_value Pointer to the end position of the current
parameter title.
*/
inline void set_param_title(char *start_title, char *end_title)
{
start_title_ptr = start_title;
end_title_ptr = end_title;
if (*start_title == '"' ||
*start_title == '\'')
{
delim_title = *start_title;
if (start_title >= start_ptr && *--start_title == '\\')
delim_title_len = 2;
else
delim_title_len = 1;
}
}
/**
Initialize the current parameter value.
*/
inline void init_param_value()
{
start_value_ptr = end_value_ptr = NULL;
delim_value_len = 0;
delim_value = '\0';
}
/**
Save pointers to the start and end positions of the current parameter
value in the parameter string. Also save the parameter value's
delimiter character.
@param start_value Pointer to the start position of the current
parameter value.
@param end_value Pointer to the end position of the current
parameter value.
*/
inline void set_param_value(char *start_value, char *end_value)
{
start_value_ptr = start_value--;
end_value_ptr = end_value;
if (*start_value == '"' ||
*start_value == '\'')
{
delim_value = *start_value;
if (*--start_value == '\\')
delim_value_len = 2;
else
delim_value_len = 1;
}
}
/**
Determine whether the current parameter in the parameter string has
extra parameter values.
@return 0 Current parameter value in the parameter string
does not have extra parameter values.
<> 0 Error code indicating that the current parameter
value in the parameter string has extra
parameter values.
*/
inline int has_extra_parameter_values()
{
int error_num = 0;
DBUG_ENTER("has_extra_parameter_values");
if (end_value_ptr)
{
/* There is a current parameter value */
char *end_param_ptr = end_value_ptr;
while (end_param_ptr < end_ptr &&
(*end_param_ptr == ' ' || *end_param_ptr == '\r' ||
*end_param_ptr == '\n' || *end_param_ptr == '\t'))
end_param_ptr++;
if (end_param_ptr < end_ptr && *end_param_ptr != '\0')
{
/* Extra values in parameter definition */
error_num = print_param_error();
}
}
DBUG_RETURN(error_num);
}
/**
Restore the current parameter's input delimiter characters in the
parameter string. They were NULLed during parameter parsing.
*/
inline void restore_delims()
{
char *end = end_title_ptr - 1;
switch (delim_title_len)
{
case 2:
*end++ = '\\';
/* Fall through */
case 1:
*end = delim_title;
}
end = end_value_ptr - 1;
switch (delim_value_len)
{
case 2:
*end++ = '\\';
/* Fall through */
case 1:
*end = delim_value;
}
}
/**
Print a parameter string error message.
@return Error code.
*/
int print_param_error();
} SPIDER_PARAM_STRING_PARSE;
uchar *spider_tbl_get_key(
SPIDER_SHARE *share,
size_t *length,
......@@ -60,7 +264,8 @@ void spider_free_tmp_share_alloc(
char *spider_get_string_between_quote(
char *ptr,
bool alloc
bool alloc,
SPIDER_PARAM_STRING_PARSE *param_string_parse = NULL
);
int spider_create_string_list(
......@@ -68,7 +273,8 @@ int spider_create_string_list(
uint **string_length_list,
uint *list_length,
char *str,
uint length
uint length,
SPIDER_PARAM_STRING_PARSE *param_string_parse
);
int spider_create_long_list(
......@@ -77,7 +283,8 @@ int spider_create_long_list(
char *str,
uint length,
long min_val,
long max_val
long max_val,
SPIDER_PARAM_STRING_PARSE *param_string_parse
);
int spider_create_longlong_list(
......@@ -86,7 +293,8 @@ int spider_create_longlong_list(
char *str,
uint length,
longlong min_val,
longlong max_val
longlong max_val,
SPIDER_PARAM_STRING_PARSE *param_string_parse
);
int spider_increase_string_list(
......
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