github / github/codeql

False Negative: CloseSql.ql misses leaked JDBC resources once the allocation site is split across helper calls or `getResultSet()`.

Aperta
#21,531 1 commento 0 reazioni 0 assegnatari Vedi su GitHub
question
Lingua principale
CodeQL
Stelle
10.1k
Fork
2.1k
Merge medio
2g 15h
PR unite (30g)
141

Descrizione

Version
codeql 2.24.3

## Checker
- Checker id: `Likely Bugs/Resource Leaks/CloseSql.ql`
- Checker description: This checker detects SQL resource objects (Connection, Statement, ResultSet) that are initialized locally and not guaranteed to be closed on method exit.

## Description of the false negative
These cases still leak JDBC resources. One is the simplest possible leaked `Connection`. The other two leak `ResultSet` instances that come from a `Statement` parameter and are never closed before the method returns.

What changes between the samples is only how the resource is obtained: directly, through a helper method, or through `Statement.getResultSet()` after `execute(...)`.

## Affected test cases
### `PosCase1.java`
The method opens a `Connection` and exits without closing it. This should be a baseline match for the rule.

### `PosCase6_Var3.java`
The `ResultSet` comes back from a helper, but it still originates from the passed-in `Statement` and still leaks.

### `PosCase6_Var4.java`
The `ResultSet` is retrieved through `stmt.getResultSet()` after `execute(...)`. That is still a live SQL resource that needs to be closed.

## Reproduction code
### `PosCase1.java`
```java
// Scenario 1: A java.sql.Connection is locally initialized, not assigned, not passed to a local constructor, has no parent, and is not closed.
package scensct.core.pos;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class PosCase1 {
public void test() throws SQLException {
// Locally initialized Connection, assigned to a variable but not closed.
Connection conn = DriverManager.getConnection("jdbc:example:db");
// No close() call before method exit.
}
}
```

### `PosCase6_Var3.java`
```java
// Scenario 6: A java.sql.ResultSet is locally initialized as a child of a non-locally-initialized Statement parameter, used directly, and not closed.
package scensct.var.pos;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class PosCase6_Var3 {
public void test(Statement stmt) throws SQLException {
ResultSet rs = fetchResult(stmt);
// rs not closed
}

private ResultSet fetchResult(Statement s) throws SQLException {
return s.executeQuery("SELECT 1");
}
}
```

### `PosCase6_Var4.java`
```java
// Scenario 6: A java.sql.ResultSet is locally initialized as a child of a non-locally-initialized Statement parameter, used directly, and not closed.
package scensct.var.pos;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class PosCase6_Var4 {
public void test(Statement stmt) throws SQLException {
boolean hasResults = stmt.execute("SELECT 1");
if (hasResults) {
ResultSet rs = stmt.getResultSet();
// rs not closed
}
}
}
```

## Cause analysis
`Likely Bugs/Resource Leaks/CloseSql.ql` appears to be tied too closely to one acquisition shape. It handles some direct JDBC constructions, but coverage gets weaker once the returned resource is produced through a helper or through a second-stage API like `getResultSet()`.

That leaves a real blind spot. In production JDBC code, `ResultSet` objects are often obtained indirectly rather than from a single inline `executeQuery(...)` call. The leak is still the same: the method owns a SQL resource and does not close it.

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Start with Likely Bugs/Resource Leaks/CloseSql.ql and compare its acquisition handling with the affected PosCase1.java, PosCase6_Var3.java, and PosCase6_Var4.java examples. Verify the checker reports the leaked Connection and both indirectly obtained ResultSet instances, while preserving existing coverage.

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

Valutazione

Stack tecnologico
java
Ambito
devtools, security
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Abbastanza chiara
Idoneità per principianti
50/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.