Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

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

Aperta Adatta ai principianti
#97 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
72/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
android, java, sqlite

Direzione di ricerca

Il bug si trova in SQLCipherStatement, dove close() imposta closed = true senza chiudere il campo cursor creato da step(), mentre reset() lo chiude già e azzera il campo. Inizia leggendo affiancati i metodi reset() e close() e conferma che il cursore non viene mai rilasciato nel percorso di close(). Il lavoro è completo quando close() chiude e azzera il cursore se è aperto, prima di impostare closed, e un test o un controllo dell'heap mostra che la memoria nativa viene rilasciata dopo molte letture puntuali senza GC manuale.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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.

Lingua principale
Java
Stelle
277
Fork
39
Merge medio
1g 11h
PR unite (30g)
1

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di sqlcipher/sqlcipher-android

Tutte le issue di sqlcipher/sqlcipher-android

Issue simili

Altre issue su Java

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.