SQLCipherStatement.close() never closes its Cursor, leaking a CursorWindow per Room query
还没有人认领这个 Issue。
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 72/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 领域
- databases, mobile-dev
调研方向
该缺陷位于 SQLCipherStatement:close() 会设置 closed = true,却没有关闭 cursor 字段(由 step() 创建),而 reset() 已经会关闭它并将字段置为 null。先并排阅读 reset() 和 close() 方法,确认 close() 路径上游标从未被释放。完成标准是:close() 在游标打开时先关闭并置空它,然后再设置 closed;并且通过测试或堆检查证明,在不手动 GC 的情况下执行大量单点读取后,原生内存已被释放。
由索引模型根据 Issue 内容生成。
描述
SQLCipherStatement.close() sets closed = true and never closes the Cursor that step() created. Only reset() closes it:
public void reset() {
if (cursor != null) {
cursor.close();
cursor = null;
}
stepped = false;
}
public void close() {
closed = true;
}
Room 3 (androidx.room3 3.0.3) prepares, steps and closes a statement per query, and it never calls reset() before close(). So every query leaves a CursorWindow for the finalizer to free.
Versions: sqlcipher-android 4.18.0 through 4.19.1 and the current default branch, with Room 3.0.3 and SQLCipherDriver.
Measured: we ran 20,000 point reads of one 20 KB row through Room with SQLCipherDriver, on Android emulators, with no manual GC.
| API 36 | API 29 | |
|---|---|---|
SQLCipherDriver as shipped |
+72 MB native heap | +244 MB native heap |
close() calling reset() first |
under 4 MB (0 KB after GC) | under 4 MB |
The framework's AndroidSQLiteDriver showed 24 KB over the same reads.
Workaround: we wrap the driver so that each statement's close() calls reset() first:
private class CursorClosingStatement(private val delegate: SQLiteStatement) : SQLiteStatement by delegate {
override fun close() {
delegate.reset()
delegate.close()
}
}
Suggested fix: in close(), close the cursor if it is open, as reset() does, before setting closed = true.
- 主要语言
- Java
- 星标
- 277
- 派生
- 39
- 平均合并
- 1 天 11 小时
- 30 天内合并 PR
- 1
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
sqlcipher/sqlcipher-android 的其他 Issue
-
难度 4/5 3-5 天 新手友好度 32/100
-
难度 4/5 3-5 天 新手友好度 32/100
sqlcipher/sqlcipher-android#95 · 4 条评论 ·
-
难度 4/5 3-5 天 新手友好度 45/100
-
难度 4/5 3-5 天 新手友好度 30/100
sqlcipher/sqlcipher-android#23 · 2 条评论 ·
查看 sqlcipher/sqlcipher-android 的全部 Issue
相似的 Issue
-
[BUG] 订单:会员凭订单号即可取消其他会员的待付款订单(取消接口不校验订单归属)可能已有人在做 @dadiyang 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 70/100
macrozheng/mall#1016 ·
-
[Bug] The producer summary counts an unreported client version as a second version and warns about a version mix可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭
难度 2/5 1-3 小时 新手友好度 74/100
apache/rocketmq-dashboard#6110 ·
维护者通常 4 天内回复
-
Feature:Resolution
难度 2/5 1-3 小时 新手友好度 72/100
intellij-elixir/intellij-elixir#4396 ·
维护者通常 1 天内回复
-
Python 3.15 support可能已有人在做 @amnesiaof 今天认领。 未关闭L: python L: python:uv
难度 2/5 1-3 小时 新手友好度 72/100
dependabot/dependabot-core#16524 · 1 条评论 ·
维护者通常 1 天内回复
-
`Processing lsp` never exits and leaves orphaned processes可能已有人在做 @overcast302 今天认领。 未关闭bug
难度 2/5 1-3 小时 新手友好度 72/100
processing/processing4#1578 · 1 条评论 ·