False Negative: CloseWriter.ql misses leaked wrapped streams when the close is skipped by an early return or hidden in a factory.
- 主要語言
- CodeQL
- 星號
- 10.1k
- 分支
- 2.1k
- 平均合併
- 2 天 15 小時
- 30 天內合併 PR
- 141
描述
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.
貢獻指南
研究方向
先閱讀 Likely Bugs/Resource Leaks/CloseWriter.ql,並檢查 PosCase2_Var3.java 和 PosCase2_Var5.java 中受影響的案例。追蹤查詢如何處理提前返回和由 helper 建立的串流,然後執行相關的 CloseWriter 測試。完成的標準是兩個案例都被回報為洩漏,且不破壞現有涵蓋率。
由索引模型根據 Issue 內容生成。
評估
- 技術堆疊
- java
- 領域
- security
- Issue 類型
- 缺陷
- 難度
- 4/5
- 預估耗時
- 3-5 天
- 活躍度
- 冷清
- 描述清晰度
- 描述清楚
- 新手友好度
- 52/100