contrast-agent 3.14.0 → 3.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +18 -15
  3. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.h +1 -0
  4. data/ext/cs__assess_string/cs__assess_string.c +24 -25
  5. data/ext/cs__assess_string/cs__assess_string.h +3 -1
  6. data/ext/cs__common/cs__common.c +4 -2
  7. data/ext/cs__common/cs__common.h +1 -1
  8. data/lib/contrast.rb +1 -1
  9. data/lib/contrast/agent/assess.rb +1 -0
  10. data/lib/contrast/agent/assess/contrast_event.rb +4 -12
  11. data/lib/contrast/agent/assess/finalizers/freeze.rb +3 -1
  12. data/lib/contrast/agent/assess/finalizers/hash.rb +45 -1
  13. data/lib/contrast/agent/assess/policy/patcher.rb +1 -1
  14. data/lib/contrast/agent/assess/policy/policy.rb +0 -2
  15. data/lib/contrast/agent/assess/policy/policy_scanner.rb +0 -1
  16. data/lib/contrast/agent/assess/policy/preshift.rb +7 -11
  17. data/lib/contrast/agent/assess/policy/propagation_method.rb +50 -33
  18. data/lib/contrast/agent/assess/policy/propagator/append.rb +8 -5
  19. data/lib/contrast/agent/assess/policy/propagator/base.rb +1 -1
  20. data/lib/contrast/agent/assess/policy/propagator/center.rb +9 -5
  21. data/lib/contrast/agent/assess/policy/propagator/database_write.rb +5 -3
  22. data/lib/contrast/agent/assess/policy/propagator/insert.rb +6 -3
  23. data/lib/contrast/agent/assess/policy/propagator/keep.rb +4 -1
  24. data/lib/contrast/agent/assess/policy/propagator/match_data.rb +6 -6
  25. data/lib/contrast/agent/assess/policy/propagator/next.rb +7 -5
  26. data/lib/contrast/agent/assess/policy/propagator/prepend.rb +8 -5
  27. data/lib/contrast/agent/assess/policy/propagator/remove.rb +8 -4
  28. data/lib/contrast/agent/assess/policy/propagator/replace.rb +5 -2
  29. data/lib/contrast/agent/assess/policy/propagator/reverse.rb +7 -5
  30. data/lib/contrast/agent/assess/policy/propagator/select.rb +15 -7
  31. data/lib/contrast/agent/assess/policy/propagator/splat.rb +14 -8
  32. data/lib/contrast/agent/assess/policy/propagator/split.rb +14 -8
  33. data/lib/contrast/agent/assess/policy/propagator/substitution.rb +30 -21
  34. data/lib/contrast/agent/assess/policy/propagator/trim.rb +11 -5
  35. data/lib/contrast/agent/assess/policy/source_method.rb +85 -58
  36. data/lib/contrast/agent/assess/policy/trigger/reflected_xss.rb +16 -11
  37. data/lib/contrast/agent/assess/policy/trigger/xpath.rb +1 -1
  38. data/lib/contrast/agent/assess/policy/trigger_method.rb +38 -15
  39. data/lib/contrast/agent/assess/policy/trigger_node.rb +14 -13
  40. data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +2 -1
  41. data/lib/contrast/agent/assess/properties.rb +2 -0
  42. data/lib/contrast/agent/assess/property/updated.rb +136 -0
  43. data/lib/contrast/agent/assess/tracker.rb +66 -0
  44. data/lib/contrast/agent/class_reopener.rb +7 -5
  45. data/lib/contrast/agent/middleware.rb +0 -1
  46. data/lib/contrast/agent/patching/policy/patcher.rb +13 -22
  47. data/lib/contrast/agent/patching/policy/policy.rb +1 -4
  48. data/lib/contrast/agent/response.rb +17 -6
  49. data/lib/contrast/agent/rewriter.rb +1 -3
  50. data/lib/contrast/agent/version.rb +1 -1
  51. data/lib/contrast/api/communication/messaging_queue.rb +1 -4
  52. data/lib/contrast/api/decorators/application_update.rb +2 -4
  53. data/lib/contrast/api/decorators/trace_event.rb +5 -5
  54. data/lib/contrast/components/app_context.rb +11 -9
  55. data/lib/contrast/components/config.rb +3 -13
  56. data/lib/contrast/components/contrast_service.rb +2 -2
  57. data/lib/contrast/config/application_configuration.rb +5 -2
  58. data/lib/contrast/config/service_configuration.rb +8 -2
  59. data/lib/contrast/configuration.rb +88 -47
  60. data/lib/contrast/extension/assess.rb +0 -2
  61. data/lib/contrast/extension/assess/array.rb +8 -5
  62. data/lib/contrast/extension/assess/erb.rb +6 -3
  63. data/lib/contrast/extension/assess/fiber.rb +9 -9
  64. data/lib/contrast/extension/assess/hash.rb +2 -3
  65. data/lib/contrast/extension/assess/kernel.rb +12 -5
  66. data/lib/contrast/extension/assess/marshal.rb +3 -2
  67. data/lib/contrast/extension/assess/regexp.rb +5 -4
  68. data/lib/contrast/extension/assess/string.rb +8 -10
  69. data/lib/contrast/framework/rack/patch/session_cookie.rb +12 -18
  70. data/lib/contrast/framework/rails/patch/assess_configuration.rb +4 -10
  71. data/lib/contrast/framework/rails/support.rb +2 -0
  72. data/lib/contrast/logger/application.rb +11 -3
  73. data/lib/contrast/utils/assess/tracking_util.rb +48 -3
  74. data/lib/contrast/utils/duck_utils.rb +0 -10
  75. data/lib/contrast/utils/env_configuration_item.rb +2 -1
  76. data/lib/contrast/utils/invalid_configuration_util.rb +21 -19
  77. data/lib/contrast/utils/string_utils.rb +10 -5
  78. data/resources/assess/policy.json +0 -10
  79. data/ruby-agent.gemspec +16 -15
  80. data/service_executables/VERSION +1 -1
  81. data/service_executables/linux/contrast-service +0 -0
  82. data/service_executables/mac/contrast-service +0 -0
  83. metadata +42 -21
  84. data/lib/contrast/agent/assess/finalizers/finalize.rb +0 -21
  85. data/lib/contrast/extension/assess/assess_extension.rb +0 -145
  86. data/lib/contrast/utils/freeze_util.rb +0 -32
@@ -16,6 +16,9 @@ module Contrast
16
16
  # copy tags from the param to the target in chunks of param size or less
17
17
  # if param is appended in space less than param length
18
18
  def propagate propagation_node, preshift, target
19
+ properties = Contrast::Agent::Assess::Tracker.properties(target)
20
+ return unless properties
21
+
19
22
  sources = propagation_node.sources
20
23
  source1 = find_source(sources[0], preshift)
21
24
  # Some appends have two args. If they don't this is probably something
@@ -25,25 +28,25 @@ module Contrast
25
28
  # if the object and the return are the same length just copy the tags
26
29
  # from the object(since nothing from args was added to return)
27
30
  if source1.length == target.length
28
- target.cs__copy_from(source1, 0, propagation_node.untags)
31
+ properties.copy_from(source1, target, 0, propagation_node.untags)
29
32
  else
30
33
  # find original in the target, copy tags to the new position in
31
34
  # target
32
35
  original_start_index = target.index(source1)
33
- target.cs__copy_from(source1, original_start_index, propagation_node.untags)
36
+ properties.copy_from(source1, target, original_start_index, propagation_node.untags)
34
37
 
35
38
  start = original_start_index + source1.length
36
39
  while start < target.length
37
- target.cs__copy_from(source2, start, propagation_node.untags)
40
+ properties.copy_from(source2, target, start, propagation_node.untags)
38
41
  start += source2.length
39
42
  next unless start > target.length
40
43
 
41
- target.cs__properties.tags_at(start - source2.length).each do |tag|
44
+ properties.tags_at(start - source2.length).each do |tag|
42
45
  tag.update_end(target.length)
43
46
  end
44
47
  end
45
48
  end
46
- target.cs__properties.cleanup_tags
49
+ properties.cleanup_tags
47
50
  end
48
51
  end
49
52
  end
@@ -22,7 +22,7 @@ module Contrast
22
22
  end
23
23
 
24
24
  def tracked_value? value
25
- Contrast::Utils::DuckUtils.quacks_to?(value, :cs__tracked?) && value.cs__tracked?
25
+ Contrast::Agent::Assess::Tracker.tracked?(value)
26
26
  end
27
27
 
28
28
  def propagate _propagation_node, _preshift, _target
@@ -12,19 +12,22 @@ module Contrast
12
12
  class Center < Contrast::Agent::Assess::Policy::Propagator::Base
13
13
  class << self
14
14
  def propagate propagation_node, preshift, target
15
+ properties = Contrast::Agent::Assess::Tracker.properties(target)
16
+ return unless properties
17
+
15
18
  sources = propagation_node.sources
16
19
  source1 = find_source(sources[0], preshift)
17
20
 
18
21
  if source1.length == target.length
19
- target.cs__copy_from(source1, 0, propagation_node.untags)
20
- target.cs__properties.cleanup_tags
22
+ properties.copy_from(source1, target, 0, propagation_node.untags)
23
+ properties.cleanup_tags
21
24
  return
22
25
  end
23
26
 
24
27
  # find original in the target, copy tags to the new position in target
25
28
  original_start_index = target[0..target.length / 2 + 1].rindex(source1)
26
29
  original_start_index ||= 1
27
- target.cs__copy_from(source1, original_start_index, propagation_node.untags)
30
+ properties.copy_from(source1, target, original_start_index, propagation_node.untags)
28
31
 
29
32
  return unless sources[1]
30
33
 
@@ -54,12 +57,13 @@ module Contrast
54
57
  end
55
58
 
56
59
  def iterate_tags target, propagation_node, source, start, stop
60
+ properties = Contrast::Agent::Assess::Tracker.properties(target)
57
61
  while start < stop
58
- target.cs__copy_from(source, start, propagation_node.untags)
62
+ properties.copy_from(source, target, start, propagation_node.untags)
59
63
  start += source.length
60
64
  next unless start > stop
61
65
 
62
- target.cs__properties.tags_at(start - source.length).each do |tag|
66
+ properties.tags_at(start - source.length).each do |tag|
63
67
  tag.update_end(stop)
64
68
  end
65
69
  end
@@ -31,12 +31,15 @@ module Contrast
31
31
  next unless value
32
32
  next if known_tainted&.include?(key)
33
33
 
34
+ properties = Contrast::Agent::Assess::Tracker.properties(value)
35
+ next unless properties
36
+
34
37
  # TODO: RUBY-540 handle sanitization, handle nested objects
35
38
  Contrast::Agent::Assess::Policy::PropagationMethod.apply_tags(propagation_node, value)
36
- value.cs__properties.build_event(propagation_node, value, preshift.object, target, preshift.args)
39
+ properties.build_event(propagation_node, value, preshift.object, target, preshift.args)
37
40
  next unless tracked_value?(value)
38
41
 
39
- tainted_columns[key] = value.cs__properties
42
+ tainted_columns[key] = properties
40
43
  end
41
44
  end
42
45
 
@@ -45,7 +48,6 @@ module Contrast
45
48
  if known_tainted
46
49
  known_tainted.concat(tainted_columns.keys)
47
50
  else
48
- class_type.send(:include, Contrast::Extension::Assess::AssessExtension) unless class_type < Contrast::Extension::Assess::AssessExtension
49
51
  ASSESS.tainted_columns[class_name] = tainted_columns.keys
50
52
  end
51
53
 
@@ -16,6 +16,9 @@ module Contrast
16
16
  # Unlike additive propagation, this currently only supports one source
17
17
  # We assume that insert changes the preshift target
18
18
  def propagate propagation_node, preshift, target
19
+ properties = Contrast::Agent::Assess::Tracker.properties(target)
20
+ return unless properties
21
+
19
22
  source = find_source(propagation_node.sources[0], preshift)
20
23
 
21
24
  patcher_target = propagation_node.targets[0]
@@ -38,10 +41,10 @@ module Contrast
38
41
  overflow = insert_point...(insert_point + source.length)
39
42
 
40
43
  # handle shifting the inserted range
41
- target.cs__properties.shift_tags([overflow])
44
+ properties.shift_tags([overflow])
42
45
 
43
- target.cs__copy_from(source, insert_point, propagation_node.untags)
44
- target.cs__properties.cleanup_tags
46
+ properties.copy_from(source, target, insert_point, propagation_node.untags)
47
+ properties.cleanup_tags
45
48
  end
46
49
  end
47
50
  end
@@ -14,8 +14,11 @@ module Contrast
14
14
  # Keep means the tags just pass from the source to the target
15
15
  # as is.
16
16
  def propagate propagation_node, preshift, target
17
+ properties = Contrast::Agent::Assess::Tracker.properties(target)
18
+ return unless properties
19
+
17
20
  source = find_source(propagation_node.sources[0], preshift)
18
- target.cs__copy_from(source, 0, propagation_node.untags)
21
+ properties.copy_from(source, target, 0, propagation_node.untags)
19
22
  end
20
23
  end
21
24
  end
@@ -67,18 +67,18 @@ module Contrast
67
67
  def square_bracket_single argument_index, preshift, return_value, propagation_node
68
68
  original_start_index = preshift.object.begin(argument_index)
69
69
  original_end_index = preshift.object.end(argument_index)
70
- original_properties = preshift.object.cs__properties
70
+ original_properties = Contrast::Agent::Assess::Tracker.properties(preshift.object)
71
71
  applicable_tags = original_properties.tags_at_range(original_start_index...original_end_index)
72
72
  return if applicable_tags.empty?
73
73
 
74
+ return_properties = Contrast::Agent::Assess::Tracker.properties(return_value)
74
75
  applicable_tags.each do |tag_name, tag_ranges|
75
- return_value.cs__properties.set_tags(tag_name, tag_ranges)
76
+ return_properties.set_tags(tag_name, tag_ranges)
76
77
  end
77
- preshift.object.cs__properties.events.each do |event|
78
- return_value.cs__properties.add_event(event)
78
+ original_properties.events.each do |event|
79
+ return_properties.add_event(event)
79
80
  end
80
- return_value.cs__properties.build_event(
81
- propagation_node, return_value, preshift.object, return_value, preshift.args)
81
+ return_properties.build_event(propagation_node, return_value, preshift.object, return_value, preshift.args)
82
82
  end
83
83
  end
84
84
  end
@@ -15,23 +15,25 @@ module Contrast
15
15
  # String has some silly methods like next. Basically, this flips a
16
16
  # character in a predictable manner
17
17
  def propagate propagation_node, preshift, target
18
- source = find_source(propagation_node.sources[0], preshift)
18
+ properties = Contrast::Agent::Assess::Tracker.properties(target)
19
+ return unless properties
19
20
 
20
- target.cs__copy_from(source, 0, propagation_node.untags)
21
+ source = find_source(propagation_node.sources[0], preshift)
22
+ properties.copy_from(source, target, 0, propagation_node.untags)
21
23
 
22
24
  # this means the char that was shifted overflowed and created new
23
25
  # chars (i.e 'z' "wraps" to create 'aa' )
24
26
  unless target.length == source.length
25
- target.cs__copy_from(source, 0, propagation_node.untags)
27
+ properties.copy_from(source, target, 0, propagation_node.untags)
26
28
 
27
29
  first_difference = (0...source.length).find { |i| source[i] != target[i] } || source.length
28
30
 
29
- target.cs__properties.tags_at(first_difference).each do |tag|
31
+ properties.tags_at(first_difference).each do |tag|
30
32
  tag.shift_end(target.length - source.length)
31
33
  end
32
34
  end
33
35
 
34
- target.cs__properties.cleanup_tags
36
+ properties.cleanup_tags
35
37
  end
36
38
  end
37
39
  end
@@ -14,6 +14,9 @@ module Contrast
14
14
  # For the source, prepend its tags to the target. It's basically the
15
15
  # opposite of append. :-P
16
16
  def propagate propagation_node, preshift, target
17
+ properties = Contrast::Agent::Assess::Tracker.properties(target)
18
+ return unless properties
19
+
17
20
  sources = propagation_node.sources
18
21
  # source1 is the copy of the thing being prepended to
19
22
  source1 = find_source(sources[0], preshift)
@@ -26,25 +29,25 @@ module Contrast
26
29
  # tags from the object(since nothing from args was added to
27
30
  # return)
28
31
  if source1.length == target.length
29
- target.cs__copy_from(source1, 0, propagation_node.untags)
32
+ properties.copy_from(source1, target, 0, propagation_node.untags)
30
33
  else
31
34
  # find original in the target, copy tags to the new position in target
32
- target.cs__copy_from(source1, original_start_index, propagation_node.untags)
35
+ properties.copy_from(source1, target, original_start_index, propagation_node.untags)
33
36
  # then we add the tags from the thing prepended to the start
34
37
  # of the target
35
38
  start = 0
36
39
  while start < original_start_index
37
- target.cs__copy_from(source2, start, propagation_node.untags)
40
+ properties.copy_from(source2, target, start, propagation_node.untags)
38
41
  start += source2.length
39
42
  next unless start > original_start_index
40
43
 
41
- target.cs__properties.tags_at(start - source2.length).each do |tag|
44
+ properties.tags_at(start - source2.length).each do |tag|
42
45
  tag.update_end(original_start_index)
43
46
  end
44
47
  end
45
48
  end
46
49
  # and finally merge the tags if any overlap.
47
- target.cs__properties.cleanup_tags
50
+ properties.cleanup_tags
48
51
  end
49
52
  end
50
53
  end
@@ -17,15 +17,19 @@ module Contrast
17
17
  # Once the tag is applied, remove the section that was removed by the delete.
18
18
  # Unlike additive propagation, this currently only supports one source
19
19
  def propagate propagation_node, preshift, target
20
- source = find_source(propagation_node.sources[0], preshift)
21
-
22
- target.cs__copy_from(source, 0, propagation_node.untags)
20
+ properties = Contrast::Agent::Assess::Tracker.properties(target)
21
+ return unless properties
23
22
 
23
+ source = find_source(propagation_node.sources[0], preshift)
24
+ properties.copy_from(source, target, 0, propagation_node.untags)
24
25
  source_chars = source.is_a?(String) ? source.chars : source.string.chars
25
26
  handle_removal(source_chars, target)
26
27
  end
27
28
 
28
29
  def handle_removal source_chars, target
30
+ properties = Contrast::Agent::Assess::Tracker.properties(target)
31
+ return unless properties
32
+
29
33
  source_idx = 0
30
34
 
31
35
  target_chars = target.chars
@@ -60,7 +64,7 @@ module Contrast
60
64
  remove_ranges << (source_idx...source_chars.length) if source_idx != source_chars.length
61
65
 
62
66
  # handle deleting the removed ranges
63
- target.cs__properties.delete_tags_at_ranges(remove_ranges)
67
+ properties.delete_tags_at_ranges(remove_ranges)
64
68
  end
65
69
  end
66
70
  end
@@ -14,9 +14,12 @@ module Contrast
14
14
  # Replace means we're replacing the target w/ the source. Anything
15
15
  # on the source should be passed to the target.
16
16
  def propagate propagation_node, preshift, target
17
+ properties = Contrast::Agent::Assess::Tracker.properties(target)
18
+ return unless properties
19
+
17
20
  source = find_source(propagation_node.sources[0], preshift)
18
- target.cs__properties.clear_tags
19
- target.cs__copy_from(source, 0, propagation_node.untags)
21
+ properties.clear_tags
22
+ properties.copy_from(source, target, 0, propagation_node.untags)
20
23
  end
21
24
  end
22
25
  end
@@ -13,13 +13,15 @@ module Contrast
13
13
  class Reverse < Contrast::Agent::Assess::Policy::Propagator::Base
14
14
  class << self
15
15
  def propagate propagation_node, preshift, target
16
- source = find_source(propagation_node.sources[0], preshift)
16
+ properties = Contrast::Agent::Assess::Tracker.properties(target)
17
+ return unless properties
17
18
 
18
- target.cs__copy_from(source, 0, propagation_node.untags)
19
+ source = find_source(propagation_node.sources[0], preshift)
20
+ properties.copy_from(source, target, 0, propagation_node.untags)
19
21
 
20
22
  length = target.length
21
- target.cs__properties.tag_keys.each do |key|
22
- tags = target.cs__properties.fetch_tag(key)
23
+ properties.tag_keys.each do |key|
24
+ tags = properties.fetch_tag(key)
23
25
  tags.each do |tag|
24
26
  new_end = length - tag.start_idx
25
27
  new_start = new_end - tag.length
@@ -27,7 +29,7 @@ module Contrast
27
29
  end
28
30
  end
29
31
 
30
- target.cs__properties.cleanup_tags
32
+ properties.cleanup_tags
31
33
  end
32
34
  end
33
35
  end
@@ -14,6 +14,9 @@ module Contrast
14
14
  class Select
15
15
  class << self
16
16
  def select_tagger patcher, preshift, ret, _block
17
+ properties = Contrast::Agent::Assess::Tracker.properties(ret)
18
+ return unless properties
19
+
17
20
  source = preshift.object
18
21
  args = preshift.args
19
22
 
@@ -21,12 +24,17 @@ module Contrast
21
24
  # Additionally, an empty string is returned when the starting index for
22
25
  # a character range is at the end of the string. Let's just skip that
23
26
  # and only track a string that has length
24
- return unless source.cs__tracked? && ret && !ret.empty?
27
+ unless ret &&
28
+ !ret.empty? &&
29
+ Contrast::Agent::Assess::Tracker.tracked?(source)
30
+ return
31
+ end
25
32
 
26
- source.cs__properties.events.each do |event|
27
- ret.cs__properties.events << event
33
+ source_properties = Contrast::Agent::Assess::Tracker.properties(source)
34
+ source_properties.events.each do |event|
35
+ properties.events << event
28
36
  end
29
- ret.cs__properties.build_event(
37
+ properties.build_event(
30
38
  patcher,
31
39
  ret,
32
40
  source,
@@ -36,10 +44,10 @@ module Contrast
36
44
  range = determine_select_range(source, args)
37
45
  return unless range
38
46
 
39
- tags = source.cs__properties.tags_at_range(range)
40
- ret.cs__properties.clear_tags
47
+ tags = source_properties.tags_at_range(range)
48
+ properties.clear_tags
41
49
  tags.each_pair do |key, value|
42
- ret.cs__properties.set_tags(key, value)
50
+ properties.set_tags(key, value)
43
51
  end
44
52
  ret
45
53
  end
@@ -17,11 +17,11 @@ module Contrast
17
17
  propagation_node.sources.each do |source|
18
18
  case source
19
19
  when Contrast::Utils::ObjectShare::OBJECT_KEY
20
- tracked_inputs << preshift.object if preshift.object.cs__tracked?
20
+ tracked_inputs << preshift.object if Contrast::Agent::Assess::Tracker.tracked?(preshift.object)
21
21
  else
22
22
  arg = preshift.args[source]
23
23
  if arg.is_a?(String)
24
- tracked_inputs << arg if arg.cs__tracked?
24
+ tracked_inputs << arg if Contrast::Agent::Assess::Tracker.tracked?(arg)
25
25
  elsif Contrast::Utils::DuckUtils.iterable_hash?(arg)
26
26
  arg.each_pair do |key, value|
27
27
  tracked_inputs << key if tracked_value?(key)
@@ -36,19 +36,25 @@ module Contrast
36
36
  end
37
37
 
38
38
  splat_tags(tracked_inputs, target)
39
- target.cs__properties.cleanup_tags
39
+ Contrast::Agent::Assess::Tracker.properties(target).cleanup_tags
40
40
  end
41
41
 
42
42
  def splat_tags tracked_inputs, target
43
43
  return if tracked_inputs.empty?
44
44
 
45
+ properties = Contrast::Agent::Assess::Tracker.properties(target)
46
+ return unless properties
47
+
45
48
  tracked_inputs.each do |input|
46
- unless input == target
47
- input.cs__properties.events.each do |event|
48
- target.cs__properties.events << event
49
- end
49
+ input_properties = Contrast::Agent::Assess::Tracker.properties(input)
50
+ next unless input_properties
51
+
52
+ properties.splat_from(input, target)
53
+ next if input == target
54
+
55
+ input_properties.events.each do |event|
56
+ properties.events << event
50
57
  end
51
- input.cs__splat_tags(target)
52
58
  end
53
59
  end
54
60
  end
@@ -53,17 +53,20 @@ module Contrast
53
53
  target.each do |elem|
54
54
  elem_length = elem.length
55
55
  range = current_index...(current_index + elem_length)
56
- tags = source.cs__properties.tags_at_range(range)
56
+ elem_properties = Contrast::Agent::Assess::Tracker.properties(elem)
57
+ next unless elem_properties
57
58
 
58
- elem.cs__properties.clear_tags
59
+ source_properties = Contrast::Agent::Assess::Tracker.properties(source)
60
+ tags = source_properties.tags_at_range(range)
61
+ elem_properties.clear_tags
59
62
  tags.each_pair do |key, value|
60
- elem.cs__properties.set_tags(key, value)
63
+ elem_properties.set_tags(key, value)
61
64
  end
62
- source.cs__properties.events.each do |event|
63
- elem.cs__properties.add_event(event)
65
+ source_properties.events.each do |event|
66
+ elem_properties.add_event(event)
64
67
  end
65
- elem.cs__properties.build_event(propagation_node, elem, preshift.object, target, preshift.args, 0)
66
- elem.cs__properties.add_properties(propagation_node.properties)
68
+ elem_properties.build_event(propagation_node, elem, preshift.object, target, preshift.args, 0)
69
+ elem_properties.add_properties(propagation_node.properties)
67
70
  current_index = current_index + elem_length + separator_length
68
71
  end
69
72
  nil
@@ -125,8 +128,11 @@ module Contrast
125
128
  index = SPLIT_TRACKER.get(:split_index)&.fetch(depth)
126
129
  return unless index
127
130
 
131
+ properties = Contrast::Agent::Assess::Tracker.properties(target)
132
+ return unless properties
133
+
128
134
  true_source = source[index]
129
- target.cs__copy_from(true_source)
135
+ properties.copy_from(true_source, target)
130
136
  rescue StandardError => e
131
137
  logger.warn('Unable to track within split context', e)
132
138
  ensure