diff --git a/source/core/nxdt_utils.c b/source/core/nxdt_utils.c index 81574c4..2df6cd4 100644 --- a/source/core/nxdt_utils.c +++ b/source/core/nxdt_utils.c @@ -33,7 +33,6 @@ #include "fatfs/ff.h" /* Reference: https://docs.microsoft.com/en-us/windows/win32/fileio/filesystem-functionality-comparison#limits. */ -/* Actually expressed in bytes, not codepoints. */ #define NT_MAX_FILENAME_LENGTH 255 /* Type definitions. */ @@ -110,7 +109,7 @@ static void utilsOverclockSystemAppletHook(AppletHookType hook, void *param); static void utilsChangeHomeButtonBlockStatus(bool block); -static size_t utilsGetUtf8StringLimit(const char *str, size_t str_size, size_t byte_limit); +static size_t utilsGetUtf8CodepointCount(const char *str, size_t str_size, size_t cp_limit, size_t *last_cp_pos); bool utilsInitializeResources(const int program_argc, const char **program_argv) { @@ -912,10 +911,11 @@ char *utilsGeneratePath(const char *prefix, const char *filename, const char *ex /* Get current path element size. */ size_t element_size = (ptr2 ? (size_t)(ptr2 - ptr1) : (path_len - (size_t)(ptr1 - path))); - /* Get UTF-8 string limit. */ - /* Use NT_MAX_FILENAME_LENGTH as the byte count limit. */ - size_t last_cp_pos = utilsGetUtf8StringLimit(ptr1, element_size, NT_MAX_FILENAME_LENGTH); - if (last_cp_pos < element_size) + /* Get UTF-8 codepoint count. */ + /* Use NT_MAX_FILENAME_LENGTH as the codepoint count limit. */ + size_t last_cp_pos = 0; + size_t cp_count = utilsGetUtf8CodepointCount(ptr1, element_size, NT_MAX_FILENAME_LENGTH, &last_cp_pos); + if (cp_count > NT_MAX_FILENAME_LENGTH) { if (ptr2) { @@ -1274,26 +1274,25 @@ NX_INLINE void utilsCloseFileDescriptor(int *fd) *fd = -1; } -static size_t utilsGetUtf8StringLimit(const char *str, size_t str_size, size_t byte_limit) +static size_t utilsGetUtf8CodepointCount(const char *str, size_t str_size, size_t cp_limit, size_t *last_cp_pos) { - if (!str || !*str || !str_size || !byte_limit) return 0; - - if (byte_limit > str_size) return str_size; + if (!str || !*str || !str_size || (!cp_limit && last_cp_pos) || (cp_limit && !last_cp_pos)) return 0; u32 code = 0; ssize_t units = 0; - size_t cur_pos = 0, last_cp_pos = 0; + size_t cur_pos = 0, cp_count = 0; const u8 *str_u8 = (const u8*)str; - while(cur_pos < str_size && cur_pos < byte_limit) + while(cur_pos < str_size) { units = decode_utf8(&code, str_u8 + cur_pos); size_t new_pos = (cur_pos + (size_t)units); if (units < 0 || !code || new_pos > str_size) break; + cp_count++; cur_pos = new_pos; - if (cur_pos < byte_limit) last_cp_pos = cur_pos; + if (cp_limit && last_cp_pos && cp_count < cp_limit) *last_cp_pos = cur_pos; } - return last_cp_pos; + return cp_count; }