brakeman 4.2.1 → 4.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +16 -0
  3. data/bundle/load.rb +2 -2
  4. data/bundle/ruby/2.5.0/gems/{sexp_processor-4.10.1 → sexp_processor-4.11.0}/History.rdoc +6 -0
  5. data/bundle/ruby/2.5.0/gems/{sexp_processor-4.10.1 → sexp_processor-4.11.0}/Manifest.txt +0 -0
  6. data/bundle/ruby/2.5.0/gems/{sexp_processor-4.10.1 → sexp_processor-4.11.0}/README.rdoc +0 -0
  7. data/bundle/ruby/2.5.0/gems/{sexp_processor-4.10.1 → sexp_processor-4.11.0}/Rakefile +0 -0
  8. data/bundle/ruby/2.5.0/gems/{sexp_processor-4.10.1 → sexp_processor-4.11.0}/lib/composite_sexp_processor.rb +0 -0
  9. data/bundle/ruby/2.5.0/gems/{sexp_processor-4.10.1 → sexp_processor-4.11.0}/lib/pt_testcase.rb +0 -0
  10. data/bundle/ruby/2.5.0/gems/{sexp_processor-4.10.1 → sexp_processor-4.11.0}/lib/sexp.rb +8 -1
  11. data/bundle/ruby/2.5.0/gems/{sexp_processor-4.10.1 → sexp_processor-4.11.0}/lib/sexp_processor.rb +1 -1
  12. data/bundle/ruby/2.5.0/gems/{sexp_processor-4.10.1 → sexp_processor-4.11.0}/lib/strict_sexp.rb +0 -0
  13. data/bundle/ruby/2.5.0/gems/{sexp_processor-4.10.1 → sexp_processor-4.11.0}/lib/unique.rb +0 -0
  14. data/bundle/ruby/2.5.0/gems/{sexp_processor-4.10.1 → sexp_processor-4.11.0}/test/test_composite_sexp_processor.rb +0 -0
  15. data/bundle/ruby/2.5.0/gems/{sexp_processor-4.10.1 → sexp_processor-4.11.0}/test/test_environment.rb +0 -0
  16. data/bundle/ruby/2.5.0/gems/{sexp_processor-4.10.1 → sexp_processor-4.11.0}/test/test_sexp.rb +17 -4
  17. data/bundle/ruby/2.5.0/gems/{sexp_processor-4.10.1 → sexp_processor-4.11.0}/test/test_sexp_processor.rb +0 -0
  18. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.0 → unicode-display_width-1.3.2}/CHANGELOG.md +8 -0
  19. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.0 → unicode-display_width-1.3.2}/MIT-LICENSE.txt +0 -0
  20. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.0 → unicode-display_width-1.3.2}/README.md +0 -0
  21. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.0 → unicode-display_width-1.3.2}/Rakefile +0 -0
  22. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.0 → unicode-display_width-1.3.2}/data/display_width.marshal.gz +0 -0
  23. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.0 → unicode-display_width-1.3.2}/lib/unicode/display_width.rb +0 -0
  24. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.0 → unicode-display_width-1.3.2}/lib/unicode/display_width/constants.rb +1 -1
  25. data/bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/lib/unicode/display_width/index.rb +8 -0
  26. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.0 → unicode-display_width-1.3.2}/lib/unicode/display_width/no_string_ext.rb +0 -0
  27. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.0 → unicode-display_width-1.3.2}/lib/unicode/display_width/string_ext.rb +0 -0
  28. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.0 → unicode-display_width-1.3.2}/spec/display_width_spec.rb +0 -0
  29. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.0 → unicode-display_width-1.3.2}/unicode-display_width.gemspec +0 -0
  30. data/lib/brakeman.rb +4 -2
  31. data/lib/brakeman/checks/base_check.rb +4 -1
  32. data/lib/brakeman/checks/check_execute.rb +3 -2
  33. data/lib/brakeman/checks/check_link_to_href.rb +3 -2
  34. data/lib/brakeman/checks/check_sanitize_methods.rb +2 -8
  35. data/lib/brakeman/checks/check_sql.rb +1 -1
  36. data/lib/brakeman/codeclimate/engine_configuration.rb +2 -2
  37. data/lib/brakeman/file_parser.rb +5 -1
  38. data/lib/brakeman/options.rb +9 -1
  39. data/lib/brakeman/parsers/template_parser.rb +1 -1
  40. data/lib/brakeman/processors/alias_processor.rb +69 -1
  41. data/lib/brakeman/processors/lib/find_all_calls.rb +18 -5
  42. data/lib/brakeman/report/pager.rb +3 -1
  43. data/lib/brakeman/version.rb +1 -1
  44. metadata +29 -29
  45. data/bundle/ruby/2.5.0/gems/unicode-display_width-1.3.0/lib/unicode/display_width/index.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 53960ae3fa041691f1eef8e4cc0a7797993fc2e0c5e1618391b4fe7a42151d00
4
- data.tar.gz: 5486c4a3cfcde489fc6f1a589688d379355896dcc35df0cb0531dd383aa37c6d
3
+ metadata.gz: b713c88d7aa856518beb948e7d39c0b43dda963378064d5a3126f9684d6d6a2d
4
+ data.tar.gz: 3ed9ad3b22f8196745f64019867776a6c09984d19fdcbe166046aadbbc4b545c
5
5
  SHA512:
6
- metadata.gz: 7e1dedfb6173d00394ac06f3cd28c3a8f75e9a88a98e7814f94b90ae244ac033d57978a80bf5bed5ff6efdc2b56837825c39467f804d2142d435235b7c892a90
7
- data.tar.gz: a830bb875a913e43a1b8d6713a596e4f2d90376a15d68e90424c1fa9f3de53716af93f8b0fb98110b6fd06196b022c737ab82232755ae5a7e977b7da6c8b4e65
6
+ metadata.gz: 90414d86f666acb334d05532d07b1edcf7cb90b8174e4682e06c6fd37c7063709043bf95767246f9529d897e0d39637a0088f2ce32fce1c1db78cd9040e38664
7
+ data.tar.gz: b3cdf474521d19cfc27cfd06d9168b3fc97284ff4ad6f73e2615c15099e93a84d0e90b24c185af5108c49b4fac07dae7acd3717f7f9e4f54f1dbd57f487cca17
data/CHANGES.md CHANGED
@@ -1,3 +1,19 @@
1
+ # 4.3.0
2
+
3
+ * Check exec-type calls even if they are targets
4
+ * Convert `Array#join` to string interpolation
5
+ * `BaseCheck#include_interp?` should return first string interpolation
6
+ * Add `--parser-timeout` option
7
+ * Track parent calls in CallIndex
8
+ * Warn about dangerous `link_to` href with `sanitize()`
9
+ * Ignore `params#to_h` and `params#to_hash` in SQL checks
10
+ * Change "".freeze to just ""
11
+ * Ignore `Process.pid` in system calls
12
+ * Index Kernel#\` calls even if they are targets
13
+ * Code Climate: omit leading dot from `only_files` (Todd Mazierski)
14
+ * `--color` can be used to force color output
15
+ * Fix reported line numbers for CVE-2018-3741 and CVE-2018-8048
16
+
1
17
  # 4.2.1
2
18
 
3
19
  * Add warning for CVE-2018-3741
@@ -4,12 +4,12 @@ $:.unshift "#{path}/bundle/ruby/2.5.0/gems/sass-3.4.25/lib"
4
4
  $:.unshift "#{path}/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/lib"
5
5
  $:.unshift "#{path}/bundle/ruby/2.5.0/gems/tilt-2.0.8/lib"
6
6
  $:.unshift "#{path}/bundle/ruby/2.5.0/gems/temple-0.7.7/lib"
7
- $:.unshift "#{path}/bundle/ruby/2.5.0/gems/unicode-display_width-1.3.0/lib"
8
7
  $:.unshift "#{path}/bundle/ruby/2.5.0/gems/highline-1.7.10/lib"
9
8
  $:.unshift "#{path}/bundle/ruby/2.5.0/gems/terminal-table-1.8.0/lib"
10
9
  $:.unshift "#{path}/bundle/ruby/2.5.0/gems/ruby_parser-3.11.0/lib"
11
- $:.unshift "#{path}/bundle/ruby/2.5.0/gems/sexp_processor-4.10.1/lib"
10
+ $:.unshift "#{path}/bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/lib"
12
11
  $:.unshift "#{path}/bundle/ruby/2.5.0/gems/ruby2ruby-2.4.1/lib"
13
12
  $:.unshift "#{path}/bundle/ruby/2.5.0/gems/slim-3.0.7/lib"
13
+ $:.unshift "#{path}/bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/lib"
14
14
  $:.unshift "#{path}/bundle/ruby/2.5.0/gems/erubis-2.7.0/lib"
15
15
  $:.unshift "#{path}/bundle/ruby/2.5.0/gems/safe_yaml-1.0.4/lib"
@@ -1,3 +1,9 @@
1
+ === 4.11.0 / 2018-04-05
2
+
3
+ * 1 minor enhancement:
4
+
5
+ * Extended deep_each to skip subtrees if block returns :skip.
6
+
1
7
  === 4.10.1 / 2018-02-15
2
8
 
3
9
  * 1 minor enhancement:
@@ -86,12 +86,19 @@ class Sexp < Array # ZenTest FULL
86
86
 
87
87
  ##
88
88
  # Recursively enumerates the sexp yielding to +block+ for every element.
89
+ #
90
+ # Returning :skip will stop traversing that subtree:
91
+ #
92
+ # sexp.deep_each do |s|
93
+ # next :skip if s.sexp_type == :if
94
+ # # ...
95
+ # end
89
96
 
90
97
  def deep_each &block
91
98
  return enum_for(:deep_each) unless block_given?
92
99
 
93
100
  self.each_sexp do |sexp|
94
- block[sexp]
101
+ next if block[sexp] == :skip
95
102
  sexp.deep_each(&block)
96
103
  end
97
104
  end
@@ -34,7 +34,7 @@ require "sexp"
34
34
  class SexpProcessor
35
35
 
36
36
  # duh
37
- VERSION = "4.10.1"
37
+ VERSION = "4.11.0"
38
38
 
39
39
  ##
40
40
  # Automatically shifts off the Sexp type before handing the
@@ -641,15 +641,28 @@ class TestSexp < SexpTestCase # ZenTest FULL
641
641
  assert_equal 5, s(:a, s(:b, s(:c, s(:d, s(:e))))).depth
642
642
  end
643
643
 
644
+ DEEP_EXP = [:lasgn, :str, :if,
645
+ :and, :true, :lit,
646
+ :if, :lvar, :str, :true]
647
+
644
648
  def test_deep_each
645
- result = []
646
- @complex_sexp.deep_each { |s| result << s if s.sexp_type == :if }
647
- assert_equal [:if, :if], result.map { |k, _| k }
649
+ act = []
650
+
651
+ @complex_sexp.deep_each { |s| act << s }
652
+ assert_equal DEEP_EXP, act.map { |k, _| k }
653
+ end
654
+
655
+ def test_deep_each_skip
656
+ exp = DEEP_EXP.first(3) + DEEP_EXP.last(4)
657
+ act = []
658
+
659
+ @complex_sexp.deep_each { |s| next :skip if s.sexp_type == :and; act << s }
660
+ assert_equal exp, act.map { |k, _| k }
648
661
  end
649
662
 
650
663
  def test_deep_each_without_block
651
664
  assert_kind_of Enumerator, @complex_sexp.deep_each
652
- assert_equal [:if, :if], @complex_sexp.deep_each.select { |s, _| s == :if }.map { |k, _| k }
665
+ assert_equal DEEP_EXP, @complex_sexp.deep_each.map(&:first)
653
666
  end
654
667
 
655
668
  def test_unary_not
@@ -1,5 +1,13 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.3.2
4
+
5
+ - Explicitly load rubygems/util, fixes regression in 1.3.1 (autoload issue)
6
+
7
+ ## 1.3.1
8
+
9
+ - Use `Gem::Util` for `gunzip`, removes deprecation warning, patch by @Schwad
10
+
3
11
  ## 1.3.0
4
12
 
5
13
  - Unicode 10
@@ -1,6 +1,6 @@
1
1
  module Unicode
2
2
  module DisplayWidth
3
- VERSION = '1.3.0'
3
+ VERSION = '1.3.2'
4
4
  UNICODE_VERSION = "10.0.0".freeze
5
5
  DATA_DIRECTORY = File.expand_path(File.dirname(__FILE__) + '/../../../data/').freeze
6
6
  INDEX_FILENAME = (DATA_DIRECTORY + '/display_width.marshal.gz').freeze
@@ -0,0 +1,8 @@
1
+ require 'rubygems/util'
2
+ require_relative 'constants'
3
+
4
+ module Unicode
5
+ module DisplayWidth
6
+ INDEX = Marshal.load(Gem::Util.gunzip(File.binread(INDEX_FILENAME)))
7
+ end
8
+ end
@@ -51,6 +51,7 @@ module Brakeman
51
51
  # * :output_files - files for output
52
52
  # * :output_formats - formats for output (:to_s, :to_tabs, :to_csv, :to_html)
53
53
  # * :parallel_checks - run checks in parallel (default: true)
54
+ # * :parser_timeout - set timeout for parsing an individual file (default: 10 seconds)
54
55
  # * :print_report - if no output file specified, print to stdout (default: false)
55
56
  # * :quiet - suppress most messages (default: true)
56
57
  # * :rails3 - force Rails 3 mode (automatic)
@@ -174,6 +175,7 @@ module Brakeman
174
175
  :output_color => true,
175
176
  :pager => true,
176
177
  :parallel_checks => true,
178
+ :parser_timeout => 10,
177
179
  :relative_path => false,
178
180
  :report_progress => true,
179
181
  :safe_methods => Set.new,
@@ -376,7 +378,7 @@ module Brakeman
376
378
 
377
379
  def self.write_report_to_files tracker, output_files
378
380
  require 'fileutils'
379
- tracker.options[:output_color] = false
381
+ tracker.options[:output_color] = false unless tracker.options[:output_color] == :force
380
382
 
381
383
  output_files.each_with_index do |output_file, idx|
382
384
  dir = File.dirname(output_file)
@@ -393,7 +395,7 @@ module Brakeman
393
395
  private_class_method :write_report_to_files
394
396
 
395
397
  def self.write_report_to_formats tracker, output_formats
396
- unless $stdout.tty?
398
+ unless $stdout.tty? or tracker.options[:output_color] == :force
397
399
  tracker.options[:output_color] = false
398
400
  end
399
401
 
@@ -119,7 +119,10 @@ class Brakeman::BaseCheck < Brakeman::SexpProcessor
119
119
 
120
120
  #Does not actually process string interpolation, but notes that it occurred.
121
121
  def process_dstr exp
122
- @string_interp = Match.new(:interp, exp)
122
+ unless @string_interp # don't overwrite existing value
123
+ @string_interp = Match.new(:interp, exp)
124
+ end
125
+
123
126
  process_default exp
124
127
  end
125
128
 
@@ -15,7 +15,8 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
15
15
 
16
16
  SAFE_VALUES = [s(:const, :RAILS_ROOT),
17
17
  s(:call, s(:const, :Rails), :root),
18
- s(:call, s(:const, :Rails), :env)]
18
+ s(:call, s(:const, :Rails), :env),
19
+ s(:call, s(:const, :Process), :pid)]
19
20
 
20
21
  SHELL_ESCAPES = [:escape, :shellescape, :join]
21
22
 
@@ -32,7 +33,7 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
32
33
  calls = tracker.find_call :targets => [:IO, :Open3, :Kernel, :'POSIX::Spawn', :Process, nil],
33
34
  :methods => [:capture2, :capture2e, :capture3, :exec, :pipeline, :pipeline_r,
34
35
  :pipeline_rw, :pipeline_start, :pipeline_w, :popen, :popen2, :popen2e,
35
- :popen3, :spawn, :syscall, :system]
36
+ :popen3, :spawn, :syscall, :system], :nested => true
36
37
 
37
38
  Brakeman.debug "Processing system calls"
38
39
  calls.each do |result|
@@ -71,14 +71,15 @@ class Brakeman::CheckLinkToHref < Brakeman::CheckLinkTo
71
71
  end
72
72
  end
73
73
 
74
+ CHECK_INSIDE_METHODS = [:url_for, :h, :sanitize]
75
+
74
76
  def check_argument? url_arg
75
77
  return unless call? url_arg
76
78
 
77
79
  target = url_arg.target
78
80
  method = url_arg.method
79
81
 
80
- method == :url_for or
81
- method == :h or
82
+ CHECK_INSIDE_METHODS.include? method or
82
83
  cgi_escaped? target, method
83
84
  end
84
85
 
@@ -46,12 +46,6 @@ class Brakeman::CheckSanitizeMethods < Brakeman::BaseCheck
46
46
 
47
47
  message = "Rails #{rails_version} has a vulnerability in #{method}: upgrade to #{@fix_version} or patch"
48
48
 
49
- if include_user_input? result[:call]
50
- confidence = :high
51
- else
52
- confidence = :medium
53
- end
54
-
55
49
  warn :result => result,
56
50
  :warning_type => "Cross-Site Scripting",
57
51
  :warning_code => code,
@@ -87,7 +81,7 @@ class Brakeman::CheckSanitizeMethods < Brakeman::BaseCheck
87
81
  warn :warning_type => "Cross-Site Scripting",
88
82
  :warning_code => :CVE_2018_8048,
89
83
  :message => message,
90
- :gem_info => gemfile_or_environment,
84
+ :gem_info => gemfile_or_environment(:loofah),
91
85
  :confidence => confidence,
92
86
  :link_path => "https://github.com/flavorjones/loofah/issues/144"
93
87
  end
@@ -111,7 +105,7 @@ class Brakeman::CheckSanitizeMethods < Brakeman::BaseCheck
111
105
  warn :warning_type => "Cross-Site Scripting",
112
106
  :warning_code => cve.tr('-', '_').to_sym,
113
107
  :message => message,
114
- :gem_info => gemfile_or_environment,
108
+ :gem_info => gemfile_or_environment(:'rails-html-sanitizer'),
115
109
  :confidence => confidence,
116
110
  :link_path => link
117
111
  end
@@ -290,7 +290,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
290
290
  end
291
291
 
292
292
  if request_value? arg
293
- unless call? arg and params? arg.target and [:permit, :slice].include? arg.method
293
+ unless call? arg and params? arg.target and [:permit, :slice, :to_h, :to_hash].include? arg.method
294
294
  # Model.where(params[:where])
295
295
  arg
296
296
  end
@@ -87,9 +87,9 @@ module Brakeman
87
87
 
88
88
  def stripped_include_path(prefix, subprefixes, path)
89
89
  if path.start_with?(prefix)
90
- path.sub(%r{^#{prefix}/?}, "./")
90
+ path.sub(%r{^#{prefix}/?}, "/")
91
91
  elsif subprefixes.any? { |subprefix| path =~ %r{^#{subprefix}/?$} }
92
- "./"
92
+ "/"
93
93
  end
94
94
  end
95
95
  end
@@ -7,6 +7,7 @@ module Brakeman
7
7
 
8
8
  def initialize tracker, app_tree
9
9
  @tracker = tracker
10
+ @timeout = @tracker.options[:parser_timeout]
10
11
  @app_tree = app_tree
11
12
  @file_list = {}
12
13
  end
@@ -33,10 +34,13 @@ module Brakeman
33
34
  def parse_ruby input, path
34
35
  begin
35
36
  Brakeman.debug "Parsing #{path}"
36
- RubyParser.new.parse input, path
37
+ RubyParser.new.parse input, path, @timeout
37
38
  rescue Racc::ParseError => e
38
39
  @tracker.error e, "Could not parse #{path}"
39
40
  nil
41
+ rescue Timeout::Error => e
42
+ @tracker.error Exception.new("Parsing #{path} took too long (> #{@timeout} seconds). Try increasing the limit with --parser-timeout"), caller
43
+ nil
40
44
  rescue => e
41
45
  @tracker.error e.exception(e.message + "\nWhile processing #{path}"), e.backtrace
42
46
  nil
@@ -127,6 +127,10 @@ module Brakeman::Options
127
127
  options[:branch_limit] = limit
128
128
  end
129
129
 
130
+ opts.on "--parser-timeout SECONDS", Integer, "Set parse timeout (Default: 10)" do |timeout|
131
+ options[:parser_timeout] = timeout
132
+ end
133
+
130
134
  opts.on "-r", "--report-direct", "Only report direct use of untrusted data" do |option|
131
135
  options[:check_arguments] = !option
132
136
  end
@@ -229,7 +233,11 @@ module Brakeman::Options
229
233
  end
230
234
 
231
235
  opts.on "--[no-]color", "Use ANSI colors in report (Default)" do |color|
232
- options[:output_color] = color
236
+ if color
237
+ options[:output_color] = :force
238
+ else
239
+ options[:output_color] = color
240
+ end
233
241
  end
234
242
 
235
243
  opts.on "-m", "--routes", "Report controller information" do
@@ -93,7 +93,7 @@ module Brakeman
93
93
  end
94
94
 
95
95
  def self.parse_inline_erb tracker, text
96
- fp = Brakeman::FileParser.new(nil, nil)
96
+ fp = Brakeman::FileParser.new(tracker, nil)
97
97
  tp = self.new(tracker, fp)
98
98
  src = tp.parse_erb '_inline_', text
99
99
  type = tp.erubis? ? :erubis : :erb
@@ -197,7 +197,6 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
197
197
  return Sexp.new(:false)
198
198
  end
199
199
 
200
-
201
200
  #See if it is possible to simplify some basic cases
202
201
  #of addition/concatenation.
203
202
  case method
@@ -287,11 +286,80 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
287
286
  if array? target and first_arg.nil? and sexp? target[1]
288
287
  exp = target[1]
289
288
  end
289
+ when :freeze
290
+ if string? target
291
+ exp = process exp.target
292
+ end
293
+ when :join
294
+ if array? target and target.length > 2 and (string? first_arg or first_arg.nil?)
295
+ exp = process_array_join(target, first_arg)
296
+ end
290
297
  end
291
298
 
292
299
  exp
293
300
  end
294
301
 
302
+ # Painful conversion of Array#join into string interpolation
303
+ def process_array_join array, join_str
304
+ result = s()
305
+
306
+ join_value = if string? join_str
307
+ join_str.value
308
+ else
309
+ nil
310
+ end
311
+
312
+ array[1..-2].each do |e|
313
+ result << join_item(e, join_value)
314
+ end
315
+
316
+ result << join_item(array.last, nil)
317
+
318
+ # Combine the strings at the beginning because that's what RubyParser does
319
+ combined_first = ""
320
+ result.each do |e|
321
+ if string? e
322
+ combined_first << e.value
323
+ elsif e.is_a? String
324
+ combined_first << e
325
+ else
326
+ break
327
+ end
328
+ end
329
+
330
+ # Remove the strings at the beginning
331
+ result.reject! do |e|
332
+ if e.is_a? String or string? e
333
+ true
334
+ else
335
+ break
336
+ end
337
+ end
338
+
339
+ result.unshift combined_first
340
+
341
+ # Have to fix up strings that follow interpolation
342
+ result.reduce(s(:dstr)) do |memo, e|
343
+ if string? e and node_type? memo.last, :evstr
344
+ e.value = "#{join_value}#{e.value}"
345
+ elsif join_value and node_type? memo.last, :evstr and node_type? e, :evstr
346
+ memo << s(:str, join_value)
347
+ end
348
+
349
+ memo << e
350
+ end
351
+ end
352
+
353
+ def join_item item, join_value
354
+ if item.is_a? String
355
+ "#{item}#{join_value}"
356
+ elsif string? item or symbol? item or number? item
357
+ s(:str, "#{item.value}#{join_value}")
358
+ else
359
+ s(:evstr, item)
360
+ end
361
+ end
362
+
295
363
  def process_iter exp
296
364
  @exp_context.push exp
297
365
  exp[1] = process exp.block_call
@@ -19,6 +19,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
19
19
  @current_method = opts[:method]
20
20
  @current_template = opts[:template]
21
21
  @current_file = opts[:file]
22
+ @current_call = nil
22
23
  process exp
23
24
  end
24
25
 
@@ -111,7 +112,8 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
111
112
  :method => method_name,
112
113
  :call => exp,
113
114
  :nested => false,
114
- :location => make_location }
115
+ :location => make_location,
116
+ :parent => @current_call }
115
117
  end
116
118
 
117
119
  #Gets the target of a call as a Symbol
@@ -189,7 +191,7 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
189
191
  def create_call_hash exp
190
192
  target = get_target exp.target
191
193
 
192
- if call? target
194
+ if call? target or node_type? target, :dxstr # need to index `` even if target of a call
193
195
  already_in_target = @in_target
194
196
  @in_target = true
195
197
  process target
@@ -199,13 +201,24 @@ class Brakeman::FindAllCalls < Brakeman::BasicProcessor
199
201
  end
200
202
 
201
203
  method = exp.method
202
- process_call_args exp
203
204
 
204
- { :target => target,
205
+ call_hash = {
206
+ :target => target,
205
207
  :method => method,
206
208
  :call => exp,
207
209
  :nested => @in_target,
208
210
  :chain => get_chain(exp),
209
- :location => make_location }
211
+ :location => make_location,
212
+ :parent => @current_call
213
+ }
214
+
215
+ old_parent = @current_call
216
+ @current_call = call_hash
217
+
218
+ process_call_args exp
219
+
220
+ @current_call = old_parent
221
+
222
+ call_hash
210
223
  end
211
224
  end
@@ -102,7 +102,9 @@ module Brakeman
102
102
  end
103
103
 
104
104
  def set_color
105
- unless @tracker and less_options.include? "-R "
105
+ return unless @tracker
106
+
107
+ unless less_options.include? "-R " or @tracker.options[:output_color] == :force
106
108
  @tracker.options[:output_color] = false
107
109
  end
108
110
  end
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "4.2.1"
2
+ Version = "4.3.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brakeman
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.1
4
+ version: 4.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Collins
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain:
11
11
  - brakeman-public_cert.pem
12
- date: 2018-03-24 00:00:00.000000000 Z
12
+ date: 2018-05-11 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Brakeman detects security vulnerabilities in Ruby on Rails applications
15
15
  via static analysis.
@@ -890,20 +890,20 @@ files:
890
890
  - bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/support/fixtures_helper.rb
891
891
  - bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/support/listeners_helper.rb
892
892
  - bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/support/platform_helper.rb
893
- - bundle/ruby/2.5.0/gems/sexp_processor-4.10.1/History.rdoc
894
- - bundle/ruby/2.5.0/gems/sexp_processor-4.10.1/Manifest.txt
895
- - bundle/ruby/2.5.0/gems/sexp_processor-4.10.1/README.rdoc
896
- - bundle/ruby/2.5.0/gems/sexp_processor-4.10.1/Rakefile
897
- - bundle/ruby/2.5.0/gems/sexp_processor-4.10.1/lib/composite_sexp_processor.rb
898
- - bundle/ruby/2.5.0/gems/sexp_processor-4.10.1/lib/pt_testcase.rb
899
- - bundle/ruby/2.5.0/gems/sexp_processor-4.10.1/lib/sexp.rb
900
- - bundle/ruby/2.5.0/gems/sexp_processor-4.10.1/lib/sexp_processor.rb
901
- - bundle/ruby/2.5.0/gems/sexp_processor-4.10.1/lib/strict_sexp.rb
902
- - bundle/ruby/2.5.0/gems/sexp_processor-4.10.1/lib/unique.rb
903
- - bundle/ruby/2.5.0/gems/sexp_processor-4.10.1/test/test_composite_sexp_processor.rb
904
- - bundle/ruby/2.5.0/gems/sexp_processor-4.10.1/test/test_environment.rb
905
- - bundle/ruby/2.5.0/gems/sexp_processor-4.10.1/test/test_sexp.rb
906
- - bundle/ruby/2.5.0/gems/sexp_processor-4.10.1/test/test_sexp_processor.rb
893
+ - bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/History.rdoc
894
+ - bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/Manifest.txt
895
+ - bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/README.rdoc
896
+ - bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/Rakefile
897
+ - bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/lib/composite_sexp_processor.rb
898
+ - bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/lib/pt_testcase.rb
899
+ - bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/lib/sexp.rb
900
+ - bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/lib/sexp_processor.rb
901
+ - bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/lib/strict_sexp.rb
902
+ - bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/lib/unique.rb
903
+ - bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/test/test_composite_sexp_processor.rb
904
+ - bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/test/test_environment.rb
905
+ - bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/test/test_sexp.rb
906
+ - bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/test/test_sexp_processor.rb
907
907
  - bundle/ruby/2.5.0/gems/slim-3.0.7/CHANGES
908
908
  - bundle/ruby/2.5.0/gems/slim-3.0.7/Gemfile
909
909
  - bundle/ruby/2.5.0/gems/slim-3.0.7/LICENSE
@@ -1220,18 +1220,18 @@ files:
1220
1220
  - bundle/ruby/2.5.0/gems/tilt-2.0.8/test/tilt_wikiclothtemplate_test.rb
1221
1221
  - bundle/ruby/2.5.0/gems/tilt-2.0.8/test/tilt_yajltemplate_test.rb
1222
1222
  - bundle/ruby/2.5.0/gems/tilt-2.0.8/tilt.gemspec
1223
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.0/CHANGELOG.md
1224
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.0/MIT-LICENSE.txt
1225
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.0/README.md
1226
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.0/Rakefile
1227
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.0/data/display_width.marshal.gz
1228
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.0/lib/unicode/display_width.rb
1229
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.0/lib/unicode/display_width/constants.rb
1230
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.0/lib/unicode/display_width/index.rb
1231
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.0/lib/unicode/display_width/no_string_ext.rb
1232
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.0/lib/unicode/display_width/string_ext.rb
1233
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.0/spec/display_width_spec.rb
1234
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.0/unicode-display_width.gemspec
1223
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/CHANGELOG.md
1224
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/MIT-LICENSE.txt
1225
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/README.md
1226
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/Rakefile
1227
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/data/display_width.marshal.gz
1228
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/lib/unicode/display_width.rb
1229
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/lib/unicode/display_width/constants.rb
1230
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/lib/unicode/display_width/index.rb
1231
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/lib/unicode/display_width/no_string_ext.rb
1232
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/lib/unicode/display_width/string_ext.rb
1233
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/spec/display_width_spec.rb
1234
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/unicode-display_width.gemspec
1235
1235
  - lib/brakeman.rb
1236
1236
  - lib/brakeman/app_tree.rb
1237
1237
  - lib/brakeman/call_index.rb
@@ -1410,7 +1410,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1410
1410
  version: '0'
1411
1411
  requirements: []
1412
1412
  rubyforge_project:
1413
- rubygems_version: 2.7.3
1413
+ rubygems_version: 2.7.6
1414
1414
  signing_key:
1415
1415
  specification_version: 4
1416
1416
  summary: Security vulnerability scanner for Ruby on Rails.
@@ -1,7 +0,0 @@
1
- require_relative 'constants'
2
-
3
- module Unicode
4
- module DisplayWidth
5
- INDEX = Marshal.load(Gem.gunzip(File.binread(INDEX_FILENAME)))
6
- end
7
- end