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

Nonterminating processing #1546

Closed
akimd opened this issue Jan 14, 2021 · 12 comments
Closed

Nonterminating processing #1546

akimd opened this issue Jan 14, 2021 · 12 comments

Comments

@akimd
Copy link

akimd commented Jan 14, 2021

Background

Brakeman version: 4.10.1
Rails version: 6
Ruby version: 3

Issue

Hi,

Brakeman appears to be nonterminating and consuming lots of cpu and space on a project. I managed to restrict this to a single model file, which is huge (135klines, it's generated code). I would like to restrict even further to see where, in its chain of treatments, brakeman seems to be stuck. Is there some feature like a more verbose of --debug for such cases? Do you have advice on how to restrict even further the scope of the problem?

Thanks in advance!

@presidentbeef
Copy link
Owner

135k lines! 😱

I assume this is happening during Processing models...?

There isn't a more verbose debug mode, unfortunately. Usually what I would do is start bisecting the file to see if I can narrow it down to a particular part of the code. But with that many lines, it may just be the size of the file!

You might try --no-branching and see if that helps. If so, it may be possible to fix if you can narrow down the code.

Otherwise, you may have to skip the file with --skip-files.

@akimd
Copy link
Author

akimd commented Jan 14, 2021

135k lines! 😱

Yeah, I know :)

Actually interrupting seems to point to always the same point, with this deep clone that seems to be non terminating. Does that ring a bell? It seems to be always about alias_processor.rb.

/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:98:in `<<'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:98:in `<<'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/alias_processor.rb:86:in `replace'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/alias_processor.rb:75:in `process_default'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:78:in `block in process'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:113:in `in_context'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:72:in `process'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/alias_processor.rb:62:in `block in process_default'
(eval):3:in `map!'
(eval):3:in `map!'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/alias_processor.rb:60:in `process_default'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/alias_processor.rb:177:in `process_call'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:76:in `block in process'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:113:in `in_context'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:72:in `process'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/alias_processor.rb:458:in `process_lasgn'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:76:in `block in process'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:113:in `in_context'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:72:in `process'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/lib/processor_helper.rb:13:in `block in process_all!'
(eval):3:in `map!'
(eval):3:in `map!'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/lib/processor_helper.rb:11:in `process_all!'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/alias_processor.rb:419:in `block in process_defn'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/alias_processor.rb:429:in `block in meth_env'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/bundle/ruby/2.7.0/gems/sexp_processor-4.15.1/lib/sexp_processor.rb:452:in `scope'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/alias_processor.rb:426:in `meth_env'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/alias_processor.rb:418:in `process_defn'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:76:in `block in process'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:113:in `in_context'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:72:in `process'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/lib/processor_helper.rb:5:in `block in process_all'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/bundle/ruby/2.7.0/gems/sexp_processor-4.15.1/lib/sexp.rb:142:in `block in each_sexp'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/bundle/ruby/2.7.0/gems/sexp_processor-4.15.1/lib/sexp.rb:139:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/bundle/ruby/2.7.0/gems/sexp_processor-4.15.1/lib/sexp.rb:139:in `each_sexp'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/lib/processor_helper.rb:4:in `process_all'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/lib/processor_helper.rb:36:in `process_class'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:76:in `block in process'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:113:in `in_context'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:72:in `process'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processor.rb:56:in `process_model'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/scanner.rb:305:in `process_model'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/scanner.rb:300:in `block in process_models'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/scanner.rb:314:in `block in track_progress'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/scanner.rb:311:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/scanner.rb:311:in `track_progress'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/scanner.rb:298:in `process_models'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/scanner.rb:57:in `process'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman.rb:373:in `scan'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman.rb:84:in `run'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/commandline.rb:157:in `run_brakeman'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/commandline.rb:125:in `regular_report'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/commandline.rb:166:in `run_report'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/commandline.rb:35:in `run'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/commandline.rb:20:in `start'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/bin/brakeman:10:in `<top (required)>'
/opt/local/bin/brakeman:23:in `load'
/opt/local/bin/brakeman:23:in `<main>'

When I add logs in replace, it seems to go slower and slower. Each new line of log seems to take longer than the previous one to come. It appears to build something bigger and bigger. A few minutes after having started, the ast it prints is large enough to overflow the number of lines my terminal displays :(

@presidentbeef
Copy link
Owner

Yes, that's right. That's the heart of Brakeman's data flow analysis and is generally the cause of most performance issues.

It may be building a string, or an array, or a set of branches (e.g. lots of assignments in nested ifs) or something of that nature.

Did --no-branching help?

@akimd
Copy link
Author

akimd commented Jan 15, 2021

No, --no-branching didn't help. Or maybe it did, but not enough for it to finish.

I also usually bisect in the file until I can pinpoint the issue, but this file is really massive :-( What I'd like to understand is "where" in the processed file Brakeman gets into this tarpit.

On a related note, it might be useful to also support a timeout mechanism for analyses. --skip is useful when you know which files to exclude.

@presidentbeef
Copy link
Owner

Based on the stack trace, looks like it's processing the value (right-hand side) of a local variable assignment, inside a method.

You could add logging to process_defn and process_lasgn in lib/brakeman/processors/alias_processor.rb to narrow down where to look in your code:

  def process_defn exp
    Brakeman.debug "Processing method `#{exp.method_name}` line #{exp.line}"
  def process_lasgn exp
    Brakeman.debug "Processing assignment to `#{exp.lhs}` line #{exp.line}"

@akimd
Copy link
Author

akimd commented Jan 15, 2021

Justin,
That was very helpful! The timestamps show how much brakeman is suffering in there. I'll see if I can spot a pattern in that method that would explain its torments.

Processing method `pl_grids_to_xlsx` line 10534
[2021-01-15 14:26:39 +0100] Processing assignment to `year` line 10535
[2021-01-15 14:26:39 +0100] Processing assignment to `package` line 10536
[2021-01-15 14:26:39 +0100] Processing assignment to `fixed_lines` line 10538
[2021-01-15 14:26:39 +0100] Processing assignment to `res_hash` line 10539
[2021-01-15 14:26:39 +0100] Processing assignment to `res_hash` line 10540
[2021-01-15 14:26:39 +0100] Processing assignment to `new_line` line 10544
[2021-01-15 14:26:39 +0100] Processing assignment to `tmp` line 10545
[2021-01-15 14:26:39 +0100] Processing assignment to `opts` line 10550
[2021-01-15 14:26:39 +0100] Processing assignment to `package` line 10557
[2021-01-15 14:26:39 +0100] Processing assignment to `fixed_lines` line 10558
[2021-01-15 14:26:39 +0100] Processing assignment to `res_hash` line 10559
[2021-01-15 14:26:39 +0100] Processing assignment to `res_hash` line 10560
[2021-01-15 14:26:39 +0100] Processing assignment to `opts` line 10565
[2021-01-15 14:26:39 +0100] Processing assignment to `package` line 10572
[2021-01-15 14:26:39 +0100] Processing assignment to `fixed_lines` line 10573
[2021-01-15 14:26:39 +0100] Processing assignment to `res_hash` line 10574
[2021-01-15 14:26:39 +0100] Processing assignment to `res_hash` line 10575
[2021-01-15 14:26:39 +0100] Processing assignment to `new_line` line 10579
[2021-01-15 14:26:39 +0100] Processing assignment to `tmp` line 10580
[2021-01-15 14:26:39 +0100] Processing assignment to `opts` line 10586
[2021-01-15 14:26:39 +0100] Processing assignment to `package` line 10593
[2021-01-15 14:26:39 +0100] Processing assignment to `fixed_lines` line 10594
[2021-01-15 14:26:39 +0100] Processing assignment to `res_hash` line 10595
[2021-01-15 14:26:39 +0100] Processing assignment to `res_hash` line 10596
[2021-01-15 14:26:39 +0100] Processing assignment to `new_line` line 10600
[2021-01-15 14:26:39 +0100] Processing assignment to `tmp` line 10601
[2021-01-15 14:26:39 +0100] Processing assignment to `tmp` line 10605
[2021-01-15 14:26:39 +0100] Processing assignment to `opts` line 10610
[2021-01-15 14:26:40 +0100] Processing assignment to `package` line 10617
[2021-01-15 14:26:40 +0100] Processing assignment to `fixed_lines` line 10618
[2021-01-15 14:26:40 +0100] Processing assignment to `fixed_lines` line 10619
[2021-01-15 14:26:40 +0100] Processing assignment to `res_hash` line 10620
[2021-01-15 14:26:41 +0100] Processing assignment to `res_hash` line 10621
[2021-01-15 14:26:41 +0100] Processing assignment to `opts` line 10627
[2021-01-15 14:26:46 +0100] Processing assignment to `package` line 10634
[2021-01-15 14:26:47 +0100] Processing assignment to `fixed_lines` line 10635
[2021-01-15 14:26:47 +0100] Processing assignment to `fixed_lines` line 10636
[2021-01-15 14:26:47 +0100] Processing assignment to `res_hash` line 10637
[2021-01-15 14:26:48 +0100] Processing assignment to `res_hash` line 10638
[2021-01-15 14:26:48 +0100] Processing assignment to `opts` line 10644
[2021-01-15 14:27:11 +0100] Processing assignment to `package` line 10651
[2021-01-15 14:27:16 +0100] Processing assignment to `fixed_lines` line 10652
[2021-01-15 14:27:16 +0100] Processing assignment to `fixed_lines` line 10653
[2021-01-15 14:27:16 +0100] Processing assignment to `res_hash` line 10654
[2021-01-15 14:27:22 +0100] Processing assignment to `res_hash` line 10655
[2021-01-15 14:27:26 +0100] Processing assignment to `opts` line 10661
[2021-01-15 14:30:12 +0100] Processing assignment to `package` line 10668
[2021-01-15 14:30:47 +0100] Processing assignment to `fixed_lines` line 10669
[2021-01-15 14:30:47 +0100] Processing assignment to `fixed_lines` line 10670
[2021-01-15 14:30:47 +0100] Processing assignment to `res_hash` line 10671
[2021-01-15 14:31:50 +0100] Processing assignment to `res_hash` line 10672
^C
Interrupted - exiting.
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/bundle/ruby/2.7.0/gems/sexp_processor-4.15.1/lib/sexp.rb:31:in `initialize'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/bundle/ruby/2.7.0/gems/sexp_processor-4.15.1/lib/sexp.rb:31:in `initialize'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:28:in `new'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:28:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:32:in `block in deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `each'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp.rb:30:in `deep_clone'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/alias_processor.rb:85:in `replace'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/alias_processor.rb:75:in `process_default'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:77:in `block in process'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:112:in `in_context'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/ruby_parser/bm_sexp_processor.rb:71:in `process'
/opt/local/lib/ruby3.0/gems/3.0.0/gems/brakeman-4.10.1/lib/brakeman/processors/alias_processor.rb:62:in `block in process_default'
(eval):3:in `map!'
[...]

@akimd
Copy link
Author

akimd commented Jan 15, 2021

Justin,
I don't understand why Brakeman chokes on this single routine. The file size is not an issue, it's only this very routine that drives it nuts. And looking at the code, I don't understand why. In particular, since each time it processes res_hash or opts it gets slower and slower, as if it were maintaining state from one chunk to the next. Although the routine actually running sequentially computations that appear to be not depending on each other. So maybe there is something interesting for you in there, like undesired state persistence over assignments.

The file below suffices to reproduce my problem.

Disclaimer: this code is not written by us, and actually is not "written" at all: it's generated. Also, there are several things in it that don't make sense to me. And I had to mascarade it a bit.

Cheers!

class Foo < ApplicationRecord
  def pl_grids_to_xlsx(year,version,opts={})
    year ||= Date.today.year
    package = Axlsx::Package.new
    opts[:xlsx_export] = true

    fixed_lines = nil
    res_hash = self.foo_grid(year,version,nil,fixed_lines,opts)
    res_hash = res_hash.map do |line|
      line[:data]["id"] = line[:id]
      line[:data] = line[:data].reject{|k,v| k.to_s.starts_with?("PrevYear") ||  k.to_s.starts_with?("NextYear") }
      line[:data] = line[:data].reject{ |k,v| [ "hide_property", ].include?(k.to_s)}
      new_line = {}
      tmp = TypeCode.find(line[:data]["type_code"].to_i)
      new_line["type_code"] = tmp.name.to_s.strip
      line[:data] = line[:data].reject{|k,v| k.to_s == "type_code" }
      new_line.merge(line[:data])
    end
    opts = { xlsx_export: true }
    opts[:package] = package
    opts[:header] = res_hash.first.try(:map){|row| row[0].to_s}
    if (opts[:header] != nil && opts[:header].index("id"))
      opts[:hidden_cols] = [opts[:header].index("id")]
    end
    opts[:data] = res_hash.map{|row| row.to_a.map{|t| t[1]}}
    package = Foo.to_xlsx(opts)

    fixed_lines = nil
    res_hash = self.bars_grid(year,version,nil,fixed_lines,opts)
    res_hash = res_hash.map do |line|
      line[:data]["id"] = line[:id]
      line[:data] = line[:data].reject{|k,v| k.to_s.starts_with?("PrevYear") ||  k.to_s.starts_with?("NextYear") }
      line[:data] = line[:data].reject{ |k,v| [].include?(k.to_s)}
    end
    opts = { xlsx_export: true }
    opts[:package] = package
    opts[:header] = res_hash.first.try(:map){|row| row[0].to_s}
    if (opts[:header] != nil && opts[:header].index("id"))
      opts[:hidden_cols] = [opts[:header].index("id")]
    end
    opts[:data] = res_hash.map{|row| row.to_a.map{|t| t[1]}}
    package = BarLine.to_xlsx(opts)

    fixed_lines = nil
    res_hash = self.bazs_lines_grid(year,version,nil,fixed_lines,opts)
    res_hash = res_hash.map do |line|
      line[:data]["id"] = line[:id]
      line[:data] = line[:data].reject{|k,v| k.to_s.starts_with?("PrevYear") ||  k.to_s.starts_with?("NextYear") }
      line[:data] = line[:data].reject{ |k,v| [].include?(k.to_s)}
      new_line = {}
      tmp = Foo.find(line[:data]["foo"].to_i)
      new_line["name"] = tmp.name.to_s.strip
      new_line["matricule"] = tmp.matricule.to_s.strip
      line[:data] = line[:data].reject{|k,v| k.to_s == "foo" }
      new_line.merge(line[:data])
    end
    opts = { xlsx_export: true }
    opts[:package] = package
    opts[:header] = res_hash.first.try(:map){|row| row[0].to_s}
    if (opts[:header] != nil && opts[:header].index("id"))
      opts[:hidden_cols] = [opts[:header].index("id")]
    end
    opts[:data] = res_hash.map{|row| row.to_a.map{|t| t[1]}}
    package = BazsLine.to_xlsx(opts)

    fixed_lines = nil
    res_hash = self.Quxs_lines_grid(year,version,nil,fixed_lines,opts)
    res_hash = res_hash.map do |line|
      line[:data]["id"] = line[:id]
      line[:data] = line[:data].reject{|k,v| k.to_s.starts_with?("PrevYear") ||  k.to_s.starts_with?("NextYear") }.reject{|k,v| k.to_s == "total"}
      line[:data] = line[:data].reject{ |k,v| [ "activity_price",  "bar_days",  "comment",  "rap", ].include?(k.to_s)}
      new_line = {}
      tmp = QuxsLine.find(line[:data]["ssp"].to_i)
      new_line["ssp_code"] = tmp.ssp_code.to_s.strip
      new_line["activity_code"] = tmp.activity_code.to_s.strip
      line[:data] = line[:data].reject{|k,v| k.to_s == "ssp" }
      tmp = TypeCode.find(line[:data]["type_code"].to_i)
      new_line["type_code"] = tmp.name.to_s.strip
      line[:data] = line[:data].reject{|k,v| k.to_s == "type_code" }
      new_line.merge(line[:data])
    end
    opts = { xlsx_export: true }
    opts[:package] = package
    opts[:header] = res_hash.first.try(:map){|row| row[0].to_s}
    if (opts[:header] != nil && opts[:header].index("id"))
      opts[:hidden_cols] = [opts[:header].index("id")]
    end
    opts[:data] = res_hash.map{|row| row.to_a.map{|t| t[1]}}
    package = QuxsLine.to_xlsx(opts)

    fixed_lines = nil
    fixed_lines = self.quuxs_lines_fixed_lines
    res_hash = self.quuxs_lines_grid(year,version,nil,fixed_lines,opts)
    res_hash = res_hash.map do |line|
      line[:data]["id"] = line[:id]
      line[:data]["title"] = fixed_lines.select { |fline| fline[:title].gsub('[CUR]', self.currency_symbol) == line[:data]["title"] }.first.try(:[], :id)
      line[:data] = line[:data].reject{|k,v| k.to_s.starts_with?("PrevYear") ||  k.to_s.starts_with?("NextYear")}
      line[:data] = line[:data].reject{ |k,v| [].include?(k.to_s)}
    end
    opts = { xlsx_export: true }
    opts[:package] = package
    opts[:header] = res_hash.first.try(:map){|row| row[0].to_s}
    if (opts[:header] != nil && opts[:header].index("id"))
      opts[:hidden_cols] = [opts[:header].index("id")]
    end
    opts[:data] = res_hash.map{|row| row.to_a.map{|t| t[1]}}
    package = QuuxsLine.to_xlsx(opts)

    fixed_lines = nil
    fixed_lines = self.quuuxs_lines_fixed_lines
    res_hash = self.quuuxs_lines_grid(year,version,nil,fixed_lines,opts)
    res_hash = res_hash.map do |line|
      line[:data]["id"] = line[:id]
      line[:data]["title"] = fixed_lines.select { |fline| fline[:title].gsub('[CUR]', self.currency_symbol) == line[:data]["title"] }.first.try(:[], :id)
      line[:data] = line[:data].reject{|k,v| k.to_s.starts_with?("PrevYear") ||  k.to_s.starts_with?("NextYear")}
      line[:data] = line[:data].reject{ |k,v| [].include?(k.to_s)}
    end
    opts = { xlsx_export: true }
    opts[:package] = package
    opts[:header] = res_hash.first.try(:map){|row| row[0].to_s}
    if (opts[:header] != nil && opts[:header].index("id"))
      opts[:hidden_cols] = [opts[:header].index("id")]
    end
    opts[:data] = res_hash.map{|row| row.to_a.map{|t| t[1]}}
    package = QuuuxLine.to_xlsx(opts)

    fixed_lines = nil
    fixed_lines = self.foes_lines_fixed_lines
    res_hash = self.foes_lines_grid(year,version,nil,fixed_lines,opts)
    res_hash = res_hash.map do |line|
      line[:data]["id"] = line[:id]
      line[:data]["title"] = fixed_lines.select { |fline| fline[:title].gsub('[CUR]', self.currency_symbol) == line[:data]["title"] }.first.try(:[], :id)
      line[:data] = line[:data].reject{|k,v| k.to_s.starts_with?("PrevYear") ||  k.to_s.starts_with?("NextYear")}
      line[:data] = line[:data].reject{ |k,v| [].include?(k.to_s)}
    end
    opts = { xlsx_export: true }
    opts[:package] = package
    opts[:header] = res_hash.first.try(:map){|row| row[0].to_s}
    if (opts[:header] != nil && opts[:header].index("id"))
      opts[:hidden_cols] = [opts[:header].index("id")]
    end
    opts[:data] = res_hash.map{|row| row.to_a.map{|t| t[1]}}
    package = FoesLine.to_xlsx(opts)

    fixed_lines = nil
    fixed_lines = self.honks_lines_fixed_lines
    res_hash = self.honks_lines_grid(year,version,nil,fixed_lines,opts)
    res_hash = res_hash.map do |line|
      line[:data]["id"] = line[:id]
      line[:data]["title"] = fixed_lines.select { |fline| fline[:title].gsub('[CUR]', self.currency_symbol) == line[:data]["title"] }.first.try(:[], :id)
      line[:data] = line[:data].reject{|k,v| k.to_s.starts_with?("PrevYear") ||  k.to_s.starts_with?("NextYear")}
      line[:data] = line[:data].reject{ |k,v| [].include?(k.to_s)}
    end
    opts = { xlsx_export: true }
    opts[:package] = package
    opts[:header] = res_hash.first.try(:map){|row| row[0].to_s}
    if (opts[:header] != nil && opts[:header].index("id"))
      opts[:hidden_cols] = [opts[:header].index("id")]
    end
    opts[:data] = res_hash.map{|row| row.to_a.map{|t| t[1]}}
    package = HonksLine.to_xlsx(opts)
  end

end

@presidentbeef
Copy link
Owner

Hi @akimd, thank you for providing this code sample! I can reproduce the slow behavior.

I agree nothing really jumps out at me, so I'll need to take a closer look.

@presidentbeef
Copy link
Owner

presidentbeef commented Feb 9, 2021

Just as a check in here: I know what's happening. It's hard to see, but after staring at the code for a while I realized there is a thread through the code where opts and res_hash are getting intertwined and passed along even though it looks like there are fresh res_hash and opts values being assigned.

I don't know yet how to fix the issue in Brakeman, but did want to let you know I have not given up yet.

@akimd
Copy link
Author

akimd commented Feb 9, 2021

Justin,
You are right, I can see that now too. This piece of code is very hairy and its structure is somewhat unclear...
Thanks for keeping on eye onto it.

If there's no way to get this to work properly, maybe a new type of timeout would be useful.

Cheers!

@presidentbeef
Copy link
Owner

Fixed with #1820

@akimd
Copy link
Author

akimd commented Jan 26, 2024

Great news, thanks a lot!

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

No branches or pull requests

2 participants