修复阅读器资源、朗读与持久化稳定性
阅读器在多会话朗读、加密 EPUB 资源、并发打开同一本书和多 UserDefaults 容器等场景下,存在旧异步结果覆盖新状态、锁屏控制串会话、大型明文资源被误拒绝、解压半成品被复用及标注跨容器混用的风险;同时高亮、书签、搜索和设置面板的空状态与自动化可访问性入口不完整。\n\n本次为朗读会话引入代次和当前 utterance 校验,远程控制改为仅响应当前会话并按自身 token 清理;加密资源 provider 先判定是否实际返回解密数据,明文大资源继续流式读取;解压缓存串行化以避免并发复用未完成目录。书签与高亮迁移至受保护文件,按 UserDefaults 容器隔离命名空间,保留标准容器旧文件兼容并确保新副本成功落盘后才删除历史数据。\n\n同步调整缓存淘汰、FoundationModels 弱链接、搜索/标注/设置面板交互与 UI 测试,并更新 Pod 生成配置及 API、风险文档。已执行 git diff --check 和 ReadViewDemo Debug Simulator 构建,结果为 BUILD SUCCEEDED。
This commit is contained in:
@@ -251,13 +251,17 @@ public protocol RDEPUBReaderPersistence: AnyObject {
|
||||
}
|
||||
```
|
||||
|
||||
默认实现 `RDEPUBUserDefaultsPersistence` 使用 UserDefaults 存储:
|
||||
默认实现 `RDEPUBUserDefaultsPersistence` 将阅读位置和全局设置存入 UserDefaults;
|
||||
书签与高亮(可能含书籍正文摘录)存入带文件保护且排除备份的 Application Support 文件。
|
||||
升级后的首次读取会自动迁移历史 UserDefaults 数据,并仅在新副本成功落盘后删除旧副本。
|
||||
不同的 `UserDefaults` 容器会自动使用独立的文件命名空间,避免多账号或测试 suite
|
||||
之间混用同一本书的标注;标准容器保留对旧版未分区文件的只读兼容。
|
||||
|
||||
| 数据 | Key 格式 |
|
||||
|------|----------|
|
||||
| 阅读位置 | `ssreader.epub.location.{bookID}` |
|
||||
| 书签 | `ssreader.epub.bookmarks.{bookID}` |
|
||||
| 高亮 | `ssreader.epub.highlights.{bookID}` |
|
||||
| 书签 | 受保护文件(历史键:`ssreader.epub.bookmarks.{bookID}`) |
|
||||
| 高亮 | 受保护文件(历史键:`ssreader.epub.highlights.{bookID}`) |
|
||||
| 全局设置 | `ssreader.epub.settings` |
|
||||
|
||||
---
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
# 代码库风险与关注点
|
||||
|
||||
**分析日期:** 2026-05-21
|
||||
**状态复核:** 2026-07-30(逐条对照源码,结论见下表;正文段落保留原始分析,勿当作现状)
|
||||
|
||||
| # | 项目 | 现状 |
|
||||
|---|------|------|
|
||||
| 1 | User Script Sandboxing 被关 | **部分处理**:已移除 Podfile 的全局强制覆盖;但显式打成 `YES` 会让 CocoaPods 的 `[CP] Embed Pods Frameworks` rsync 阶段被沙箱拒绝而构建失败(已实测)。要真正开启需先改掉 `use_frameworks!` 动态框架集成方式。 |
|
||||
| 2 | 外链未做 allowlist | **已修**:`RDEPUBReaderController+ExternalLinks.swift` 有 scheme allowlist + 二次确认弹窗 + delegate 否决。 |
|
||||
| 3 | Zip Slip 未加固 | **已修**:`RDEPUBParser+Archive.swift` 的 `validatedExtractionDestination` 做 standardized 前缀校验并拒绝 `..`/绝对路径。 |
|
||||
| 4 | 高亮/选中文本明文写 UserDefaults | **已修**:新增 `RDEPUBProtectedContentStore`,高亮与书签改写 Application Support 下带 file protection 的文件、排除备份,首次读取自动迁移并删除明文;另加 `clearReadingData(for:)` / `clearAllReadingContent()`。 |
|
||||
| 5 | Scheme handler 整文件读内存 | **原判断有误**:>512KB 早已走 `respondWithStreaming` 64KB 分块。本次补上 `maximumInMemoryResourceBytes`(默认 64MB)给走不了流式的加密 provider 分支兜底。 |
|
||||
| 6 | 分页 WKWebView 可能加载外部资源 | 未复核。 |
|
||||
| 7 | 解压缓存无限累积 | **已修**:`pruneExtractionCache(keeping:)` 先按 `extractionCacheMaximumAge`(30 天)再按 `extractionCacheMaximumTotalBytes`(512MB)做 LRU 淘汰;复用时 touch mtime;另有 `clearExtractionCache()`。 |
|
||||
| 8+ | 其余性能/可维护性项 | 未复核。 |
|
||||
|
||||
## 高风险:安全与隐私
|
||||
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
|
||||
| 文档 | 说明 |
|
||||
|------|------|
|
||||
| [CONCERNS.md](CONCERNS.md) | 代码库风险与关注点:12 项安全/性能/可维护性风险 |
|
||||
| [CONCERNS.md](CONCERNS.md) | 代码库风险与关注点:12 项安全/性能/可维护性风险(顶部有 2026-07-30 状态复核表) |
|
||||
| [TESTING.md](TESTING.md) | 测试基础设施:UI 测试文件清单、运行方式、覆盖率 |
|
||||
| [CONVENTIONS.md](CONVENTIONS.md) | 编码规范:命名约定、代码风格、导入规范、错误处理 |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user