summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-07-15 10:26:31 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-07-15 10:26:31 +0300
commitced3ec4c9ce0853c564532fbe90656cf1c3c2bed (patch)
treef5ef6e497ebc440eaaabfc8ceaf6edc8d18d88f6 /storage
parent9936cfd531a49b0ba124c4eb38a6099ec420c7fd (diff)
downloadmariadb-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.cc47
-rw-r--r--storage/innobase/fsp/fsp0file.cc25
-rw-r--r--storage/innobase/include/fil0fil.h7
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