github / github/codeql

False Negative: CloseWriter.ql misses leaked wrapped streams when the close is skipped by an early return or hidden in a factory.

Aperta
#21,534 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/CloseWriter.ql`
- Checker description: This checker detects instances where a Writer or OutputStream is created but not guaranteed to be closed on method exit, potentially causing resource leaks.

## Description of the false negative
Both examples still leak the underlying file stream. One exits the method before the wrapper is closed. The other moves stream construction into a helper and then never closes the returned wrapper.

Those are ordinary resource-leak scenarios. Neither refactoring changes the ownership or lifetime of the stream.

## Affected test cases
### `PosCase2_Var3.java`
The `return` bypasses the only `close()` call. `bos` and the wrapped `FileOutputStream` both remain unclosed on the live path.

```java
// FileOutputStream passed to BufferedOutputStream where inner resource not guaranteed to be closed should be flagged.
package scensct.var.pos;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class PosCase2_Var3 {
public void writeBuffered() throws IOException {
// Variant 3: Introduce early return that skips close
FileOutputStream fos = new FileOutputStream("data.bin");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write(1);
if (System.currentTimeMillis() > 0) {
return; // exit without closing
}
// Unreachable code, close never called
bos.close();
}
}
```

### `PosCase2_Var5.java`
The factory method only hides allocation. It does not transfer cleanup responsibility anywhere else, and the caller still never closes the returned stream.

```java
// FileOutputStream passed to BufferedOutputStream where inner resource not guaranteed to be closed should be flagged.
package scensct.var.pos;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class PosCase2_Var5 {
public void writeBuffered() throws IOException {
// Variant 5: Wrap in a method that returns the BufferedOutputStream without closing
BufferedOutputStream bos = openBufferedStream("data.bin");
bos.write(1);
// Not closed
}

private BufferedOutputStream openBufferedStream(String file) throws IOException {
FileOutputStream fos = new FileOutputStream(file);
return new BufferedOutputStream(fos);
}
}
```

## Cause analysis
`Likely Bugs/Resource Leaks/CloseWriter.ql` looks too dependent on one direct construction-and-close pattern. As soon as the leak is expressed through an early return or a helper that returns the wrapper, the result disappears.

That is too brittle for a resource-leak query. In real code, stream creation is often factored into small helpers, and missing close calls frequently happen on short-circuit exits.

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Start by reading Likely Bugs/Resource Leaks/CloseWriter.ql and inspect the affected PosCase2_Var3.java and PosCase2_Var5.java cases. Trace how the query handles early returns and helper-created streams, then run the relevant CloseWriter tests. Done means both cases are reported as leaks without breaking existing coverage.

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

Valutazione

Stack tecnologico
java
Ambito
security
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Specificata chiaramente
Idoneità per principianti
52/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.