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
@@ -11,7 +11,7 @@ module Contrast
11
11
  access_component :logging
12
12
 
13
13
  UTF8 = 'utf-8'
14
- HTTP_PREFIX = 'HTTP-'
14
+ HTTP_PREFIX = 'HTTP_'
15
15
 
16
16
  # Convenience method. We assume that we're working on Strings or tags
17
17
  # String representations of things. To that end, we'll to_s anything
@@ -69,6 +69,10 @@ module Contrast
69
69
  # Given a string return a normalized version of that string.
70
70
  # Keys are memoized so that the normalization process doesn't need
71
71
  # to happen every time.
72
+ #
73
+ # @param str [String] the String to normalize
74
+ # @return [String] a copy of the given String, upper cased, trimmed,
75
+ # dashes replaced with underscore, and HTTP trimmed
72
76
  def self.normalized_key str
73
77
  return nil unless str
74
78
 
@@ -77,10 +81,11 @@ module Contrast
77
81
  if @_normalized_keys.key?(str)
78
82
  @_normalized_keys[str]
79
83
  else
80
- up = str.upcase.strip
81
- up = up.gsub(/[_-]/, '-')
82
- up = up[5..-1] if up.start_with?(HTTP_PREFIX)
83
- @_normalized_keys[str] = up
84
+ upped = str.upcase
85
+ stripped = upped.strip! || upped
86
+ trimmed = stripped.tr!('-', '_') || stripped
87
+ cut = trimmed.start_with?(HTTP_PREFIX) ? trimmed[5..-1] : trimmed
88
+ @_normalized_keys[str] = cut
84
89
  end
85
90
  end
86
91
  end
@@ -1,14 +1,4 @@
1
1
  {
2
- "tracked_classes": [
3
- "ActionDispatch::Http::UploadedFile",
4
- "Fiber",
5
- "Symbol",
6
- "Pathname",
7
- "File",
8
- "MatchData",
9
- "URI::Generic",
10
- "Rack::File::Iterator"
11
- ],
12
2
  "sources":[
13
3
  {
14
4
  "class_name":"Rack::Request",
@@ -2,20 +2,6 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require_relative './lib/contrast/agent/version'
5
- require 'bundler'
6
- # https://github.com/grpc/grpc/issues/21514#issuecomment-581417788
7
- module BundlerHack
8
- def __materialize__
9
- if name == 'google-protobuf'
10
- Bundler.settings.temporary(force_ruby_platform: true) do
11
- super
12
- end
13
- else
14
- super
15
- end
16
- end
17
- end
18
- Bundler::LazySpecification.prepend(BundlerHack)
19
5
 
20
6
  lib = File.expand_path('lib', __dir__)
21
7
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
@@ -36,6 +22,7 @@ def self.add_dev_dependencies spec
36
22
  spec.add_development_dependency 'amazing_print'
37
23
  spec.add_development_dependency 'bundler'
38
24
  spec.add_development_dependency 'climate_control' # mock ENV
25
+ spec.add_development_dependency 'debase'
39
26
  spec.add_development_dependency 'debride'
40
27
  spec.add_development_dependency 'execjs'
41
28
  spec.add_development_dependency 'factory_bot'
@@ -53,6 +40,7 @@ def self.add_dev_dependencies spec
53
40
  spec.add_development_dependency 'rubocop', '0.89.1'
54
41
  spec.add_development_dependency 'rubocop-performance', '1.7.1'
55
42
  spec.add_development_dependency 'rubocop-rspec', '1.42.0'
43
+ spec.add_development_dependency 'ruby-debug-ide'
56
44
  spec.add_development_dependency 'simplecov', '~> 0.18'
57
45
  spec.add_development_dependency 'sinatra', '>= 2'
58
46
  spec.add_development_dependency 'sqlite3', '1.3.9'
@@ -71,7 +59,7 @@ def self.add_dependencies spec
71
59
  spec.add_dependency 'ougai', '~> 1.8'
72
60
  spec.add_dependency 'parser', '~> 2.6'
73
61
  spec.add_dependency 'protobuf', '~> 3.10'
74
- spec.add_dependency 'rack', '>= 2.0', '< 3.0'
62
+ spec.add_dependency 'rack', '~> 2.0'
75
63
  end
76
64
 
77
65
  # Enumerate the files required to build the Agent.
@@ -95,6 +83,19 @@ def self.add_files spec
95
83
  spec.files += Dir['service_executables/**/*']
96
84
  spec.files += Dir['funchook/**/*']
97
85
  spec.files += Dir['shared_libraries/**/*']
86
+
87
+ # Clean up compiled funchook files that may have been generated during
88
+ # testing. Only a concern locally, but better than leaving it to chance.
89
+ spec.files.delete_if do |file|
90
+ file.end_with?('ext/libfunchook.dylib',
91
+ 'ext/libfunchook.so',
92
+ 'ext/funchook.h',
93
+ 'shared_libraries/libfunchook.dylib',
94
+ 'shared_libraries/libfunchook.so',
95
+ 'shared_libraries/funchook.h',
96
+ 'funchook/src/libfunchook.dylib',
97
+ 'funchook/src/libfunchook.so')
98
+ end
98
99
  end
99
100
 
100
101
  def self.add_metadata spec
@@ -1 +1 @@
1
- 2.11.1
1
+ 2.12.0
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: contrast-agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.14.0
4
+ version: 3.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - galen.palmer@contrastsecurity.com
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: exe
14
14
  cert_chain: []
15
- date: 2020-08-20 00:00:00.000000000 Z
15
+ date: 2020-09-18 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: amazing_print
@@ -56,6 +56,20 @@ dependencies:
56
56
  - - ">="
57
57
  - !ruby/object:Gem::Version
58
58
  version: '0'
59
+ - !ruby/object:Gem::Dependency
60
+ name: debase
61
+ requirement: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
59
73
  - !ruby/object:Gem::Dependency
60
74
  name: debride
61
75
  requirement: !ruby/object:Gem::Requirement
@@ -294,6 +308,20 @@ dependencies:
294
308
  - - '='
295
309
  - !ruby/object:Gem::Version
296
310
  version: 1.42.0
311
+ - !ruby/object:Gem::Dependency
312
+ name: ruby-debug-ide
313
+ requirement: !ruby/object:Gem::Requirement
314
+ requirements:
315
+ - - ">="
316
+ - !ruby/object:Gem::Version
317
+ version: '0'
318
+ type: :development
319
+ prerelease: false
320
+ version_requirements: !ruby/object:Gem::Requirement
321
+ requirements:
322
+ - - ">="
323
+ - !ruby/object:Gem::Version
324
+ version: '0'
297
325
  - !ruby/object:Gem::Dependency
298
326
  name: simplecov
299
327
  requirement: !ruby/object:Gem::Requirement
@@ -438,22 +466,16 @@ dependencies:
438
466
  name: rack
439
467
  requirement: !ruby/object:Gem::Requirement
440
468
  requirements:
441
- - - ">="
469
+ - - "~>"
442
470
  - !ruby/object:Gem::Version
443
471
  version: '2.0'
444
- - - "<"
445
- - !ruby/object:Gem::Version
446
- version: '3.0'
447
472
  type: :runtime
448
473
  prerelease: false
449
474
  version_requirements: !ruby/object:Gem::Requirement
450
475
  requirements:
451
- - - ">="
476
+ - - "~>"
452
477
  - !ruby/object:Gem::Version
453
478
  version: '2.0'
454
- - - "<"
455
- - !ruby/object:Gem::Version
456
- version: '3.0'
457
479
  description: This gem instantiates a Rack middleware for rack-based web applications
458
480
  in order to provide Interactive Application Security Testing and Protection.
459
481
  email:
@@ -462,20 +484,20 @@ executables:
462
484
  - contrast_service
463
485
  extensions:
464
486
  - ext/cs__common/extconf.rb
465
- - ext/cs__assess_string/extconf.rb
466
- - ext/cs__assess_active_record_named/extconf.rb
467
- - ext/cs__assess_hash/extconf.rb
468
487
  - ext/cs__assess_yield_track/extconf.rb
469
- - ext/cs__assess_basic_object/extconf.rb
470
488
  - ext/cs__assess_module/extconf.rb
489
+ - ext/cs__assess_active_record_named/extconf.rb
490
+ - ext/cs__contrast_patch/extconf.rb
491
+ - ext/cs__assess_string/extconf.rb
492
+ - ext/cs__assess_fiber_track/extconf.rb
471
493
  - ext/cs__assess_regexp/extconf.rb
472
- - ext/cs__protect_kernel/extconf.rb
473
- - ext/cs__assess_string_interpolation26/extconf.rb
474
494
  - ext/cs__assess_kernel/extconf.rb
495
+ - ext/cs__assess_hash/extconf.rb
475
496
  - ext/cs__assess_marshal_module/extconf.rb
476
- - ext/cs__assess_fiber_track/extconf.rb
477
- - ext/cs__contrast_patch/extconf.rb
478
497
  - ext/cs__assess_array/extconf.rb
498
+ - ext/cs__protect_kernel/extconf.rb
499
+ - ext/cs__assess_basic_object/extconf.rb
500
+ - ext/cs__assess_string_interpolation26/extconf.rb
479
501
  extra_rdoc_files: []
480
502
  files:
481
503
  - ".clang-format"
@@ -674,7 +696,6 @@ files:
674
696
  - lib/contrast/agent/assess/contrast_event.rb
675
697
  - lib/contrast/agent/assess/events/event_factory.rb
676
698
  - lib/contrast/agent/assess/events/source_event.rb
677
- - lib/contrast/agent/assess/finalizers/finalize.rb
678
699
  - lib/contrast/agent/assess/finalizers/freeze.rb
679
700
  - lib/contrast/agent/assess/finalizers/hash.rb
680
701
  - lib/contrast/agent/assess/policy/dynamic_source_factory.rb
@@ -719,6 +740,7 @@ files:
719
740
  - lib/contrast/agent/assess/properties.rb
720
741
  - lib/contrast/agent/assess/property/evented.rb
721
742
  - lib/contrast/agent/assess/property/tagged.rb
743
+ - lib/contrast/agent/assess/property/updated.rb
722
744
  - lib/contrast/agent/assess/rule.rb
723
745
  - lib/contrast/agent/assess/rule/base.rb
724
746
  - lib/contrast/agent/assess/rule/provider.rb
@@ -727,6 +749,7 @@ files:
727
749
  - lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb
728
750
  - lib/contrast/agent/assess/rule/redos.rb
729
751
  - lib/contrast/agent/assess/tag.rb
752
+ - lib/contrast/agent/assess/tracker.rb
730
753
  - lib/contrast/agent/at_exit_hook.rb
731
754
  - lib/contrast/agent/class_reopener.rb
732
755
  - lib/contrast/agent/deadzone/policy/deadzone_node.rb
@@ -858,7 +881,6 @@ files:
858
881
  - lib/contrast/configuration.rb
859
882
  - lib/contrast/extension/assess.rb
860
883
  - lib/contrast/extension/assess/array.rb
861
- - lib/contrast/extension/assess/assess_extension.rb
862
884
  - lib/contrast/extension/assess/erb.rb
863
885
  - lib/contrast/extension/assess/eval_trigger.rb
864
886
  - lib/contrast/extension/assess/exec_trigger.rb
@@ -909,7 +931,6 @@ files:
909
931
  - lib/contrast/utils/class_util.rb
910
932
  - lib/contrast/utils/duck_utils.rb
911
933
  - lib/contrast/utils/env_configuration_item.rb
912
- - lib/contrast/utils/freeze_util.rb
913
934
  - lib/contrast/utils/gemfile_reader.rb
914
935
  - lib/contrast/utils/hash_digest.rb
915
936
  - lib/contrast/utils/heap_dump_util.rb
@@ -1,21 +0,0 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: true
3
-
4
- require 'contrast/agent/assess/finalizers/hash'
5
- require 'contrast/agent/assess/finalizers/freeze'
6
-
7
- module Contrast
8
- module Agent
9
- module Assess
10
- module Finalizers
11
- # Our module for handling finalizing, allowing for the tracking of
12
- # Objects without impacting GC and causing a memory leak. Access to any
13
- # Finalizers object should run through this module as the Finalizers
14
- # have tightly coupled dependencies on each other.
15
- module Finalize
16
- PROPERTIES_HASH = Contrast::Agent::Assess::Finalizers::Hash.new
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,145 +0,0 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: true
3
-
4
- require 'contrast/agent/assess/properties'
5
- require 'contrast/agent/assess/finalizers/finalize'
6
-
7
- module Contrast
8
- module Extension
9
- module Assess
10
- # This module is responsible for maintaining the data we need to
11
- # construct a trace event for the object in which it is included. Rather
12
- # than have this code all over the place, any class that wants to use
13
- # dataflow features should be sent
14
- # 'include Contrast::Extension::Assess::AssessExtension'
15
- module AssessExtension
16
- def cs__transfer_properties dup
17
- Contrast::Agent::Assess::Finalizers::Finalize::PROPERTIES_HASH[dup] ||= Contrast::Agent::Assess::Finalizers::Finalize::PROPERTIES_HASH[self].dup
18
- end
19
-
20
- # Lazily build properties object. Only objects that have been tracked
21
- # will have the @_cs__properties, but all will respond to the
22
- # cs__properties method call. You should only call this method if you
23
- # either intend to start tracking an object or you have already checked
24
- # cs__tracked? and it is true.
25
- def cs__properties
26
- Contrast::Agent::Assess::Finalizers::Finalize::PROPERTIES_HASH[self] ||= Contrast::Agent::Assess::Properties.new
27
- end
28
-
29
- # This is a way to check if we are already tracking an object without
30
- # adding tracking to it. If the object already has been tracked we will
31
- # return the tracking state of its properties. If the object hasn't
32
- # already been tracked we will return false without starting to track
33
- # it
34
- def cs__tracked?
35
- !!Contrast::Agent::Assess::Finalizers::Finalize::PROPERTIES_HASH[self]&.tracked?
36
- end
37
-
38
- def cs__reset_properties
39
- Contrast::Agent::Assess::Finalizers::Finalize::PROPERTIES_HASH[self] = nil
40
- end
41
-
42
- # copy tags and info from object to self if object support methods
43
- # obj: the object from which to copy tags and events
44
- # shift: how far to shift the tags, negative moves left
45
- # skip_tags: array of tags to skip copying
46
- def cs__copy_from obj, shift = 0, skip_tags = nil
47
- return if obj.equal?(self)
48
- return unless Contrast::Utils::DuckUtils.quacks_to?(obj,
49
- :cs__tracked?)
50
- return unless obj.cs__tracked?
51
- return unless cs__properties
52
-
53
- cs__adjust_duplicate(obj)
54
-
55
- obj.cs__properties.events.each do |event|
56
- cs__properties.events << event
57
- end
58
-
59
- obj.cs__properties.tag_keys.each do |key|
60
- next if skip_tags&.include?(key)
61
-
62
- new_tags = []
63
- value = obj.cs__properties.fetch_tag(key)
64
- value.each do |tag|
65
- new_tags << tag.copy_modified(shift)
66
- end
67
- existing = cs__properties.fetch_tag(key)
68
- if existing
69
- existing.concat(new_tags)
70
- Contrast::Utils::TagUtil.size_aware_merge(self, existing)
71
- else
72
- cs__properties.set_tags(key, new_tags)
73
- end
74
- end
75
- end
76
-
77
- # Some propagation occurred, but we're not sure what the
78
- # exact transformation was. To be safe, we just explode
79
- # all the tags from the source to the return.
80
- #
81
- # If the return already had that tag, the existing tag
82
- # range is recycled to save us an object.
83
- def cs__splat_tags ret, source = self
84
- return unless Contrast::Utils::DuckUtils.trackable?(ret)
85
-
86
- length = Contrast::Utils::StringUtils.ret_length(ret)
87
- return if length.zero?
88
-
89
- cs__splat_from_source(ret, length, source)
90
- cs__splat_from_ret(ret, length)
91
- end
92
-
93
- def cs__splat_from_source ret, ret_length, source
94
- splat_source = Contrast::Utils::DuckUtils.trackable?(source)
95
- splat_source &&= source.cs__tracked?
96
- return unless splat_source
97
-
98
- source.cs__properties.tag_keys.each do |key|
99
- existing = ret.cs__properties.fetch_tag(key)
100
- # if the tag already exists, drop all but the first range
101
- # then change that range to cover the entire return
102
- if existing
103
- existing.drop(existing.length - 1)
104
- range = existing[0]
105
- range.repurpose(0, ret_length)
106
- else
107
- ret.cs__properties.add_tag(key, 0...ret_length)
108
- end
109
- end
110
- end
111
-
112
- def cs__splat_from_ret ret, length
113
- return unless ret.cs__tracked?
114
-
115
- ret.cs__properties.tag_keys.each do |key|
116
- next unless key
117
-
118
- existing = ret.cs__properties.fetch_tag(key)
119
- next unless existing
120
-
121
- existing.each do |range|
122
- range.update_end(length) if range.end_idx > length
123
- end
124
- end
125
- end
126
-
127
- private
128
-
129
- # Because of how our tracking works now, sometimes the Source and
130
- # Target are the same, but their IDs in our map will be different due
131
- # to PreShift duplication. To account for this, we have to ensure that
132
- # the Object we're copying from does not have the same Properties
133
- # that the Object we're copying to does. If they are the same, wipe the
134
- # Target so that the copy method can update events and ranges as
135
- # necessary.
136
- # DO NOT TAKE THIS OUT!
137
- def cs__adjust_duplicate obj
138
- cs__reset_properties if obj.cs__properties == cs__properties
139
- cs__reset_properties if obj.cs__properties.__id__ == cs__properties.dupped_from
140
- cs__reset_properties if obj.cs__properties.dupped_from == cs__properties.__id__
141
- end
142
- end
143
- end
144
- end
145
- end
@@ -1,32 +0,0 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
- # frozen_string_literal: true
3
-
4
- require 'contrast/utils/duck_utils'
5
-
6
- module Contrast
7
- module Utils
8
- # This utility allows us to act on frozen objects, creating an unfrozen
9
- # duplicate in those cases where that is possible.
10
- class FreezeUtil
11
- class << self
12
- # Make every attempt to duplicate the frozen object so that it can
13
- # be tracked.
14
- #
15
- # @param original [Object] something frozen, usually a String
16
- # @return [Object] the original or an unfrozen copy
17
- def unfreeze_dup original
18
- return original unless original.cs__frozen?
19
-
20
- copy = original.dup
21
- if Contrast::Utils::DuckUtils.iterable_hash?(copy)
22
- copy.each_key do |key|
23
- value = original[key]
24
- copy[key] = value.dup
25
- end
26
- end
27
- copy
28
- end
29
- end
30
- end
31
- end
32
- end