diff options
author | Sergei Golubchik <serg@mariadb.org> | 2019-01-25 23:12:35 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2019-01-27 18:54:12 +0100 |
commit | 2175bfce3e9da8332f10ab0e0286dc93915533a2 (patch) | |
tree | b45ab5e6be1ed5619c229202db5139d69b3cbc23 /sql-common | |
parent | 21f9037186f8a4bfb45486b9c28dd146e9df0e00 (diff) | |
download | mariadb-git-2175bfce3e9da8332f10ab0e0286dc93915533a2.tar.gz |
Crude "auto-load-data-local-infile" modemariadb-5.5.63
Disable LOAD DATA LOCAL INFILE suport by default and
auto-enable it for the duration of one query, if the query
string starts with the word "load". In all other cases the application
should enable LOAD DATA LOCAL INFILE support explicitly.
Diffstat (limited to 'sql-common')
-rw-r--r-- | sql-common/client.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/sql-common/client.c b/sql-common/client.c index 952b6a199ee..bec778e7d51 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -115,6 +115,12 @@ my_bool net_flush(NET *net); #include <my_context.h> #include <mysql_async.h> +typedef enum { + ALWAYS_ACCEPT, /* heuristics is disabled, use CLIENT_LOCAL_FILES */ + WAIT_FOR_QUERY, /* heuristics is enabled, not sending files */ + ACCEPT_FILE_REQUEST /* heuristics is enabled, ready to send a file */ +} auto_local_infile_state; + #define native_password_plugin_name "mysql_native_password" #define old_password_plugin_name "mysql_old_password" @@ -1765,8 +1771,10 @@ mysql_init(MYSQL *mysql) --enable-local-infile */ -#if defined(ENABLED_LOCAL_INFILE) && !defined(MYSQL_SERVER) +#if ENABLED_LOCAL_INFILE && !defined(MYSQL_SERVER) mysql->options.client_flag|= CLIENT_LOCAL_FILES; + mysql->auto_local_infile= ENABLED_LOCAL_INFILE == LOCAL_INFILE_MODE_AUTO + ? WAIT_FOR_QUERY : ALWAYS_ACCEPT; #endif #ifdef HAVE_SMEM @@ -3951,8 +3959,14 @@ static my_bool cli_read_query_result(MYSQL *mysql) ulong field_count; MYSQL_DATA *fields; ulong length; +#ifdef MYSQL_CLIENT + my_bool can_local_infile= mysql->auto_local_infile != WAIT_FOR_QUERY; +#endif DBUG_ENTER("cli_read_query_result"); + if (mysql->auto_local_infile == ACCEPT_FILE_REQUEST) + mysql->auto_local_infile= WAIT_FOR_QUERY; + if ((length = cli_safe_read(mysql)) == packet_error) DBUG_RETURN(1); free_old_query(mysql); /* Free old result */ @@ -3989,7 +4003,8 @@ get_info: { int error; - if (!(mysql->options.client_flag & CLIENT_LOCAL_FILES)) + if (!(mysql->options.client_flag & CLIENT_LOCAL_FILES) || + !can_local_infile) { set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate); DBUG_RETURN(1); @@ -4027,6 +4042,13 @@ int STDCALL mysql_send_query(MYSQL* mysql, const char* query, ulong length) { DBUG_ENTER("mysql_send_query"); + if (mysql->options.client_flag & CLIENT_LOCAL_FILES && + mysql->auto_local_infile == WAIT_FOR_QUERY && + (*query == 'l' || *query == 'L')) + { + if (strncasecmp(query, STRING_WITH_LEN("load")) == 0) + mysql->auto_local_infile= ACCEPT_FILE_REQUEST; + } DBUG_RETURN(simple_command(mysql, COM_QUERY, (uchar*) query, length, 1)); } @@ -4241,10 +4263,12 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg) mysql->options.protocol=MYSQL_PROTOCOL_PIPE; /* Force named pipe */ break; case MYSQL_OPT_LOCAL_INFILE: /* Allow LOAD DATA LOCAL ?*/ - if (!arg || test(*(uint*) arg)) + if (!arg || *(uint*) arg) mysql->options.client_flag|= CLIENT_LOCAL_FILES; else mysql->options.client_flag&= ~CLIENT_LOCAL_FILES; + mysql->auto_local_infile= arg && *(uint*)arg == LOCAL_INFILE_MODE_AUTO + ? WAIT_FOR_QUERY : ALWAYS_ACCEPT; break; case MYSQL_INIT_COMMAND: add_init_command(&mysql->options,arg); |