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.
- checksums.yaml +4 -4
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +18 -15
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.h +1 -0
- data/ext/cs__assess_string/cs__assess_string.c +24 -25
- data/ext/cs__assess_string/cs__assess_string.h +3 -1
- data/ext/cs__common/cs__common.c +4 -2
- data/ext/cs__common/cs__common.h +1 -1
- data/lib/contrast.rb +1 -1
- data/lib/contrast/agent/assess.rb +1 -0
- data/lib/contrast/agent/assess/contrast_event.rb +4 -12
- data/lib/contrast/agent/assess/finalizers/freeze.rb +3 -1
- data/lib/contrast/agent/assess/finalizers/hash.rb +45 -1
- data/lib/contrast/agent/assess/policy/patcher.rb +1 -1
- data/lib/contrast/agent/assess/policy/policy.rb +0 -2
- data/lib/contrast/agent/assess/policy/policy_scanner.rb +0 -1
- data/lib/contrast/agent/assess/policy/preshift.rb +7 -11
- data/lib/contrast/agent/assess/policy/propagation_method.rb +50 -33
- data/lib/contrast/agent/assess/policy/propagator/append.rb +8 -5
- data/lib/contrast/agent/assess/policy/propagator/base.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/center.rb +9 -5
- data/lib/contrast/agent/assess/policy/propagator/database_write.rb +5 -3
- data/lib/contrast/agent/assess/policy/propagator/insert.rb +6 -3
- data/lib/contrast/agent/assess/policy/propagator/keep.rb +4 -1
- data/lib/contrast/agent/assess/policy/propagator/match_data.rb +6 -6
- data/lib/contrast/agent/assess/policy/propagator/next.rb +7 -5
- data/lib/contrast/agent/assess/policy/propagator/prepend.rb +8 -5
- data/lib/contrast/agent/assess/policy/propagator/remove.rb +8 -4
- data/lib/contrast/agent/assess/policy/propagator/replace.rb +5 -2
- data/lib/contrast/agent/assess/policy/propagator/reverse.rb +7 -5
- data/lib/contrast/agent/assess/policy/propagator/select.rb +15 -7
- data/lib/contrast/agent/assess/policy/propagator/splat.rb +14 -8
- data/lib/contrast/agent/assess/policy/propagator/split.rb +14 -8
- data/lib/contrast/agent/assess/policy/propagator/substitution.rb +30 -21
- data/lib/contrast/agent/assess/policy/propagator/trim.rb +11 -5
- data/lib/contrast/agent/assess/policy/source_method.rb +85 -58
- data/lib/contrast/agent/assess/policy/trigger/reflected_xss.rb +16 -11
- data/lib/contrast/agent/assess/policy/trigger/xpath.rb +1 -1
- data/lib/contrast/agent/assess/policy/trigger_method.rb +38 -15
- data/lib/contrast/agent/assess/policy/trigger_node.rb +14 -13
- data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +2 -1
- data/lib/contrast/agent/assess/properties.rb +2 -0
- data/lib/contrast/agent/assess/property/updated.rb +136 -0
- data/lib/contrast/agent/assess/tracker.rb +66 -0
- data/lib/contrast/agent/class_reopener.rb +7 -5
- data/lib/contrast/agent/middleware.rb +0 -1
- data/lib/contrast/agent/patching/policy/patcher.rb +13 -22
- data/lib/contrast/agent/patching/policy/policy.rb +1 -4
- data/lib/contrast/agent/response.rb +17 -6
- data/lib/contrast/agent/rewriter.rb +1 -3
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/api/communication/messaging_queue.rb +1 -4
- data/lib/contrast/api/decorators/application_update.rb +2 -4
- data/lib/contrast/api/decorators/trace_event.rb +5 -5
- data/lib/contrast/components/app_context.rb +11 -9
- data/lib/contrast/components/config.rb +3 -13
- data/lib/contrast/components/contrast_service.rb +2 -2
- data/lib/contrast/config/application_configuration.rb +5 -2
- data/lib/contrast/config/service_configuration.rb +8 -2
- data/lib/contrast/configuration.rb +88 -47
- data/lib/contrast/extension/assess.rb +0 -2
- data/lib/contrast/extension/assess/array.rb +8 -5
- data/lib/contrast/extension/assess/erb.rb +6 -3
- data/lib/contrast/extension/assess/fiber.rb +9 -9
- data/lib/contrast/extension/assess/hash.rb +2 -3
- data/lib/contrast/extension/assess/kernel.rb +12 -5
- data/lib/contrast/extension/assess/marshal.rb +3 -2
- data/lib/contrast/extension/assess/regexp.rb +5 -4
- data/lib/contrast/extension/assess/string.rb +8 -10
- data/lib/contrast/framework/rack/patch/session_cookie.rb +12 -18
- data/lib/contrast/framework/rails/patch/assess_configuration.rb +4 -10
- data/lib/contrast/framework/rails/support.rb +2 -0
- data/lib/contrast/logger/application.rb +11 -3
- data/lib/contrast/utils/assess/tracking_util.rb +48 -3
- data/lib/contrast/utils/duck_utils.rb +0 -10
- data/lib/contrast/utils/env_configuration_item.rb +2 -1
- data/lib/contrast/utils/invalid_configuration_util.rb +21 -19
- data/lib/contrast/utils/string_utils.rb +10 -5
- data/resources/assess/policy.json +0 -10
- data/ruby-agent.gemspec +16 -15
- data/service_executables/VERSION +1 -1
- data/service_executables/linux/contrast-service +0 -0
- data/service_executables/mac/contrast-service +0 -0
- metadata +42 -21
- data/lib/contrast/agent/assess/finalizers/finalize.rb +0 -21
- data/lib/contrast/extension/assess/assess_extension.rb +0 -145
- 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 = '
|
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
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
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
|
data/ruby-agent.gemspec
CHANGED
@@ -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', '
|
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
|
data/service_executables/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.12.0
|
Binary file
|
Binary file
|
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.
|
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-
|
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
|