System: Fix some bugs in GetTitleForPath

The previous implementation had a few issues in certain edge cases:
- If the path contained no '/' or '\', then the string_view constructor
  is called with a count that exceeds the length of the string
  (effectively `title_end - (char *)0`, which is undefined behavior,
  at least in C).
- If the only '/' was the filesystem root, the last character of
  the title was truncated, and the '/' remained. For example,
  "/title.bin" resulted in "/titl".
- At least in C, it is undefined behavior to use the the < operator
  with a null pointer, which is done in std::max if the path did
  not have both '/' and '\'.

The first issue results in a std::bad_alloc exception on my machine.
This commit is contained in:
Michael Forney 2020-12-24 19:36:58 -08:00 committed by Connor McLaughlin
parent fcc6bf0cb7
commit 64c0ca14a3
1 changed files with 5 additions and 11 deletions

View File

@ -314,17 +314,11 @@ ConsoleRegion GetConsoleRegionForDiscRegion(DiscRegion region)
std::string_view GetTitleForPath(const char* path) std::string_view GetTitleForPath(const char* path)
{ {
const char* extension = std::strrchr(path, '.'); std::string_view path_view = path;
if (path == extension) std::size_t title_start = path_view.find_last_of("/\\");
return path; if (title_start != std::string_view::npos)
path_view.remove_prefix(title_start + 1);
const char* path_end = path + std::strlen(path); return path_view.substr(0, path_view.find_last_of('.'));
const char* title_end = extension ? (extension - 1) : (path_end);
const char* title_start = std::max(std::strrchr(path, '/'), std::strrchr(path, '\\'));
if (!title_start || title_start == path)
return std::string_view(path, title_end - title_start);
else
return std::string_view(title_start + 1, title_end - title_start);
} }
std::string GetGameCodeForPath(const char* image_path) std::string GetGameCodeForPath(const char* image_path)