diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-07-15 10:26:31 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-07-15 10:26:31 +0300 |
commit | ced3ec4c9ce0853c564532fbe90656cf1c3c2bed (patch) | |
tree | f5ef6e497ebc440eaaabfc8ceaf6edc8d18d88f6 /storage | |
parent | 9936cfd531a49b0ba124c4eb38a6099ec420c7fd (diff) | |
download | mariadb-git-ced3ec4c9ce0853c564532fbe90656cf1c3c2bed.tar.gz |
Revert MDEV-20453 (string_view)
In fsp_path_to_space_name(), we would access a byte right before
the start of the string, tripping AddressSanitizer.
This reverts commit d87006a1c1e775ac75b6cc21c8a243b8b4e61571
and commit a7634281aa64a549d19cd20ead7e80d0267271ee.
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 47 | ||||
-rw-r--r-- | storage/innobase/fsp/fsp0file.cc | 25 | ||||
-rw-r--r-- | storage/innobase/include/fil0fil.h | 7 |
3 files changed, 55 insertions, 24 deletions
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index ae579ce46ba..f076f32e50f 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -3487,6 +3487,53 @@ fil_space_read_name_and_filepath( return(success); } +/** Convert a file name to a tablespace name. +@param[in] filename directory/databasename/tablename.ibd +@return database/tablename string, to be freed with ut_free() */ +char* +fil_path_to_space_name( + const char* filename) +{ + /* Strip the file name prefix and suffix, leaving + only databasename/tablename. */ + ulint filename_len = strlen(filename); + const char* end = filename + filename_len; +#ifdef HAVE_MEMRCHR + const char* tablename = 1 + static_cast<const char*>( + memrchr(filename, OS_PATH_SEPARATOR, + filename_len)); + const char* dbname = 1 + static_cast<const char*>( + memrchr(filename, OS_PATH_SEPARATOR, + tablename - filename - 1)); +#else /* HAVE_MEMRCHR */ + const char* tablename = filename; + const char* dbname = NULL; + + while (const char* t = static_cast<const char*>( + memchr(tablename, OS_PATH_SEPARATOR, + ulint(end - tablename)))) { + dbname = tablename; + tablename = t + 1; + } +#endif /* HAVE_MEMRCHR */ + + ut_ad(dbname != NULL); + ut_ad(tablename > dbname); + ut_ad(tablename < end); + ut_ad(end - tablename > 4); + ut_ad(memcmp(end - 4, DOT_IBD, 4) == 0); + + char* name = mem_strdupl(dbname, ulint(end - dbname) - 4); + + ut_ad(name[tablename - dbname - 1] == OS_PATH_SEPARATOR); +#if OS_PATH_SEPARATOR != '/' + /* space->name uses '/', not OS_PATH_SEPARATOR. */ + name[tablename - dbname - 1] = '/'; +#endif + + return(name); +} + /** Discover the correct IBD file to open given a remote or missing filepath from the REDO log. Administrators can move a crashed database to another location on the same machine and try to recover it. diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc index 670beac2579..653b74c73be 100644 --- a/storage/innobase/fsp/fsp0file.cc +++ b/storage/innobase/fsp/fsp0file.cc @@ -30,7 +30,6 @@ Created 2013-7-26 by Kevin Lewis #include "page0page.h" #include "srv0start.h" -#include "string_view.h" /** Initialize the name, size and order of this datafile @param[in] name tablespace name, will be copied @param[in] flags tablespace flags */ @@ -259,28 +258,6 @@ Datafile::same_as( #endif /* WIN32 */ } -/** Convert a file name to a tablespace name. -@param[in] filename directory/databasename/tablename.ibd -@return database/tablename string, to be freed with ut_free() */ -static char *fsp_path_to_space_name(string_view filename) -{ - auto last_slash= filename.rfind(OS_PATH_SEPARATOR); - auto prev_last_slash= - filename.substr(0, last_slash).rfind(OS_PATH_SEPARATOR); - filename.remove_prefix(prev_last_slash + 1); - ut_ad(filename.ends_with(DOT_IBD)); - filename.remove_suffix(strlen(DOT_IBD)); - - char *name= mem_strdupl(filename.data(), filename.size()); - -#if OS_PATH_SEPARATOR != '/' - /* space->name uses '/', not OS_PATH_SEPARATOR. */ - name[last_slash - prev_last_slash - 1]= '/'; -#endif - - return name; -} - /** Allocate and set the datafile or tablespace name in m_name. If a name is provided, use it; else extract a file-per-table tablespace name from m_filepath. The value of m_name @@ -294,7 +271,7 @@ Datafile::set_name(const char* name) if (name != NULL) { m_name = mem_strdup(name); } else { - m_name = fsp_path_to_space_name(m_filepath); + m_name = fil_path_to_space_name(m_filepath); } } diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index ecba2db8e06..21f21d95ebc 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -1495,6 +1495,13 @@ fil_space_read_name_and_filepath( char** name, char** filepath); +/** Convert a file name to a tablespace name. +@param[in] filename directory/databasename/tablename.ibd +@return database/tablename string, to be freed with ut_free() */ +char* +fil_path_to_space_name( + const char* filename); + /** Generate redo log for swapping two .ibd files @param[in] old_table old table @param[in] new_table new table |