brakeman 5.0.4 → 5.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +40 -1
  3. data/README.md +1 -1
  4. data/bundle/load.rb +5 -4
  5. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/CHANGELOG.md +8 -0
  6. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/FAQ.md +0 -0
  7. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/Gemfile +0 -0
  8. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/MIT-LICENSE +0 -0
  9. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/README.md +19 -13
  10. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/REFERENCE.md +10 -3
  11. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/TODO +0 -0
  12. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/haml.gemspec +0 -0
  13. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/attribute_builder.rb +55 -0
  14. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/attribute_compiler.rb +4 -2
  15. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/attribute_parser.rb +0 -0
  16. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/buffer.rb +0 -56
  17. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/compiler.rb +0 -0
  18. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/engine.rb +0 -0
  19. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/error.rb +0 -0
  20. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/escapable.rb +0 -0
  21. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/exec.rb +0 -0
  22. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/filters.rb +0 -0
  23. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/generator.rb +0 -0
  24. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/helpers/action_view_extensions.rb +0 -0
  25. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/helpers/action_view_mods.rb +0 -0
  26. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/helpers/action_view_xss_mods.rb +0 -0
  27. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/helpers/safe_erubi_template.rb +0 -0
  28. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/helpers/safe_erubis_template.rb +0 -0
  29. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/helpers/xss_mods.rb +0 -0
  30. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/helpers.rb +0 -0
  31. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/options.rb +0 -0
  32. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/parser.rb +0 -0
  33. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/plugin.rb +18 -1
  34. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/railtie.rb +5 -0
  35. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/sass_rails_filter.rb +0 -0
  36. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/template/options.rb +0 -0
  37. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/template.rb +0 -0
  38. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/temple_engine.rb +2 -1
  39. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/temple_line_counter.rb +0 -0
  40. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/util.rb +0 -0
  41. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml/version.rb +1 -1
  42. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/lib/haml.rb +0 -0
  43. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/yard/default/fulldoc/html/css/common.sass +0 -0
  44. data/bundle/ruby/2.7.0/gems/{haml-5.2.1 → haml-5.2.2}/yard/default/layout/html/footer.erb +0 -0
  45. data/bundle/ruby/2.7.0/gems/parallel-1.21.0/MIT-LICENSE.txt +20 -0
  46. data/bundle/ruby/2.7.0/gems/parallel-1.21.0/lib/parallel/processor_count.rb +45 -0
  47. data/bundle/ruby/2.7.0/gems/parallel-1.21.0/lib/parallel/version.rb +4 -0
  48. data/bundle/ruby/2.7.0/gems/parallel-1.21.0/lib/parallel.rb +532 -0
  49. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.0}/History.rdoc +76 -0
  50. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.0}/Manifest.txt +3 -0
  51. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.0}/README.rdoc +1 -0
  52. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.0}/compare/normalize.rb +6 -1
  53. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.0}/debugging.md +0 -0
  54. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/gauntlet.md +106 -0
  55. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.0}/lib/rp_extensions.rb +15 -36
  56. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/rp_stringscanner.rb +33 -0
  57. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby20_parser.rb +7122 -0
  58. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.0}/lib/ruby20_parser.y +326 -249
  59. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby21_parser.rb +7176 -0
  60. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.0}/lib/ruby21_parser.y +321 -246
  61. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby22_parser.rb +7222 -0
  62. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.0}/lib/ruby22_parser.y +325 -248
  63. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby23_parser.rb +7231 -0
  64. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0/lib/ruby24_parser.y → ruby_parser-3.18.0/lib/ruby23_parser.y} +326 -257
  65. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby24_parser.rb +7262 -0
  66. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0/lib/ruby30_parser.y → ruby_parser-3.18.0/lib/ruby24_parser.y} +327 -302
  67. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby25_parser.rb +7262 -0
  68. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0/lib/ruby26_parser.y → ruby_parser-3.18.0/lib/ruby25_parser.y} +326 -264
  69. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby26_parser.rb +7281 -0
  70. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0/lib/ruby27_parser.y → ruby_parser-3.18.0/lib/ruby26_parser.y} +325 -285
  71. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby27_parser.rb +8511 -0
  72. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0/lib/ruby_parser.yy → ruby_parser-3.18.0/lib/ruby27_parser.y} +897 -377
  73. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby30_parser.rb +8741 -0
  74. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby30_parser.y +3463 -0
  75. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby3_parser.yy +3467 -0
  76. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.0}/lib/ruby_lexer.rb +261 -609
  77. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.0}/lib/ruby_lexer.rex +27 -20
  78. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.0}/lib/ruby_lexer.rex.rb +59 -23
  79. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby_lexer_strings.rb +638 -0
  80. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.0}/lib/ruby_parser.rb +0 -0
  81. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby_parser.yy +3481 -0
  82. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.0}/lib/ruby_parser_extras.rb +296 -115
  83. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.16.0 → ruby_parser-3.18.0}/tools/munge.rb +34 -6
  84. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/tools/ripper.rb +44 -0
  85. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/History.rdoc +15 -0
  86. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/Manifest.txt +0 -0
  87. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/README.rdoc +0 -0
  88. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/lib/composite_sexp_processor.rb +0 -0
  89. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/lib/pt_testcase.rb +7 -2
  90. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/lib/sexp.rb +19 -9
  91. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/lib/sexp_matcher.rb +0 -0
  92. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/lib/sexp_processor.rb +1 -1
  93. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/lib/strict_sexp.rb +25 -3
  94. data/bundle/ruby/2.7.0/gems/{sexp_processor-4.15.3 → sexp_processor-4.16.0}/lib/unique.rb +0 -0
  95. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/CHANGELOG.md +4 -0
  96. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/MIT-LICENSE.txt +0 -0
  97. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/README.md +1 -1
  98. data/bundle/ruby/2.7.0/gems/unicode-display_width-1.8.0/data/display_width.marshal.gz +0 -0
  99. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/lib/unicode/display_width/constants.rb +2 -2
  100. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/lib/unicode/display_width/index.rb +0 -0
  101. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/lib/unicode/display_width/no_string_ext.rb +0 -0
  102. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/lib/unicode/display_width/string_ext.rb +0 -0
  103. data/bundle/ruby/2.7.0/gems/{unicode-display_width-1.7.0 → unicode-display_width-1.8.0}/lib/unicode/display_width.rb +0 -0
  104. data/lib/brakeman/app_tree.rb +1 -1
  105. data/lib/brakeman/checks/check_detailed_exceptions.rb +1 -1
  106. data/lib/brakeman/checks/check_evaluation.rb +1 -1
  107. data/lib/brakeman/checks/check_execute.rb +10 -0
  108. data/lib/brakeman/checks/check_json_parsing.rb +1 -1
  109. data/lib/brakeman/checks/check_render.rb +15 -1
  110. data/lib/brakeman/checks/check_sql.rb +58 -8
  111. data/lib/brakeman/checks/check_verb_confusion.rb +1 -1
  112. data/lib/brakeman/file_parser.rb +45 -15
  113. data/lib/brakeman/options.rb +7 -2
  114. data/lib/brakeman/processors/alias_processor.rb +91 -9
  115. data/lib/brakeman/processors/controller_alias_processor.rb +6 -43
  116. data/lib/brakeman/processors/haml_template_processor.rb +9 -0
  117. data/lib/brakeman/processors/lib/call_conversion_helper.rb +12 -6
  118. data/lib/brakeman/processors/library_processor.rb +9 -0
  119. data/lib/brakeman/processors/model_processor.rb +32 -0
  120. data/lib/brakeman/report/ignore/config.rb +1 -1
  121. data/lib/brakeman/report/ignore/interactive.rb +1 -1
  122. data/lib/brakeman/report/report_csv.rb +1 -1
  123. data/lib/brakeman/report/report_github.rb +31 -0
  124. data/lib/brakeman/report/report_sarif.rb +22 -3
  125. data/lib/brakeman/report/report_text.rb +1 -1
  126. data/lib/brakeman/report.rb +4 -1
  127. data/lib/brakeman/rescanner.rb +1 -1
  128. data/lib/brakeman/scanner.rb +16 -13
  129. data/lib/brakeman/tracker/collection.rb +57 -7
  130. data/lib/brakeman/tracker/method_info.rb +70 -0
  131. data/lib/brakeman/tracker.rb +33 -4
  132. data/lib/brakeman/util.rb +34 -18
  133. data/lib/brakeman/version.rb +1 -1
  134. data/lib/brakeman.rb +8 -2
  135. data/lib/ruby_parser/bm_sexp.rb +24 -0
  136. metadata +103 -94
  137. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/rp_stringscanner.rb +0 -64
  138. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby20_parser.rb +0 -7075
  139. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby21_parser.rb +0 -7148
  140. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby22_parser.rb +0 -7185
  141. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby23_parser.rb +0 -7199
  142. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby23_parser.y +0 -2643
  143. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby24_parser.rb +0 -7219
  144. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby25_parser.rb +0 -7218
  145. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby25_parser.y +0 -2651
  146. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby26_parser.rb +0 -7240
  147. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby27_parser.rb +0 -7358
  148. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/lib/ruby30_parser.rb +0 -7358
  149. data/bundle/ruby/2.7.0/gems/ruby_parser-3.16.0/tools/ripper.rb +0 -39
  150. data/bundle/ruby/2.7.0/gems/unicode-display_width-1.7.0/data/display_width.marshal.gz +0 -0
@@ -76,12 +76,31 @@ def munge s
76
76
 
77
77
  # other
78
78
 
79
+ 'kTERMINATOR', "tSTRING_END",
80
+ '"kTERMINATOR"', "tSTRING_END",
81
+ 'kTRCURLY', "tSTRING_DEND",
82
+
83
+ '"symbol literal"', "tSYMBEG",
84
+ '"string literal"', "tSTRING_BEG",
85
+ '"backtick literal"', "tXSTRING_BEG",
86
+ '"regexp literal"', "tREGEXP_BEG",
87
+ '"word list"', "tWORDS_BEG",
88
+ '"verbatim word list"', "tQWORDS_BEG",
89
+ '"symbol list"', "tSYMBOLS_BEG",
90
+ '"verbatim symbol list"', "tQSYMBOLS_BEG",
91
+ '"terminator"', "tSTRING_END",
92
+ '"\'}\'"', "tSTRING_DEND",
93
+
94
+ '"string literal"',"tSTRING_BEG",
95
+ '"literal content"', "tSTRING_CONTENT",
96
+ /\$/, "", # try to remove these lumps?
97
+
79
98
  'tLBRACK2', "tLBRACK", # HACK
80
99
 
81
100
  "' '", "tSPACE", # needs to be later to avoid bad hits
82
101
 
83
102
  "/* empty */", "none",
84
- /^\s*$/, "none",
103
+ /^\s*$/, "",
85
104
 
86
105
  "keyword_BEGIN", "klBEGIN",
87
106
  "keyword_END", "klEND",
@@ -89,6 +108,7 @@ def munge s
89
108
  /\bk_([a-z_]+)/, proc { "k#{$1.upcase}" },
90
109
  /modifier_(\w+)/, proc { "k#{$1.upcase}_MOD" },
91
110
  "kVARIABLE", "keyword_variable", # ugh
111
+ "tCONST", "kCONST",
92
112
 
93
113
  # 2.6 collapses klBEGIN to kBEGIN
94
114
  "klBEGIN", "kBEGIN",
@@ -112,9 +132,11 @@ def munge s
112
132
  '"do (for condition)"', "kDO_COND",
113
133
  '"do (for lambda)"', "kDO_LAMBDA",
114
134
  '"do (for block)"', "kDO_BLOCK",
135
+ '"local variable or method"', "tIDENTIFIER",
115
136
 
116
137
  /\"(\w+) \(modifier\)\"/, proc { |x| "k#{$1.upcase}_MOD" },
117
138
  /\"(\w+)\"/, proc { |x| "k#{$1.upcase}" },
139
+ /\"`(\w+)'\"/, proc { |x| "k#{$1.upcase}" },
118
140
 
119
141
  /@(\d+)(\s+|$)/, "",
120
142
  /\$?@(\d+) */, "", # TODO: remove?
@@ -130,7 +152,11 @@ def munge s
130
152
  end
131
153
  end
132
154
 
133
- s.strip.squeeze " "
155
+ if s.empty? then
156
+ nil
157
+ else
158
+ s.strip.squeeze " "
159
+ end
134
160
  end
135
161
 
136
162
  ARGF.each_line do |line|
@@ -144,19 +170,19 @@ ARGF.each_line do |line|
144
170
  when /^Reading a token: Next token is token (.*?) \(\)/ then
145
171
  token = munge $1
146
172
  next if last_token == token
147
- puts "next token is %p (%p)" % [token, last_token]
173
+ puts "next token is %p" % [token]
148
174
  last_token = token
149
175
  when /^Reading a token: / then
150
176
  next # skip
151
177
  when /^read\s+:(\w+)/ then # read :tNL(tNL) nil
152
178
  token = munge $1
153
179
  next if last_token == token
154
- puts "next token is %p (%p)" % [token, last_token]
180
+ puts "next token is %p" % [token]
155
181
  last_token = token
156
182
  when /^Next token is token ("[^"]+"|\S+)/ then
157
183
  token = munge $1
158
184
  next if last_token == token
159
- puts "next token is %p (%p)" % [token, last_token]
185
+ puts "next token is %p" % [token]
160
186
  last_token = token
161
187
  when /^read\s+false/ then # read false($end) "$end"
162
188
  puts "next token is EOF"
@@ -164,6 +190,8 @@ ARGF.each_line do |line|
164
190
  # do nothing
165
191
  when /^.:scan=>\["([^"]+)"/ then
166
192
  puts "scan = %p" % [$1]
193
+ when /^.:getch=>\["([^"]+)/ then
194
+ puts "SCAN = %p" % [$1]
167
195
  when /^Reducing stack by rule (\d+) \(line (\d+)\):/ then
168
196
  reduce_line = $2.to_i
169
197
  when /^ \$\d+ = (?:token|nterm) (.+) \(.*\)/ then
@@ -172,7 +200,7 @@ ARGF.each_line do |line|
172
200
  when /^-> \$\$ = (?:token|nterm) (.+) \(.*\)/ then
173
201
  stack << "none" if stack.empty?
174
202
  item = munge $1
175
- x = stack.map { |s| s.strip }.join " "
203
+ x = stack.compact.map { |s| munge s.strip }.compact.join " "
176
204
  if x != item then # prevent kdef -> kdef
177
205
  if $v && reduce_line then
178
206
  puts "reduce #{x} --> #{item} at #{reduce_line}".squeeze " "
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby -ws
2
+
3
+ $b ||= false # bug mode -- ripper is buggy, use Ripper.sexp
4
+ $d ||= false # debug -- turn on yydebug
5
+ $p ||= false # Use pp
6
+
7
+ require "ripper/sexp"
8
+ require "pp" if $p
9
+
10
+ if ARGV.empty? then
11
+ warn "reading from stdin"
12
+ ARGV << "-"
13
+ end
14
+
15
+ class MySexpBuilder < Ripper::SexpBuilderPP
16
+ def on_parse_error msg
17
+ Kernel.warn msg
18
+ end
19
+ end
20
+
21
+ ARGV.each do |path|
22
+ src = path == "-" ? $stdin.read : File.read(path)
23
+
24
+ sexp = if $b then
25
+ Ripper.sexp src
26
+ else
27
+ rip = MySexpBuilder.new src
28
+ rip.yydebug = $d
29
+ rip.parse
30
+
31
+ if rip.error? then
32
+ warn "skipping"
33
+ next
34
+ end
35
+ end
36
+
37
+ puts "accept"
38
+
39
+ if $p then
40
+ pp sexp
41
+ else
42
+ p sexp
43
+ end
44
+ end
@@ -1,3 +1,18 @@
1
+ === 4.16.0 / 2021-10-27
2
+
3
+ * 4 minor enhancements:
4
+
5
+ * Added Sexp#value (pushed up from ruby_parser).
6
+ * Aliased Sexp#concat to #_concat and use that so it can be overridden.
7
+ * Cache the #hash result.
8
+ * StrictSexp mode (4) now covers concat.
9
+
10
+ * 3 bug fixes:
11
+
12
+ * Fix some doco on each_sexp to clarify that it is not recursive.
13
+ * Fixed a bug calling enum_for when using each_of_type w/ no block.
14
+ * Minor fixes to pt_testcase.rb for custom timeouts and better error handling.
15
+
1
16
  === 4.15.3 / 2021-05-15
2
17
 
3
18
  * 1 minor enhancement:
@@ -150,7 +150,8 @@ class ParseTreeTestCase < Minitest::Test
150
150
 
151
151
  before_process_hook klass, node, data, input_name, output_name
152
152
  refute_nil data[input_name], "testcase does not exist?"
153
- @result = processor.process input
153
+ timeout = (ENV["RP_TIMEOUT"] || 10).to_i
154
+ @result = processor.process input, "(string)", timeout
154
155
  assert_equal(expected, @result,
155
156
  "failed on input: #{data[input_name].inspect}")
156
157
  after_process_hook klass, node, data, input_name, output_name
@@ -158,7 +159,11 @@ class ParseTreeTestCase < Minitest::Test
158
159
  extra_input.each do |extra|
159
160
  processor.process(extra)
160
161
  end
161
- extra = processor.extra_methods rescue []
162
+ extra = if processor.respond_to?(:extra_methods) then
163
+ processor.extra_methods
164
+ else
165
+ []
166
+ end
162
167
  assert_equal extra_expected, extra
163
168
  end
164
169
  end
@@ -31,13 +31,15 @@ class Sexp < Array # ZenTest FULL
31
31
  super(args)
32
32
  end
33
33
 
34
+ alias _concat concat
35
+
34
36
  ##
35
37
  # Creates a new Sexp from Array +a+.
36
38
 
37
39
  def self.from_array a
38
40
  ary = Array === a ? a : [a]
39
41
 
40
- self.new.concat(ary.map { |x|
42
+ self.new._concat(ary.map { |x|
41
43
  case x
42
44
  when Sexp
43
45
  x
@@ -54,7 +56,7 @@ class Sexp < Array # ZenTest FULL
54
56
  # same +file+, +line+, and +comment+ as self.
55
57
 
56
58
  def new(*body)
57
- r = self.class.new.concat(body) # ensures a sexp from map
59
+ r = self.class.new._concat(body) # ensures a sexp from map
58
60
  r.file = self.file if self.file
59
61
  r.line = self.line if self.line
60
62
  r.comments = self.comments if self.comments
@@ -62,7 +64,7 @@ class Sexp < Array # ZenTest FULL
62
64
  end
63
65
 
64
66
  def map &blk # :nodoc:
65
- self.new.concat(super(&blk)) # ensures a sexp from map
67
+ self.new._concat(super(&blk)) # ensures a sexp from map
66
68
  end
67
69
 
68
70
  def == obj # :nodoc:
@@ -74,7 +76,7 @@ class Sexp < Array # ZenTest FULL
74
76
  end
75
77
 
76
78
  def hash
77
- [self.class, *self].hash
79
+ @hash ||= [self.class, *self].hash
78
80
  end
79
81
 
80
82
  ##
@@ -93,7 +95,7 @@ class Sexp < Array # ZenTest FULL
93
95
  end
94
96
 
95
97
  ##
96
- # Recursively enumerates the sexp yielding to +block+ for every element.
98
+ # Recursively enumerates the sexp yielding to +block+ for every sub-Sexp.
97
99
  #
98
100
  # Returning :skip will stop traversing that subtree:
99
101
  #
@@ -122,7 +124,7 @@ class Sexp < Array # ZenTest FULL
122
124
  # Enumeratates the sexp yielding to +b+ when the node_type == +t+.
123
125
 
124
126
  def each_of_type t, &b
125
- return enum_for(:each_of_type) unless block_given?
127
+ return enum_for(:each_of_type, t) unless block_given?
126
128
 
127
129
  each_sexp do | sexp |
128
130
  sexp.each_of_type(t, &b)
@@ -131,7 +133,7 @@ class Sexp < Array # ZenTest FULL
131
133
  end
132
134
 
133
135
  ##
134
- # Recursively enumerates all sub-sexps skipping non-Sexp elements.
136
+ # Enumerates all sub-sexps skipping non-Sexp elements.
135
137
 
136
138
  def each_sexp
137
139
  return enum_for(:each_sexp) unless block_given?
@@ -289,11 +291,11 @@ class Sexp < Array # ZenTest FULL
289
291
  # the values without the node type.
290
292
 
291
293
  def sexp_body from = 1
292
- self.new.concat(self[from..-1] || [])
294
+ self.new._concat(self[from..-1] || [])
293
295
  end
294
296
 
295
297
  ##
296
- # Returns the Sexp body, ie the values without the node type.
298
+ # Sets the Sexp body to new content.
297
299
 
298
300
  def sexp_body= v
299
301
  self[1..-1] = v
@@ -362,6 +364,14 @@ class Sexp < Array # ZenTest FULL
362
364
  end
363
365
 
364
366
  alias to_s inspect # :nodoc:
367
+
368
+ ##
369
+ # Return the value (last item) of a single element sexp (eg `s(:lit, 42)`).
370
+
371
+ def value
372
+ raise "multi item sexp" if size > 2
373
+ last
374
+ end
365
375
  end
366
376
 
367
377
  ##
@@ -34,7 +34,7 @@ require "sexp"
34
34
  class SexpProcessor
35
35
 
36
36
  # duh
37
- VERSION = "4.15.3"
37
+ VERSION = "4.16.0"
38
38
 
39
39
  ##
40
40
  # Automatically shifts off the Sexp type before handing the
@@ -36,6 +36,7 @@
36
36
  # 4 = sexp << => no
37
37
 
38
38
  class Sexp
39
+ # alias :_concat :concat in sexp.rb so we have access to the original
39
40
  alias :safe_idx :[]
40
41
  alias :safe_asgn :[]=
41
42
  alias :sexp_type= :sexp_type=
@@ -43,9 +44,10 @@ class Sexp
43
44
  alias :shift :shift
44
45
 
45
46
  def self.nuke_method name, level
47
+ return unless __strict >= level
46
48
  define_method name do |*args|
47
49
  raise "no mutation allowed on sexps: %s.%s %s" % [self, name, args]
48
- end if __strict >= level
50
+ end
49
51
  end
50
52
 
51
53
  def self.__strict
@@ -87,7 +89,7 @@ class Sexp
87
89
 
88
90
  nuke_method :collect!, 4
89
91
  nuke_method :compact!, 4
90
- # nuke_method :concat, 4 # HACK: using self.class.new.concat(...) for speed
92
+ nuke_method :concat, 4 # HACK: using self.class.new.concat(...) for speed
91
93
  nuke_method :flatten!, 4
92
94
  nuke_method :map!, 4
93
95
  nuke_method :pop, 4
@@ -111,7 +113,7 @@ class Sexp
111
113
  end
112
114
 
113
115
  def sexp_body from = 1
114
- self.new.concat(safe_idx(from..-1) || [])
116
+ self.new._concat(safe_idx(from..-1) || [])
115
117
  end
116
118
 
117
119
  def sexp_type= v
@@ -123,4 +125,24 @@ class Sexp
123
125
  end
124
126
  end unless Sexp.new.respond_to? :safe_asgn if ENV["STRICT_SEXP"]
125
127
 
128
+ if ENV["SP_DEBUG"] && !ENV["STRICT_SEXP"] then
129
+ class Sexp
130
+ mutators = %i[
131
+ []= clear collect! compact! concat delete delete_at
132
+ delete_if drop drop_while fill flatten! replace insert
133
+ keep_if map! pop push reject! reverse! rotate! select!
134
+ shift shuffle! slice! sort! sort_by! transpose uniq!
135
+ unshift
136
+ ]
137
+
138
+ mutators.each do |method|
139
+ define_method method do |*|
140
+ warn "Sexp modified by %p at %s" % [__method__, caller.first] if
141
+ $VERBOSE or (defined?(@hash) and @hash)
142
+ super
143
+ end
144
+ end
145
+ end
146
+ end
147
+
126
148
  # :startdoc:
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.8.0
4
+
5
+ - Unicode 14.0 (last release of 1.x)
6
+
3
7
  ## 1.7.0
4
8
 
5
9
  - Unicode 13
@@ -2,7 +2,7 @@
2
2
 
3
3
  Determines the monospace display width of a string in Ruby. Implementation based on [EastAsianWidth.txt](https://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: **13.0.0** (March 2020)
5
+ Unicode version: **14.0.0** (September 2021)
6
6
 
7
7
  Supported Rubies: **2.7**, **2.6**, **2.5**, **2.4**
8
8
 
@@ -1,7 +1,7 @@
1
1
  module Unicode
2
2
  module DisplayWidth
3
- VERSION = '1.7.0'
4
- UNICODE_VERSION = "13.0.0".freeze
3
+ VERSION = '1.8.0'
4
+ UNICODE_VERSION = "14.0.0"
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
@@ -28,7 +28,7 @@ module Brakeman
28
28
  # Accepts an array of filenames and paths with the following format and
29
29
  # returns a Regexp to match them:
30
30
  # * "path1/file1.rb" - Matches a specific filename in the project directory.
31
- # * "path1/" - Matches any path that conatains "path1" in the project directory.
31
+ # * "path1/" - Matches any path that contains "path1" in the project directory.
32
32
  # * "/path1/ - Matches any path that is rooted at "path1" in the project directory.
33
33
  #
34
34
  def self.regex_for_paths(paths)
@@ -26,7 +26,7 @@ class Brakeman::CheckDetailedExceptions < Brakeman::BaseCheck
26
26
  def check_detailed_exceptions
27
27
  tracker.controllers.each do |_name, controller|
28
28
  controller.methods_public.each do |method_name, definition|
29
- src = definition[:src]
29
+ src = definition.src
30
30
  body = src.body.last
31
31
  next unless body
32
32
 
@@ -10,7 +10,7 @@ class Brakeman::CheckEvaluation < Brakeman::BaseCheck
10
10
  #Process calls
11
11
  def run_check
12
12
  Brakeman.debug "Finding eval-like calls"
13
- calls = tracker.find_call :method => [:eval, :instance_eval, :class_eval, :module_eval]
13
+ calls = tracker.find_call methods: [:eval, :instance_eval, :class_eval, :module_eval], nested: true
14
14
 
15
15
  Brakeman.debug "Processing eval-like calls"
16
16
  calls.each do |call|
@@ -87,6 +87,16 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
87
87
  dangerous_interp?(first_arg) ||
88
88
  dangerous_string_building?(first_arg)
89
89
  end
90
+ when :capture2, :capture2e, :capture3
91
+ # Open3 capture methods can take a :stdin_data argument which is used as the
92
+ # the input to the called command so it is not succeptable to command injection.
93
+ # As such if the last argument is a hash (and therefore execution options) it
94
+ # should be ignored
95
+
96
+ args.pop if hash?(args.last) && args.length > 2
97
+ failure = include_user_input?(args) ||
98
+ dangerous_interp?(args) ||
99
+ dangerous_string_building?(args)
90
100
  else
91
101
  failure = include_user_input?(args) ||
92
102
  dangerous_interp?(args) ||
@@ -74,7 +74,7 @@ class Brakeman::CheckJSONParsing < Brakeman::BaseCheck
74
74
  warning_type = "Denial of Service"
75
75
  confidence = :medium
76
76
  gem_name = "#{name} gem"
77
- message = msg(msg_version(version, gem_name), " has a symbol creation vulnerablity. Upgrade to ")
77
+ message = msg(msg_version(version, gem_name), " has a symbol creation vulnerability. Upgrade to ")
78
78
 
79
79
  if version >= "1.7.0"
80
80
  confidence = :high
@@ -33,6 +33,7 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
33
33
  view = result[:call][2]
34
34
 
35
35
  if sexp? view and original? result
36
+ return if renderable?(view)
36
37
 
37
38
  if input = has_immediate_user_input?(view)
38
39
  if string_interp? view
@@ -94,4 +95,17 @@ class Brakeman::CheckRender < Brakeman::BaseCheck
94
95
  end
95
96
  end
96
97
  end
97
- end
98
+
99
+ def renderable? exp
100
+ return false unless call?(exp) and constant?(exp.target)
101
+
102
+ target_class_name = class_name(exp.target)
103
+ known_renderable_class?(target_class_name) or tracker.find_method(:render_in, target_class_name)
104
+ end
105
+
106
+ def known_renderable_class? class_name
107
+ klass = tracker.find_class(class_name)
108
+ return false if klass.nil?
109
+ klass.ancestor? :"ViewComponent::Base"
110
+ end
111
+ end
@@ -22,7 +22,19 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
22
22
  :find_by_sql, :maximum, :minimum, :pluck, :sum, :update_all]
23
23
  @sql_targets.concat [:from, :group, :having, :joins, :lock, :order, :reorder, :where] if tracker.options[:rails3]
24
24
  @sql_targets.concat [:find_by, :find_by!, :find_or_create_by, :find_or_create_by!, :find_or_initialize_by, :not] if tracker.options[:rails4]
25
- @sql_targets << :delete_by << :destroy_by if tracker.options[:rails6]
25
+
26
+ if tracker.options[:rails6]
27
+ @sql_targets.concat [:delete_by, :destroy_by, :rewhere, :reselect]
28
+
29
+ @sql_targets.delete :delete_all
30
+ @sql_targets.delete :destroy_all
31
+ end
32
+
33
+ if version_between?("6.1.0", "9.9.9")
34
+ @sql_targets.delete :order
35
+ @sql_targets.delete :reorder
36
+ @sql_targets.delete :pluck
37
+ end
26
38
 
27
39
  if version_between?("2.0.0", "3.9.9") or tracker.config.rails_version.nil?
28
40
  @sql_targets << :first << :last << :all
@@ -185,7 +197,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
185
197
  else
186
198
  check_find_arguments call.last_arg
187
199
  end
188
- when :where, :having, :find_by, :find_by!, :find_or_create_by, :find_or_create_by!, :find_or_initialize_by,:not, :delete_by, :destroy_by
200
+ when :where, :rewhere, :having, :find_by, :find_by!, :find_or_create_by, :find_or_create_by!, :find_or_initialize_by,:not, :delete_by, :destroy_by
189
201
  check_query_arguments call.arglist
190
202
  when :order, :group, :reorder
191
203
  check_order_arguments call.arglist
@@ -199,7 +211,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
199
211
  unsafe_sql? call.first_arg
200
212
  when :sql
201
213
  unsafe_sql? call.first_arg
202
- when :update_all, :select
214
+ when :update_all, :select, :reselect
203
215
  check_update_all_arguments call.args
204
216
  when *@connection_calls
205
217
  check_by_sql_arguments call.first_arg
@@ -572,13 +584,17 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
572
584
  end
573
585
 
574
586
  IGNORE_METHODS_IN_SQL = Set[:id, :merge_conditions, :table_name, :quoted_table_name,
575
- :quoted_primary_key, :to_i, :to_f, :sanitize_sql, :sanitize_sql_array,
587
+ :quoted_primary_key, :to_i, :to_f, :sanitize_sql, :sanitize_sql_array, :sanitize_sql_like,
576
588
  :sanitize_sql_for_assignment, :sanitize_sql_for_conditions, :sanitize_sql_hash,
577
589
  :sanitize_sql_hash_for_assignment, :sanitize_sql_hash_for_conditions,
578
590
  :to_sql, :sanitize, :primary_key, :table_name_prefix, :table_name_suffix,
579
591
  :where_values_hash, :foreign_key, :uuid
580
592
  ]
581
593
 
594
+ def ignore_methods_in_sql
595
+ @ignore_methods_in_sql ||= IGNORE_METHODS_IN_SQL + (tracker.options[:sql_safe_methods] || [])
596
+ end
597
+
582
598
  def safe_value? exp
583
599
  return true unless sexp? exp
584
600
 
@@ -589,10 +605,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
589
605
  if exp.method == :to_s or exp.method == :to_sym
590
606
  safe_value? exp.target
591
607
  else
592
- IGNORE_METHODS_IN_SQL.include? exp.method or
593
- quote_call? exp or
594
- arel? exp or
595
- exp.method.to_s.end_with? "_id"
608
+ ignore_call? exp
596
609
  end
597
610
  when :if
598
611
  safe_value? exp.then_clause and safe_value? exp.else_clause
@@ -607,6 +620,17 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
607
620
  end
608
621
  end
609
622
 
623
+ def ignore_call? exp
624
+ return unless call? exp
625
+
626
+ ignore_methods_in_sql.include? exp.method or
627
+ quote_call? exp or
628
+ arel? exp or
629
+ exp.method.to_s.end_with? "_id" or
630
+ number_target? exp or
631
+ date_target? exp
632
+ end
633
+
610
634
  QUOTE_METHODS = [:quote, :quote_column_name, :quoted_date, :quote_string, :quote_table_name]
611
635
 
612
636
  def quote_call? exp
@@ -695,4 +719,30 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
695
719
  active_record_models.include? klass
696
720
  end
697
721
  end
722
+
723
+ def number_target? exp
724
+ return unless call? exp
725
+
726
+ if number? exp.target
727
+ true
728
+ elsif call? exp.target
729
+ number_target? exp.target
730
+ else
731
+ false
732
+ end
733
+ end
734
+
735
+ DATE_CLASS = s(:const, :Date)
736
+
737
+ def date_target? exp
738
+ return unless call? exp
739
+
740
+ if exp.target == DATE_CLASS
741
+ true
742
+ elsif call? exp.target
743
+ date_target? exp.target
744
+ else
745
+ false
746
+ end
747
+ end
698
748
  end
@@ -32,7 +32,7 @@ class Brakeman::CheckVerbConfusion < Brakeman::BaseCheck
32
32
  return
33
33
  end
34
34
 
35
- process method[:src]
35
+ process method.src
36
36
  end
37
37
 
38
38
  def process_if exp