فهرست منبع

Kernel/FileSystem: Fix handling of FAT names that don't fill an entry

 * Fix bug where last character of a filename or extension would be
   truncated (HELLO.TXT -> HELL.TX).
 * Fix bug where additional NULL characters would be added to long
   filenames that did not completely fill one of the Long Filename Entry
   character fields.
Taj Morton 2 سال پیش
والد
کامیت
31eeea08ba
2فایلهای تغییر یافته به همراه17 افزوده شده و 3 حذف شده
  1. 15 2
      Kernel/FileSystem/FATFS/Inode.cpp
  2. 2 1
      Kernel/FileSystem/FATFS/Inode.h

+ 15 - 2
Kernel/FileSystem/FATFS/Inode.cpp

@@ -167,7 +167,20 @@ ErrorOr<NonnullOwnPtr<KString>> FATInode::compute_filename(FATEntry& entry, Vect
             filename.append(lfn_entry.characters3[1]);
         }
 
-        return TRY(KString::try_create(byte_terminated_string(filename.string_view(), lfn_entry_text_termination)));
+        // Long Filenames have two terminators:
+        // 1. Completely unused "entries" (the `characterN` fields of
+        //    `lfn_entry`) are filled with 0xFF (`lfn_entry_unused_byte`).
+        // 2. Partially used entries (within `characterN`) are null-padded.
+        //
+        // `filename` is truncated first to eliminate unused entries, and
+        // then further truncated to remove any existing null padding characters.
+        //
+        // Page 8 of the Long Filename Specification
+        // (http://www.osdever.net/documents/LongFileName.pdf)
+        // details this encoding ("If the long name does not fill...").
+        return TRY(KString::try_create(
+            byte_terminated_string(
+                byte_terminated_string(filename.string_view(), lfn_entry_unused_byte), lfn_entry_character_termination)));
     }
 
     VERIFY_NOT_REACHED();
@@ -184,7 +197,7 @@ Time FATInode::fat_date_time(FATPackedDate date, FATPackedTime time)
 StringView FATInode::byte_terminated_string(StringView string, u8 fill_byte)
 {
     if (auto index = string.find_last_not(fill_byte); index.has_value())
-        return string.substring_view(0, index.value());
+        return string.substring_view(0, index.value() + 1);
     return string;
 }
 

+ 2 - 1
Kernel/FileSystem/FATFS/Inode.h

@@ -36,7 +36,8 @@ private:
     static constexpr u8 end_entry_byte = 0x00;
     static constexpr u8 unused_entry_byte = 0xE5;
 
-    static constexpr u8 lfn_entry_text_termination = 0xFF;
+    static constexpr u8 lfn_entry_character_termination = 0x00;
+    static constexpr u8 lfn_entry_unused_byte = 0xFF;
 
     static constexpr u16 first_fat_year = 1980;