DirectoryEnumerator: Handle non-null-terminated strings in CaseInsensitiveCompare

std::string_view instances aren't required to be null terminated. Given
this, we can make the functions a little safer by performing an explicit
bounded comparison on the range of characters, making the code more
generic with regards to handling the underlying string data.
This commit is contained in:
Lioncash 2019-08-10 00:52:38 -04:00
parent ac6f2a1ed2
commit a572439967
2 changed files with 12 additions and 17 deletions

View File

@ -6,20 +6,16 @@ namespace nod {
struct CaseInsensitiveCompare { struct CaseInsensitiveCompare {
bool operator()(std::string_view lhs, std::string_view rhs) const { bool operator()(std::string_view lhs, std::string_view rhs) const {
#if _WIN32 return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), [](char lhs, char rhs) {
if (_stricmp(lhs.data(), rhs.data()) < 0) return std::tolower(static_cast<unsigned char>(lhs)) < std::tolower(static_cast<unsigned char>(rhs));
#else });
if (strcasecmp(lhs.data(), rhs.data()) < 0)
#endif
return true;
return false;
} }
#if _WIN32 #if _WIN32
bool operator()(std::wstring_view lhs, std::wstring_view rhs) const { bool operator()(std::wstring_view lhs, std::wstring_view rhs) const {
if (_wcsicmp(lhs.data(), rhs.data()) < 0) return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), [](wchar_t lhs, wchar_t rhs) {
return true; return std::towlower(lhs) < std::towlower(rhs);
return false; });
} }
#endif #endif
}; };

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#if _WIN32 && UNICODE #if _WIN32 && UNICODE
#include <wctype.h> #include <cwctype>
#include <direct.h> #include <direct.h>
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1 #define WIN32_LEAN_AND_MEAN 1
@ -16,20 +16,19 @@
#define WINDOWS_STORE 0 #define WINDOWS_STORE 0
#endif #endif
#else #else
#include <ctype.h> #include <cctype>
#include <sys/file.h>
#include <unistd.h>
#include <cerrno> #include <cerrno>
#include <sys/file.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/statvfs.h> #include <sys/statvfs.h>
#include <unistd.h>
#endif #endif
#include <sys/stat.h> #include <sys/stat.h>
#include <algorithm>
#include <cstring>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <cstring>
#include <algorithm>
#include "logvisor/logvisor.hpp" #include "logvisor/logvisor.hpp"
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable : 4996) #pragma warning(disable : 4996)