From 3d5ab84ec15cbe03a4b54e9002d8fe9c3eb782b8 Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Tue, 3 Dec 2024 13:47:30 +0000 Subject: [PATCH] [iso] fix FAT filenames being truncated on image extraction * Needed to read 12 chars instead of stopping at 11 and therefore inserting a NUL. * Closes #2534. * Also enable detection of bootriscv64.efi and bootloongarch64.efi bootloaders from FAT images. --- src/iso.c | 29 ++++++++++++----------------- src/rufus.h | 1 + src/rufus.rc | 10 +++++----- src/syslinux/libfat/dumpdir.c | 21 ++++++++++++++------- 4 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/iso.c b/src/iso.c index 66c7bf969c2..9f42c3ab495 100644 --- a/src/iso.c +++ b/src/iso.c @@ -1758,8 +1758,8 @@ BOOL HasEfiImgBootLoaders(void) int32_t dc, c; struct libfat_filesystem *lf_fs = NULL; struct libfat_direntry direntry; - char name[12] = { 0 }, bootloader_name[32]; - int i, j, k; + char bootloader_name[16]; + int i; if ((image_path == NULL) || !HAS_EFI_IMG(img_report)) return FALSE; @@ -1799,24 +1799,19 @@ BOOL HasEfiImgBootLoaders(void) goto out; dc = direntry.entry[26] + (direntry.entry[27] << 8); - for (i = 0; i < ARRAYSIZE(efi_archname); i++) { - static_sprintf(bootloader_name, "boot%s.efi", efi_archname[i]); - // TODO: bootriscv64.efi and bootloongarch64.efi need LFN support - if (strlen(bootloader_name) > 12) - continue; - for (j = 0, k = 0; bootloader_name[j] != 0; j++) { - if (bootloader_name[j] == '.') { - while (k < 8) - name[k++] = ' '; - } else { - name[k++] = toupper(bootloader_name[j]); - } - } - c = libfat_searchdir(lf_fs, dc, name, &direntry); + for (i = 1; i < ARRAYSIZE(efi_archname); i++) { + // We consider it unlikely that any bootri#####.efi or bootlo#####.efi files + // in the /efi/boot/ subdirectory will be anything but 'bootriscv64.efi' and + // 'bootloongarch64.efi', so we'll use the ~1 LFN shortened names for them. + static_sprintf(bootloader_name, "BOOT%c%c%c%cEFI", efi_archname[i][0], efi_archname[i][1], + strlen(efi_archname[i]) > 4 ? '~' : efi_archname[i][2], + strlen(efi_archname[i]) > 4 ? '1' : (strlen(efi_archname[i]) > 3 ? efi_archname[i][3] : ' ')); + safe_strtoupper(bootloader_name); + c = libfat_searchdir(lf_fs, dc, bootloader_name, &direntry); if (c > 0) { if (!ret) uprintf(" Detected EFI bootloader(s) (from '%s'):", img_report.efi_img_path); - uprintf(" ● '%s'", bootloader_name); + uprintf(" ● 'boot%s.efi'", efi_archname[i]); ret = TRUE; } } diff --git a/src/rufus.h b/src/rufus.h index 18839db3bb7..507e66c4343 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -184,6 +184,7 @@ static __inline void safe_strcp(char* dst, const size_t dst_max, const char* src #define safe_vsnprintf vsnprintf #endif #define safe_strtolower(str) do { if (str != NULL) CharLowerA(str); } while(0) +#define safe_strtoupper(str) do { if (str != NULL) CharUpperA(str); } while(0) static __inline void static_repchr(char* p, char s, char r) { if (p != NULL) while (*p != 0) { if (*p == s) *p = r; p++; } } diff --git a/src/rufus.rc b/src/rufus.rc index 1f5044b813a..4ba60c56e90 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 232, 326 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_ACCEPTFILES -CAPTION "Rufus 4.7.2214" +CAPTION "Rufus 4.7.2215" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -399,8 +399,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,7,2214,0 - PRODUCTVERSION 4,7,2214,0 + FILEVERSION 4,7,2215,0 + PRODUCTVERSION 4,7,2215,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -418,13 +418,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "4.7.2214" + VALUE "FileVersion", "4.7.2215" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", " 2011-2024 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-4.7.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "4.7.2214" + VALUE "ProductVersion", "4.7.2215" END END BLOCK "VarFileInfo" diff --git a/src/syslinux/libfat/dumpdir.c b/src/syslinux/libfat/dumpdir.c index bc037189a6d..3493340a5c6 100644 --- a/src/syslinux/libfat/dumpdir.c +++ b/src/syslinux/libfat/dumpdir.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 2019 Pete Batard + * Copyright 2019-2024 Pete Batard * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,6 +19,10 @@ #include #include "libfatint.h" +#ifndef ARRAYSIZE +#define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a))) +#endif + static struct fat_dirent* get_next_dirent(struct libfat_filesystem *fs, libfat_sector_t *sector, int *offset) { @@ -41,12 +45,12 @@ static struct fat_dirent* get_next_dirent(struct libfat_filesystem *fs, static void fill_utf16(wchar_t *name, unsigned char *entry) { int i; - for (i=0; i<5; i++) - name[i] = read16((le16_t*)&entry[1 + 2*i]); - for (i=5; i<11; i++) - name[i] = read16((le16_t*)&entry[4 + 2*i]); - for (i=11; i<12; i++) - name[i] = read16((le16_t*)&entry[6 + 2*i]); + for (i = 0; i < 5; i++) + name[i] = read16((le16_t*)&entry[1 + 2 * i]); + for (i = 5; i < 11; i++) + name[i] = read16((le16_t*)&entry[4 + 2 * i]); + for (i = 11; i < 13; i++) + name[i] = read16((le16_t*)&entry[6 + 2 * i]); } int libfat_dumpdir(struct libfat_filesystem *fs, libfat_dirpos_t *dp, @@ -94,11 +98,14 @@ int libfat_dumpdir(struct libfat_filesystem *fs, libfat_dirpos_t *dp, if ((j >= 0) && (i != j - 1)) return -3; j = i; + if (i > ARRAYSIZE(di->name) - 13) + i = ARRAYSIZE(di->name) - 13; fill_utf16(&di->name[13 * i], dep->name); dep = get_next_dirent(fs, &dp->sector, &dp->offset); if (!dep) return -1; } + di->name[ARRAYSIZE(di->name) - 1] = 0; if (di->name[0] == 0) { for (i = 0, j = 0; i < 12; i++) {