Class: Contrast::Agent::Assess::Policy::Propagator::Insert

Inherits:
Base
  • Object
show all
Defined in:
lib/contrast/agent/assess/policy/propagator/insert.rb

Overview

Propagation that results in all the tags of the source being applied to the target at the point of insertion. The target’s preexisting tags are shifted to account for this insertion.

Class Method Summary collapse

Methods inherited from Base

find_source, tracked_value?

Class Method Details

.propagate(propagation_node, preshift, target) ⇒ Object

For the source, append its tags to the target. Once the tag is applied, shift it to the location of the insert Unlike additive propagation, this currently only supports one source We assume that insert changes the preshift target

propagation action required by this method.

Parameters:

Returns:

  • (Object)

    the target with the tags applied



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/contrast/agent/assess/policy/propagator/insert.rb', line 24

def propagate propagation_node, preshift, target
  return unless (properties = Contrast::Agent::Assess::Tracker.properties!(target))

  source = find_source(propagation_node.sources[1], preshift)

  patcher_target = propagation_node.targets[0]
  preshift_target = case patcher_target
                    when Contrast::Utils::ObjectShare::OBJECT_KEY
                      preshift.object
                    else
                      # this is hardly reached b/c insert supports only one source
                      # changed to second argument: string.insert[idx, string_to_insert]
                      # previously was args[int] => produces exception
                      preshift.args[1]
                    end

  # Find the first difference between the source to which
  # we inserted and the result. That is the insertion
  # point on which all tags need to be adjusted
  # If the insertion point is the end of the string, preshift length is returned
  # https://stackoverflow.com/questions/31714522/find-the-first-differing-character-between-two-strings-in-ruby
  insert_point = (0...preshift_target.length).find do |i|
    preshift_target[i] != target[i]
  end || preshift_target.length
  # Depending what's inserted, we might be wrong. For instance, inserting 'foo'
  # into 'asdfasdf' could result in 'asdfoofasdf'. we'd be off by one b/c of the 'f'
  insert_point = target.rindex(source, insert_point)
  overflow = insert_point...(insert_point + source.length)

  # handle shifting the inserted range
  properties.shift_tags([overflow])

  properties.copy_from(source, target, insert_point, propagation_node.untags)
  properties.cleanup_tags
end