v0.3.3: 代码安全审查与Bug修复

CRITICAL 修复:
- 路径遍历防护绕过:validatePath在normalize()之后检查..,可被绕过读取任意文件
- 编辑器异步创建竞态条件:editor.create()完成后组件已卸载导致内存泄漏
- editor.create() Promise缺少.catch() → 未捕获的Promise拒绝
- handleOpenRecent空文件被跳过:result.content truthy检查阻塞空文件打开

MAJOR 修复:
- DIR_WATCH/TAB_SWITCHED IPC缺少路径校验,可被用于监视任意文件
- AboutDialog内联箭头函数使React.memo完全失效
- ConfirmDialog关闭时焦点恢复逻辑反转
- markdown.ts一刀切屏蔽..导致合法相对路径图片不显示

安全加固:
- 移除未被使用的path.normalize导入
- 所有文件操作IPC使用validatePath统一校验
- 编辑器初始化添加cancelled标志防止卸载后设置实例

验证: TypeScript零错误, ESLint零错误零警告, 78/78测试通过
This commit is contained in:
thzxx
2026-06-04 13:02:19 +08:00
parent 8bcd8a2b2b
commit efa7f61809
18 changed files with 72 additions and 33 deletions
@@ -11,7 +11,7 @@ interface ConfirmDialogProps {
onCancel: () => void
}
export function ConfirmDialog({
export const ConfirmDialog = React.memo(function ConfirmDialog({
open,
title,
message,
@@ -24,22 +24,18 @@ export function ConfirmDialog({
const confirmRef = useRef<HTMLButtonElement>(null)
const previousFocusRef = useRef<HTMLElement | null>(null)
// 保存焦点并在打开时聚焦确认按钮
// 打开时保存焦点并聚焦确认按钮;关闭时恢复焦点
useEffect(() => {
if (!open) return
if (!open) {
previousFocusRef.current?.focus()
return
}
previousFocusRef.current = document.activeElement as HTMLElement
const timer = setTimeout(() => confirmRef.current?.focus(), 50)
return () => clearTimeout(timer)
}, [open])
// 关闭时恢复焦点
useEffect(() => {
if (open) return
return () => {
previousFocusRef.current?.focus()
clearTimeout(timer)
}
}, [open])
@@ -107,6 +103,6 @@ export function ConfirmDialog({
</div>
</div>
)
}
})
ConfirmDialog.displayName = 'ConfirmDialog'