module Brakeman::Util
def all_literals? exp, expected_type = :array
def all_literals? exp, expected_type = :array node_type? exp, expected_type and exp.length > 1 and exp.all? { |e| e.is_a? Symbol or node_type? e, :lit, :str } end
def array? exp
def array? exp exp.is_a? Sexp and exp.node_type == :array end
def block? exp
def block? exp exp.is_a? Sexp and (exp.node_type == :block or exp.node_type == :rlist) end
def call? exp
def call? exp exp.is_a? Sexp and (exp.node_type == :call or exp.node_type == :safe_call) end
def camelize lower_case_and_underscored_word
Convert a string from "something_like_this" to "SomethingLikeThis"
def camelize lower_case_and_underscored_word lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } end
def class_name exp
Returns a class name as a Symbol.
def class_name exp case exp when Sexp case exp.node_type when :const, :colon3 exp.value when :lvar exp.value.to_sym when :colon2 "#{class_name(exp.lhs)}::#{exp.rhs}".to_sym when :self @current_class || @current_module || nil else exp end when Symbol exp when nil nil else exp end end
def constant? exp
def constant? exp node_type? exp, :const, :colon2, :colon3 end
def contains_class? exp
Returns true if the given _exp_ contains a :class node.
def contains_class? exp todo = [exp] until todo.empty? current = todo.shift if node_type? current, :class return true elsif sexp? current todo = current.sexp_body.concat todo end end false end
def cookies? exp
def cookies? exp recurse_check?(exp) { |child| child.node_type == :cookies or ALL_COOKIES.include? child } end
def dir_glob? exp
def dir_glob? exp exp = exp.block_call if node_type? exp, :iter return unless call? exp (exp.target == DIR_CONST and exp.method == :glob) or dir_glob? exp.target end
def false? exp
def false? exp exp.is_a? Sexp and (exp.node_type == :false or exp.node_type == :nil) end
def hash? exp
Check if _exp_ represents a hash: s(:hash, {...})
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
def hash_access hash, key
Get value from hash using key.
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
def hash_insert hash, key, value
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
def hash_iterate hash
end
end
names << value[1]
if symbol? key and key[1] == :name
hash_iterate(h) do |key, value|
names = []
h = Sexp.new(:hash, (:lit, :name), (:str, "bob"), (:lit, :name), (:str, "jane"))
For example:
and yields the key and value pairs to the given block.
(:hash, (:lit, :key), (:str, "value"))
Takes an Sexp like
def hash_iterate hash hash = remove_kwsplat(hash) 1.step(hash.length - 1, 2) do |i| yield hash[i], hash[i + 1] end end
def hash_values hash
def hash_values hash values = hash.each_sexp.each_slice(2).map do |_, value| value end Sexp.new(:array).concat(values).line(hash.line) end
def integer? exp
def integer? exp exp.is_a? Sexp and exp.node_type == :lit and exp[1].is_a? Integer end
def kwsplat? exp
def kwsplat? exp exp.is_a? Sexp and exp.node_type == :hash and exp[1].is_a? Sexp and exp[1].node_type == :kwsplat end
def literal? exp
def literal? exp exp.is_a? Sexp and LITERALS.include? exp.node_type end
def make_call target, method, *args
def make_call target, method, *args call = Sexp.new(:call, target, method) if args.empty? or args.first.empty? #nothing to do elsif node_type? args.first, :arglist call.concat args.first.sexp_body elsif args.first.node_type.is_a? Sexp #just a list of args call.concat args.first else call.concat args end call end
def node_type? exp, *types
def node_type? exp, *types exp.is_a? Sexp and types.include? exp.node_type end
def number? exp
def number? exp exp.is_a? Sexp and exp.node_type == :lit and exp[1].is_a? Numeric end
def params? exp
def params? exp recurse_check?(exp) { |child| child.node_type == :params or ALL_PARAMETERS.include? child } end
def pluralize word
def pluralize word if word.end_with? 's' word + 'es' else word + 's' end end
def rails_version
def rails_version @tracker.config.rails_version end
def recurse_check? exp, &check
def recurse_check? exp, &check if exp.is_a? Sexp return true if yield(exp) if call? exp if recurse_check? exp[1], &check return true elsif exp[2] == :[] return recurse_check? exp[1], &check end end end false end
def regexp? exp
def regexp? exp exp.is_a? Sexp and exp.node_type == :lit and exp[1].is_a? Regexp end
def remove_kwsplat exp
def remove_kwsplat exp if exp.any? { |e| node_type? e, :kwsplat } exp.reject { |e| node_type? e, :kwsplat } else exp end end
def request_headers? exp
def request_headers? exp return unless sexp? exp if exp[1] == REQUEST_ENV if exp.method == :[] if string? exp.first_arg # Only care about HTTP headers, which are prefixed by 'HTTP_' exp.first_arg.value.start_with?('HTTP_'.freeze) else true # request.env[something] end else false # request.env.something end else false end end
def request_value? exp
def request_value? exp params? exp or cookies? exp or request_headers? exp end
def result? exp
def result? exp exp.is_a? Sexp and exp.node_type == :result end
def safe_literal line = nil
def safe_literal line = nil s(:lit, :BRAKEMAN_SAFE_LITERAL).line(line || 0) end
def safe_literal? exp
def safe_literal? exp exp == SAFE_LITERAL end
def safe_literal_target? exp
def safe_literal_target? exp if call? exp safe_literal_target? exp.target else safe_literal? exp end end
def set_env_defaults
Adds params, session, and cookies to environment
def set_env_defaults @env[PARAMETERS] = PARAMS_SEXP @env[SESSION] = SESSION_SEXP @env[COOKIES] = COOKIES_SEXP end
def sexp? exp
def sexp? exp exp.is_a? Sexp end
def simple_literal? exp
def simple_literal? exp exp.is_a? Sexp and SIMPLE_LITERALS.include? exp.node_type end
def string? exp
def string? exp exp.is_a? Sexp and exp.node_type == :str end
def string_interp? exp
def string_interp? exp exp.is_a? Sexp and exp.node_type == :dstr end
def symbol? exp
def symbol? exp exp.is_a? Sexp and exp.node_type == :lit and exp[1].is_a? Symbol end
def template_path_to_name path
Convert path/filename to view name
def template_path_to_name path names = path.relative.split('/') names.last.gsub!(/(\.(html|js)\..*|\.(rhtml|haml|erb|slim))$/, '') if names.include? 'views' names[(names.index('views') + 1)..-1] else names end.join('/').to_sym end
def true? exp
def true? exp exp.is_a? Sexp and (exp.node_type == :true or exp.node_type == :lit or exp.node_type == :string) end
def underscore camel_cased_word
Convert a string from "Something::LikeThis" to "something/like_this"
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