From f43951c1f8b2ce6657b9f8a525bda356596af8ee Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 26 Oct 2026 23:10:03 +0800 Subject: [PATCH] =?UTF-8?q?fix(fat32):=20=E4=BB=A5=20.=20/=20..=20?= =?UTF-8?q?=E7=BB=93=E5=B0=BE=E7=9A=84=E8=B7=AF=E5=BE=84=E4=BC=9A=E8=AF=AF?= =?UTF-8?q?=E5=BC=80=E7=AC=AC=E4=B8=80=E4=B8=AA=E5=AD=90=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dir_open_path 在 follow_path 返回后仍按“父目录中的最后一项”回读目录项。 当路径以 “.” 或 “..” 结尾时,follow_path 已经把 dp 打开成目标目录, 这段回读会把目标目录的第一个子项当成最终项再打开: 根目录 cd .. → full=/.. → follow_path 打开根 → 回读根的第一项 APP → 实际进入 /APP,于是 ls 显示的是 app 里的 helloworld.asm。 现在检测末尾的 “.” / “..”,与根路径一样直接返回已打开的 dp。 --- .../Kernel/drivers/fs/fat32/fat32_types.vp | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp b/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp index 4c3a1ce..356f718 100644 --- a/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp +++ b/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp @@ -1329,11 +1329,31 @@ class volinfo: if path[pi] == '/' or path[pi] == '\\': pi += 1 while path[pi] == '/' or path[pi] == '\\': pi += 1 is_root: int = 1 if path[pi] == 0 else 0 + # 路径末尾是 "." / ".." 时,follow_path 已经把 dp 打开成目标目录本身。 + # 不能再按"父目录中的最后一项"去回读目录项:那会把目标目录的第一个子项 + # 当成最终项打开(例如根目录 cd .. 会误入第一个子目录 APP)。 + last: int = 0 + lp: int = 0 + while path[lp] != 0: + if path[lp] != '/' and path[lp] != '\\': + last = lp + lp += 1 + ends_special: int = 0 + if path[last] == '.': + if last == 0: + ends_special = 1 + elif path[last - 1] == '/' or path[last - 1] == '\\': + ends_special = 1 + elif path[last - 1] == '.': + if last == 1: + ends_special = 1 + elif path[last - 2] == '/' or path[last - 2] == '\\': + ends_special = 1 lfn_buf: [256]uint16 string.memset(&lfn_buf, 0, 256 * 2) res: FRESULT = self.follow_path(&dp, path, uint16*(&lfn_buf[0])) if res != FRESULT.FR_OK: return res - if is_root: return FRESULT.FR_OK + if is_root or ends_special: return FRESULT.FR_OK entry_sector: uint64 = dp.sector + (dp.offset / (512 / ENTRY_SIZE)) entry_offset_in_sector: uint32 = (dp.offset % (512 / ENTRY_SIZE)) * ENTRY_SIZE res_wr: FRESULT = self.win_read(entry_sector)