fix: 修复第二轮代码审计发现的全部 15 个问题
严重 Bug(6 个): - C-01: settingsRepository.save() 改为先 load 再 merge 再 put,避免数据丢失 - C-02: 原子写入临时文件写到目标同目录(避免跨盘 rename EXDEV 失败) - C-03: registerIpcHandlers 移到 initWindow 外部,macOS activate 不重复注册 - C-04: rehypeFixImages 拒绝包含 .. 的路径(路径遍历防护) - C-05: initWindow 开头重置 isClosing/closeTimeout - C-06: 右键菜单添加边界修正(Math.min 防溢出屏幕) 中等问题(5 个): - M-01: Sidebar 路径比较归一化(norm = p.replace(/\\/g, '/')) - M-02: 自动展开 while 循环添加 prev 防护无限循环 - M-03: 单标签时隐藏关闭其他标签菜单项 - M-04: Banner .banner-btn:hover 添加暗色主题覆盖 - M-05: closeTab 优先从 MRU 栈取最近使用的标签 低级问题(4 个): - L-01: 删除死代码 useSearch hook(useFileWatch.ts) - L-02: file-watcher error 事件显式调用 watcher.close() - L-03: scrollSync 插值算法保持原样(O(N²) 仅影响超大文件) - L-04: modified 标签关闭按钮始终可见 TypeScript 检查零错误,构建成功。
This commit is contained in:
@@ -19,18 +19,25 @@ export function Sidebar() {
|
||||
const isVisible = useSidebarStore(s => s.isVisible)
|
||||
const expandDirs = useSidebarStore(s => s.expandDirs)
|
||||
|
||||
// 计算当前活动标签的文件路径(用于文件树高亮)
|
||||
// M-01: 归一化路径分隔符(Windows 混合 \\ 和 /)
|
||||
const norm = (p: string) => p.replace(/\\/g, '/')
|
||||
const activeFilePath = tabs.find(t => t.id === activeTabId)?.filePath ?? null
|
||||
|
||||
// 自动展开到活动文件所在的目录
|
||||
useEffect(() => {
|
||||
if (!activeFilePath || !rootPath) return
|
||||
if (!activeFilePath.startsWith(rootPath)) return
|
||||
// M-01: 归一化后比较
|
||||
const normActive = norm(activeFilePath)
|
||||
const normRoot = norm(rootPath)
|
||||
if (!normActive.startsWith(normRoot)) return
|
||||
|
||||
// 提取文件的所有父目录路径
|
||||
const dirsToExpand: string[] = []
|
||||
let dir = activeFilePath.replace(/[/\\][^/\\]+$/, '') // 移除文件名
|
||||
while (dir && dir.length >= rootPath.length && dir !== rootPath) {
|
||||
// M-02: 添加 prev 防护无限循环
|
||||
let prev = ''
|
||||
while (dir && dir.length >= rootPath.length && dir !== rootPath && dir !== prev) {
|
||||
prev = dir
|
||||
dirsToExpand.push(dir)
|
||||
dir = dir.replace(/[/\\][^/\\]+$/, '')
|
||||
}
|
||||
@@ -107,10 +114,11 @@ export function Sidebar() {
|
||||
}
|
||||
}
|
||||
}, [tabs, switchToTab, createTab])
|
||||
// M-01: 独立文件区(归一化路径比较)
|
||||
const independentFiles = tabs.filter(t => {
|
||||
if (!t.filePath) return false
|
||||
if (!rootPath) return true
|
||||
return !t.filePath.startsWith(rootPath)
|
||||
return !norm(t.filePath).startsWith(norm(rootPath))
|
||||
})
|
||||
|
||||
if (!isVisible) return null
|
||||
|
||||
Reference in New Issue
Block a user