libobs: Ensure buffer size for utf-16 converted filepaths - #13749
libobs: Ensure buffer size for utf-16 converted filepaths#13749Dankirk wants to merge 5 commits into
Conversation
2dbc7fe to
985e41a
Compare
Match GetAppConfigPathPtr and os_get_path_ptr_internal file path formatting with GetAppConfigPath and os_get_path_internal. Empty/null strings return base path. Remove arbitrary path length limit with dynamic allocation.
Use dynamically allocated paths instead of arbitrary static allocations, that may not be fit long paths on all OSs. Filepaths from Windows W apis get stored internally in UTF-8, which may increase the bytes needed. Changed some A api calls to W variants to support longer paths, and to get them in supported encoding isntead of ansi code page. Fix overflow in os_stat() when used with long filename. Fix off-by-one length check in nvvfx-load sdk path.
Define FILENAME_MAX_LENGTH_UTF8 (_MAX_PATH * 3) for storing utf-16 converted paths in utf-8 on Windows for cases where dynamic allocation could may be performance issue and for simplicity. A UTF-16 code unit (wchar_t) can be up to 3 bytes/chars in UTF-8. Change os_dirent filename to be char pointer, so it is OS agnostic about the actual allocation size. It is also compiled in to lua/python wraps, so we can't use platform specific defines.
|
Tested this on Windows with both long directory names and long file names. For naming I used 180 "€"s that when converted from wchar_t (utf-16) to char (utf-8) expand to triple size of 540 chars, well over the MAX_PATH of 260 for ANSI apis and some 512 byte allocations in the app. List of things that couldn't, but can now handle such filenames:
Notably the GetConfigPath and os_get_config_path return relative paths, which means many parts of OBS can work while OBS resides in a path with long name. I still changed these to use dynamic allocation instead of static 512 bytes. Some of the configs (and others) also end up being turned into absolute paths. Absolute paths had a limit of 260 bytes. At least these can now handle longer paths:
The nvidia video and audio SDKs work (Switched to W apis). Though they currently work only with the default install directory, which shouldn't(?) really have any non-ascii or long paths. Could probably check if the SDKs have a registery entry for the install directory, in case they weren't installed in default directory. Out of scope for this though. Freetype2 font loading from Windows fonts directory works (Switched to W apis). Could probably test it with with font filenames that aren't ascii. There is also parts I haven't really tested, but they follow the pattern as everywhere else:
For the future |
Description
File paths from Windows W apis get stored internally in UTF-8, but there are many cases the internal buffer is too small to contain a valid path from W api. For example
char file[MAX_PATH](260) is too small. In other cases 512 bytes is assumed long enough, but many OSs/filesystems support paths longer than that.This update:
Prefers dynamic heap allocation for file paths over static stack size, because their max size varies widely by filesystem/OS
Changed many A api calls to W variants to support longer paths. (255 utf-16 code units vs 255 bytes)
Minor bugfixes
os_stat()when used with long filename (incorrectly usedsizeof()instead_countof())nvafx-loadandnvvfx-loadsdk pathBPtrre-assignment leaking the pointer (re-assignment was not used previously)Minor changes
GetAppConfigPathPtrandos_get_config_path_ptrto format the path identically toGetAppConfigPathandos_get_config_path. Previously there was difference with null/empty string.os_direntuses a char pointer instead of an array to hide the platform specific allocation size of filename.Motivation and Context
This is mainly findings while working on other things with encodings, but is also somewhat related to recent change about using absolute paths for DLLs, which could trigger one of these length checks.
How Has This Been Tested?
Tried happy paths using a scene with all source types active and restarting the app.
EDIT: Tested long paths as detailed in comment below.
Types of changes
Checklist: