class Sqreen::Rules::ArgumentFilter

Constants

MAX_DEPTH

Public Class Methods

new(rule) click to toggle source
# File lib/sqreen/rules/execjs_cb.rb, line 162
def initialize(rule)
  @conditions = rule.fetch(Attrs::CONDITIONS, {})
  build_arg_requirements rule
end

Private Class Methods

hash_val_included(needed, haystack, min_length = 8, max_depth = 20) click to toggle source
# File lib/sqreen/rules/execjs_cb.rb, line 217
def hash_val_included(needed, haystack, min_length = 8, max_depth = 20)
  new_obj = {}
  insert = []
  to_do = haystack.map { |k, v| [new_obj, k, v, 0] }
  until to_do.empty?
    where, key, value, deepness = to_do.pop
    safe_key = key.is_a?(Integer) ? key : key.to_s
    if value.is_a?(Hash) && deepness < max_depth
      val = {}
      insert << [where, safe_key, val]
      to_do += value.map { |k, v| [val, k, v, deepness + 1] }
    elsif value.is_a?(Array) && deepness < max_depth
      val = []
      insert << [where, safe_key, val]
      i = -1
      to_do += value.map { |v| [val, i += 1, v, deepness + 1] }
    elsif deepness >= max_depth # if we are after max_depth don't try to filter
      insert << [where, safe_key, value]
    else
      v = value.to_s
      if v.size >= min_length && ConditionEvaluator.str_include?(needed.to_s, v)
        case where
        when Array
          where << value
        else
          where[safe_key] = value
        end
      end
    end
  end
  insert.reverse.each do |wh, ikey, ival|
    case wh
    when Array
      wh << ival unless ival.respond_to?(:empty?) && ival.empty?
    else
      wh[ikey] = ival unless ival.respond_to?(:empty?) && ival.empty?
    end
  end
  new_obj
end

Public Instance Methods

build_arg_requirements(rule) click to toggle source
# File lib/sqreen/rules/execjs_cb.rb, line 190
def build_arg_requirements(rule)
  @ba_expressions = {}
  callbacks = rule[Attrs::CALLBACKS]
  callbacks.each do |name, args_or_func|
    next unless args_or_func.is_a?(Array)
    args_bas = args_or_func[0..-2] unless args_or_func.empty?
    @ba_expressions[name] =
      ExecJSCB.build_accessors(args_bas).map(&:expression)
  end
end
filter(cbname, arguments) click to toggle source
# File lib/sqreen/rules/execjs_cb.rb, line 167
def filter(cbname, arguments)
  condition = @conditions[cbname]
  return arguments if condition.nil? || @ba_expressions[cbname].nil?

  each_hash_val_include(condition) do |needle, haystack, min_length|
    # We could actually run the binding accessor expression here.
    needed_idx = @ba_expressions[cbname].index(needle)
    next unless needed_idx

    haystack_idx = @ba_expressions[cbname].index(haystack)
    next unless haystack_idx

    arguments[haystack_idx] = ArgumentFilter.hash_val_included(
      arguments[needed_idx],
      arguments[haystack_idx],
      min_length.to_i,
      MAX_DEPTH
    )
  end

  arguments
end

Private Instance Methods

each_hash_val_include(condition, depth = 10) { |values| ... } click to toggle source
# File lib/sqreen/rules/execjs_cb.rb, line 203
def each_hash_val_include(condition, depth = 10)
  return if depth <= 0
  condition.each do |key, values|
    if key == ConditionEvaluator::HASH_INC_OPERATOR
      yield values
    else
      values.map do |v|
        each_hash_val_include(v, depth - 1) { |vals| yield vals } if v.is_a?(Hash)
      end
    end
  end
end