contrast-agent 3.14.0 → 3.15.0

Sign up to get free protection for your applications and to get access to all the features.
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