Skip to content

Python: Improve performance of FileNotClosed query by using basic block reachability #19641

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

joefarebrother
Copy link
Contributor

@Copilot Copilot AI review requested due to automatic review settings June 2, 2025 14:01
@joefarebrother joefarebrother requested a review from a team as a code owner June 2, 2025 14:01
@joefarebrother joefarebrother added the no-change-note-required This PR does not need a change note label Jun 2, 2025
@github-actions github-actions bot added the Python label Jun 2, 2025
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR improves the performance of the FileNotClosed query by replacing full CFG reachability checks with basic-block–level reachability approximations and adds a test to illustrate the approximation’s limitations.

  • Introduce bbSuccessor, bbReachableStrict, and bbReachableRefl predicates for faster reachability.
  • Update guardsExceptions in FileClose (and its WithStatement override) to use these new predicates.
  • Add a new closed29 test demonstrating a spurious false positive due to the approximation.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
python/ql/test/query-tests/Resources/FileNotAlwaysClosed/resources_test.py Add closed29 test case that tags a spurious false positive with $SPURIOUS.
python/ql/src/Resources/FileNotAlwaysClosedQuery.qll Replace full CFG reachability with block-level reachability and refine exception guards.
Comments suppressed due to low confidence (1)

python/ql/test/query-tests/Resources/FileNotAlwaysClosed/resources_test.py:285

  • [nitpick] In closed29, the variable f28 duplicates the name from closed28. Consider renaming it to f29 (or a more descriptive name) to avoid confusion.
f28 = open(path) # $SPURIOUS:notClosedOnException 

Co-authored-by: Copilot <[email protected]>
private predicate cfgGetASuccessorPlus(ControlFlowNode src, ControlFlowNode sink) =
fastTC(cfgGetASuccessor/2)(src, sink)
private predicate bbReachableStrict(BasicBlock src, BasicBlock sink) =
fastTC(bbSuccessor/2)(src, sink)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should be able to use doubleBoundedFastTC here, for even better performance.

Comment on lines +56 to +57
bbReachableRefl(raises.asCfgNode().getBasicBlock().getAnExceptionalSuccessor(),
this.asCfgNode().getBasicBlock())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In case they belong to the same basic block, there is no logic guaranteeing that raises comes before this in that basic block.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-change-note-required This PR does not need a change note Python
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants