SQLCipherStatement.close() never closes its Cursor, leaking a CursorWindow per Room query
Dieses Issue hat noch niemand übernommen.
Bewertung
- Schwierigkeit
- 2/5
- Geschätzter Aufwand
- 1-3 Stunden
- Anfängerfreundlichkeit
- 72/100
- Issue-Typ
- Bug
- Klarheit
- Klar beschrieben
- Aktivitätsstatus
- Aktiv
- Bereich
- databases, mobile-dev
Rechercherichtung
Der Fehler liegt in SQLCipherStatement, wo close() closed = true setzt, ohne das Feld cursor zu schließen, das step() erzeugt, während reset() es bereits schließt und das Feld auf null setzt. Beginne damit, die Methoden reset() und close() nebeneinander zu lesen, und bestätige, dass der Cursor auf dem Pfad von close() nie freigegeben wird. Fertig ist, wenn close() den Cursor, sofern er geöffnet ist, schließt und auf null setzt, bevor closed gesetzt wird, und ein Test oder eine Heap-Prüfung zeigt, dass der native Speicher nach vielen Punktlesevorgängen ohne manuelle GC freigegeben wird.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
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.
- Vorherrschende Sprache
- Java
- Sterne
- 277
- Forks
- 39
- Ø Merge
- 1 T. 11 Std.
- Gemergte PRs (30 T.)
- 1
Entwicklungsumgebung
Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus sqlcipher/sqlcipher-android
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 32/100
sqlcipher/sqlcipher-android#96 · 2 Kommentare · 1 Reaktion ·
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 32/100
sqlcipher/sqlcipher-android#95 · 5 Kommentare ·
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 45/100
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 30/100
sqlcipher/sqlcipher-android#23 · 2 Kommentare ·
Alle Issues in sqlcipher/sqlcipher-android
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
Maintainer antworten meist innerhalb von 1 Tag
-
bug new windows
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 62/100
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
GantMan/jail-monkey#380 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 72/100
objectionary/jucs#145 ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
objectionary/lints#1559 ·
Maintainer antworten meist innerhalb von 2 Tagen