diff options
author | Elias Fleckenstein <eliasfleckenstein@web.de> | 2022-05-17 22:12:00 +0200 |
---|---|---|
committer | Elias Fleckenstein <eliasfleckenstein@web.de> | 2022-05-17 22:12:00 +0200 |
commit | 21df26984da91143c15587f5a03c98d68c3adc4e (patch) | |
tree | aaa707a628ad331f67890023dffe1b4f60dd01d3 /src/util/string.cpp | |
parent | b09fc5de5cdb021f43ad32b7e3f50dc75c0bc622 (diff) | |
parent | eabf05758e3ba5f6f4bb1b8d1d1f02179b84e410 (diff) | |
download | dragonfireclient-21df26984da91143c15587f5a03c98d68c3adc4e.tar.xz |
Merge branch 'master' of https://github.com/minetest/minetest
Diffstat (limited to 'src/util/string.cpp')
-rw-r--r-- | src/util/string.cpp | 70 |
1 files changed, 58 insertions, 12 deletions
diff --git a/src/util/string.cpp b/src/util/string.cpp index eec5ab4cd..b805b2f78 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -39,8 +39,13 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <windows.h> #endif -#if defined(_ICONV_H_) && (defined(__FreeBSD__) || defined(__NetBSD__) || \ - defined(__OpenBSD__) || defined(__DragonFly__)) +#ifdef __NetBSD__ + #include <sys/param.h> + #if __NetBSD_Version__ <= 999001500 + #define BSD_ICONV_USED + #endif +#elif defined(_ICONV_H_) && (defined(__FreeBSD__) || defined(__OpenBSD__) || \ + defined(__DragonFly__)) #define BSD_ICONV_USED #endif @@ -79,6 +84,14 @@ static bool convert(const char *to, const char *from, char *outbuf, #ifdef __ANDROID__ // On Android iconv disagrees how big a wchar_t is for whatever reason const char *DEFAULT_ENCODING = "UTF-32LE"; +#elif defined(__NetBSD__) + // NetBSD does not allow "WCHAR_T" as a charset input to iconv. + #include <sys/endian.h> + #if BYTE_ORDER == BIG_ENDIAN + const char *DEFAULT_ENCODING = "UTF-32BE"; + #else + const char *DEFAULT_ENCODING = "UTF-32LE"; + #endif #else const char *DEFAULT_ENCODING = "WCHAR_T"; #endif @@ -94,7 +107,7 @@ std::wstring utf8_to_wide(const std::string &input) std::wstring out; out.resize(outbuf_size / sizeof(wchar_t)); -#ifdef __ANDROID__ +#if defined(__ANDROID__) || defined(__NetBSD__) SANITY_CHECK(sizeof(wchar_t) == 4); #endif @@ -481,6 +494,7 @@ const static std::unordered_map<std::string, u32> s_named_colors = { {"plum", 0xdda0dd}, {"powderblue", 0xb0e0e6}, {"purple", 0x800080}, + {"rebeccapurple", 0x663399}, {"red", 0xff0000}, {"rosybrown", 0xbc8f8f}, {"royalblue", 0x4169e1}, @@ -808,9 +822,11 @@ std::wstring translate_string(const std::wstring &s) #endif } -static const std::array<std::wstring, 22> disallowed_dir_names = { +static const std::array<std::wstring, 30> disallowed_dir_names = { // Problematic filenames from here: // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#file-and-directory-names + // Plus undocumented values from here: + // https://googleprojectzero.blogspot.com/2016/02/the-definitive-guide-on-win32-to-nt.html L"CON", L"PRN", L"AUX", @@ -824,6 +840,9 @@ static const std::array<std::wstring, 22> disallowed_dir_names = { L"COM7", L"COM8", L"COM9", + L"COM\u00B2", + L"COM\u00B3", + L"COM\u00B9", L"LPT1", L"LPT2", L"LPT3", @@ -833,6 +852,11 @@ static const std::array<std::wstring, 22> disallowed_dir_names = { L"LPT7", L"LPT8", L"LPT9", + L"LPT\u00B2", + L"LPT\u00B3", + L"LPT\u00B9", + L"CONIN$", + L"CONOUT$", }; /** @@ -840,12 +864,7 @@ static const std::array<std::wstring, 22> disallowed_dir_names = { */ static const std::wstring disallowed_path_chars = L"<>:\"/\\|?*."; -/** - * 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); @@ -857,7 +876,18 @@ std::string sanitizeDirName(const std::string &str, const std::string &optional_ } } - 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 @@ -869,8 +899,24 @@ 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); } + + +void safe_print_string(std::ostream &os, const std::string &str) +{ + std::ostream::fmtflags flags = os.flags(); + os << std::hex; + for (const char c : str) { + if (IS_ASCII_PRINTABLE_CHAR(c) || IS_UTF8_MULTB_START(c) || + IS_UTF8_MULTB_INNER(c) || c == '\n' || c == '\t') { + os << c; + } else { + os << '<' << std::setw(2) << (int)c << '>'; + } + } + os.setf(flags); +} |