From 4103d91111fe298c7fa880686ca5d2adaa5cd1f7 Mon Sep 17 00:00:00 2001 From: Pablo Curiel Date: Sun, 3 Sep 2023 02:29:16 +0200 Subject: [PATCH] nxdt_utils: treat max filename length as bytes. Fixes issues while using USB dumping with a Linux host. We're still preserving the arbitrary max filename length for SD card files. --- .github/workflows/rewrite.yml | 2 +- source/core/nxdt_utils.c | 34 ++++++++++++++++++---------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/.github/workflows/rewrite.yml b/.github/workflows/rewrite.yml index 1caa8e0..6e6913c 100644 --- a/.github/workflows/rewrite.yml +++ b/.github/workflows/rewrite.yml @@ -31,7 +31,7 @@ jobs: - name: Update packages run: | sudo -n apt-get update - sudo -n apt-get upgrade -y patch autoconf automake tar bzip2 diffutils pkgconf fakeroot p7zip-full git file zstd + sudo -n apt-get upgrade -y patch autoconf automake tar bzip2 diffutils pkgconf fakeroot git file zstd sudo -n dkp-pacman --noconfirm -U \ "https://wii.leseratte10.de/devkitPro/other-stuff/dkp-toolchain-vars-1.0.3-2-any.pkg.tar.zst" \ "https://wii.leseratte10.de/devkitPro/cmake/switch-cmake-1.5.0-1-any.pkg.tar.xz" diff --git a/source/core/nxdt_utils.c b/source/core/nxdt_utils.c index a5e0ec7..6c456e5 100644 --- a/source/core/nxdt_utils.c +++ b/source/core/nxdt_utils.c @@ -32,8 +32,10 @@ #include "nxdt_bfsar.h" #include "fatfs/ff.h" -/* Reference: https://docs.microsoft.com/en-us/windows/win32/fileio/filesystem-functionality-comparison#limits. */ -#define NT_MAX_FILENAME_LENGTH 255 +/// Reference: https://docs.microsoft.com/en-us/windows/win32/fileio/filesystem-functionality-comparison#limits. +/// Reference: https://en.wikipedia.org/wiki/Comparison_of_file_systems#Limits. +/// Most modern filesystems use a 255-byte limit instead of 255-character/codepoint limit, so that's what we're gonna use. +#define FS_MAX_FILENAME_LENGTH 255 #define SDMC_MAX_FILENAME_LENGTH 128 /* Arbitrarily set, I'm tired of FS sysmodule shenanigans. */ /* Type definitions. */ @@ -110,7 +112,7 @@ static void utilsOverclockSystemAppletHook(AppletHookType hook, void *param); static void utilsChangeHomeButtonBlockStatus(bool block); -static size_t utilsGetUtf8CodepointCount(const char *str, size_t str_size, size_t cp_limit, size_t *last_cp_pos); +static size_t utilsGetUtf8StringLimit(const char *str, size_t str_size, size_t byte_limit); bool utilsInitializeResources(const int program_argc, const char **program_argv) { @@ -873,7 +875,7 @@ char *utilsGeneratePath(const char *prefix, const char *filename, const char *ex size_t path_len = (prefix_len + strlen(filename) + extension_len); if (append_path_sep) path_len++; - size_t max_filename_len = ((use_prefix && !strncmp(prefix, DEVOPTAB_SDMC_DEVICE, strlen(DEVOPTAB_SDMC_DEVICE))) ? SDMC_MAX_FILENAME_LENGTH : NT_MAX_FILENAME_LENGTH); + const size_t max_filename_len = ((use_prefix && !strncmp(prefix, DEVOPTAB_SDMC_DEVICE, strlen(DEVOPTAB_SDMC_DEVICE))) ? SDMC_MAX_FILENAME_LENGTH : FS_MAX_FILENAME_LENGTH); char *path = NULL, *ptr1 = NULL, *ptr2 = NULL; bool filename_only = false, success = false; @@ -914,11 +916,10 @@ 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 codepoint count. */ - /* Use our max filename length as the codepoint count limit. */ - size_t last_cp_pos = 0; - size_t cp_count = utilsGetUtf8CodepointCount(ptr1, element_size, max_filename_len, &last_cp_pos); - if (cp_count > max_filename_len) + /* Get UTF-8 string limit. */ + /* Use our max filename length as the byte count limit. */ + size_t last_cp_pos = utilsGetUtf8StringLimit(ptr1, element_size, max_filename_len); + if (last_cp_pos < element_size) { if (ptr2) { @@ -1277,25 +1278,26 @@ NX_INLINE void utilsCloseFileDescriptor(int *fd) *fd = -1; } -static size_t utilsGetUtf8CodepointCount(const char *str, size_t str_size, size_t cp_limit, size_t *last_cp_pos) +static size_t utilsGetUtf8StringLimit(const char *str, size_t str_size, size_t byte_limit) { - if (!str || !*str || !str_size || (!cp_limit && last_cp_pos) || (cp_limit && !last_cp_pos)) return 0; + if (!str || !*str || !str_size || !byte_limit) return 0; + + if (byte_limit > str_size) return str_size; u32 code = 0; ssize_t units = 0; - size_t cur_pos = 0, cp_count = 0; + size_t cur_pos = 0, last_cp_pos = 0; const u8 *str_u8 = (const u8*)str; - while(cur_pos < str_size) + while(cur_pos < str_size && cur_pos < byte_limit) { 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 (cp_limit && last_cp_pos && cp_count < cp_limit) *last_cp_pos = cur_pos; + if (cur_pos < byte_limit) last_cp_pos = cur_pos; } - return cp_count; + return last_cp_pos; }