github / github/codeql

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

Abierto
#21,531 1 comentario 0 reacciones 0 asignados Ver en GitHub
question
Lenguaje dominante
CodeQL
Estrellas
10.1k
Forks
2.1k
Merge medio
2 d 15 h
PR fusionados (30 d)
141

Descripción

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.

Guía de contribución

Abrir la guía de contribución

Línea de trabajo

Comienza por Likely Bugs/Resource Leaks/CloseSql.ql y compara su gestión de la adquisición con los ejemplos afectados PosCase1.java, PosCase6_Var3.java y PosCase6_Var4.java. Verifica que el checker informe de la Connection filtrada y de ambas instancias de ResultSet obtenidas indirectamente, preservando la cobertura existente.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
java
Área
devtools, security
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Tranquilo
Claridad
Bastante claro
Aptitud para principiantes
50/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.