Module: Brakeman::Util
- Included in:
- AliasProcessor, BaseCheck, BaseProcessor, OutputProcessor, Processor, Report, RescanReport
- Defined in:
- lib/brakeman/util.rb
Overview
This is a mixin containing utility methods.
Constant Summary collapse
- QUERY_PARAMETERS =
Sexp.new(:call, Sexp.new(:call, nil, :request, Sexp.new(:arglist)), :query_parameters, Sexp.new(:arglist))
- PATH_PARAMETERS =
Sexp.new(:call, Sexp.new(:call, nil, :request, Sexp.new(:arglist)), :path_parameters, Sexp.new(:arglist))
- REQUEST_PARAMETERS =
Sexp.new(:call, Sexp.new(:call, nil, :request, Sexp.new(:arglist)), :request_parameters, Sexp.new(:arglist))
- REQUEST_PARAMS =
Sexp.new(:call, Sexp.new(:call, nil, :request, Sexp.new(:arglist)), :parameters, Sexp.new(:arglist))
- REQUEST_ENV =
Sexp.new(:call, Sexp.new(:call, nil, :request, Sexp.new(:arglist)), :env, Sexp.new(:arglist))
- PARAMETERS =
Sexp.new(:call, nil, :params, Sexp.new(:arglist))
- COOKIES =
Sexp.new(:call, nil, :cookies, Sexp.new(:arglist))
- SESSION =
Sexp.new(:call, nil, :session, Sexp.new(:arglist))
- ALL_PARAMETERS =
Set[PARAMETERS, QUERY_PARAMETERS, PATH_PARAMETERS, REQUEST_PARAMETERS, REQUEST_PARAMS]
Instance Method Summary collapse
-
#array?(exp) ⇒ Boolean
Check if exp represents an array: s(:array, […]).
-
#call?(exp) ⇒ Boolean
Check if exp represents a method call: s(:call, …).
-
#camelize(lower_case_and_underscored_word) ⇒ Object
Convert a string from “something_like_this” to “SomethingLikeThis”.
-
#contains_class?(exp) ⇒ Boolean
Returns true if the given exp contains a :class node.
-
#context_for(warning, tracker = nil) ⇒ Object
Return array of lines surrounding the warning location from the original file.
- #cookies?(exp) ⇒ Boolean
-
#false?(exp) ⇒ Boolean
Check if exp represents a :false or :nil node.
-
#file_by_name(name, type, tracker = nil) ⇒ Object
Attempt to determine path to context file based on the reported name in the warning.
-
#file_for(warning, tracker = nil) ⇒ Object
Return file name related to given warning.
-
#hash?(exp) ⇒ Boolean
Check if exp represents a hash: s(:hash, …) This also includes pseudo hashes params, session, and cookies.
-
#hash_access(hash, key) ⇒ Object
Get value from hash using key.
-
#hash_insert(hash, key, value) ⇒ Object
Insert value into Hash Sexp.
-
#hash_iterate(hash) ⇒ Object
Takes an Sexp like (:hash, (:lit, :key), (:str, “value”)) and yields the key and value pairs to the given block.
-
#integer?(exp) ⇒ Boolean
Check if exp represents an Integer: s(:lit, …).
-
#node_type?(exp, *types) ⇒ Boolean
Check if exp is a Sexp and the node type matches one of the given types.
-
#number?(exp) ⇒ Boolean
Check if exp represents a number: s(:lit, …).
-
#params?(exp) ⇒ Boolean
Check if exp is a params hash.
-
#pluralize(word) ⇒ Object
Use ActiveSupport::Inflector to pluralize a word.
-
#regexp?(exp) ⇒ Boolean
Check if exp represents a Regexp: s(:lit, /…/).
- #request_env?(exp) ⇒ Boolean
-
#request_value?(exp) ⇒ Boolean
Check if exp is params, cookies, or request_env.
-
#result?(exp) ⇒ Boolean
Check if exp represents a result: s(:result, …).
-
#set_env_defaults ⇒ Object
Adds params, session, and cookies to environment so they can be replaced by their respective Sexps.
-
#sexp?(exp) ⇒ Boolean
Check if exp is a Sexp.
-
#string?(exp) ⇒ Boolean
Check if exp represents a String: s(:str, “…”).
-
#symbol?(exp) ⇒ Boolean
Check if exp represents a Symbol: s(:lit, :…).
-
#table_to_csv(table) ⇒ Object
rely on Terminal::Table to build the structure, extract the data out in CSV format.
-
#true?(exp) ⇒ Boolean
Check if exp represents a :true, :lit, or :string node.
- #truncate_table(str) ⇒ Object
-
#underscore(camel_cased_word) ⇒ Object
Convert a string from “Something::LikeThis” to “something/like_this”.
Instance Method Details
#array?(exp) ⇒ Boolean
Check if exp represents an array: s(:array, […])
117 118 119 |
# File 'lib/brakeman/util.rb', line 117 def array? exp exp.is_a? Sexp and exp.node_type == :array end |
#call?(exp) ⇒ Boolean
Check if exp represents a method call: s(:call, …)
132 133 134 |
# File 'lib/brakeman/util.rb', line 132 def call? exp exp.is_a? Sexp and exp.node_type == :call end |
#camelize(lower_case_and_underscored_word) ⇒ Object
Convert a string from “something_like_this” to “SomethingLikeThis”
Taken from ActiveSupport.
28 29 30 |
# File 'lib/brakeman/util.rb', line 28 def camelize lower_case_and_underscored_word lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } end |
#contains_class?(exp) ⇒ Boolean
Returns true if the given exp contains a :class node.
Useful for checking if a module is just a module or if it is a namespace.
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/brakeman/util.rb', line 226 def contains_class? exp todo = [exp] until todo.empty? current = todo.shift if node_type? current, :class return true elsif sexp? current todo = current[1..-1].concat todo end end false end |
#context_for(warning, tracker = nil) ⇒ Object
Return array of lines surrounding the warning location from the original file.
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
# File 'lib/brakeman/util.rb', line 318 def context_for warning, tracker = nil file = file_for warning, tracker context = [] return context unless warning.line and file and File.exist? file current_line = 0 start_line = warning.line - 5 end_line = warning.line + 5 start_line = 1 if start_line < 0 File.open file do |f| f.each_line do |line| current_line += 1 next if line.strip == "" if current_line > end_line break end if current_line >= start_line context << [current_line, line] end end end context end |
#cookies?(exp) ⇒ Boolean
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/brakeman/util.rb', line 186 def exp if exp.is_a? Sexp return true if exp.node_type == :cookies or exp == COOKIES if exp.node_type == :call if exp[1] return true elsif exp[2] == :[] return exp[1] end end end false end |
#false?(exp) ⇒ Boolean
Check if exp represents a :false or :nil node
164 165 166 167 |
# File 'lib/brakeman/util.rb', line 164 def false? exp exp.is_a? Sexp and (exp.node_type == :false or exp.node_type == :nil) end |
#file_by_name(name, type, tracker = nil) ⇒ Object
Attempt to determine path to context file based on the reported name in the warning.
For example,
file_by_name FileController #=> "/rails/root/app/controllers/file_controller.rb
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 |
# File 'lib/brakeman/util.rb', line 272 def file_by_name name, type, tracker = nil return nil unless name string_name = name.to_s name = name.to_sym unless type if string_name =~ /Controller$/ type = :controller elsif camelize(string_name) == string_name type = :model else type = :template end end path = tracker.[:app_path] case type when :controller if tracker.controllers[name] and tracker.controllers[name][:file] path = tracker.controllers[name][:file] else path += "/app/controllers/#{underscore(string_name)}.rb" end when :model if tracker.models[name] and tracker.models[name][:file] path = tracker.models[name][:file] else path += "/app/controllers/#{underscore(string_name)}.rb" end when :template if tracker.templates[name] and tracker.templates[name][:file] path = tracker.templates[name][:file] elsif string_name.include? " " name = string_name.split[0].to_sym path = file_for tracker, name, :template else path = nil end end path end |
#file_for(warning, tracker = nil) ⇒ Object
Return file name related to given warning. Uses warning.file
if it exists
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/brakeman/util.rb', line 243 def file_for warning, tracker = nil if tracker.nil? tracker = @tracker || self.tracker end if warning.file File. warning.file, tracker.[:app_path] else case warning.warning_set when :controller file_by_name warning.controller, :controller, tracker when :template file_by_name warning.template[:name], :template, tracker when :model file_by_name warning.model, :model, tracker when :warning file_by_name warning.class, nil, tracker else nil end end end |
#hash?(exp) ⇒ Boolean
Check if exp represents a hash: s(:hash, …) This also includes pseudo hashes params, session, and cookies.
109 110 111 112 113 114 |
# File 'lib/brakeman/util.rb', line 109 def hash? exp exp.is_a? Sexp and (exp.node_type == :hash or exp.node_type == :params or exp.node_type == :session or exp.node_type == :cookies) end |
#hash_access(hash, key) ⇒ Object
Get value from hash using key.
If key is a Symbol, it will be converted to a Sexp(:lit, key).
87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/brakeman/util.rb', line 87 def hash_access hash, key if key.is_a? Symbol key = Sexp.new(:lit, key) end if index = hash.find_index(key) and index > 0 return hash[index + 1] end nil end |
#hash_insert(hash, key, value) ⇒ Object
Insert value into Hash Sexp
69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/brakeman/util.rb', line 69 def hash_insert hash, key, value index = 1 hash_iterate hash.dup do |k,v| if k == key hash[index + 1] = value return hash end index += 2 end hash << key << value hash end |
#hash_iterate(hash) ⇒ Object
Takes an Sexp like (:hash, (:lit, :key), (:str, “value”)) and yields the key and value pairs to the given block.
For example:
h = Sexp.new(:hash, (:lit, :name), (:str, “bob”), (:lit, :name), (:str, “jane”)) names = [] hash_iterate(h) do |key, value|
if symbol? key and key[1] == :name
names << value[1]
end
end names #[“bob”]
62 63 64 65 66 |
# File 'lib/brakeman/util.rb', line 62 def hash_iterate hash 1.step(hash.length - 1, 2) do |i| yield hash[i], hash[i + 1] end end |
#integer?(exp) ⇒ Boolean
Check if exp represents an Integer: s(:lit, …)
142 143 144 |
# File 'lib/brakeman/util.rb', line 142 def integer? exp exp.is_a? Sexp and exp.node_type == :lit and exp[1].is_a? Integer end |
#node_type?(exp, *types) ⇒ Boolean
Check if exp is a Sexp and the node type matches one of the given types.
219 220 221 |
# File 'lib/brakeman/util.rb', line 219 def node_type? exp, *types exp.is_a? Sexp and types.include? exp.node_type end |
#number?(exp) ⇒ Boolean
Check if exp represents a number: s(:lit, …)
147 148 149 |
# File 'lib/brakeman/util.rb', line 147 def number? exp exp.is_a? Sexp and exp.node_type == :lit and exp[1].is_a? Numeric end |
#params?(exp) ⇒ Boolean
Check if exp is a params hash
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/brakeman/util.rb', line 170 def params? exp if exp.is_a? Sexp return true if exp.node_type == :params or ALL_PARAMETERS.include? exp if exp.node_type == :call if params? exp[1] return true elsif exp[2] == :[] return params? exp[1] end end end false end |
#pluralize(word) ⇒ Object
Use ActiveSupport::Inflector to pluralize a word.
44 45 46 |
# File 'lib/brakeman/util.rb', line 44 def pluralize word ActiveSupport::Inflector.pluralize word end |
#regexp?(exp) ⇒ Boolean
Check if exp represents a Regexp: s(:lit, /…/)
137 138 139 |
# File 'lib/brakeman/util.rb', line 137 def regexp? exp exp.is_a? Sexp and exp.node_type == :lit and exp[1].is_a? Regexp end |
#request_env?(exp) ⇒ Boolean
202 203 204 |
# File 'lib/brakeman/util.rb', line 202 def request_env? exp call? exp and (exp == REQUEST_ENV or exp[1] == REQUEST_ENV) end |
#request_value?(exp) ⇒ Boolean
Check if exp is params, cookies, or request_env
207 208 209 210 211 |
# File 'lib/brakeman/util.rb', line 207 def request_value? exp params? exp or exp or request_env? exp end |
#result?(exp) ⇒ Boolean
Check if exp represents a result: s(:result, …)
152 153 154 |
# File 'lib/brakeman/util.rb', line 152 def result? exp exp.is_a? Sexp and exp.node_type == :result end |
#set_env_defaults ⇒ Object
Adds params, session, and cookies to environment so they can be replaced by their respective Sexps.
101 102 103 104 105 |
# File 'lib/brakeman/util.rb', line 101 def set_env_defaults @env[PARAMETERS] = Sexp.new(:params) @env[SESSION] = Sexp.new(:session) @env[COOKIES] = Sexp.new(:cookies) end |
#sexp?(exp) ⇒ Boolean
Check if exp is a Sexp.
214 215 216 |
# File 'lib/brakeman/util.rb', line 214 def sexp? exp exp.is_a? Sexp end |
#string?(exp) ⇒ Boolean
Check if exp represents a String: s(:str, “…”)
122 123 124 |
# File 'lib/brakeman/util.rb', line 122 def string? exp exp.is_a? Sexp and exp.node_type == :str end |
#symbol?(exp) ⇒ Boolean
Check if exp represents a Symbol: s(:lit, :…)
127 128 129 |
# File 'lib/brakeman/util.rb', line 127 def symbol? exp exp.is_a? Sexp and exp.node_type == :lit and exp[1].is_a? Symbol end |
#table_to_csv(table) ⇒ Object
rely on Terminal::Table to build the structure, extract the data out in CSV format
366 367 368 369 370 371 372 |
# File 'lib/brakeman/util.rb', line 366 def table_to_csv table output = CSV.generate_line(table.headings.cells.map{|cell| cell.to_s.strip}) table.rows.each do |row| output << CSV.generate_line(row.cells.map{|cell| cell.to_s.strip}) end output end |
#true?(exp) ⇒ Boolean
Check if exp represents a :true, :lit, or :string node
157 158 159 160 161 |
# File 'lib/brakeman/util.rb', line 157 def true? exp exp.is_a? Sexp and (exp.node_type == :true or exp.node_type == :lit or exp.node_type == :string) end |
#truncate_table(str) ⇒ Object
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 |
# File 'lib/brakeman/util.rb', line 348 def truncate_table str @terminal_width ||= if $stdin && $stdin.tty? ::HighLine::SystemExtensions::terminal_size[0] else 80 end lines = str.lines lines.map do |line| if line.chomp.length > @terminal_width line[0..(@terminal_width - 3)] + ">>\n" else line end end.join end |
#underscore(camel_cased_word) ⇒ Object
Convert a string from “Something::LikeThis” to “something/like_this”
Taken from ActiveSupport.
35 36 37 38 39 40 41 |
# File 'lib/brakeman/util.rb', line 35 def underscore camel_cased_word camel_cased_word.to_s.gsub(/::/, '/'). gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). gsub(/([a-z\d])([A-Z])/,'\1_\2'). tr("-", "_"). downcase end |