Skip to content
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

Fix FileNotFoundError caused by SubprocessShellFalse, Improve CombineStartswithEndswith, Add CombineIsinstanceIssubclass #489

Closed
wants to merge 4 commits into from

Conversation

LucasFaudman
Copy link
Contributor

SubprocessShellFalse

  • Problem: Current SubprocessShellFalse codemod will cause a FileNotFoundError when the first arg is a string.
  • Example: Consider subprocess.run('ls -l', shell=True). The codemod would break this code since with shell=False subprocess will try to find a non-existant file name 'ls -l'.
  • Solution: Only run codeMod if the first arg is not a m.SimpleString() | m.ConcatenatedString() | m.FormattedString(). (This does not solve the case where the first arg is a cst.Name() )

CombineStartswithEndswith

  • Problem: Current CombineStartswithEndswith only supports m.SimpleString() and does not support chaining more than 2 startswith or endswith calls.
  • Solution:
    • Allow arg to be of type m.Tuple()| m.SimpleString() | m.ConcatenatedString() | m.FormattedString() | m.Name()
    • Join all the startswith and endswith calls into a single call and remove duplicate args with the same evaluated_value
# Input
s.startswith('a') or s.startswith('b') or s.startswith('c')
s.startswith(f'{a}') or s.startswith(('con' 'cat', someVar)) or s.startswith('simple')
# CodeMod result before changes
s.startswith(('a', 'b')) or s.startswith('c')
s.startswith(f'{a}') or s.startswith(('con' 'cat', someVar)) or s.startswith('simple')    
# After 
s.startswith(('a', 'b', 'c'))
s.startswith((f'{a}', 'con' 'cat', someVar, 'simple'))

CombineIsinstanceIssubclass

  • New CodeMod very similar to CombineStartswithEndswith but for isinstance and issubclass calls.
# Input
isinstance(a, int) or isinstance(a, float) or isinstance(a, str)
issubclass(a, str) or issubclass(a, (bytes, bytearray)) or issubclass(a, memoryview)

# Output
isinstance(a, (int, float, str))
issubclass(a, (str, bytes, bytearray, memoryview))

Lucas Faudman added 3 commits April 19, 2024 11:28
…ng subprocess calls with strings as the first argument
…nstance(x, (bytes, list)) -> isinstance(x, (str, bytes, list)
Copy link

sonarcloud bot commented Apr 19, 2024

Quality Gate Passed Quality Gate passed

Issues
0 New issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
No data about Duplication

See analysis details on SonarCloud

Copy link

codecov bot commented Apr 19, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 94.16%. Comparing base (e33e8ea) to head (4811970).
Report is 177 commits behind head on main.

❗ Current head 4811970 differs from pull request most recent head 6dc6831. Consider uploading reports for the commit 6dc6831 to get more accurate results

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #489      +/-   ##
==========================================
- Coverage   96.60%   94.16%   -2.45%     
==========================================
  Files         101      141      +40     
  Lines        4275     5996    +1721     
==========================================
+ Hits         4130     5646    +1516     
- Misses        145      350     +205     
Files Coverage Δ
src/codemodder/codemods/utils.py 92.12% <100.00%> (+0.37%) ⬆️
src/codemodder/codemods/utils_decorators.py 100.00% <100.00%> (ø)
src/core_codemods/combine_isinstance_issubclass.py 100.00% <100.00%> (ø)
src/core_codemods/combine_startswith_endswith.py 100.00% <100.00%> (ø)
src/core_codemods/subprocess_shell_false.py 100.00% <100.00%> (ø)

... and 6 files with indirect coverage changes

@drdavella
Copy link
Member

Hi @LucasFaudman! Nice to see your contribution here 😄

We will take a look at this PR. At a glance it seems like it potentially solves #382.

Also, in general it's a bit easier if individual fixes are separated into individual PRs. This makes it easier to review and generally speeds things up since comments that only affect one fix don't have to block other fixes.

If there's any chance you can break this into three separate PRs, that would be appreciated. If not, we'll do our best as-is.

@LucasFaudman
Copy link
Contributor Author

Hi @LucasFaudman! Nice to see your contribution here 😄

We will take a look at this PR. At a glance it seems like it potentially solves #382.

Also, in general it's a bit easier if individual fixes are separated into individual PRs. This makes it easier to review and generally speeds things up since comments that only affect one fix don't have to block other fixes.

If there's any chance you can break this into three separate PRs, that would be appreciated. If not, we'll do our best as-is.

Sure, I know you mentioned that before, sorry about that. I have my local git workflows setup to BFG my branch history on merging into public repos to prevent to making security mistakes which is why I've made the large PRs in the past.

This afternoon i'll re-branch this into 3 PRs and leave a comment on #382 clarifying the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants