diff --git a/mysql-test/main/lotofstack.result b/mysql-test/main/lotofstack.result index dfe12c3f796d3..eb51ccd8e0472 100644 --- a/mysql-test/main/lotofstack.result +++ b/mysql-test/main/lotofstack.result @@ -108,4 +108,11 @@ SELECT ST_GeomFromText(CONCAT(REPEAT('GEOMETRYCOLLECTION(',5000),'POINT(1 1)',RE # set @a=concat(0x0107000000, repeat(0x010000000107000000, 120000), 0x00000000); SELECT ST_GeomFromWKB(@a); +# +# MDEV-39750 ExtractValue does not control recursion depth. +# +SELECT ExtractValue('', REPEAT('(', 100000)); +ERROR HY000: Thread stack overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed. Consider increasing the thread_stack system variable. +SELECT ExtractValue('', REPEAT('/n', 100000)); +ERROR HY000: Thread stack overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed. Consider increasing the thread_stack system variable. # End of 10.6 tests diff --git a/mysql-test/main/lotofstack.test b/mysql-test/main/lotofstack.test index 768c87160b62f..7c8dfa21271e2 100644 --- a/mysql-test/main/lotofstack.test +++ b/mysql-test/main/lotofstack.test @@ -149,4 +149,15 @@ set @a=concat(0x0107000000, repeat(0x010000000107000000, 120000), 0x00000000); SELECT ST_GeomFromWKB(@a); --enable_result_log +--echo # +--echo # MDEV-39750 ExtractValue does not control recursion depth. +--echo # +--replace_regex /overrun: [0-9]* bytes used of a [0-9]* byte stack, and [0-9]* bytes needed/overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed/ +--error ER_STACK_OVERRUN_NEED_MORE +SELECT ExtractValue('', REPEAT('(', 100000)); + +--replace_regex /overrun: [0-9]* bytes used of a [0-9]* byte stack, and [0-9]* bytes needed/overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed/ +--error ER_STACK_OVERRUN_NEED_MORE +SELECT ExtractValue('', REPEAT('/n', 100000)); + --echo # End of 10.6 tests diff --git a/mysql-test/main/mysqld--help,win.rdiff b/mysql-test/main/mysqld--help,win.rdiff index 07b7c87b5d4c6..7594959fb07ec 100644 --- a/mysql-test/main/mysqld--help,win.rdiff +++ b/mysql-test/main/mysqld--help,win.rdiff @@ -1,6 +1,6 @@ --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result -@@ -180,6 +180,7 @@ The following specify which files/extra groups are read (specified before remain +@@ -190,6 +190,7 @@ The following specify which files/extra groups are read (specified before remain --console Write error output on screen; don't remove the console window on windows. --core-file Write core on crashes @@ -8,7 +8,7 @@ -h, --datadir=name Path to the database root directory --date-format=name The DATE format (ignored) --datetime-format=name -@@ -649,6 +650,7 @@ The following specify which files/extra groups are read (specified before remain +@@ -677,6 +678,7 @@ The following specify which files/extra groups are read (specified before remain Use MySQL-5.6 (instead of MariaDB-5.3) format for TIME, DATETIME, TIMESTAMP columns. (Defaults to on; use --skip-mysql56-temporal-format to disable.) @@ -16,7 +16,17 @@ --net-buffer-length=# Buffer length for TCP/IP and socket communication --net-read-timeout=# -@@ -1280,6 +1282,10 @@ The following specify which files/extra groups are read (specified before remain +@@ -1192,8 +1194,7 @@ The following specify which files/extra groups are read (specified before remain + (Defaults to on; use --skip-secure-auth to disable.) + --secure-file-priv=name + Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to +- files within specified directory. Empty value means no +- limits except /proc ++ files within specified directory. + --secure-timestamp=name + Restricts direct setting of a session timestamp. Possible + levels are: YES - timestamp cannot deviate from the +@@ -1346,6 +1347,10 @@ The following specify which files/extra groups are read (specified before remain Log slow queries to given log file. Defaults logging to 'hostname'-slow.log. Must be enabled to activate other slow log options @@ -27,7 +37,7 @@ --socket=name Socket file to use for connection --sort-buffer-size=# Each thread that needs to do a sort allocates a buffer of -@@ -1304,6 +1310,7 @@ The following specify which files/extra groups are read (specified before remain +@@ -1371,6 +1376,7 @@ The following specify which files/extra groups are read (specified before remain deleting or updating every row in a table. --stack-trace Print a symbolic stack trace on failure (Defaults to on; use --skip-stack-trace to disable.) @@ -35,7 +45,7 @@ --standard-compliant-cte Allow only CTEs compliant to SQL standard (Defaults to on; use --skip-standard-compliant-cte to disable.) -@@ -1379,6 +1386,12 @@ The following specify which files/extra groups are read (specified before remain +@@ -1446,6 +1452,12 @@ The following specify which files/extra groups are read (specified before remain --thread-pool-max-threads=# Maximum allowed number of worker threads in the thread pool @@ -48,7 +58,7 @@ --thread-pool-oversubscribe=# How many additional active worker threads in a group are allowed. -@@ -1417,8 +1430,8 @@ The following specify which files/extra groups are read (specified before remain +@@ -1485,8 +1497,8 @@ The following specify which files/extra groups are read (specified before remain automatically convert it to an on-disk MyISAM or Aria table. -t, --tmpdir=name Path for temporary files. Several paths may be specified, @@ -59,7 +69,7 @@ --transaction-alloc-block-size=# Allocation block size for transactions to be stored in binary log -@@ -1633,6 +1646,7 @@ myisam-sort-buffer-size 134216704 +@@ -1704,6 +1716,7 @@ myisam-sort-buffer-size 134216704 myisam-stats-method NULLS_UNEQUAL myisam-use-mmap FALSE mysql56-temporal-format TRUE @@ -67,7 +77,7 @@ net-buffer-length 16384 net-read-timeout 30 net-retry-count 10 -@@ -1787,6 +1801,7 @@ slave-transaction-retry-interval 0 +@@ -1862,6 +1875,7 @@ slave-transaction-retry-interval 0 slave-type-conversions slow-launch-time 2 slow-query-log FALSE @@ -75,7 +85,7 @@ sort-buffer-size 2097152 sql-mode STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION sql-safe-updates FALSE -@@ -1813,6 +1828,8 @@ thread-pool-dedicated-listener FALSE +@@ -1888,6 +1902,8 @@ thread-pool-dedicated-listener FALSE thread-pool-exact-stats FALSE thread-pool-idle-timeout 60 thread-pool-max-threads 65536 diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result index 7ce8ef6cd9709..451e474c66e22 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -1192,7 +1192,8 @@ The following specify which files/extra groups are read (specified before remain (Defaults to on; use --skip-secure-auth to disable.) --secure-file-priv=name Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to - files within specified directory + files within specified directory. Empty value means no + limits except /proc --secure-timestamp=name Restricts direct setting of a session timestamp. Possible levels are: YES - timestamp cannot deviate from the diff --git a/mysql-test/main/xml.result b/mysql-test/main/xml.result index 1cf232e547506..e699a8fb10850 100644 --- a/mysql-test/main/xml.result +++ b/mysql-test/main/xml.result @@ -1414,11 +1414,4 @@ ExtractValue(@xml, '/employee/dt3') NULL Warnings: Warning 1525 Incorrect XML value: 'parse error at line 10 pos 27: unexpected END-OF-INPUT' -# -# MDEV-39750 ExtractValue does not control recursion depth. -# -SELECT ExtractValue('', REPEAT('(', 100000)); -ERROR HY000: Thread stack overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed. Consider increasing the thread_stack system variable. -SELECT ExtractValue('', REPEAT('/n', 100000)); -ERROR HY000: Thread stack overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed. Consider increasing the thread_stack system variable. # End of 10.6 tests diff --git a/mysql-test/main/xml.test b/mysql-test/main/xml.test index f849e81d974a9..bc1e36a0eb838 100644 --- a/mysql-test/main/xml.test +++ b/mysql-test/main/xml.test @@ -899,17 +899,5 @@ set @xml= ' SELECT ExtractValue(@xml, '/employee/dt3'); ---echo # ---echo # MDEV-39750 ExtractValue does not control recursion depth. ---echo # - ---replace_regex /overrun: [0-9]* bytes used of a [0-9]* byte stack, and [0-9]* bytes needed/overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed/ ---error ER_STACK_OVERRUN_NEED_MORE -SELECT ExtractValue('', REPEAT('(', 100000)); - ---replace_regex /overrun: [0-9]* bytes used of a [0-9]* byte stack, and [0-9]* bytes needed/overrun: 'used bytes' used of a 'available' byte stack, and 'X' bytes needed/ ---error ER_STACK_OVERRUN_NEED_MORE -SELECT ExtractValue('', REPEAT('/n', 100000)); - --echo # End of 10.6 tests diff --git a/mysql-test/suite/sys_vars/r/secure_file_priv.result b/mysql-test/suite/sys_vars/r/secure_file_priv.result index 74f816df59d88..06968a185e773 100644 --- a/mysql-test/suite/sys_vars/r/secure_file_priv.result +++ b/mysql-test/suite/sys_vars/r/secure_file_priv.result @@ -6,14 +6,17 @@ INSERT INTO t1 VALUES ("one"),("two"),("three"),("four"),("five"); SHOW VARIABLES LIKE 'secure_file_priv'; Variable_name Value secure_file_priv -Warnings: -Warning 1287 ' INTO FROM...' instead +SELECT * INTO OUTFILE '$MYSQLTEST_VARDIR/../bug50373.txt' FROM t1; +DELETE FROM t1; +LOAD DATA INFILE '$MYSQLTEST_VARDIR/../bug50373.txt' INTO TABLE t1; +SELECT * FROM t1; c1 one two three four five +SELECT load_file('$MYSQLTEST_VARDIR/../bug50373.txt') AS loaded_file; loaded_file one two @@ -22,3 +25,11 @@ four five DROP TABLE t1; +# +# MDEV-40589 default exclude list for secure-file-priv +# +CREATE TABLE t1 (c1 VARCHAR(50)); +LOAD DATA INFILE '/proc/cpuinfo' INTO TABLE t1; +ERROR HY000: The MariaDB server is running with the --secure-file-priv option so it cannot execute this statement +DROP TABLE t1; +# End of 10.6 tests diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index e180131318374..dc70fd1d09e3d 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -3115,7 +3115,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME SECURE_FILE_PRIV VARIABLE_SCOPE GLOBAL VARIABLE_TYPE VARCHAR -VARIABLE_COMMENT Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files within specified directory +VARIABLE_COMMENT Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files within specified directory. Empty value means no limits except /proc NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 5add3ed05dc70..e6516a59b3a95 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -3565,7 +3565,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME SECURE_FILE_PRIV VARIABLE_SCOPE GLOBAL VARIABLE_TYPE VARCHAR -VARIABLE_COMMENT Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files within specified directory +VARIABLE_COMMENT Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files within specified directory. Empty value means no limits except /proc NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL diff --git a/mysql-test/suite/sys_vars/t/secure_file_priv-master.opt b/mysql-test/suite/sys_vars/t/secure_file_priv.opt similarity index 100% rename from mysql-test/suite/sys_vars/t/secure_file_priv-master.opt rename to mysql-test/suite/sys_vars/t/secure_file_priv.opt diff --git a/mysql-test/suite/sys_vars/t/secure_file_priv.test b/mysql-test/suite/sys_vars/t/secure_file_priv.test index 395bdaed34379..a46afb313a37f 100644 --- a/mysql-test/suite/sys_vars/t/secure_file_priv.test +++ b/mysql-test/suite/sys_vars/t/secure_file_priv.test @@ -4,7 +4,6 @@ CREATE TABLE t1 (c1 VARCHAR(50)); INSERT INTO t1 VALUES ("one"),("two"),("three"),("four"),("five"); SHOW VARIABLES LIKE 'secure_file_priv'; ---disable_query_log # Atempt to create a file where we normally aren't allowed to create one. # @@ -17,37 +16,26 @@ SHOW VARIABLES LIKE 'secure_file_priv'; # If we run tests with --mem, it will be /dev/shm. # If we run tests with --parallel, it will be mysql-test/var # (because MYSQLTEST_VARDIR in this case is mysql-test/var/N). ---disable_cursor_protocol - ---perl -use File::Basename; -my $protected_file= dirname($ENV{MYSQLTEST_VARDIR}).'/bug50373.txt'; -# Ensure bug50373.txt does not exist (e.g. leftover from previous -# test runs). -unlink $protected_file; -open(FILE, ">", "$ENV{MYSQL_TMP_DIR}/bug50373.inc") or die; -print FILE "--disable_ps2_protocol\n"; -print FILE "SELECT * FROM t1 INTO OUTFILE '".$protected_file."';\n"; -print FILE "--enable_ps2_protocol\n"; -print FILE "DELETE FROM t1;\n"; -print FILE "LOAD DATA INFILE '".$protected_file."' INTO TABLE t1;\n"; -print FILE "SELECT * FROM t1;\n"; -print FILE "SELECT load_file('",$protected_file,"') AS loaded_file;\n"; -close(FILE); -EOF - ---enable_prepare_warnings ---source $MYSQL_TMP_DIR/bug50373.inc ---disable_prepare_warnings ---remove_file $MYSQL_TMP_DIR/bug50373.inc ---enable_query_log +--disable_cursor_protocol +--disable_ps2_protocol +evalp SELECT * INTO OUTFILE '$MYSQLTEST_VARDIR/../bug50373.txt' FROM t1; +--enable_ps2_protocol --enable_cursor_protocol - +DELETE FROM t1; +evalp LOAD DATA INFILE '$MYSQLTEST_VARDIR/../bug50373.txt' INTO TABLE t1; +SELECT * FROM t1; +evalp SELECT load_file('$MYSQLTEST_VARDIR/../bug50373.txt') AS loaded_file; DROP TABLE t1; ---perl -use File::Basename; -unlink dirname($ENV{MYSQLTEST_VARDIR}).'/bug50373.txt'; -EOF +--remove_file $MYSQLTEST_VARDIR/../bug50373.txt + +--echo # +--echo # MDEV-40589 default exclude list for secure-file-priv +--echo # +CREATE TABLE t1 (c1 VARCHAR(50)); +--error ER_OPTION_PREVENTS_STATEMENT +LOAD DATA INFILE '/proc/cpuinfo' INTO TABLE t1; +DROP TABLE t1; +--echo # End of 10.6 tests diff --git a/sql/mysqld.cc b/sql/mysqld.cc index f4f0ba33938dd..9f4a48c6d5af0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8860,45 +8860,39 @@ fn_format_relative_to_data_home(char * to, const char *name, bool is_secure_file_path(char *path) { - char buff1[FN_REFLEN], buff2[FN_REFLEN]; - size_t opt_secure_file_priv_len; - /* - All paths are secure if opt_secure_file_path is 0 - */ - if (!opt_secure_file_priv) - return TRUE; + char buf1[FN_REFLEN], buf2[FN_REFLEN]; + const char *cmp; - opt_secure_file_priv_len= strlen(opt_secure_file_priv); + if (opt_secure_file_priv) + cmp= opt_secure_file_priv; + else +#ifdef _WIN32 + return TRUE; // All paths are secure if opt_secure_file_priv is unset +#else + cmp= "/proc/"; // Check that it doesn't start with this prefix +#endif if (strlen(path) >= FN_REFLEN) return FALSE; - if (my_realpath(buff1, path, 0)) - { - /* - The supplied file path might have been a file and not a directory. - */ - size_t length= dirname_length(path); // Guaranteed to be < FN_REFLEN - memcpy(buff2, path, length); - buff2[length]= '\0'; - if (length == 0 || my_realpath(buff1, buff2, 0)) - return FALSE; - } - convert_dirname(buff2, buff1, NullS); - if (!lower_case_file_system) + if (my_realpath(buf1, path, 0)) { - if (strncmp(opt_secure_file_priv, buff2, opt_secure_file_priv_len)) + /* The supplied file path might have been a file and not a directory. */ + size_t length= dirname_length(path); // Guaranteed to be < FN_REFLEN + memcpy(buf2, path, length); + buf2[length]= '\0'; + if (length == 0 || my_realpath(buf1, buf2, 0)) return FALSE; } + convert_dirname(buf2, buf1, NullS); + + size_t cmp_len= strlen(cmp); + bool matched; + if (lower_case_file_system) + matched= !files_charset_info->strnncoll(buf2, strlen(buf2), cmp, cmp_len, 1); else - { - if (files_charset_info->strnncoll(buff2, strlen(buff2), - opt_secure_file_priv, - opt_secure_file_priv_len, - TRUE)) - return FALSE; - } - return TRUE; + matched= !strncmp(cmp, buf2, cmp_len); + return opt_secure_file_priv ? matched : !matched; } diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index eaa099e65ab06..08b826c8ea638 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3357,11 +3357,15 @@ static Sys_var_mybool Sys_require_secure_transport( ON_CHECK(check_require_secure_transport), ON_UPDATE(0)); static Sys_var_charptr_fscs Sys_secure_file_priv( - "secure_file_priv", - "Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files " - "within specified directory", - PREALLOCATED READ_ONLY GLOBAL_VAR(opt_secure_file_priv), - CMD_LINE(REQUIRED_ARG), DEFAULT(0)); + "secure_file_priv", + "Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files " + "within specified directory." +#ifndef _WIN32 + " Empty value means no limits except /proc" +#endif + , + PREALLOCATED READ_ONLY GLOBAL_VAR(opt_secure_file_priv), + CMD_LINE(REQUIRED_ARG), DEFAULT(0)); static bool check_server_id(sys_var *self, THD *thd, set_var *var) { diff --git a/sql/table.cc b/sql/table.cc index a14580c6fad1f..166842e8a1b1b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -113,10 +113,8 @@ static std::atomic last_table_id; /* Functions defined in this file */ -static bool fix_type_pointers(const char ***typelib_value_names, - uint **typelib_value_lengths, - TYPELIB *point_to_type, uint types, - char *names, size_t names_length); +static bool fix_type_pointers(const char ***, const char **, uint **, + TYPELIB *, uint, char *, size_t); static field_index_t find_field(Field **fields, uchar *record, uint start, uint length); @@ -767,7 +765,7 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end, uint i, j, n_length; KEY_PART_INFO *key_part= NULL; ulong *rec_per_key= NULL; - KEY_PART_INFO *first_key_part= NULL; + KEY_PART_INFO *first_key_part= NULL, *key_part_end; uint first_key_parts= 0; if (!keys) @@ -775,7 +773,7 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end, if (!(keyinfo = (KEY*) alloc_root(&share->mem_root, len))) return 1; bzero((char*) keyinfo, len); - key_part= reinterpret_cast (keyinfo); + key_part_end= key_part= reinterpret_cast (keyinfo); } /* @@ -831,6 +829,7 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end, sizeof(ulong) * *ext_key_parts))) return 1; first_key_part= key_part; + key_part_end= key_part + *ext_key_parts; first_key_parts= first_keyinfo->user_defined_key_parts; keyinfo->flags= first_keyinfo->flags; keyinfo->key_length= first_keyinfo->key_length; @@ -844,6 +843,8 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end, keyinfo->rec_per_key= rec_per_key; for (j=keyinfo->user_defined_key_parts ; j-- ; key_part++) { + if (key_part >= key_part_end) + return 1; if (strpos + (new_frm_ver >= 1 ? 9 : 7) >= frm_image_end) return 1; if (!(keyinfo->algorithm == HA_KEY_ALG_LONG_HASH)) @@ -901,6 +902,8 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end, } if (curr_key_part == curr_key_part_end) { + if (key_part >= key_part_end) + return 1; *key_part++= first_key_part[j]; *rec_per_key++= 0; keyinfo->ext_key_parts++; @@ -914,13 +917,17 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end, share->ext_key_parts++; share->ext_key_parts+= keyinfo->ext_key_parts; } + if (key_part > key_part_end) + return 1; + size_t max_keyname_len= MY_MIN(len, (uint)(frm_image_end - strpos)); keynames->str= (char*) key_part; - keynames->length= strnmov(keynames->str, (char *) strpos, - frm_image_end - strpos) - keynames->str; + keynames->length= strnmov(keynames->str, (char *)strpos, + max_keyname_len) - keynames->str; + if (keynames->length >= max_keyname_len) + return 1; // meaning key name was not \0-terminated + keynames->length++; // include '\0', to make fix_type_pointers() happy. strpos+= keynames->length; - if (*strpos++) // key names are \0-terminated - return 1; - keynames->length++; // Include '\0', to make fix_type_pointers() happy. + len-= (uint)keynames->length; //reading index comments for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++) @@ -932,11 +939,13 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end, keyinfo->comment.length= uint2korr(strpos); strpos+= 2; - if (strpos + keyinfo->comment.length >= frm_image_end) + if (strpos + keyinfo->comment.length >= frm_image_end || + keyinfo->comment.length > len) return 1; keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos, keyinfo->comment.length); strpos+= keyinfo->comment.length; + len-= (uint)keyinfo->comment.length; } DBUG_ASSERT(MY_TEST(keyinfo->flags & HA_USES_COMMENT) == (keyinfo->comment.length > 0)); @@ -1055,7 +1064,8 @@ static void mysql57_calculate_null_position(TABLE_SHARE *share, uchar **null_pos, uint *null_bit_pos, const uchar *strpos, - const uchar *vcol_screen_pos) + const uchar *vcol_screen_pos, + const uchar *vcol_screen_end) { uint field_pack_length= 17; @@ -1066,6 +1076,8 @@ static void mysql57_calculate_null_position(TABLE_SHARE *share, if ((strpos[10] & MYSQL57_GENERATED_FIELD)) { + if (vcol_screen_pos + MYSQL57_GCOL_HEADER_SIZE >= vcol_screen_end) + return; /* Skip virtual (not stored) generated field */ bool stored_in_db= vcol_screen_pos[3]; vcol_screen_pos+= (uint2korr(vcol_screen_pos + 1) + @@ -1786,6 +1798,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, const uchar *forminfo; const uchar *frm_image_end = frm_image + frm_length; uchar *record, *null_flags, *null_pos, *UNINIT_VAR(mysql57_vcol_null_pos); + uchar *data_start, *data_end; + uchar *first_stored= 0, *first_virtual= 0, *next_stored= 0, *next_virtual= 0; const uchar *disk_buff, *strpos; ulong pos, record_offset; ulong rec_buff_length; @@ -1793,13 +1807,13 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, KEY *keyinfo; KEY_PART_INFO *key_part= NULL; Field **field_ptr, *reg_field; - const char **interval_array; + const char **interval_array, **interval_array_end; uint *typelib_value_lengths= NULL; enum legacy_db_type legacy_db_type; my_bitmap_map *bitmaps; bool null_bits_are_used; uint vcol_screen_length; - uchar *vcol_screen_pos; + uchar *vcol_screen_pos, *vcol_screen_end; LEX_CUSTRING options; LEX_CSTRING se_name= empty_clex_str; KEY first_keyinfo; @@ -1809,7 +1823,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, bool vers_can_native= false, frm_created= 0; Field_data_type_info_array field_data_type_info_array; MEM_ROOT *old_root= thd->mem_root; - Virtual_column_info **table_check_constraints; + Virtual_column_info **table_check_constr; bool *interval_unescaped= NULL; extra2_fields extra2; bool extra_index_flags_present= FALSE; @@ -1850,6 +1864,14 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, /* Length of the MariaDB extra2 segment in the form file. */ len = uint2korr(frm_image+4); + if (frm_length < FRM_HEADER_SIZE + len || + !(pos= uint4korr(frm_image + FRM_HEADER_SIZE + len))) + goto err; + + forminfo= frm_image + pos; + if (forminfo + FRM_FORMINFO_SIZE >= frm_image_end) + goto err; + if (read_extra2(frm_image, len, &extra2)) goto err; @@ -1869,17 +1891,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (!share->default_part_plugin) goto err; } -#endif - - if (frm_length < FRM_HEADER_SIZE + len || - !(pos= uint4korr(frm_image + FRM_HEADER_SIZE + len))) - goto err; - forminfo= frm_image + pos; - if (forminfo + FRM_FORMINFO_SIZE >= frm_image_end) - goto err; - -#ifdef WITH_PARTITION_STORAGE_ENGINE if (frm_image[61] && !share->default_part_plugin) { enum legacy_db_type db_type= (enum legacy_db_type) (uint) frm_image[61]; @@ -1971,6 +1983,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, share->keys_in_use.init(keys); ext_key_parts= key_parts; + if ((key_parts && !keys) || key_parts < keys) + goto err; + if (extra2.index_flags.str && extra2.index_flags.length != keys) goto err; @@ -2127,12 +2142,10 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, { //reading long table comment if (next_chunk + 2 > buff_end) - { - DBUG_PRINT("error", - ("long table comment is not defined in .frm")); goto err; - } share->comment.length = uint2korr(next_chunk); + if (next_chunk + 2 + share->comment.length > buff_end) + goto err; if (! (share->comment.str= strmake_root(&share->mem_root, (char*)next_chunk + 2, share->comment.length))) { @@ -2141,17 +2154,18 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, next_chunk+= 2 + share->comment.length; } - DBUG_ASSERT(next_chunk <= buff_end); - if (share->db_create_options & HA_OPTION_TEXT_CREATE_OPTIONS_legacy) { if (options.str) goto err; + if (next_chunk + 4 > buff_end) + goto err; options.length= uint4korr(next_chunk); options.str= next_chunk + 4; next_chunk+= options.length + 4; + if (next_chunk > buff_end) + goto err; } - DBUG_ASSERT(next_chunk <= buff_end); } else { @@ -2163,7 +2177,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, share->key_block_size= uint2korr(frm_image+62); keyinfo= share->key_info; - if (extra2.index_flags.str) extra_index_flags_present= TRUE; @@ -2208,6 +2221,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, disk_buff= frm_image + pos + FRM_FORMINFO_SIZE; share->fields= uint2korr(forminfo+258); + if (share->fields > MAX_FIELDS) + goto err; if (extra2.field_flags.str && extra2.field_flags.length != share->fields) goto err; pos= uint2korr(forminfo+260); /* Length of all screens */ @@ -2229,6 +2244,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, share->comment.length); } + if (hash_fields > share->fields || share->null_fields > share->fields) + goto err; + DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d vcol_screen_length: %d", interval_count,interval_parts, keys,n_length,int_length, com_length, vcol_screen_length)); /* @@ -2253,12 +2271,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, &share->field, (uint)(share->fields+1)*sizeof(Field*), &share->intervals, (uint)interval_count*sizeof(TYPELIB), &share->check_constraints, (uint) share->table_check_constraints * sizeof(Virtual_column_info*), - /* - This looks wrong: shouldn't it be (+2+interval_count) - instread of (+3) ? - */ - &interval_array, (uint) (share->fields+interval_parts+ keys+3)*sizeof(char *), - &typelib_value_lengths, total_typelib_value_count * sizeof(uint *), + &interval_array, (uint)total_typelib_value_count * sizeof(char *), + &typelib_value_lengths, (uint)total_typelib_value_count * sizeof(uint), &names, (uint) (n_length+int_length), &comment_pos, (uint) com_length, &vcol_screen_pos, vcol_screen_length, @@ -2274,10 +2288,13 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, } field_ptr= share->field; - table_check_constraints= share->check_constraints; + interval_array_end= interval_array + total_typelib_value_count; + table_check_constr= share->check_constraints; read_length=(uint) (share->fields * field_pack_length + pos+ (uint) (n_length+int_length+com_length+ vcol_screen_length)); + if (disk_buff + read_length > frm_image_end) + goto err; strpos= disk_buff+pos; if (!interval_count) @@ -2291,21 +2308,24 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, com_length); memcpy(vcol_screen_pos, disk_buff+read_length-vcol_screen_length, vcol_screen_length); + vcol_screen_end= vcol_screen_pos + vcol_screen_length; - if (fix_type_pointers(&interval_array, &typelib_value_lengths, - &share->fieldnames, 1, names, n_length) || + if (fix_type_pointers(&interval_array, interval_array_end, + &typelib_value_lengths, &share->fieldnames, 1, names, + n_length) || share->fieldnames.count != share->fields) goto err; - if (fix_type_pointers(&interval_array, &typelib_value_lengths, - share->intervals, interval_count, - names + n_length, int_length)) + if (fix_type_pointers(&interval_array, interval_array_end, + &typelib_value_lengths, share->intervals, + interval_count, names + n_length, int_length)) goto err; - if (keynames.length && - (fix_type_pointers(&interval_array, &typelib_value_lengths, - &share->keynames, 1, keynames.str, keynames.length) || - share->keynames.count != keys)) + if ((keynames.length && + fix_type_pointers(&interval_array, interval_array_end, + &typelib_value_lengths, &share->keynames, 1, + keynames.str, keynames.length)) || + share->keynames.count != keys) goto err; /* Allocate handler */ @@ -2329,14 +2349,12 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, */ share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8; } -#ifndef WE_WANT_TO_SUPPORT_VERY_OLD_FRM_FILES else { share->null_bytes= (share->null_fields+7)/8; null_flags= null_pos= record + 1 + share->reclength - share->null_bytes; null_bit_pos= 0; } -#endif use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH; if (use_hash) @@ -2357,7 +2375,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, mysql57_vcol_null_bit_pos= null_bit_pos; mysql57_calculate_null_position(share, &mysql57_vcol_null_pos, &mysql57_vcol_null_bit_pos, - strpos, vcol_screen_pos); + strpos, vcol_screen_pos, vcol_screen_end); } /* Set system versioning information. */ @@ -2406,20 +2424,22 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (extra2.without_overlaps.str) { - if (extra2.application_period.str == NULL) + if (extra2.application_period.str == NULL || + extra2.without_overlaps.length < frm_keyno_size) goto err; const uchar *key_pos= extra2.without_overlaps.str; period.unique_keys= read_frm_keyno(key_pos); + if (period.unique_keys > keys || + extra2.without_overlaps.length != (period.unique_keys+1)*frm_keyno_size) + goto err; for (uint k= 0; k < period.unique_keys; k++) { key_pos+= frm_keyno_size; uint key_nr= read_frm_keyno(key_pos); + if (key_nr >= keys) + goto err; key_info[key_nr].without_overlaps= true; } - - if ((period.unique_keys + 1) * frm_keyno_size - != extra2.without_overlaps.length) - goto err; } if (extra2.field_data_type_info.length && @@ -2453,6 +2473,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, comment.str= (char*) comment_pos; comment.length= comment_length; comment_pos+= comment_length; + if (com_length < comment_length) + goto err; + com_length-= comment_length; } if (strpos[13] == MYSQL_TYPE_VIRTUAL && @@ -2465,7 +2488,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, */ uint vcol_info_length= (uint) strpos[12]; - if (!vcol_info_length) // Expect non-null expression + if (vcol_info_length < 4 || + vcol_screen_pos + vcol_info_length > vcol_screen_end) goto err; attr.frm_unpack_basic(strpos); @@ -2567,15 +2591,17 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, byte 4 = stored_in_db byte 5.. = expr */ - if ((uint)(vcol_screen_pos)[0] != 1) + if (vcol_screen_pos + MYSQL57_GCOL_HEADER_SIZE > vcol_screen_end || + vcol_screen_pos[0] != 1) goto err; vcol_info= new (&share->mem_root) Virtual_column_info(); uint vcol_info_length= uint2korr(vcol_screen_pos + 1); - if (!vcol_info_length) // Expect non-empty expression - goto err; vcol_info->stored_in_db= vcol_screen_pos[3]; vcol_info->utf8= 0; vcol_screen_pos+= vcol_info_length + MYSQL57_GCOL_HEADER_SIZE;; + if (!vcol_info_length || // Expect non-empty expression + vcol_screen_pos > vcol_screen_end) + goto err; share->virtual_fields++; } } @@ -2632,6 +2658,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, attr.pack_flag&= ~FIELDFLAG_LONG_DECIMAL; } + if (interval_nr > interval_count) + goto err; + if (interval_nr && attr.charset->mbminlen > 1 && !interval_unescaped[interval_nr - 1]) { @@ -2727,6 +2756,52 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (!reg_field) // Not supported field type goto err; + /* + Verify that fields follow one another in the record without overlaps. + That is the next field starts where the previous field ended. + Virtual fields complicate the check. Stored fields follow each other in + the record order, virtual fields also follow each in the record order + but they're always at the end of the record, and can be interleaved + with normal fields in the table. + + We detect this dynamically - as long as the next field starts where the + previous ended, assume they're normal fields. When the next field starts + with a gap - it's the first virtual (and the future virtual fields must + follow that field). If the next field starts before the previous - it + means the table started from virtual fields and this is the first stored + field. Either ("gap" or "before") can happen only once. + */ + if (!next_stored) // first field, i == 0 + { + first_stored= reg_field->ptr; + next_stored= first_stored + reg_field->pack_length_in_rec(); + } + else if (reg_field->ptr == next_stored) // next stored field + next_stored+= reg_field->pack_length_in_rec(); + else if (reg_field->ptr > next_stored) // virtual + { + if (next_virtual) + { + if (reg_field->ptr != next_virtual) + goto err; + next_virtual+= reg_field->pack_length_in_rec(); + } + else + { + first_virtual= reg_field->ptr; + next_virtual= first_virtual + reg_field->pack_length_in_rec(); + } + } + else // reg_field < next_stored. can happen if the i=0 field was virtual + { + if (next_virtual) + goto err; + first_virtual= first_stored; + next_virtual= next_stored; + first_stored= reg_field->ptr; + next_stored= first_stored + reg_field->pack_length_in_rec(); + } + if (attr.unireg_check == Field::TIMESTAMP_DNUN_FIELD || attr.unireg_check == Field::TIMESTAMP_DN_FIELD) { @@ -2810,7 +2885,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, /* We want to store the value for the last bits */ swap_variables(uchar*, null_pos, mysql57_vcol_null_pos); swap_variables(uint, null_bit_pos, mysql57_vcol_null_bit_pos); - DBUG_ASSERT((null_pos + (null_bit_pos + 7) / 8) <= share->field[0]->ptr); + if ((null_pos + (null_bit_pos + 7) / 8) > share->field[0]->ptr) + goto err; } /* Fix key->name and key_part->field */ @@ -2838,7 +2914,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, hash_keypart->fieldnr= hash_field_used_no + 1; hash_field= share->field[hash_field_used_no]; hash_field->flags|= LONG_UNIQUE_HASH_FIELD;//Used in parse_vcol_defs - DBUG_ASSERT(hash_field->invisible == INVISIBLE_FULL); + if (hash_field->invisible != INVISIBLE_FULL || + hash_field->pack_length() != HA_HASH_FIELD_LENGTH) + goto err; keyinfo->flags|= HA_NOSAME; share->virtual_fields++; share->stored_fields--; @@ -2867,7 +2945,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, key_part= keyinfo->key_part; for (i=0 ; i < keyinfo->user_defined_key_parts ;i++) { - DBUG_ASSERT(key_part[i].fieldnr > 0); + if (key_part[i].fieldnr <= 0 || key_part[i].fieldnr > share->fields) + goto err; // Table field corresponding to the i'th key part. Field *table_field= share->field[key_part[i].fieldnr - 1]; @@ -2935,6 +3014,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, for (i= 0; i < first_keyinfo.user_defined_key_parts; i++) { uint fieldnr= keyinfo[0].key_part[i].fieldnr; + if (fieldnr <= 0 || fieldnr > share->fields) + goto err; if (share->field[fieldnr-1]->key_length() != keyinfo[0].key_part[i].length) { @@ -2982,6 +3063,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, { uint length_bytes= 0; uint fieldnr= keyinfo->key_part[i].fieldnr; + if (fieldnr <= 0 || fieldnr > share->fields) + goto err; field= share->field[fieldnr-1]; if (field->null_ptr) @@ -3059,7 +3142,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, share->default_values, (uint) key_part->offset, (uint) key_part->length); - if (!key_part->fieldnr) + if (key_part->fieldnr <= 0 || key_part->fieldnr > share->fields) goto err; field= key_part->field= share->field[key_part->fieldnr-1]; @@ -3211,7 +3294,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, } else share->primary_key= MAX_KEY; - if (new_field_pack_flag <= 1) + if (new_field_pack_flag <= 1 && share->null_fields) { /* Old file format with default as not null */ uint null_length= (share->null_fields+7)/8; @@ -3224,8 +3307,6 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, /* Handle virtual expressions */ if (vcol_screen_length && share->frm_version >= FRM_VER_EXPRESSSIONS) { - uchar *vcol_screen_end= vcol_screen_pos + vcol_screen_length; - /* Skip header */ vcol_screen_pos+= FRM_VCOL_NEW_BASE_SIZE; share->vcol_defs.str+= FRM_VCOL_NEW_BASE_SIZE; @@ -3238,6 +3319,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, while (vcol_screen_pos < vcol_screen_end) { Virtual_column_info *vcol_info; + if (vcol_screen_end - vcol_screen_pos < FRM_VCOL_NEW_HEADER_SIZE) + goto err; + uint type= (uint) vcol_screen_pos[0]; uint field_nr= uint2korr(vcol_screen_pos+1); uint expr_length= uint2korr(vcol_screen_pos+3); @@ -3250,17 +3334,21 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (field_nr != UINT_MAX16) { - DBUG_ASSERT(field_nr < share->fields); + if (field_nr >= share->fields) + goto err; reg_field= share->field[field_nr]; } else { reg_field= 0; - DBUG_ASSERT(name_length); + if (!name_length || type != VCOL_CHECK_TABLE) + goto err; } vcol_screen_pos+= FRM_VCOL_NEW_HEADER_SIZE; vcol_info->set_vcol_type((enum_vcol_info_type) type); + if ((uint)(vcol_screen_end-vcol_screen_pos) < name_length+expr_length) + goto err; if (name_length) { vcol_info->name.str= strmake_root(&share->mem_root, @@ -3274,7 +3362,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, switch (type) { case VCOL_GENERATED_VIRTUAL: { - uint recpos; + if (reg_field->vcol_info) + goto err; reg_field->vcol_info= vcol_info; share->virtual_fields++; share->stored_fields--; @@ -3283,37 +3372,43 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, if (reg_field->flags & PART_KEY_FLAG) vcol_info->set_vcol_type(VCOL_GENERATED_VIRTUAL_INDEXED); /* Correct stored_rec_length as non stored fields are last */ - recpos= (uint) (reg_field->ptr - record); + uint recpos= (uint) (reg_field->ptr - record); if (share->stored_rec_length >= recpos) share->stored_rec_length= recpos-1; break; } case VCOL_GENERATED_STORED: vcol_info->stored_in_db= 1; - DBUG_ASSERT(!reg_field->vcol_info); + if (reg_field->vcol_info) + goto err; reg_field->vcol_info= vcol_info; share->virtual_fields++; break; case VCOL_DEFAULT: vcol_info->stored_in_db= 1; - DBUG_ASSERT(!reg_field->default_value); + if (reg_field->default_value) + goto err; reg_field->default_value= vcol_info; share->default_expressions++; break; case VCOL_CHECK_FIELD: - DBUG_ASSERT(!reg_field->check_constraint); + if (reg_field->check_constraint) + goto err; reg_field->check_constraint= vcol_info; share->field_check_constraints++; break; case VCOL_CHECK_TABLE: - *(table_check_constraints++)= vcol_info; + if ((uint)(table_check_constr - share->check_constraints) >= + share->table_check_constraints) + goto err; + *(table_check_constr++)= vcol_info; break; } } } - DBUG_ASSERT((uint) (table_check_constraints - share->check_constraints) == - (uint) (share->table_check_constraints - - share->field_check_constraints)); + if (table_check_constr - share->check_constraints != + (int)share->table_check_constraints - (int)share->field_check_constraints) + goto err; if (options.str) { @@ -3366,6 +3461,19 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, share->can_cmp_whole_record= (share->blob_fields == 0 && share->varchar_fields == 0); + data_start= share->default_values; + data_end= data_start + share->reclength; + if (share->null_field_first) + data_start+= share->null_bytes; + else + data_end-= share->null_bytes; + + if (data_end < data_start || + (first_virtual && first_virtual != next_stored) || + first_stored < data_start || + (next_virtual ? next_virtual : next_stored) > data_end) + goto err; + share->column_bitmap_size= bitmap_buffer_size(share->fields); bitmap_count= 1; @@ -4817,19 +4925,20 @@ void open_table_error(TABLE_SHARE *share, enum open_frm_error error, } /* open_table_error */ - /* - ** fix a str_type to a array type - ** typeparts separated with some char. differents types are separated - ** with a '\0' - */ +/* + fix a str_type to a array type + typeparts separated with some char. differents types are separated + with a '\0' +*/ static bool -fix_type_pointers(const char ***typelib_value_names, +fix_type_pointers(const char ***typelib_value_names, const char **names_end, uint **typelib_value_lengths, TYPELIB *point_to_type, uint types, char *ptr, size_t length) { const char *end= ptr + length; + names_end--; // simplify the check below, reserve place for 0 at the end while (types--) { @@ -4861,7 +4970,7 @@ fix_type_pointers(const char ***typelib_value_names, { // Now scan the next value+sep pair char *vend= (char*) memchr(ptr, sep, end - ptr); - if (!vend) + if (!vend || *typelib_value_names >= names_end) return true; // Bad format *((*typelib_value_names)++)= ptr; *((*typelib_value_lengths)++)= (uint) (vend - ptr); diff --git a/storage/connect/mysql-test/connect/r/drop-open-error.result b/storage/connect/mysql-test/connect/r/drop-open-error.result index f9b9b7e87d29f..8f5341bbcceb0 100644 --- a/storage/connect/mysql-test/connect/r/drop-open-error.result +++ b/storage/connect/mysql-test/connect/r/drop-open-error.result @@ -5,11 +5,3 @@ drop table mdev9949; Warnings: Warning 1017 Can't find file: 'DATADIR/test/mdev9949.dos' (errno: 2 "No such file or directory") drop table t1; -select @@secure_file_priv 'must be NULL'; -must be NULL -NULL -create table t1 (a char(16)) engine=myisam; -insert into t1 values('Hello World!'); -create table t2 engine=connect file_name='foo/bar.txt' as select * from t1; -ERROR HY000: Got error 174 'Open(a+b) error 2 on foo/bar.txt: No such file or directory' from CONNECT -drop table t1; diff --git a/storage/connect/mysql-test/connect/t/drop-open-error.opt b/storage/connect/mysql-test/connect/t/drop-open-error.opt deleted file mode 100644 index 22520f0aa9901..0000000000000 --- a/storage/connect/mysql-test/connect/t/drop-open-error.opt +++ /dev/null @@ -1 +0,0 @@ ---secure-file-priv="" diff --git a/storage/connect/mysql-test/connect/t/drop-open-error.test b/storage/connect/mysql-test/connect/t/drop-open-error.test index dd286c9646606..97d938e431087 100644 --- a/storage/connect/mysql-test/connect/t/drop-open-error.test +++ b/storage/connect/mysql-test/connect/t/drop-open-error.test @@ -18,14 +18,3 @@ copy_file $MTR_SUITE_DIR/std_data/mdev9949.frm $datadir/test/mdev9949.frm; --replace_result $MARIADB_DATADIR DATADIR/ './' 'DATADIR/' drop table mdev9949; drop table t1; - -# -# MDEV-7935 CREATE TABLE ... AS SELECT ... can cause a Server crash (Assertion `0' in Protocol::end_statement) -# -select @@secure_file_priv 'must be NULL'; # otherwise foo/bar.txt won't be allowed -create table t1 (a char(16)) engine=myisam; -insert into t1 values('Hello World!'); -replace_regex @on .*/foo/@on foo/@; -error ER_GET_ERRMSG; -create table t2 engine=connect file_name='foo/bar.txt' as select * from t1; -drop table t1;