Module: Contrast::Utils::Assess::PropagationMethodUtils

Included in:
Agent::Assess::Policy::PropagationMethod
Defined in:
lib/contrast/utils/assess/propagation_method_utils.rb

Overview

This module will include all methods for some internal validations in the PropagationMethod module and some other module methods from the same place, so we can ease the main module

Constant Summary collapse

APPEND_ACTION =
'APPEND'
CENTER_ACTION =
'CENTER'
INSERT_ACTION =
'INSERT'
BUFFER_ACTION =
'BUFFER'
KEEP_ACTION =
'KEEP'
NEXT_ACTION =
'NEXT'
NOOP_ACTION =
'NOOP'
PREPEND_ACTION =
'PREPEND'
REPLACE_ACTION =
'REPLACE'
REMOVE_ACTION =
'REMOVE'
REVERSE_ACTION =
'REVERSE'
RESPONSE_ACTION =
'RESPONSE'
SPLAT_ACTION =
'SPLAT'
SPLIT_ACTION =
'SPLIT'
DB_WRITE_ACTION =
'DB_WRITE'
CUSTOM_ACTION =
'CUSTOM'
ZERO_LENGTH_ACTIONS =
[DB_WRITE_ACTION, CUSTOM_ACTION, KEEP_ACTION, REPLACE_ACTION, SPLAT_ACTION].cs__freeze
PROPAGATION_ACTIONS =
{
    APPEND_ACTION => Contrast::Agent::Assess::Policy::Propagator::Append,
    CENTER_ACTION => Contrast::Agent::Assess::Policy::Propagator::Center,
    INSERT_ACTION => Contrast::Agent::Assess::Policy::Propagator::Insert,
    KEEP_ACTION => Contrast::Agent::Assess::Policy::Propagator::Keep,
    NEXT_ACTION => Contrast::Agent::Assess::Policy::Propagator::Next,
    BUFFER_ACTION => Contrast::Agent::Assess::Policy::Propagator::Buffer,
    NOOP_ACTION => nil,
    PREPEND_ACTION => Contrast::Agent::Assess::Policy::Propagator::Prepend,
    REPLACE_ACTION => Contrast::Agent::Assess::Policy::Propagator::Replace,
    REMOVE_ACTION => Contrast::Agent::Assess::Policy::Propagator::Remove,
    REVERSE_ACTION => Contrast::Agent::Assess::Policy::Propagator::Reverse,
    RESPONSE_ACTION => Contrast::Agent::Assess::Policy::Propagator::Response,
    SPLAT_ACTION => Contrast::Agent::Assess::Policy::Propagator::Splat,
    SPLIT_ACTION => Contrast::Agent::Assess::Policy::Propagator::Split
}.cs__freeze

Instance Method Summary collapse

Instance Method Details

#appropriate_source?(propagation_node, propagation_data, preshift) ⇒ Boolean

A source is appropriate if it is available for propagation

Parameters:

Returns:

  • (Boolean)


149
150
151
152
153
# File 'lib/contrast/utils/assess/propagation_method_utils.rb', line 149

def appropriate_source? propagation_node, propagation_data, preshift
  return true if preshift

  propagation_node.use_original_object? && propagation_data&.object
end

#appropriate_target?(propagation_node, target) ⇒ Boolean

We cannot propagate to frozen things that have not been updated to work with our property tracking, unless they’re duplicable and the return. We probably shouldn’t propagate to frozen things at all, as they’re supposed to be immutable, but third parties do jenky things, so allow it as long as it is safe to do.

Parameters:

Returns:

  • (Boolean)

    if the target can be propagated to



132
133
134
135
136
137
# File 'lib/contrast/utils/assess/propagation_method_utils.rb', line 132

def appropriate_target? propagation_node, target
  # special handle Returns b/c we can do unfreezing magic during propagation
  return true if propagation_node.targets[0] == Contrast::Utils::ObjectShare::RETURN_KEY

  Contrast::Agent::Assess::Tracker.trackable?(target)
end

#can_propagate?(propagation_node, preshift, target, propagation_data) ⇒ Boolean

Before we do any work, we should check if we even need to. If the source and target of this patcher are not tracked, there’s no need to do anything. A copy of nothing is still nothing.

Parameters:

Returns:

  • (Boolean)


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/contrast/utils/assess/propagation_method_utils.rb', line 101

def can_propagate? propagation_node, preshift, target, propagation_data
  return false unless appropriate_target?(propagation_node, target)
  return true if Contrast::Utils::Assess::TrackingUtil.tracked?(target)
  return false unless appropriate_source?(propagation_node, propagation_data, preshift)

  propagation_node.sources.each do |source|
    case source
    when Contrast::Utils::ObjectShare::OBJECT_KEY
      source_object = if propagation_node.use_original_object?
                        propagation_data.object
                      else
                        preshift.object
                      end
      return true if Contrast::Utils::Assess::TrackingUtil.tracked?(source_object)
    else
      # has to be P, there's no ret source type (yet? ever?)
      return true if preshift.args && Contrast::Utils::Assess::TrackingUtil.tracked?(preshift.args[source])
    end
  end
  false
end

#determine_target(propagation_node, ret, object, args) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
# File 'lib/contrast/utils/assess/propagation_method_utils.rb', line 46

def determine_target propagation_node, ret, object, args
  target = propagation_node.targets[0]
  case target
  when Contrast::Utils::ObjectShare::OBJECT_KEY
    object
  when Contrast::Utils::ObjectShare::RETURN_KEY
    ret
  else
    args[target]
  end
end

#valid_length?(target, action) ⇒ Boolean

If the action required needs a length and the target does not have one, the length is not valid

Parameters:

  • target (Object)

    the thing to which to propagate

  • action (String)

    the name of the action taken during this propagation

Returns:

  • (Boolean)


79
80
81
82
83
84
85
86
87
# File 'lib/contrast/utils/assess/propagation_method_utils.rb', line 79

def valid_length? target, action
  return true if ZERO_LENGTH_ACTIONS.include?(action)

  if Contrast::Utils::DuckUtils.quacks_to?(target, :length)
    target.length != 0 # rubocop:disable Style/ZeroLengthPredicate
  else
    !target.to_s.empty?
  end
end

#valid_target?(target, propagation_node) ⇒ Boolean

Custom actions tend to be the more complex of our propagations. Often, the method has to make decisions about the target based on the context with which the method was called. As such, defer determining if the target is valid to that method.

In all other cases, a target is valid for propagation if it is not nil

Parameters:

Returns:

  • (Boolean)


68
69
70
71
72
# File 'lib/contrast/utils/assess/propagation_method_utils.rb', line 68

def valid_target? target, propagation_node
  return true if propagation_node.action == CUSTOM_ACTION

  !!target
end