brakeman 3.6.2 → 3.7.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 +9 -0
  3. data/bundle/load.rb +1 -1
  4. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/rp_extensions.rb +5 -1
  5. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby18_parser.rb +1617 -1613
  6. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby18_parser.y +15 -9
  7. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby19_parser.rb +1572 -1570
  8. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby19_parser.y +19 -15
  9. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby20_parser.rb +2415 -2413
  10. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby20_parser.y +34 -23
  11. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby21_parser.rb +2535 -2515
  12. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby21_parser.y +34 -23
  13. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby22_parser.rb +2558 -2543
  14. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby22_parser.y +35 -24
  15. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby23_parser.rb +2504 -2483
  16. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby23_parser.y +35 -24
  17. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby24_parser.rb +2504 -2483
  18. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby24_parser.y +35 -24
  19. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby_lexer.rb +84 -11
  20. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby_parser.yy +35 -24
  21. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/lib/ruby_parser_extras.rb +112 -89
  22. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/test/test_ruby_lexer.rb +67 -0
  23. data/bundle/ruby/2.3.0/gems/ruby_parser-3.9.0/test/test_ruby_parser.rb +32 -1
  24. data/bundle/ruby/2.3.0/gems/{unicode-display_width-1.2.1 → unicode-display_width-1.3.0}/CHANGELOG.md +4 -0
  25. data/bundle/ruby/2.3.0/gems/{unicode-display_width-1.2.1 → unicode-display_width-1.3.0}/MIT-LICENSE.txt +0 -0
  26. data/bundle/ruby/2.3.0/gems/{unicode-display_width-1.2.1 → unicode-display_width-1.3.0}/README.md +1 -1
  27. data/bundle/ruby/2.3.0/gems/{unicode-display_width-1.2.1 → unicode-display_width-1.3.0}/Rakefile +0 -0
  28. data/bundle/ruby/2.3.0/gems/unicode-display_width-1.3.0/data/display_width.marshal.gz +0 -0
  29. data/bundle/ruby/2.3.0/gems/{unicode-display_width-1.2.1 → unicode-display_width-1.3.0}/lib/unicode/display_width.rb +0 -0
  30. data/bundle/ruby/2.3.0/gems/{unicode-display_width-1.2.1 → unicode-display_width-1.3.0}/lib/unicode/display_width/constants.rb +2 -2
  31. data/bundle/ruby/2.3.0/gems/{unicode-display_width-1.2.1 → unicode-display_width-1.3.0}/lib/unicode/display_width/index.rb +0 -0
  32. data/bundle/ruby/2.3.0/gems/{unicode-display_width-1.2.1 → unicode-display_width-1.3.0}/lib/unicode/display_width/no_string_ext.rb +0 -0
  33. data/bundle/ruby/2.3.0/gems/{unicode-display_width-1.2.1 → unicode-display_width-1.3.0}/lib/unicode/display_width/string_ext.rb +0 -0
  34. data/bundle/ruby/2.3.0/gems/{unicode-display_width-1.2.1 → unicode-display_width-1.3.0}/spec/display_width_spec.rb +0 -0
  35. data/bundle/ruby/2.3.0/gems/{unicode-display_width-1.2.1 → unicode-display_width-1.3.0}/unicode-display_width.gemspec +0 -0
  36. data/lib/brakeman.rb +7 -0
  37. data/lib/brakeman/checks/check_redirect.rb +26 -3
  38. data/lib/brakeman/processors/alias_processor.rb +91 -3
  39. data/lib/brakeman/processors/base_processor.rb +9 -1
  40. data/lib/brakeman/report/ignore/interactive.rb +9 -4
  41. data/lib/brakeman/tracker/constants.rb +11 -2
  42. data/lib/brakeman/version.rb +1 -1
  43. data/lib/ruby_parser/bm_sexp.rb +0 -8
  44. metadata +14 -14
  45. data/bundle/ruby/2.3.0/gems/unicode-display_width-1.2.1/data/display_width.marshal.gz +0 -0
@@ -1153,6 +1153,47 @@ class TestRubyLexer < Minitest::Test
1153
1153
  :tNL, nil, :expr_beg)
1154
1154
  end
1155
1155
 
1156
+ def test_yylex_heredoc_double_squiggly
1157
+ setup_lexer_class Ruby23Parser
1158
+
1159
+ assert_lex3("a = <<~\"EOF\"\n blah blah\n EOF\n\n",
1160
+ nil,
1161
+ :tIDENTIFIER, "a", :expr_cmdarg,
1162
+ :tEQL, "=", :expr_beg,
1163
+ :tSTRING_BEG, "\"", :expr_beg,
1164
+ :tSTRING_CONTENT, "blah blah\n", :expr_beg,
1165
+ :tSTRING_END, "EOF", :expr_end,
1166
+ :tNL, nil, :expr_beg)
1167
+ end
1168
+
1169
+ # mri handles tabs in a pretty specific way:
1170
+ # https://github.com/ruby/ruby/blob/trunk/parse.y#L5925
1171
+ def test_yylex_heredoc_double_squiggly_with_tab_indentation_remaining
1172
+ setup_lexer_class Ruby23Parser
1173
+
1174
+ assert_lex3("a = <<~\"EOF\"\n blah blah\n \tblah blah\n EOF\n\n",
1175
+ nil,
1176
+ :tIDENTIFIER, "a", :expr_cmdarg,
1177
+ :tEQL, "=", :expr_beg,
1178
+ :tSTRING_BEG, "\"", :expr_beg,
1179
+ :tSTRING_CONTENT, "blah blah\n\tblah blah\n", :expr_beg,
1180
+ :tSTRING_END, "EOF", :expr_end,
1181
+ :tNL, nil, :expr_beg)
1182
+ end
1183
+
1184
+ def test_yylex_heredoc_double_squiggly_with_tab_indentation_removed
1185
+ setup_lexer_class Ruby23Parser
1186
+
1187
+ assert_lex3("a = <<~\"EOF\"\n blah blah\n\t blah blah\n EOF\n\n",
1188
+ nil,
1189
+ :tIDENTIFIER, "a", :expr_cmdarg,
1190
+ :tEQL, "=", :expr_beg,
1191
+ :tSTRING_BEG, "\"", :expr_beg,
1192
+ :tSTRING_CONTENT, "blah blah\n blah blah\n", :expr_beg,
1193
+ :tSTRING_END, "EOF", :expr_end,
1194
+ :tNL, nil, :expr_beg)
1195
+ end
1196
+
1156
1197
  def test_yylex_heredoc_double_eos
1157
1198
  refute_lex("a = <<\"EOF\"\nblah",
1158
1199
  :tIDENTIFIER, "a",
@@ -1223,6 +1264,19 @@ class TestRubyLexer < Minitest::Test
1223
1264
  :tNL, nil, :expr_beg)
1224
1265
  end
1225
1266
 
1267
+ def test_yylex_heredoc_none_squiggly
1268
+ setup_lexer_class Ruby23Parser
1269
+
1270
+ assert_lex3("a = <<~EOF\n blah\n blah\n EOF\n",
1271
+ nil,
1272
+ :tIDENTIFIER, "a", :expr_cmdarg,
1273
+ :tEQL, "=", :expr_beg,
1274
+ :tSTRING_BEG, "\"", :expr_beg,
1275
+ :tSTRING_CONTENT, "blah\nblah\n", :expr_beg,
1276
+ :tSTRING_END, "EOF", :expr_end,
1277
+ :tNL, nil, :expr_beg)
1278
+ end
1279
+
1226
1280
  def test_yylex_heredoc_single
1227
1281
  assert_lex3("a = <<'EOF'\n blah blah\nEOF\n\n",
1228
1282
  nil,
@@ -1273,6 +1327,19 @@ class TestRubyLexer < Minitest::Test
1273
1327
  :tNL, nil, :expr_beg)
1274
1328
  end
1275
1329
 
1330
+ def test_yylex_heredoc_single_squiggly
1331
+ setup_lexer_class Ruby23Parser
1332
+
1333
+ assert_lex3("a = <<~'EOF'\n blah blah\n EOF\n\n",
1334
+ nil,
1335
+ :tIDENTIFIER, "a", :expr_cmdarg,
1336
+ :tEQL, "=", :expr_beg,
1337
+ :tSTRING_BEG, "\"", :expr_beg,
1338
+ :tSTRING_CONTENT, "blah blah\n", :expr_beg,
1339
+ :tSTRING_END, "EOF", :expr_end,
1340
+ :tNL, nil, :expr_beg)
1341
+ end
1342
+
1276
1343
  def test_yylex_identifier
1277
1344
  assert_lex3("identifier",
1278
1345
  nil,
@@ -571,6 +571,14 @@ module TestRubyParserShared
571
571
  assert_parse rb, pt
572
572
  end
573
573
 
574
+ def test_str_newline_hash_line_number
575
+ rb = "\"\\n\\n\\n\\n#\"\n1"
576
+ pt = s(:block, s(:str, "\n\n\n\n#").line(1),
577
+ s(:lit, 1).line(2))
578
+
579
+ assert_parse rb, pt
580
+ end
581
+
574
582
  def after_process_hook klass, node, data, input_name, output_name
575
583
  assert_equal 1, @result.line, "should have proper line number"
576
584
  end
@@ -811,7 +819,6 @@ module TestRubyParserShared
811
819
  end
812
820
 
813
821
  def test_parse_line_rescue
814
- skip "not yet"
815
822
  rb = "begin\n a\n rescue\n b\n rescue\n c\n end\n"
816
823
  pt = s(:rescue,
817
824
  s(:call, nil, :a).line(2),
@@ -1709,6 +1716,16 @@ module TestRubyParserShared
1709
1716
  assert_parse rb, pt
1710
1717
  end
1711
1718
 
1719
+ def test_defs_as_arg_with_do_block_inside
1720
+ rb = "p def self.b; x.y do; end; end"
1721
+ pt = s(:call,
1722
+ nil,
1723
+ :p,
1724
+ s(:defs, s(:self), :b, s(:args),
1725
+ s(:iter, s(:call, s(:call, nil, :x), :y), 0)))
1726
+
1727
+ assert_parse rb, pt
1728
+ end
1712
1729
  end
1713
1730
 
1714
1731
  module TestRubyParserShared19Plus
@@ -3239,6 +3256,20 @@ module TestRubyParserShared20Plus
3239
3256
 
3240
3257
  assert_parse rb, pt
3241
3258
  end
3259
+
3260
+ def test_bug_249
3261
+ rb = "mount (Class.new do\ndef initialize\nend\n end).new, :at => 'endpoint'"
3262
+ pt = s(:call, nil, :mount,
3263
+ s(:call,
3264
+ s(:iter,
3265
+ s(:call, s(:const, :Class), :new),
3266
+ 0,
3267
+ s(:defn, :initialize, s(:args), s(:nil))),
3268
+ :new),
3269
+ s(:hash, s(:lit, :at), s(:str, "endpoint")))
3270
+
3271
+ assert_parse rb, pt
3272
+ end
3242
3273
  end
3243
3274
 
3244
3275
  module TestRubyParserShared22Plus
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.3.0
4
+
5
+ - Unicode 10
6
+
3
7
  ## 1.2.1
4
8
 
5
9
  - Fix bug that `emoji: true` would fail for emoji without modifier
@@ -2,7 +2,7 @@
2
2
 
3
3
  Determines the monospace display width of a string in Ruby. Implementation based on [EastAsianWidth.txt](http://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt) and other data, 100% in Ruby. Other than [wcwidth()](https://github.com/janlelis/wcswidth-ruby), which fulfills a similar purpose, it does not rely on the OS vendor to provide an up-to-date method for measuring string width.
4
4
 
5
- Unicode version: **9.0.0**
5
+ Unicode version: **10.0.0**
6
6
 
7
7
  ## Introduction to Character Widths
8
8
 
@@ -1,7 +1,7 @@
1
1
  module Unicode
2
2
  module DisplayWidth
3
- VERSION = '1.2.1'
4
- UNICODE_VERSION = "9.0.0".freeze
3
+ VERSION = '1.3.0'
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
7
7
  end
@@ -90,6 +90,13 @@ module Brakeman
90
90
  options[:quiet] = true
91
91
  end
92
92
 
93
+ if options[:rails4]
94
+ options[:rails3] = true
95
+ elsif options[:rails5]
96
+ options[:rails3] = true
97
+ options[:rails4] = true
98
+ end
99
+
93
100
  options[:output_formats] = get_output_formats options
94
101
  options[:github_url] = get_github_url options
95
102
 
@@ -105,11 +105,34 @@ class Brakeman::CheckRedirect < Brakeman::BaseCheck
105
105
  arg = call.first_arg
106
106
 
107
107
  if hash? arg
108
- if value = hash_access(arg, :only_path)
109
- return true if true?(value)
110
- end
108
+ return has_only_path? arg
111
109
  elsif call? arg and arg.method == :url_for
112
110
  return check_url_for(arg)
111
+ elsif call? arg and hash? arg.first_arg and use_unsafe_hash_method? arg
112
+ return has_only_path? arg.first_arg
113
+ end
114
+
115
+ false
116
+ end
117
+
118
+ def use_unsafe_hash_method? arg
119
+ return call_has_param(arg, :to_unsafe_hash) || call_has_param(arg, :to_unsafe_h)
120
+ end
121
+
122
+ def call_has_param arg, key
123
+ if call? arg and call? arg.target
124
+ target = arg.target
125
+ method = target.method
126
+
127
+ node_type? target.target, :params and method == key
128
+ else
129
+ false
130
+ end
131
+ end
132
+
133
+ def has_only_path? arg
134
+ if value = hash_access(arg, :only_path)
135
+ return true if true?(value)
113
136
  end
114
137
 
115
138
  false
@@ -87,6 +87,73 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
87
87
  end
88
88
  end
89
89
 
90
+ def process_bracket_call exp
91
+ r = replace(exp)
92
+
93
+ if r != exp
94
+ return r
95
+ end
96
+
97
+ exp.arglist = process_default(exp.arglist)
98
+
99
+ r = replace(exp)
100
+
101
+ if r != exp
102
+ return r
103
+ end
104
+
105
+ t = process(exp.target.deep_clone)
106
+
107
+ # sometimes t[blah] has a match in the env
108
+ # but we don't want to actually set the target
109
+ # in case the target is big...which is what this
110
+ # whole method is trying to avoid
111
+ if t != exp.target
112
+ e = exp.deep_clone
113
+ e.target = t
114
+
115
+ r = replace(e)
116
+
117
+ if r != e
118
+ return r
119
+ end
120
+ else
121
+ t = nil
122
+ end
123
+
124
+ if hash? t
125
+ if v = hash_access(t, exp.first_arg)
126
+ v.deep_clone(exp.line)
127
+ else
128
+ case t.node_type
129
+ when :params
130
+ exp.target = PARAMS_SEXP.deep_clone(exp.target.line)
131
+ when :session
132
+ exp.target = SESSION_SEXP.deep_clone(exp.target.line)
133
+ when :cookies
134
+ exp.target = COOKIES_SEXP.deep_clone(exp.target.line)
135
+ end
136
+
137
+ exp
138
+ end
139
+ elsif array? t
140
+ if v = process_array_access(t, exp.args)
141
+ v.deep_clone(exp.line)
142
+ else
143
+ exp
144
+ end
145
+ elsif t
146
+ exp.target = t
147
+ exp
148
+ else
149
+ if exp.target # `self` target is reported as `nil` https://github.com/seattlerb/ruby_parser/issues/250
150
+ exp.target = process_default exp.target
151
+ end
152
+
153
+ exp
154
+ end
155
+ end
156
+
90
157
  ARRAY_CONST = s(:const, :Array)
91
158
  HASH_CONST = s(:const, :Hash)
92
159
  RAILS_TEST = s(:call, s(:call, s(:const, :Rails), :env), :test?)
@@ -99,7 +166,12 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
99
166
  if exp.node_type == :safe_call
100
167
  exp.node_type = :call
101
168
  end
102
- exp = process_default exp
169
+
170
+ if exp.method == :[]
171
+ return process_bracket_call exp
172
+ else
173
+ exp = process_default exp
174
+ end
103
175
 
104
176
  #In case it is replaced with something else
105
177
  unless call? exp
@@ -391,7 +463,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
391
463
  # x[:y] = 1
392
464
  def process_attrasgn exp
393
465
  tar_variable = exp.target
394
- target = exp.target = process(exp.target)
466
+ target = process(exp.target)
395
467
  method = exp.method
396
468
  index_arg = exp.first_arg
397
469
  value_arg = exp.second_arg
@@ -406,6 +478,10 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
406
478
  if hash? target
407
479
  env[tar_variable] = hash_insert target.deep_clone, index, value
408
480
  end
481
+
482
+ unless node_type? target, :hash
483
+ exp.target = target
484
+ end
409
485
  elsif method.to_s[-1,1] == "="
410
486
  exp.first_arg = process(index_arg)
411
487
  value = get_rhs(exp)
@@ -413,6 +489,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
413
489
  match = Sexp.new(:call, target, method.to_s[0..-2].to_sym)
414
490
 
415
491
  set_value match, value
492
+ exp.target = target
416
493
  else
417
494
  raise "Unrecognized assignment: #{exp}"
418
495
  end
@@ -522,7 +599,14 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
522
599
  exp.rhs = process exp.rhs
523
600
  end
524
601
 
525
- @tracker.add_constant exp.lhs, exp.rhs, :file => current_file_name if @tracker
602
+ if @tracker
603
+ @tracker.add_constant exp.lhs,
604
+ exp.rhs,
605
+ :file => current_file_name,
606
+ :module => @current_module,
607
+ :class => @current_class,
608
+ :method => @current_method
609
+ end
526
610
 
527
611
  if exp.lhs.is_a? Symbol
528
612
  match = Sexp.new(:const, exp.lhs)
@@ -598,6 +682,10 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
598
682
  env.current[var] = condition.target[1]
599
683
  exp[branch_index] = process_if_branch branch
600
684
  env.current[var] = previous_value
685
+ elsif i == 1 and array_include_all_literals? condition and node_type? branch, :return
686
+ var = condition.first_arg
687
+ env.current[var] = condition.target[1]
688
+ exp[branch_index] = process_if_branch branch
601
689
  else
602
690
  exp[branch_index] = process_if_branch branch
603
691
  end
@@ -183,7 +183,15 @@ class Brakeman::BaseProcessor < Brakeman::SexpProcessor
183
183
  end
184
184
 
185
185
  def process_cdecl exp
186
- @tracker.add_constant exp.lhs, exp.rhs, :file => current_file_name if @tracker
186
+ if @tracker
187
+ @tracker.add_constant exp.lhs,
188
+ exp.rhs,
189
+ :file => current_file_name,
190
+ :module => @current_module,
191
+ :class => @current_class,
192
+ :method => @current_method
193
+ end
194
+
187
195
  exp
188
196
  end
189
197
 
@@ -101,7 +101,7 @@ module Brakeman
101
101
  end
102
102
 
103
103
  def pre_show_help
104
- say "-" * 20
104
+ say "-" * 30
105
105
  say "Actions:", :cyan
106
106
  show_help
107
107
  end
@@ -189,7 +189,11 @@ q - Quit, do not update ignored warnings
189
189
  end
190
190
 
191
191
  def process_warnings
192
- @new_warnings.each do |w|
192
+ @warning_count = @new_warnings.length
193
+
194
+ @new_warnings.each_with_index do |w, index|
195
+ @current_index = index
196
+
193
197
  if skip_ignored? w or @skip_rest
194
198
  next
195
199
  elsif @ignore_rest
@@ -261,7 +265,8 @@ q - Quit, do not update ignored warnings
261
265
  end
262
266
 
263
267
  def pretty_display warning
264
- say "-" * 20
268
+ progress = "#{@current_index + 1}/#{@warning_count}"
269
+ say "-------- #{progress} #{"-" * (20 - progress.length)}", :cyan
265
270
  show_confidence warning
266
271
 
267
272
  label "Category"
@@ -302,7 +307,7 @@ q - Quit, do not update ignored warnings
302
307
  end
303
308
 
304
309
  def summarize_changes
305
- say "-" * 20
310
+ say "-" * 30
306
311
 
307
312
  say "Ignoring #{@ignore_config.ignored_warnings.length} warnings", :yellow
308
313
  say "Showing #{@ignore_config.shown_warnings.length} warnings", :green