Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

SQLCipherStatement.close() never closes its Cursor, leaking a CursorWindow per Room query

Offen Anfängerfreundlich
#97 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

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
Tech-Stack
android, java, sqlite

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

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus sqlcipher/sqlcipher-android

Alle Issues in sqlcipher/sqlcipher-android

Ähnliche Issues

Weitere Issues zu Java

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.