]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Update directory name sanitization
authorShadowNinja <shadowninja@minetest.net>
Tue, 1 Feb 2022 02:11:51 +0000 (21:11 -0500)
committerrubenwardy <rw@rubenwardy.com>
Fri, 8 Apr 2022 13:55:21 +0000 (14:55 +0100)
Only ASCII spaces have to be handles specially, and leading spaces are
also disallowed.

src/unittest/test_utilities.cpp
src/util/string.cpp
src/util/string.h

index 228a9559ff3cfafdb9f0845a33eb2cf85d3fff77..10ea8d36a839a30671b898472bb045a11ffbf48e 100644 (file)
@@ -636,8 +636,12 @@ void TestUtilities::testBase64()
 
 void TestUtilities::testSanitizeDirName()
 {
-       UASSERT(sanitizeDirName("a", "_") == "a");
-       UASSERT(sanitizeDirName("COM1", "_") == "_COM1");
-       UASSERT(sanitizeDirName("cOm\u00B2 .txt:a", "_") == "cOm\u00B2 _txt_a");
-       UASSERT(sanitizeDirName("cOnIn$ ", "_") == "_cOnIn$ ");
+       UASSERT(sanitizeDirName("a", "~") == "a");
+       UASSERT(sanitizeDirName("  ", "~") == "__");
+       UASSERT(sanitizeDirName(" a ", "~") == "_a_");
+       UASSERT(sanitizeDirName("COM1", "~") == "~COM1");
+       UASSERT(sanitizeDirName("COM1", ":") == "_COM1");
+       UASSERT(sanitizeDirName("cOm\u00B2", "~") == "~cOm\u00B2");
+       UASSERT(sanitizeDirName("cOnIn$", "~") == "~cOnIn$");
+       UASSERT(sanitizeDirName(" cOnIn$ ", "~") == "_cOnIn$_");
 }
index 689f58f7f304d5ad8f14205dfa992e17879b0ca2..39cd446677df4c38741c98bce2a6420a3c405a84 100644 (file)
@@ -864,40 +864,29 @@ static const std::array<std::wstring, 30> disallowed_dir_names = {
 static const std::wstring disallowed_path_chars = L"<>:\"/\\|?*.";
 
 
-/**
- * @param str
- * @return A copy of \p str with trailing whitespace removed.
- */
-static std::wstring wrtrim(const std::wstring &str)
-{
-       size_t back = str.size();
-       while (back > 0 && std::isspace(str[back - 1]))
-               --back;
-
-       return str.substr(0, back);
-}
-
-
-/**
- * Sanitize the name of a new directory. This consists of two stages:
- * 1. Check for 'reserved filenames' that can't be used on some filesystems
- *     and add a prefix to them
- * 2. Remove 'unsafe' characters from the name by replacing them with '_'
- */
 std::string sanitizeDirName(const std::string &str, const std::string &optional_prefix)
 {
        std::wstring safe_name = utf8_to_wide(str);
 
-       std::wstring dev_name = wrtrim(safe_name);
-
        for (std::wstring disallowed_name : disallowed_dir_names) {
-               if (str_equal(dev_name, disallowed_name, true)) {
+               if (str_equal(safe_name, disallowed_name, true)) {
                        safe_name = utf8_to_wide(optional_prefix) + safe_name;
                        break;
                }
        }
 
-       for (unsigned long i = 0; i < safe_name.length(); i++) {
+       // Replace leading and trailing spaces with underscores.
+       size_t start = safe_name.find_first_not_of(L' ');
+       size_t end = safe_name.find_last_not_of(L' ');
+       if (start == std::wstring::npos || end == std::wstring::npos)
+               start = end = safe_name.size();
+       for (size_t i = 0; i < start; i++)
+               safe_name[i] = L'_';
+       for (size_t i = end + 1; i < safe_name.size(); i++)
+               safe_name[i] = L'_';
+
+       // Replace other disallowed characters with underscores
+       for (size_t i = 0; i < safe_name.length(); i++) {
                bool is_valid = true;
 
                // Unlikely, but control characters should always be blacklisted
@@ -909,7 +898,7 @@ std::string sanitizeDirName(const std::string &str, const std::string &optional_
                }
 
                if (!is_valid)
-                       safe_name[i] = '_';
+                       safe_name[i] = L'_';
        }
 
        return wide_to_utf8(safe_name);
index f4ca1a7de65cb2be281d937f9fcbcdce0e212543..d8ec633ee63e51a0c944d4b07bcf764a0ffcae2e 100644 (file)
@@ -749,7 +749,7 @@ inline irr::core::stringw utf8_to_stringw(const std::string &input)
 /**
  * Sanitize the name of a new directory. This consists of two stages:
  * 1. Check for 'reserved filenames' that can't be used on some filesystems
- *    and prefix them
+ *    and add a prefix to them
  * 2. Remove 'unsafe' characters from the name by replacing them with '_'
  */
 std::string sanitizeDirName(const std::string &str, const std::string &optional_prefix);