mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-33783 CREATE SERVER segfaults on wrong mysql.servers
Do basic checking of mysql.servers compatibility.
This commit is contained in:
@ -462,7 +462,7 @@ get_server_from_table_to_cache(TABLE *table)
|
||||
|
||||
RETURN VALUES
|
||||
0 - no error
|
||||
other - error code
|
||||
other - ER_ error code
|
||||
*/
|
||||
|
||||
static int
|
||||
@ -546,15 +546,19 @@ insert_server_record_into_cache(FOREIGN_SERVER *server)
|
||||
advance of insertion into the mysql.servers table
|
||||
|
||||
RETURN VALUE
|
||||
VOID
|
||||
|
||||
0 - no errors
|
||||
>0 - ER_ error code
|
||||
*/
|
||||
|
||||
static void
|
||||
static int
|
||||
store_server_fields(TABLE *table, FOREIGN_SERVER *server)
|
||||
{
|
||||
|
||||
table->use_all_columns();
|
||||
|
||||
if (table->s->fields < 9)
|
||||
return ER_CANT_FIND_SYSTEM_REC;
|
||||
|
||||
/*
|
||||
"server" has already been prepped by prepare_server_struct_for_<>
|
||||
so, all we need to do is check if the value is set (> -1 for port)
|
||||
@ -563,30 +567,43 @@ store_server_fields(TABLE *table, FOREIGN_SERVER *server)
|
||||
have changed will be set. If an insert, then all will be set,
|
||||
even if with empty strings
|
||||
*/
|
||||
if (server->host)
|
||||
if (server->host &&
|
||||
table->field[1]->store(server->host,
|
||||
(uint) strlen(server->host), system_charset_info);
|
||||
if (server->db)
|
||||
(uint) strlen(server->host), system_charset_info))
|
||||
goto err;
|
||||
if (server->db &&
|
||||
table->field[2]->store(server->db,
|
||||
(uint) strlen(server->db), system_charset_info);
|
||||
if (server->username)
|
||||
(uint) strlen(server->db), system_charset_info))
|
||||
goto err;
|
||||
if (server->username &&
|
||||
table->field[3]->store(server->username,
|
||||
(uint) strlen(server->username), system_charset_info);
|
||||
if (server->password)
|
||||
(uint) strlen(server->username), system_charset_info))
|
||||
goto err;
|
||||
if (server->password &&
|
||||
table->field[4]->store(server->password,
|
||||
(uint) strlen(server->password), system_charset_info);
|
||||
if (server->port > -1)
|
||||
table->field[5]->store(server->port);
|
||||
|
||||
if (server->socket)
|
||||
(uint) strlen(server->password), system_charset_info))
|
||||
goto err;
|
||||
if (server->port > -1 &&
|
||||
table->field[5]->store(server->port))
|
||||
goto err;
|
||||
if (server->socket &&
|
||||
table->field[6]->store(server->socket,
|
||||
(uint) strlen(server->socket), system_charset_info);
|
||||
if (server->scheme)
|
||||
(uint) strlen(server->socket), system_charset_info))
|
||||
goto err;
|
||||
if (server->scheme &&
|
||||
table->field[7]->store(server->scheme,
|
||||
(uint) strlen(server->scheme), system_charset_info);
|
||||
if (server->owner)
|
||||
(uint) strlen(server->scheme), system_charset_info))
|
||||
goto err;
|
||||
if (server->owner &&
|
||||
table->field[8]->store(server->owner,
|
||||
(uint) strlen(server->owner), system_charset_info);
|
||||
(uint) strlen(server->owner), system_charset_info))
|
||||
goto err;
|
||||
return 0;
|
||||
|
||||
err:
|
||||
THD *thd= table->in_use;
|
||||
DBUG_ASSERT(thd->is_error());
|
||||
return thd->get_stmt_da()->get_sql_errno();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -608,7 +625,7 @@ store_server_fields(TABLE *table, FOREIGN_SERVER *server)
|
||||
|
||||
RETURN VALUE
|
||||
0 - no errors
|
||||
>0 - error code
|
||||
>0 - ER_ error code
|
||||
|
||||
*/
|
||||
|
||||
@ -642,7 +659,8 @@ int insert_server_record(TABLE *table, FOREIGN_SERVER *server)
|
||||
error= 1;
|
||||
}
|
||||
/* store each field to be inserted */
|
||||
store_server_fields(table, server);
|
||||
if ((error= store_server_fields(table, server)))
|
||||
DBUG_RETURN(error);
|
||||
|
||||
DBUG_PRINT("info",("record for server '%s' not found!",
|
||||
server->server_name));
|
||||
@ -972,9 +990,15 @@ update_server_record(TABLE *table, FOREIGN_SERVER *server)
|
||||
|
||||
table->use_all_columns();
|
||||
/* set the field that's the PK to the value we're looking for */
|
||||
table->field[0]->store(server->server_name,
|
||||
if (table->field[0]->store(server->server_name,
|
||||
server->server_name_length,
|
||||
system_charset_info);
|
||||
system_charset_info))
|
||||
{
|
||||
DBUG_ASSERT(0); /* Protected by servers_cache */
|
||||
THD *thd= table->in_use;
|
||||
DBUG_ASSERT(thd->is_error());
|
||||
return thd->get_stmt_da()->get_sql_errno();
|
||||
}
|
||||
|
||||
if (unlikely((error=
|
||||
table->file->ha_index_read_idx_map(table->record[0], 0,
|
||||
@ -992,7 +1016,8 @@ update_server_record(TABLE *table, FOREIGN_SERVER *server)
|
||||
{
|
||||
/* ok, so we can update since the record exists in the table */
|
||||
store_record(table,record[1]);
|
||||
store_server_fields(table, server);
|
||||
if ((error= store_server_fields(table, server)))
|
||||
goto end;
|
||||
if (unlikely((error=table->file->ha_update_row(table->record[1],
|
||||
table->record[0])) &&
|
||||
error != HA_ERR_RECORD_IS_THE_SAME))
|
||||
|
Reference in New Issue
Block a user