Class: Sqreen::Rules::BindingAccessorMatcherCB

Inherits:
RuleCB show all
Defined in:
lib/sqreen/rules/binding_accessor_matcher_cb.rb

Overview

Callback that match on a list or matcher+binding accessor

Defined Under Namespace

Classes: MatcherElem

Constant Summary collapse

MAX_LENGTH =
1024 * 128

Constants inherited from RuleCB

RuleCB::DEFAULT_PAYLOAD

Constants included from CallCountable

CallCountable::COUNT_CALLS, CallCountable::FAILING, CallCountable::POST, CallCountable::PRE

Constants inherited from CB

CB::DEFAULT_PRIORITY

Instance Attribute Summary collapse

Attributes inherited from RuleCB

#block, #payload_tpl, #test

Attributes included from CallCountable

#call_count_interval, #call_counts

Attributes inherited from FrameworkCB

#framework

Attributes inherited from CB

#klass, #method, #overtimeable

Instance Method Summary collapse

Methods inherited from RuleCB

#advise_action, #overtime!, #priority, #record_event, #record_exception, #rule_name, #rulespack_id

Methods included from CallCountable

#count_callback_calls, #failing_with_count, #post_with_count, #pre_with_count

Methods included from Conditionable

#condition_callbacks, #failing_with_conditions, #post_with_conditions, #pre_with_conditions

Methods inherited from FrameworkCB

#record_observation, #whitelisted?

Methods inherited from CB

#failing?, #framework, #overtime!, #post?, #pre?, #priority, #to_s, #whitelisted?

Constructor Details

#initialize(klass, method, rule_hash) ⇒ BindingAccessorMatcherCB

Returns a new instance of BindingAccessorMatcherCB.



26
27
28
29
30
31
32
33
34
# File 'lib/sqreen/rules/binding_accessor_matcher_cb.rb', line 26

def initialize(klass, method, rule_hash)
  super(klass, method, rule_hash)
  @rules = []
  if @data.empty? || @data['values'].nil? || @data['values'].empty?
    msg = "no rules in data (had #{@data.keys})"
    raise Sqreen::Exception, msg
  end
  prepare_rules(@data['values'])
end

Instance Attribute Details

#rulesObject (readonly)

Returns the value of attribute rules.



16
17
18
# File 'lib/sqreen/rules/binding_accessor_matcher_cb.rb', line 16

def rules
  @rules
end

Instance Method Details

#pre(inst, args, budget = nil, &_block) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/sqreen/rules/binding_accessor_matcher_cb.rb', line 53

def pre(inst, args, budget = nil, &_block)
  finish = budget + Sqreen.time unless budget.nil?
  resol_cache = Hash.new do |hash, accessor|
    hash[accessor] = accessor.resolve(binding, framework, inst, args)
  end
  @rules.each do |id, accessors, matcher, matcher_ref|
    accessors.each do |accessor|
      val = resol_cache[accessor]
      val = [val] if val.is_a?(String)
      next unless val.respond_to?(:each)
      next if val.respond_to?(:seek)
      val.each do |v|
        return nil if !budget.nil? && Sqreen.time > finish
        next if !v.is_a?(String) || (!matcher.min_size.nil? && v.size < matcher.min_size)
        next if v.size > MAX_LENGTH
        next if matcher.match(v).nil?
        infos = {
          'id' => id,
          'binding_accessor' => accessor.expression,
          'matcher' => matcher_ref,
          'found' => v,
        }
        record_event(infos)
        return advise_action(:raise, :infos => infos)
      end
    end
  end
  nil
end

#prepare_rules(rules) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/sqreen/rules/binding_accessor_matcher_cb.rb', line 36

def prepare_rules(rules)
  accessors = Hash.new do |hash, key|
    hash[key] = BindingAccessor.new(key, true)
  end
  @rules = rules.map do |r|
    if r['binding_accessor'].empty?
      raise Sqreen::Exception, "no accessors #{r['id']}"
    end
    [
      r['id'],
      r['binding_accessor'].map { |expression| accessors[expression] },
      MatcherElem.new(r['matcher']),
      r['matcher']['value'],
    ]
  end
end