Skip to content

fix: 子文件夹多级路径被静默截断为最后一级 - #18

Merged
freestylefly merged 1 commit into
freestylefly:mainfrom
zhangweijian97:fix/subfolder-paths
Sep 30, 2026
Merged

freestylefly merged 1 commit into
freestylefly:mainfrom
zhangweijian97:fix/subfolder-paths

Conversation

@zhangweijian97

Copy link
Copy Markdown
Contributor

Fixes #16

动机

设置 → 沉淀到 Obsidian 的「子文件夹」填多级路径(如 参考/微信流)时,KnowledgeDelivery.deliver 把整个值交给 DisplayName.sanitize,而 sanitize 的第一步取 lastPathComponent——路径被静默截断为最后一级(微信流),前面的层级被丢弃且无任何提示,归档落在非预期位置。

改动

  • DisplayName 新增 subfolderPath(_:):按 / 拆段 → 每段独立过 sanitize → 过滤空段 → 重新以 / 连接;无可用段时返回空串。sanitize 本体不动——它的语义是单个文件名的消毒(清洗归档名等多处依赖其 lastPathComponent 行为),多级路径需要的是路径级处理,两者不该互相迁就。
  • KnowledgeDelivery 改用 subfolderPath,空结果回退默认「微信流」(与原行为一致);下游 createDirectory(withIntermediateDirectories: true) 天然支持多级创建,无需其他改动。
  • DisplayNameTests 新增 7 条断言:多级保留 / 空段过滤(a//b、/a/b/)/ 段内非法字符清洗(a:b/c → a-b/c)/ 空串与 nil / 单级不回归。

安全性说明(预答)

  • 路径穿越:.. 段会被 sanitize 的 fallback 前缀中和(实测 "a/../b" → "a/共享文件../b"),无法逃出知识库文件夹。
  • 超深路径:唯一输入源是用户自己的设置框;异常深的路径在 createDirectory 处干净失败(ENAMETOOLONG),无残留目录。

验证

  • swift test:151 tests, 0 failures(基线 150 + 新增 1;变异检查确认——若实现退回 sanitize,7 条断言中至少 3 条必红)
  • 真机端到端:子文件夹设为 参考/微信流 后转发聊天记录,笔记与附件确认落盘在 <知识库>/参考/微信流/
  • 本地化:本 PR 不新增任何本地化键;check-localizations 在当前 main 基线上即 exit=1(65 条存量失败,与技能包相关),与本改动无关——已用 stash 基线对照逐字节确认

界面变化

无(纯逻辑修复)。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

知识库「子文件夹」填多级路径被静默截断为最后一级

2 participants