contrast-agent 5.3.0 → 6.1.1
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/.simplecov +1 -1
- data/Rakefile +1 -1
- data/ext/build_funchook.rb +3 -3
- data/ext/cs__assess_array/cs__assess_array.c +7 -0
- data/ext/cs__assess_basic_object/cs__assess_basic_object.c +24 -6
- data/ext/cs__assess_fiber_track/cs__assess_fiber_track.c +1 -1
- data/ext/cs__assess_hash/cs__assess_hash.c +3 -4
- data/ext/cs__assess_kernel/cs__assess_kernel.c +1 -2
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +26 -12
- data/ext/cs__assess_module/cs__assess_module.c +1 -1
- data/ext/cs__assess_regexp/cs__assess_regexp.c +15 -2
- data/ext/cs__assess_regexp/cs__assess_regexp.h +2 -0
- data/ext/cs__assess_string/cs__assess_string.c +21 -1
- data/ext/cs__assess_test/cs__assess_test.h +9 -0
- data/ext/cs__assess_test/cs__assess_tests.c +22 -0
- data/ext/cs__assess_test/extconf.rb +5 -0
- data/ext/cs__common/cs__common.c +113 -11
- data/ext/cs__common/cs__common.h +29 -5
- data/ext/cs__contrast_patch/cs__contrast_patch.c +55 -44
- data/ext/cs__os_information/cs__os_information.c +13 -10
- data/ext/cs__scope/cs__scope.c +146 -97
- data/ext/cs__tests/cs__tests.c +12 -0
- data/ext/cs__tests/cs__tests.h +3 -0
- data/ext/cs__tests/extconf.rb +5 -0
- data/ext/extconf_common.rb +1 -1
- data/lib/contrast/agent/assess/contrast_object.rb +16 -16
- data/lib/contrast/agent/assess/events/source_event.rb +17 -19
- data/lib/contrast/agent/assess/finalizers/hash.rb +4 -2
- data/lib/contrast/agent/assess/policy/policy.rb +9 -10
- data/lib/contrast/agent/assess/policy/policy_node.rb +58 -36
- data/lib/contrast/agent/assess/policy/policy_node_utils.rb +51 -0
- data/lib/contrast/agent/assess/policy/policy_scanner.rb +2 -16
- data/lib/contrast/agent/assess/policy/preshift.rb +8 -2
- data/lib/contrast/agent/assess/policy/propagation_method.rb +48 -14
- data/lib/contrast/agent/assess/policy/propagation_node.rb +2 -3
- data/lib/contrast/agent/assess/policy/propagator/base.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/buffer.rb +119 -0
- data/lib/contrast/agent/assess/policy/propagator/database_write.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/keep.rb +19 -4
- data/lib/contrast/agent/assess/policy/propagator/remove.rb +18 -2
- data/lib/contrast/agent/assess/policy/propagator/splat.rb +17 -3
- data/lib/contrast/agent/assess/policy/propagator/split.rb +17 -21
- data/lib/contrast/agent/assess/policy/propagator/substitution.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/substitution_utils.rb +1 -1
- data/lib/contrast/agent/assess/policy/propagator/trim.rb +2 -2
- data/lib/contrast/agent/assess/policy/propagator.rb +1 -0
- data/lib/contrast/agent/assess/policy/source_method.rb +7 -7
- data/lib/contrast/agent/assess/policy/source_node.rb +1 -1
- data/lib/contrast/agent/assess/policy/trigger_method.rb +11 -17
- data/lib/contrast/agent/assess/policy/trigger_node.rb +16 -16
- data/lib/contrast/agent/assess/policy/trigger_validation/redos_validator.rb +1 -1
- data/lib/contrast/agent/assess/property/evented.rb +2 -2
- data/lib/contrast/agent/assess/property/tagged.rb +3 -3
- data/lib/contrast/agent/assess/rule/provider/hardcoded_key.rb +6 -8
- data/lib/contrast/agent/assess/rule/provider/hardcoded_password.rb +6 -7
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +12 -7
- data/lib/contrast/agent/assess/rule/response/auto_complete_rule.rb +1 -1
- data/lib/contrast/agent/assess/rule/response/base_rule.rb +13 -6
- data/lib/contrast/agent/assess/rule/response/body_rule.rb +3 -3
- data/lib/contrast/agent/assess/rule/response/cache_control_header_rule.rb +66 -43
- data/lib/contrast/agent/assess/rule/response/click_jacking_header_rule.rb +4 -4
- data/lib/contrast/agent/assess/rule/response/csp_header_insecure_rule.rb +6 -6
- data/lib/contrast/agent/assess/rule/response/csp_header_missing_rule.rb +4 -4
- data/lib/contrast/agent/assess/rule/response/hsts_header_rule.rb +4 -4
- data/lib/contrast/agent/assess/rule/response/parameters_pollution_rule.rb +1 -1
- data/lib/contrast/agent/assess/rule/response/x_content_type_header_rule.rb +4 -4
- data/lib/contrast/agent/assess/rule/response/x_xss_protection_header_rule.rb +3 -4
- data/lib/contrast/agent/assess/tag.rb +13 -14
- data/lib/contrast/agent/at_exit_hook.rb +12 -1
- data/lib/contrast/agent/deadzone/policy/deadzone_node.rb +0 -7
- data/lib/contrast/agent/deadzone/policy/policy.rb +0 -6
- data/lib/contrast/agent/exclusion_matcher.rb +3 -3
- data/lib/contrast/agent/inventory/database_config.rb +10 -3
- data/lib/contrast/agent/middleware.rb +10 -5
- data/lib/contrast/agent/patching/policy/after_load_patch.rb +3 -5
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +2 -2
- data/lib/contrast/agent/patching/policy/method_policy_extend.rb +4 -4
- data/lib/contrast/agent/patching/policy/patch.rb +20 -19
- data/lib/contrast/agent/patching/policy/patch_status.rb +10 -3
- data/lib/contrast/agent/patching/policy/patcher.rb +4 -4
- data/lib/contrast/agent/patching/policy/policy.rb +13 -15
- data/lib/contrast/agent/patching/policy/policy_node.rb +32 -21
- data/lib/contrast/agent/patching/policy/trigger_node.rb +1 -1
- data/lib/contrast/agent/protect/exploitable_collection.rb +38 -0
- data/lib/contrast/agent/protect/input_analyzer/input_analyzer.rb +132 -75
- data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +4 -3
- data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +3 -3
- data/lib/contrast/agent/protect/policy/applies_xxe_rule.rb +1 -1
- data/lib/contrast/agent/protect/policy/rule_applicator.rb +4 -4
- data/lib/contrast/agent/protect/rule/base.rb +53 -9
- data/lib/contrast/agent/protect/rule/base_service.rb +31 -12
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +23 -3
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_input_classification.rb +83 -0
- data/lib/contrast/agent/protect/rule/cmdi/cmdi_worth_watching.rb +64 -0
- data/lib/contrast/agent/protect/rule/default_scanner.rb +2 -1
- data/lib/contrast/agent/protect/rule/deserialization.rb +18 -7
- data/lib/contrast/agent/protect/rule/http_method_tampering/http_method_tampering_input_classification.rb +96 -0
- data/lib/contrast/agent/protect/rule/http_method_tampering.rb +72 -46
- data/lib/contrast/agent/protect/rule/no_sqli/no_sqli_input_classification.rb +231 -0
- data/lib/contrast/agent/protect/rule/no_sqli.rb +28 -2
- data/lib/contrast/agent/protect/rule/path_traversal.rb +13 -3
- data/lib/contrast/agent/protect/rule/sqli/sqli_input_classification.rb +18 -54
- data/lib/contrast/agent/protect/rule/sqli/sqli_worth_watching.rb +2 -5
- data/lib/contrast/agent/protect/rule/sqli.rb +16 -23
- data/lib/contrast/agent/protect/rule/unsafe_file_upload/unsafe_file_upload_input_classification.rb +82 -0
- data/lib/contrast/agent/protect/rule/unsafe_file_upload/unsafe_file_upload_matcher.rb +45 -0
- data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +42 -0
- data/lib/contrast/agent/protect/rule/xss.rb +17 -0
- data/lib/contrast/agent/protect/rule/xxe/entity_wrapper.rb +14 -13
- data/lib/contrast/agent/protect/rule/xxe.rb +25 -3
- data/lib/contrast/agent/reaction_processor.rb +1 -1
- data/lib/contrast/agent/reporting/attack_result/attack_result.rb +63 -0
- data/lib/contrast/agent/reporting/attack_result/rasp_rule_sample.rb +52 -0
- data/lib/contrast/agent/reporting/attack_result/response_type.rb +29 -0
- data/lib/contrast/agent/reporting/attack_result/user_input.rb +87 -0
- data/lib/contrast/agent/reporting/masker/masker.rb +243 -0
- data/lib/contrast/agent/reporting/masker/masker_utils.rb +62 -0
- data/lib/contrast/agent/reporting/report.rb +2 -0
- data/lib/contrast/agent/reporting/reporter.rb +29 -22
- data/lib/contrast/agent/reporting/reporter_heartbeat.rb +49 -0
- data/lib/contrast/agent/reporting/reporting_events/agent_startup.rb +34 -0
- data/lib/contrast/agent/reporting/reporting_events/application_activity.rb +51 -0
- data/lib/contrast/agent/reporting/reporting_events/application_defend_activity.rb +96 -0
- data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_activity.rb +70 -0
- data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample.rb +182 -0
- data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample_activity.rb +56 -0
- data/lib/contrast/agent/reporting/reporting_events/application_defend_attack_sample_stack.rb +22 -0
- data/lib/contrast/agent/reporting/reporting_events/application_defend_attacker_activity.rb +70 -0
- data/lib/contrast/agent/reporting/reporting_events/application_inventory.rb +13 -5
- data/lib/contrast/agent/reporting/reporting_events/application_inventory_activity.rb +60 -0
- data/lib/contrast/agent/reporting/reporting_events/application_reporting_event.rb +27 -0
- data/lib/contrast/agent/reporting/reporting_events/application_startup.rb +44 -0
- data/lib/contrast/agent/reporting/reporting_events/application_startup_instrumentation.rb +27 -0
- data/lib/contrast/agent/reporting/reporting_events/application_update.rb +7 -12
- data/lib/contrast/agent/reporting/reporting_events/discovered_route.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_events/finding.rb +10 -4
- data/lib/contrast/agent/reporting/reporting_events/finding_event.rb +2 -4
- data/lib/contrast/agent/reporting/reporting_events/finding_event_object.rb +3 -3
- data/lib/contrast/agent/reporting/reporting_events/library_usage_observation.rb +5 -5
- data/lib/contrast/agent/reporting/reporting_events/observed_library_usage.rb +6 -2
- data/lib/contrast/agent/reporting/reporting_events/observed_route.rb +16 -12
- data/lib/contrast/agent/reporting/reporting_events/poll.rb +6 -2
- data/lib/contrast/agent/reporting/reporting_events/preflight.rb +10 -8
- data/lib/contrast/agent/reporting/reporting_events/preflight_message.rb +8 -11
- data/lib/contrast/agent/reporting/reporting_events/reporting_event.rb +2 -1
- data/lib/contrast/agent/reporting/reporting_events/route_coverage.rb +8 -6
- data/lib/contrast/agent/reporting/reporting_events/server_activity.rb +12 -20
- data/lib/contrast/agent/reporting/reporting_events/server_reporting_event.rb +27 -0
- data/lib/contrast/agent/reporting/reporting_utilities/audit.rb +17 -27
- data/lib/contrast/agent/reporting/reporting_utilities/build_preflight.rb +38 -0
- data/lib/contrast/agent/reporting/reporting_utilities/dtm_message.rb +8 -0
- data/lib/contrast/agent/reporting/reporting_utilities/endpoints.rb +6 -0
- data/lib/contrast/agent/reporting/reporting_utilities/headers.rb +1 -2
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client.rb +29 -13
- data/lib/contrast/agent/reporting/reporting_utilities/reporter_client_utils.rb +64 -76
- data/lib/contrast/agent/reporting/reporting_utilities/reporting_storage.rb +1 -1
- data/lib/contrast/agent/reporting/reporting_utilities/response.rb +17 -7
- data/lib/contrast/agent/reporting/reporting_utilities/response_extractor.rb +100 -0
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler.rb +75 -13
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler_mode.rb +63 -0
- data/lib/contrast/agent/reporting/reporting_utilities/response_handler_utils.rb +163 -122
- data/lib/contrast/agent/reporting/settings/application_settings.rb +10 -1
- data/lib/contrast/agent/reporting/settings/assess.rb +5 -5
- data/lib/contrast/agent/reporting/settings/assess_server_feature.rb +7 -35
- data/lib/contrast/agent/reporting/settings/exclusions.rb +3 -3
- data/lib/contrast/agent/reporting/settings/protect.rb +21 -6
- data/lib/contrast/agent/reporting/settings/protect_server_feature.rb +6 -6
- data/lib/contrast/agent/reporting/settings/reaction.rb +3 -3
- data/lib/contrast/agent/reporting/settings/sampling.rb +36 -0
- data/lib/contrast/agent/reporting/settings/sensitive_data_masking.rb +110 -0
- data/lib/contrast/agent/reporting/settings/sensitive_data_masking_rule.rb +58 -0
- data/lib/contrast/agent/reporting/settings/server_features.rb +2 -2
- data/lib/contrast/agent/request.rb +5 -5
- data/lib/contrast/agent/request_context.rb +25 -21
- data/lib/contrast/agent/request_context_extend.rb +12 -25
- data/lib/contrast/agent/request_handler.rb +7 -3
- data/lib/contrast/agent/response.rb +2 -0
- data/lib/contrast/agent/rule_set.rb +2 -2
- data/lib/contrast/agent/scope.rb +1 -1
- data/lib/contrast/agent/service_heartbeat.rb +6 -48
- data/lib/contrast/agent/static_analysis.rb +1 -1
- data/lib/contrast/agent/telemetry/base.rb +155 -0
- data/lib/contrast/agent/telemetry/events/event.rb +35 -0
- data/lib/contrast/agent/telemetry/events/exceptions/obfuscate.rb +119 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_base.rb +59 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_event.rb +44 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message.rb +115 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_message_exception.rb +83 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exception_stack_frame.rb +64 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exceptions.rb +20 -0
- data/lib/contrast/agent/telemetry/events/exceptions/telemetry_exceptions_report.rb +30 -0
- data/lib/contrast/agent/telemetry/events/metric_event.rb +28 -0
- data/lib/contrast/agent/telemetry/events/startup_metrics_event.rb +123 -0
- data/lib/contrast/agent/thread_watcher.rb +52 -68
- data/lib/contrast/agent/version.rb +1 -1
- data/lib/contrast/agent/worker_thread.rb +8 -0
- data/lib/contrast/agent.rb +4 -3
- data/lib/contrast/api/communication/messaging_queue.rb +29 -12
- data/lib/contrast/api/communication/response_processor.rb +7 -10
- data/lib/contrast/api/communication/service_lifecycle.rb +1 -1
- data/lib/contrast/api/communication/socket.rb +1 -1
- data/lib/contrast/api/communication/socket_client.rb +1 -1
- data/lib/contrast/api/communication/speedracer.rb +3 -3
- data/lib/contrast/api/decorators/activity.rb +33 -0
- data/lib/contrast/api/decorators/address.rb +1 -1
- data/lib/contrast/api/decorators/agent_startup.rb +10 -9
- data/lib/contrast/api/decorators/application_settings.rb +1 -1
- data/lib/contrast/api/decorators/application_startup.rb +4 -4
- data/lib/contrast/api/decorators/http_request.rb +1 -1
- data/lib/contrast/api/decorators/response_type.rb +17 -0
- data/lib/contrast/api/decorators.rb +1 -0
- data/lib/contrast/components/agent.rb +1 -1
- data/lib/contrast/components/app_context.rb +0 -4
- data/lib/contrast/components/assess.rb +14 -0
- data/lib/contrast/components/base.rb +1 -1
- data/lib/contrast/components/config.rb +19 -28
- data/lib/contrast/components/contrast_service.rb +13 -1
- data/lib/contrast/components/protect.rb +2 -2
- data/lib/contrast/components/sampling.rb +8 -12
- data/lib/contrast/components/settings.rb +151 -19
- data/lib/contrast/config/agent_configuration.rb +34 -41
- data/lib/contrast/config/api_configuration.rb +16 -75
- data/lib/contrast/config/api_proxy_configuration.rb +9 -48
- data/lib/contrast/config/application_configuration.rb +24 -95
- data/lib/contrast/config/assess_configuration.rb +21 -76
- data/lib/contrast/config/assess_rules_configuration.rb +13 -38
- data/lib/contrast/config/base_configuration.rb +11 -76
- data/lib/contrast/config/certification_configuration.rb +15 -68
- data/lib/contrast/config/exception_configuration.rb +15 -59
- data/lib/contrast/config/heap_dump_configuration.rb +19 -73
- data/lib/contrast/config/inventory_configuration.rb +11 -55
- data/lib/contrast/config/logger_configuration.rb +8 -41
- data/lib/contrast/config/protect_configuration.rb +23 -10
- data/lib/contrast/config/protect_rule_configuration.rb +23 -37
- data/lib/contrast/config/protect_rules_configuration.rb +39 -43
- data/lib/contrast/config/request_audit_configuration.rb +16 -55
- data/lib/contrast/config/root_configuration.rb +71 -14
- data/lib/contrast/config/ruby_configuration.rb +14 -47
- data/lib/contrast/config/sampling_configuration.rb +12 -65
- data/lib/contrast/config/server_configuration.rb +13 -45
- data/lib/contrast/config/service_configuration.rb +18 -54
- data/lib/contrast/configuration.rb +25 -17
- data/lib/contrast/extension/assess/array.rb +1 -1
- data/lib/contrast/extension/assess/erb.rb +1 -1
- data/lib/contrast/extension/assess/marshal.rb +1 -1
- data/lib/contrast/extension/assess/string.rb +20 -1
- data/lib/contrast/extension/extension.rb +2 -2
- data/lib/contrast/extension/module.rb +0 -1
- data/lib/contrast/framework/base_support.rb +8 -8
- data/lib/contrast/framework/grape/support.rb +3 -3
- data/lib/contrast/framework/manager.rb +7 -7
- data/lib/contrast/framework/manager_extend.rb +1 -1
- data/lib/contrast/framework/rack/patch/session_cookie.rb +1 -1
- data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +14 -3
- data/lib/contrast/framework/rails/patch/assess_configuration.rb +3 -3
- data/lib/contrast/framework/rails/patch/rails_application_configuration.rb +1 -1
- data/lib/contrast/framework/rails/patch/support.rb +14 -46
- data/lib/contrast/framework/rails/support.rb +2 -2
- data/lib/contrast/framework/sinatra/support.rb +1 -1
- data/lib/contrast/logger/aliased_logging.rb +94 -0
- data/lib/contrast/logger/application.rb +1 -5
- data/lib/contrast/logger/cef_log.rb +15 -15
- data/lib/contrast/logger/format.rb +1 -1
- data/lib/contrast/logger/log.rb +8 -8
- data/lib/contrast/tasks/config.rb +100 -4
- data/lib/contrast/tasks/service.rb +2 -2
- data/lib/contrast/utils/assess/object_store.rb +36 -0
- data/lib/contrast/utils/assess/propagation_method_utils.rb +6 -0
- data/lib/contrast/utils/assess/tracking_util.rb +4 -4
- data/lib/contrast/utils/class_util.rb +9 -22
- data/lib/contrast/utils/findings.rb +3 -3
- data/lib/contrast/utils/hash_digest.rb +6 -7
- data/lib/contrast/utils/head_dump_utils_extend.rb +1 -1
- data/lib/contrast/utils/input_classification.rb +73 -0
- data/lib/contrast/utils/invalid_configuration_util.rb +2 -2
- data/lib/contrast/utils/log_utils.rb +7 -5
- data/lib/contrast/utils/lru_cache.rb +1 -1
- data/lib/contrast/utils/metrics_hash.rb +1 -1
- data/lib/contrast/utils/middleware_utils.rb +15 -14
- data/lib/contrast/utils/net_http_base.rb +5 -5
- data/lib/contrast/utils/object_share.rb +2 -1
- data/lib/contrast/utils/os.rb +1 -6
- data/lib/contrast/utils/patching/policy/patch_utils.rb +6 -7
- data/lib/contrast/utils/request_utils.rb +2 -2
- data/lib/contrast/utils/response_utils.rb +18 -33
- data/lib/contrast/utils/sha256_builder.rb +4 -4
- data/lib/contrast/utils/stack_trace_utils.rb +31 -13
- data/lib/contrast/utils/telemetry.rb +22 -7
- data/lib/contrast/utils/telemetry_client.rb +28 -16
- data/lib/contrast/utils/telemetry_hash.rb +41 -0
- data/lib/contrast/utils/telemetry_identifier.rb +18 -3
- data/lib/contrast/utils/timer.rb +1 -1
- data/lib/contrast.rb +9 -0
- data/resources/assess/policy.json +99 -1
- data/resources/deadzone/policy.json +0 -86
- data/ruby-agent.gemspec +10 -9
- data/service_executables/VERSION +1 -1
- data/service_executables/linux/contrast-service +0 -0
- data/service_executables/mac/contrast-service +0 -0
- metadata +99 -29
- data/lib/contrast/agent/metric_telemetry_event.rb +0 -26
- data/lib/contrast/agent/startup_metrics_telemetry_event.rb +0 -121
- data/lib/contrast/agent/telemetry.rb +0 -137
- data/lib/contrast/agent/telemetry_event.rb +0 -33
- data/lib/contrast/utils/exclude_key.rb +0 -20
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e548b3df856f888229a5125c351404c3f5b04fcd7ecb5c91937f480ce91c9d42
|
|
4
|
+
data.tar.gz: 00c6ee55996e75602d1b80da133a362d3205cb5ef5de0f5c1a35b214528fea2a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ad8d0f64dc798a22072e977cf0ff83ba47df54a3f24802386a52d2d338f365a02cac5db943868a55ecdf7641e44384f580e55e5d1b05a78522e88c5244013346
|
|
7
|
+
data.tar.gz: 804a464d38a9e023da53ce82009573571a6197c9f3f00642988457ac32b8ecc8631ea0a3cfd8bc678918df8afbb1cb24c51fa79dff1fe8fb278c5e966bff74e1
|
data/.simplecov
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright (c) 2022 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
SimpleCov.minimum_coverage
|
|
4
|
+
SimpleCov.minimum_coverage(line: 94)
|
|
5
5
|
SimpleCov.start do
|
|
6
6
|
add_filter '/spec/'
|
|
7
7
|
enable_coverage :branch
|
data/Rakefile
CHANGED
data/ext/build_funchook.rb
CHANGED
|
@@ -52,13 +52,13 @@ unless find_header('funchook.h', ext_path)
|
|
|
52
52
|
|
|
53
53
|
TARGET_PATHS.each do |target_path|
|
|
54
54
|
unless File.writable?(target_path)
|
|
55
|
-
puts
|
|
55
|
+
puts("Unable to copy into #{ target_path } - directory not writable")
|
|
56
56
|
next
|
|
57
57
|
end
|
|
58
|
-
puts
|
|
58
|
+
puts("Copying #{ source_file_path } into #{ target_path }")
|
|
59
59
|
FileUtils.cp(source_file_path, target_path)
|
|
60
60
|
rescue StandardError
|
|
61
|
-
puts
|
|
61
|
+
puts("Error while copying #{ source_file } to #{ target_path }")
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
64
|
end
|
|
@@ -22,7 +22,9 @@ static VALUE contrast_assess_array_join(const int argc, const VALUE *argv,
|
|
|
22
22
|
}
|
|
23
23
|
/* Finally, default to empty String. Implicit since nil.to_s is ''*/
|
|
24
24
|
|
|
25
|
+
/* call the Array.join but patched one */
|
|
25
26
|
result = rb_funcall2(ary, rb_sym_assess_array_join, argc, argv);
|
|
27
|
+
/* call the Contrast::Extensions::Assess::ArrayPropagator#cs__track_join */
|
|
26
28
|
result = rb_funcall(array_propagator, rb_sym_assess_track_array_join, 3,
|
|
27
29
|
ary, sep, result);
|
|
28
30
|
|
|
@@ -33,6 +35,11 @@ void Init_cs__assess_array(void) {
|
|
|
33
35
|
array_propagator =
|
|
34
36
|
rb_define_class_under(core_assess, "ArrayPropagator", rb_cObject);
|
|
35
37
|
rb_sym_assess_track_array_join = rb_intern("cs__track_join");
|
|
38
|
+
/*
|
|
39
|
+
* Here we need to check before using the alias or prepend spec
|
|
40
|
+
* This patch is happening here, we register the cs__track_join
|
|
41
|
+
* method of the Array propagator, and call it here from Ruby.
|
|
42
|
+
*/
|
|
36
43
|
rb_sym_assess_array_join =
|
|
37
44
|
contrast_register_patch("Array", "join", contrast_assess_array_join);
|
|
38
45
|
}
|
|
@@ -3,8 +3,24 @@
|
|
|
3
3
|
|
|
4
4
|
#include "cs__assess_basic_object.h"
|
|
5
5
|
#include "../cs__common/cs__common.h"
|
|
6
|
+
#include "../cs__scope/cs__scope.h"
|
|
6
7
|
#include <ruby.h>
|
|
7
8
|
|
|
9
|
+
/*
|
|
10
|
+
* Source code of instance_eval:
|
|
11
|
+
*
|
|
12
|
+
* static VALUE
|
|
13
|
+
* rb_obj_instance_eval_internal(int argc, const VALUE *argv, VALUE self)
|
|
14
|
+
* {
|
|
15
|
+
* VALUE klass = singleton_class_for_eval(self);
|
|
16
|
+
* return specific_eval(argc, argv, klass, self, RB_PASS_CALLED_KEYWORDS);
|
|
17
|
+
* }
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
VALUE contrast_check_and_register_instance_patch(
|
|
21
|
+
const char *module_name, const char *method_name,
|
|
22
|
+
VALUE(c_fn)(const int, VALUE *, const VALUE));
|
|
23
|
+
|
|
8
24
|
void contrast_assess_instance_eval_trigger_check(VALUE self, VALUE source,
|
|
9
25
|
VALUE ret) {
|
|
10
26
|
rb_funcall(basic_eval_trigger, instance_trigger_check_method, 3, self,
|
|
@@ -19,19 +35,21 @@ contrast_assess_basic_object_instance_eval(const int argc, const VALUE *argv,
|
|
|
19
35
|
return rb_obj_instance_eval(argc, argv, self);
|
|
20
36
|
}
|
|
21
37
|
|
|
22
|
-
|
|
23
|
-
RTEST(rb_funcall(contrast_patcher(), rb_sym_in_scope, 0));
|
|
38
|
+
VALUE nested_scope = inst_methods_in_cntr_scope(contrast_patcher(), 0);
|
|
24
39
|
|
|
25
|
-
|
|
40
|
+
/* Enter scope */
|
|
41
|
+
inst_methods_enter_cntr_scope(contrast_patcher(), 0);
|
|
26
42
|
|
|
43
|
+
/* Call the source: */
|
|
27
44
|
VALUE ret = rb_obj_instance_eval(argc, argv, self);
|
|
28
45
|
|
|
29
|
-
if (
|
|
46
|
+
if (nested_scope == Qfalse && argc > 0) {
|
|
30
47
|
VALUE data = argv[0];
|
|
31
48
|
contrast_assess_instance_eval_trigger_check(self, data, ret);
|
|
32
49
|
}
|
|
33
50
|
|
|
34
|
-
|
|
51
|
+
/* Exit scope */
|
|
52
|
+
inst_methods_exit_cntr_scope(contrast_patcher(), 0);
|
|
35
53
|
|
|
36
54
|
return ret;
|
|
37
55
|
}
|
|
@@ -47,6 +65,6 @@ void Init_cs__assess_basic_object(void) {
|
|
|
47
65
|
* but if someone else patched BasicObject#instance_eval,
|
|
48
66
|
* IDK if this is intentional... noting it. -ajm
|
|
49
67
|
*/
|
|
50
|
-
|
|
68
|
+
contrast_check_and_register_instance_patch("BasicObject", "instance_eval",
|
|
51
69
|
contrast_assess_basic_object_instance_eval);
|
|
52
70
|
}
|
|
@@ -30,7 +30,7 @@ VALUE rb_fiber_new_hook(VALUE (*func)(ANYARGS), VALUE obj) {
|
|
|
30
30
|
ID meth;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
/*
|
|
33
|
+
/* underlying object is first entry in Enumerator struct def.
|
|
34
34
|
* that's all statically defined w/in enumerator.c, so we can't
|
|
35
35
|
* reference the data types and be safe about it. (yippee.)
|
|
36
36
|
* we cut out the TypedData_Get_Struct middleman & just go for it.
|
|
@@ -17,7 +17,6 @@ static VALUE contrast_assess_hash_bracket_constructor(const int argc,
|
|
|
17
17
|
const VALUE hash) {
|
|
18
18
|
VALUE result;
|
|
19
19
|
|
|
20
|
-
|
|
21
20
|
/* Array of Arrays: Hash[ [ [key, value], ... ] ] -> new_hash */
|
|
22
21
|
if (RB_TYPE_P(argv[0], T_ARRAY)) {
|
|
23
22
|
int i;
|
|
@@ -34,13 +33,13 @@ static VALUE contrast_assess_hash_bracket_constructor(const int argc,
|
|
|
34
33
|
}
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
const VALUE *
|
|
36
|
+
const VALUE *argv_final = argv;
|
|
38
37
|
/* unhandled case - shouldn't need it since issue is only unfrozen
|
|
39
38
|
* String keys
|
|
40
39
|
* # Hash[ object ] -> new_hash
|
|
41
40
|
*/
|
|
42
|
-
result =
|
|
43
|
-
|
|
41
|
+
result = rb_funcall2(hash, rb_sym_assess_hash_bracket_constructor, argc,
|
|
42
|
+
argv_final);
|
|
44
43
|
|
|
45
44
|
return result;
|
|
46
45
|
}
|
|
@@ -9,8 +9,7 @@
|
|
|
9
9
|
VALUE
|
|
10
10
|
contrast_patched_kernel_exec(const int argc, const VALUE *argv,
|
|
11
11
|
const VALUE self) {
|
|
12
|
-
|
|
13
|
-
inst_methods_in_cntr_scope(contrast_patcher(), 0);
|
|
12
|
+
VALUE nested_scope = inst_methods_in_cntr_scope(contrast_patcher(), 0);
|
|
14
13
|
|
|
15
14
|
if (nested_scope == Qfalse && argc > 0) {
|
|
16
15
|
/* enter scope */
|
|
@@ -5,36 +5,50 @@
|
|
|
5
5
|
#include "../cs__common/cs__common.h"
|
|
6
6
|
#include <ruby.h>
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
/*
|
|
9
|
+
* Marshal#load source:
|
|
10
|
+
* static VALUE
|
|
11
|
+
* marshal_load(int argc, VALUE *argv)
|
|
12
|
+
* {
|
|
13
|
+
* VALUE port, proc;
|
|
14
|
+
*
|
|
15
|
+
* rb_check_arity(argc, 1, 2);
|
|
16
|
+
* port = argv[0];
|
|
17
|
+
* proc = argc > 1 ? argv[1] : Qnil;
|
|
18
|
+
* return rb_marshal_load_with_proc(port, proc);
|
|
19
|
+
* }
|
|
20
|
+
*/
|
|
21
|
+
static VALUE contrast_marshal_module_load(const int argc, const VALUE *argv) {
|
|
10
22
|
VALUE result;
|
|
11
23
|
VALUE source_string;
|
|
12
24
|
|
|
13
|
-
|
|
25
|
+
/* Our patches need to apply only in the case where there was valid input.
|
|
26
|
+
*/
|
|
14
27
|
if (argc >= 1) {
|
|
15
28
|
source_string = argv[0];
|
|
16
29
|
} else {
|
|
17
30
|
source_string = Qnil;
|
|
18
31
|
}
|
|
19
32
|
|
|
20
|
-
|
|
33
|
+
/* Run our protect code ahead of the original method */
|
|
21
34
|
if (source_string != Qnil) {
|
|
22
|
-
rb_funcall(marshal_propagator, rb_sym_protect_marshal_load, 1,
|
|
35
|
+
rb_funcall(marshal_propagator, rb_sym_protect_marshal_load, 1,
|
|
36
|
+
source_string);
|
|
23
37
|
}
|
|
24
38
|
|
|
25
|
-
|
|
39
|
+
/* Invoke the original method */
|
|
26
40
|
result = rb_call_super(argc, argv);
|
|
27
41
|
|
|
28
|
-
|
|
42
|
+
/* Run our assess code after the original method */
|
|
29
43
|
if (source_string != Qnil) {
|
|
30
44
|
VALUE tracked =
|
|
31
45
|
rb_funcall(properties_hash, rb_sym_hash_tracked, 1, source_string);
|
|
32
46
|
|
|
33
|
-
|
|
47
|
+
/* Assuming the source is tracked and needs assess checks */
|
|
34
48
|
if (tracked == Qtrue) {
|
|
35
49
|
VALUE skip =
|
|
36
50
|
rb_funcall(contrast_patcher(), rb_sym_skip_assess_analysis, 0);
|
|
37
|
-
|
|
51
|
+
/* And Assess is enabled and applies to this request */
|
|
38
52
|
if (skip == Qfalse) {
|
|
39
53
|
rb_funcall(marshal_propagator, rb_sym_assess_marshal_load, 2,
|
|
40
54
|
source_string, result);
|
|
@@ -45,7 +59,7 @@ static VALUE contrast_marshal_module_load(const int argc,
|
|
|
45
59
|
}
|
|
46
60
|
|
|
47
61
|
void Init_cs__assess_marshal_module(void) {
|
|
48
|
-
|
|
62
|
+
/* Contrast::Agent::Assess::Tracker::PROPERTIES_HASH */
|
|
49
63
|
VALUE tracker = rb_define_class_under(assess, "Tracker", rb_cObject);
|
|
50
64
|
properties_hash = rb_const_get(tracker, rb_intern("PROPERTIES_HASH"));
|
|
51
65
|
marshal_propagator =
|
|
@@ -53,6 +67,6 @@ void Init_cs__assess_marshal_module(void) {
|
|
|
53
67
|
rb_sym_assess_marshal_load = rb_intern("cs__load_assess");
|
|
54
68
|
rb_sym_protect_marshal_load = rb_intern("cs__load_protect");
|
|
55
69
|
|
|
56
|
-
contrast_register_singleton_prepend_patch(
|
|
57
|
-
|
|
70
|
+
contrast_register_singleton_prepend_patch("Marshal", "load",
|
|
71
|
+
&contrast_marshal_module_load);
|
|
58
72
|
}
|
|
@@ -13,7 +13,7 @@ void contrast_assess_eval_trigger_check(VALUE module, VALUE source, VALUE ret) {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
int nested_scope = inst_methods_in_cntr_scope(contrast_patcher(), 0);
|
|
16
|
-
|
|
16
|
+
/* enter scope */
|
|
17
17
|
inst_methods_enter_cntr_scope(contrast_patcher(), 0);
|
|
18
18
|
|
|
19
19
|
if (nested_scope == Qfalse) {
|
|
@@ -3,8 +3,20 @@
|
|
|
3
3
|
|
|
4
4
|
#include "cs__assess_regexp.h"
|
|
5
5
|
#include "../cs__common/cs__common.h"
|
|
6
|
+
#include "../cs__contrast_patch/cs__contrast_patch.h"
|
|
6
7
|
#include <ruby.h>
|
|
7
8
|
|
|
9
|
+
extern VALUE contrast_force_patch(const int argc, VALUE *argv) {
|
|
10
|
+
return contrast_check_and_register_instance_patch(
|
|
11
|
+
"Regexp", "=~", contrast_assess_regexp_equal_squiggle);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* check if method is prepended and register instance alias or prepend patch */
|
|
15
|
+
VALUE contrast_check_and_register_instance_patch(const char *module_name,
|
|
16
|
+
const char *method_name,
|
|
17
|
+
VALUE(c_fn)(const int, VALUE *,
|
|
18
|
+
const VALUE));
|
|
19
|
+
|
|
8
20
|
void contrast_alias_method(const VALUE target, const char *to,
|
|
9
21
|
const char *from);
|
|
10
22
|
|
|
@@ -46,7 +58,8 @@ void Init_cs__assess_regexp(void) {
|
|
|
46
58
|
rb_global_variable(&rb_sym_string);
|
|
47
59
|
rb_sym_back_ref = ID2SYM(rb_intern("back_ref"));
|
|
48
60
|
rb_global_variable(&rb_sym_back_ref);
|
|
61
|
+
rb_define_singleton_method(assess, "contrast_force_repatch_regexp", contrast_force_patch, 0);
|
|
49
62
|
|
|
50
|
-
rb_sym_assess_regexp_equal_squiggle =
|
|
51
|
-
|
|
63
|
+
rb_sym_assess_regexp_equal_squiggle = contrast_check_and_register_instance_patch(
|
|
64
|
+
"Regexp", "=~", contrast_assess_regexp_equal_squiggle);
|
|
52
65
|
}
|
|
@@ -5,6 +5,25 @@
|
|
|
5
5
|
#include "../cs__common/cs__common.h"
|
|
6
6
|
#include <ruby.h>
|
|
7
7
|
|
|
8
|
+
/*
|
|
9
|
+
* The -@ method source:
|
|
10
|
+
*
|
|
11
|
+
* static VALUE
|
|
12
|
+
* str_uminus(VALUE str)
|
|
13
|
+
* {
|
|
14
|
+
* if (!BARE_STRING_P(str) && !rb_obj_frozen_p(str)) {
|
|
15
|
+
* str = rb_str_dup(str);
|
|
16
|
+
* }
|
|
17
|
+
* return rb_fstring(str);
|
|
18
|
+
* }
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/*
|
|
22
|
+
* This patch won't do the Prepend. We would call to the String instance'
|
|
23
|
+
* uminus directly and skip other propagation from prepended modules.
|
|
24
|
+
* We could come back to this one and rethink it's prepend patching.
|
|
25
|
+
*/
|
|
26
|
+
|
|
8
27
|
static VALUE contrast_assess_string_freeze(const int argc, VALUE *argv,
|
|
9
28
|
const VALUE obj) {
|
|
10
29
|
if (!OBJ_FROZEN(obj)) {
|
|
@@ -39,10 +58,11 @@ void Init_cs__assess_string(void) {
|
|
|
39
58
|
rb_sym_dup = rb_intern("dup");
|
|
40
59
|
rb_sym_freeze = rb_intern("freeze");
|
|
41
60
|
rb_sym_pre_freeze = rb_intern("pre_freeze");
|
|
42
|
-
|
|
61
|
+
/* Contrast::Agent::Assess::Tracker::PROPERTIES_HASH */
|
|
43
62
|
VALUE tracker = rb_define_class_under(assess, "Tracker", rb_cObject);
|
|
44
63
|
properties_hash = rb_const_get(tracker, rb_intern("PROPERTIES_HASH"));
|
|
45
64
|
|
|
65
|
+
/* We only do alias for this one */
|
|
46
66
|
rb_sym_assess_string_uminus =
|
|
47
67
|
contrast_register_patch("String", "-@", &contrast_assess_string_uminus);
|
|
48
68
|
rb_sym_assess_string_freeze = contrast_register_patch(
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#include "../cs__common/cs__common.h";
|
|
2
|
+
#include "ruby.h"
|
|
3
|
+
#include <ruby/re.h>
|
|
4
|
+
|
|
5
|
+
static VALUE dummy_regexp;
|
|
6
|
+
static VALUE test_regexp;
|
|
7
|
+
|
|
8
|
+
VALUE rb_equal_squiggle(const int argc, const VALUE *argv) {
|
|
9
|
+
return rb_call_super(argc, argv);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
void rb_force_prepend(void) {
|
|
13
|
+
rb_prepend_module(rb_cRegexp, dummy_regexp);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
void Init_cs__assess_test(void) {
|
|
17
|
+
test_regexp = rb_define_module("ForcePrepend");
|
|
18
|
+
rb_define_singleton_method(test_regexp, "cs__force_prepend",
|
|
19
|
+
rb_force_prepend, 0);
|
|
20
|
+
dummy_regexp = rb_define_module("DummyMod");
|
|
21
|
+
rb_define_method(dummy_regexp, "=~", rb_equal_squiggle, -1);
|
|
22
|
+
}
|
data/ext/cs__common/cs__common.c
CHANGED
|
@@ -59,13 +59,14 @@ VALUE contrast_patcher() {
|
|
|
59
59
|
return patcher;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
/* register instance alias patch */
|
|
62
63
|
VALUE contrast_register_patch(const char *module_name, const char *method_name,
|
|
63
|
-
VALUE(c_fn)(const int, VALUE *,
|
|
64
|
-
const VALUE)) {
|
|
64
|
+
VALUE(c_fn)(const int, VALUE *, const VALUE)) {
|
|
65
65
|
return _contrast_register_patch(module_name, method_name, c_fn,
|
|
66
66
|
IMPL_ALIAS_INSTANCE);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/* register singleton alias patch */
|
|
69
70
|
VALUE contrast_register_singleton_patch(const char *module_name,
|
|
70
71
|
const char *method_name,
|
|
71
72
|
VALUE(c_fn)(const int, VALUE *,
|
|
@@ -74,22 +75,49 @@ VALUE contrast_register_singleton_patch(const char *module_name,
|
|
|
74
75
|
IMPL_ALIAS_SINGLETON);
|
|
75
76
|
}
|
|
76
77
|
|
|
78
|
+
/* register instance prepend patch */
|
|
77
79
|
VALUE contrast_register_prepend_patch(const char *module_name,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
const char *method_name,
|
|
81
|
+
VALUE(c_fn)(const int, VALUE *,
|
|
82
|
+
const VALUE)) {
|
|
81
83
|
return _contrast_register_patch(module_name, method_name, c_fn,
|
|
82
84
|
IMPL_PREPEND_INSTANCE);
|
|
83
85
|
}
|
|
84
86
|
|
|
87
|
+
/* register singleton prepend patch */
|
|
85
88
|
VALUE contrast_register_singleton_prepend_patch(const char *module_name,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
const char *method_name,
|
|
90
|
+
VALUE(c_fn)(const int, VALUE *,
|
|
91
|
+
const VALUE)) {
|
|
89
92
|
return _contrast_register_patch(module_name, method_name, c_fn,
|
|
90
93
|
IMPL_PREPEND_SINGLETON);
|
|
91
94
|
}
|
|
92
95
|
|
|
96
|
+
/* check if method is prepended and register instance alias or prepend patch */
|
|
97
|
+
/* module name c_char "Module"; */
|
|
98
|
+
/* method name c_char "method"; */
|
|
99
|
+
/* c_func => pointer */
|
|
100
|
+
VALUE contrast_check_and_register_instance_patch(
|
|
101
|
+
const char *module_name, const char *method_name,
|
|
102
|
+
VALUE(c_fn)(const int, VALUE *, const VALUE)) {
|
|
103
|
+
|
|
104
|
+
VALUE object, method, is_prepended, patch_type;
|
|
105
|
+
/* check if method is prepended */
|
|
106
|
+
object = rb_const_get(rb_cObject, rb_intern(module_name));
|
|
107
|
+
method = ID2SYM(rb_intern(method_name));
|
|
108
|
+
is_prepended = contrast_check_prepended(object, method, Qtrue);
|
|
109
|
+
|
|
110
|
+
if (is_prepended == Qtrue) {
|
|
111
|
+
/* prepend patch */
|
|
112
|
+
return _contrast_register_patch(module_name, method_name, c_fn,
|
|
113
|
+
IMPL_PREPEND_INSTANCE);
|
|
114
|
+
} else {
|
|
115
|
+
/* alias patch */
|
|
116
|
+
return _contrast_register_patch(module_name, method_name, c_fn,
|
|
117
|
+
IMPL_ALIAS_INSTANCE);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
93
121
|
static VALUE
|
|
94
122
|
_contrast_register_patch(const char *module_name, const char *method_name,
|
|
95
123
|
VALUE(c_fn)(const int, VALUE *, const VALUE),
|
|
@@ -134,8 +162,9 @@ _contrast_register_patch(const char *module_name, const char *method_name,
|
|
|
134
162
|
break;
|
|
135
163
|
case IMPL_PREPEND_INSTANCE:
|
|
136
164
|
impl = ID2SYM(rb_sym_prepend_instance);
|
|
165
|
+
break;
|
|
137
166
|
case IMPL_PREPEND_SINGLETON:
|
|
138
|
-
|
|
167
|
+
impl = ID2SYM(rb_sym_prepend_singleton);
|
|
139
168
|
break;
|
|
140
169
|
}
|
|
141
170
|
|
|
@@ -146,8 +175,75 @@ _contrast_register_patch(const char *module_name, const char *method_name,
|
|
|
146
175
|
}
|
|
147
176
|
|
|
148
177
|
int rb_ver_below_three() {
|
|
149
|
-
|
|
150
|
-
|
|
178
|
+
int ruby_version =
|
|
179
|
+
FIX2INT(rb_funcall(rb_const_get(rb_cObject, rb_intern("RUBY_VERSION")),
|
|
180
|
+
rb_intern("to_i"), 0));
|
|
181
|
+
return ruby_version < 3;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/* used for direct check on object: String.cs__prepended? *args */
|
|
185
|
+
extern VALUE contrast_check_prepended(VALUE self, VALUE method_name,
|
|
186
|
+
VALUE is_instance) {
|
|
187
|
+
return _contrast_check_prepended(self, method_name, is_instance);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/* used for passing object to look if not called on itself.
|
|
191
|
+
Contrast::Agent::Assess.cs__object_method_prepended? object, :method_name,
|
|
192
|
+
true/false */
|
|
193
|
+
extern VALUE contrast_lookout_prepended(VALUE self, VALUE object_name,
|
|
194
|
+
VALUE method_name, VALUE is_instance) {
|
|
195
|
+
/* object_name must be the object, the self value is needed to prevent
|
|
196
|
+
lookout for self, since is always passed first we skip it */
|
|
197
|
+
VALUE result =
|
|
198
|
+
_contrast_check_prepended(object_name, method_name, is_instance);
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
static VALUE _contrast_check_prepended(VALUE object, VALUE method_name,
|
|
203
|
+
VALUE is_instance) {
|
|
204
|
+
VALUE entry, ancestors, object_idx, entry_methods;
|
|
205
|
+
VALUE result = Qfalse;
|
|
206
|
+
int i;
|
|
207
|
+
int y;
|
|
208
|
+
|
|
209
|
+
/* get self ancestors */
|
|
210
|
+
ancestors = rb_mod_ancestors(object);
|
|
211
|
+
/* get the size of the array */
|
|
212
|
+
int length = RARRAY_LEN(ancestors);
|
|
213
|
+
/* Locate self in ancestors: */
|
|
214
|
+
for (i = 0; i < length; ++i) {
|
|
215
|
+
entry = rb_ary_entry(ancestors, i);
|
|
216
|
+
if (entry == object) {
|
|
217
|
+
object_idx = i;
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* find all the prepended modules */
|
|
223
|
+
/* we have the object place in ancestors: */
|
|
224
|
+
/* [suspect, suspect, object, ...] */
|
|
225
|
+
for (i = 0; i < object_idx; ++i) {
|
|
226
|
+
entry = rb_ary_entry(ancestors, i);
|
|
227
|
+
if (is_instance == Qtrue) {
|
|
228
|
+
entry_methods = rb_class_instance_methods(1, entry, entry);
|
|
229
|
+
} else {
|
|
230
|
+
entry_methods = rb_obj_singleton_methods(1, entry, entry);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/* Loop through the instance/singleton methods of the prepended modules
|
|
234
|
+
*/
|
|
235
|
+
int entry_methods_length = RARRAY_LEN(entry_methods);
|
|
236
|
+
for (y = 0; y <= entry_methods_length; ++y) {
|
|
237
|
+
if (rb_ary_entry(entry_methods, y) == method_name) {
|
|
238
|
+
result = Qtrue;
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (result == Qtrue) {
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return result;
|
|
151
247
|
}
|
|
152
248
|
|
|
153
249
|
void Init_cs__common(void) {
|
|
@@ -190,4 +286,10 @@ void Init_cs__common(void) {
|
|
|
190
286
|
|
|
191
287
|
core_extensions = rb_define_module_under(contrast, "Extension");
|
|
192
288
|
core_assess = rb_define_module_under(core_extensions, "Assess");
|
|
289
|
+
/* defined for direct object check */
|
|
290
|
+
rb_define_singleton_method(rb_cObject, "cs__prepended?",
|
|
291
|
+
contrast_check_prepended, 2);
|
|
292
|
+
/* defined for object lookout */
|
|
293
|
+
rb_define_singleton_method(assess, "cs__object_method_prepended?",
|
|
294
|
+
contrast_lookout_prepended, 4);
|
|
193
295
|
}
|
data/ext/cs__common/cs__common.h
CHANGED
|
@@ -57,15 +57,39 @@ VALUE contrast_register_singleton_patch(const char *module_name,
|
|
|
57
57
|
VALUE(c_fn)(const int, VALUE *,
|
|
58
58
|
const VALUE));
|
|
59
59
|
|
|
60
|
-
VALUE
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
VALUE contrast_register_prepend_patch(const char *module_name,
|
|
61
|
+
const char *method_name,
|
|
62
|
+
VALUE(c_fn)(const int, VALUE *,
|
|
63
|
+
const VALUE));
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
|
|
66
|
+
VALUE contrast_register_singleton_prepend_patch(const char *module_name,
|
|
67
|
+
const char *method_name,
|
|
68
|
+
VALUE(c_fn)(const int, VALUE *,
|
|
69
|
+
const VALUE));
|
|
70
|
+
|
|
71
|
+
VALUE contrast_register_prepend_patch(const char *module_name,
|
|
72
|
+
const char *method_name,
|
|
73
|
+
VALUE(c_fn)(const int, VALUE *,
|
|
74
|
+
const VALUE));
|
|
75
|
+
|
|
76
|
+
static VALUE _contrast_register_patch(const char *module_name, const char *method_name,
|
|
66
77
|
VALUE(c_fn)(const int, VALUE *, const VALUE),
|
|
67
78
|
patch_impl patch_impl);
|
|
68
79
|
|
|
80
|
+
static VALUE _contrast_check_prepended(VALUE self, VALUE method_name, VALUE is_instance);
|
|
81
|
+
|
|
82
|
+
extern VALUE contrast_check_prepended(VALUE self, VALUE method_name, VALUE is_instance);
|
|
83
|
+
|
|
84
|
+
extern VALUE contrast_lookout_prepended(VALUE self, VALUE object_name, VALUE method_name,
|
|
85
|
+
VALUE is_instance);
|
|
86
|
+
|
|
87
|
+
/* check if method is prepended and register instance alias or prepend patch */
|
|
88
|
+
VALUE contrast_check_and_register_instance_patch(const char *module_name,
|
|
89
|
+
const char *method_name,
|
|
90
|
+
VALUE(c_fn)(const int, VALUE *,
|
|
91
|
+
const VALUE));
|
|
92
|
+
|
|
69
93
|
VALUE contrast_patcher();
|
|
70
94
|
|
|
71
95
|
void Init_cs__common(void);
|