You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
httprespbodyclose: branch_state_merge gap still unfixed (issue 62115 auto-expired, 10th reverse-phantom) #63918
Summary
Issue #62115 (this bugs prior filing, sg72a2) was auto-expired closed as not_planned, but the underlying bug in pkg/linters/httprespbodyclose/httprespbodyclose.go is 100 percent unchanged. This is the 10th confirmed reverse-phantom closure across this Sergo run history (a closed-not_planned issue whose code was never touched).
Bug
inspectFunc (line 61) keeps exactly one map[types.Object]*respVarState per function, populated by a single flat ast.Inspect over the whole function body (inspectNode, line 76). The map is not scoped to branches: if one arm of an if/else closes the response body manually and the sibling arm defers the close of the SAME variable, both writes land in the SAME respVarState entry. The final check (line 68) is hasManualClose and not hasDeferClose, so the sibling defer sets hasDeferClose=true and silently masks the manual-close arms genuine violation.
Example that is not flagged even though the manual-close branch leaks Body without a defer:
resp, err:=http.Get(url)
iferr!=nil {
returnerr
}
iffastPath {
resp.Body.Close() // never deferred, should be flagged, is not
} else {
deferresp.Body.Close()
}
Evidence
respVars is declared once per FuncDecl/FuncLit at line 61 and shared across the whole ast.Inspect at line 63.
markBodyClose (line 111) and the DeferStmt handler (line 94) both write into the same map entry keyed only by types.Object, with no branch or path awareness.
CI-enforced on both native and wasm (.github/workflows/cgo.yml lines 1487 and 1490 both include -httprespbodyclose), yet testdata has no if/else sibling-branch case.
Same root-cause class (branch_state_merge) already confirmed to affect the shared pkg/linters/internal/resourcetracker.go framework used by manualmutexunlock/fileclosenotdeferred/contextcancelnotdeferred (issue 62304, still open) - httprespbodyclose has its own standalone copy of the same design flaw.
Recommendation
Scope respVarState per control-flow branch, or track hasManualClose/hasDeferClose along an execution path rather than a flat per-object map, so a manual close in one branch cannot be masked by a defer in a sibling branch.
Effort: Medium, requires branch-aware state tracking, likely shareable with whatever fix lands for the resourcetracker framework.
Activity