contrast-agent 4.3.2 → 4.7.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 (317) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +1 -1
  3. data/.simplecov +1 -1
  4. data/Gemfile +1 -1
  5. data/LICENSE.txt +1 -1
  6. data/Rakefile +2 -3
  7. data/exe/contrast_service +1 -1
  8. data/ext/build_funchook.rb +4 -4
  9. data/ext/cs__assess_active_record_named/cs__active_record_named.c +1 -1
  10. data/ext/cs__assess_active_record_named/extconf.rb +1 -1
  11. data/ext/cs__assess_array/cs__assess_array.c +1 -1
  12. data/ext/cs__assess_array/extconf.rb +1 -1
  13. data/ext/cs__assess_basic_object/cs__assess_basic_object.c +1 -1
  14. data/ext/cs__assess_basic_object/extconf.rb +1 -1
  15. data/ext/cs__assess_fiber_track/cs__assess_fiber_track.c +1 -1
  16. data/ext/cs__assess_fiber_track/extconf.rb +1 -1
  17. data/ext/cs__assess_hash/cs__assess_hash.c +4 -2
  18. data/ext/cs__assess_hash/extconf.rb +1 -1
  19. data/ext/cs__assess_kernel/cs__assess_kernel.c +1 -1
  20. data/ext/cs__assess_kernel/extconf.rb +1 -1
  21. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +1 -1
  22. data/ext/cs__assess_marshal_module/extconf.rb +1 -1
  23. data/ext/cs__assess_module/cs__assess_module.c +1 -1
  24. data/ext/cs__assess_module/extconf.rb +1 -1
  25. data/ext/cs__assess_regexp/cs__assess_regexp.c +1 -1
  26. data/ext/cs__assess_regexp/extconf.rb +1 -1
  27. data/ext/cs__assess_string/cs__assess_string.c +1 -1
  28. data/ext/cs__assess_string/extconf.rb +1 -1
  29. data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.c +1 -1
  30. data/ext/cs__assess_string_interpolation26/extconf.rb +1 -1
  31. data/ext/cs__assess_yield_track/cs__assess_yield_track.c +1 -1
  32. data/ext/cs__assess_yield_track/extconf.rb +1 -1
  33. data/ext/cs__common/cs__common.c +5 -5
  34. data/ext/cs__common/cs__common.h +4 -4
  35. data/ext/cs__common/extconf.rb +1 -1
  36. data/ext/cs__contrast_patch/cs__contrast_patch.c +22 -25
  37. data/ext/cs__contrast_patch/extconf.rb +1 -1
  38. data/ext/cs__protect_kernel/cs__protect_kernel.c +1 -1
  39. data/ext/cs__protect_kernel/extconf.rb +1 -1
  40. data/ext/extconf_common.rb +2 -6
  41. data/lib/contrast-agent.rb +1 -1
  42. data/lib/contrast.rb +20 -1
  43. data/lib/contrast/agent.rb +6 -4
  44. data/lib/contrast/agent/assess.rb +2 -11
  45. data/lib/contrast/agent/assess/contrast_event.rb +54 -71
  46. data/lib/contrast/agent/assess/contrast_object.rb +7 -4
  47. data/lib/contrast/agent/assess/events/event_factory.rb +3 -2
  48. data/lib/contrast/agent/assess/events/source_event.rb +7 -2
  49. data/lib/contrast/agent/assess/finalizers/freeze.rb +1 -1
  50. data/lib/contrast/agent/assess/finalizers/hash.rb +33 -34
  51. data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +34 -16
  52. data/lib/contrast/agent/assess/policy/patcher.rb +11 -18
  53. data/lib/contrast/agent/assess/policy/policy.rb +1 -1
  54. data/lib/contrast/agent/assess/policy/policy_node.rb +26 -34
  55. data/lib/contrast/agent/assess/policy/policy_scanner.rb +1 -1
  56. data/lib/contrast/agent/assess/policy/preshift.rb +4 -2
  57. data/lib/contrast/agent/assess/policy/propagation_method.rb +32 -30
  58. data/lib/contrast/agent/assess/policy/propagation_node.rb +20 -9
  59. data/lib/contrast/agent/assess/policy/propagator.rb +1 -1
  60. data/lib/contrast/agent/assess/policy/propagator/append.rb +29 -14
  61. data/lib/contrast/agent/assess/policy/propagator/base.rb +1 -1
  62. data/lib/contrast/agent/assess/policy/propagator/center.rb +3 -2
  63. data/lib/contrast/agent/assess/policy/propagator/custom.rb +1 -1
  64. data/lib/contrast/agent/assess/policy/propagator/database_write.rb +22 -17
  65. data/lib/contrast/agent/assess/policy/propagator/insert.rb +4 -2
  66. data/lib/contrast/agent/assess/policy/propagator/keep.rb +1 -1
  67. data/lib/contrast/agent/assess/policy/propagator/match_data.rb +3 -2
  68. data/lib/contrast/agent/assess/policy/propagator/next.rb +1 -1
  69. data/lib/contrast/agent/assess/policy/propagator/prepend.rb +1 -1
  70. data/lib/contrast/agent/assess/policy/propagator/remove.rb +23 -19
  71. data/lib/contrast/agent/assess/policy/propagator/replace.rb +1 -1
  72. data/lib/contrast/agent/assess/policy/propagator/reverse.rb +1 -1
  73. data/lib/contrast/agent/assess/policy/propagator/select.rb +3 -13
  74. data/lib/contrast/agent/assess/policy/propagator/splat.rb +24 -14
  75. data/lib/contrast/agent/assess/policy/propagator/split.rb +18 -15
  76. data/lib/contrast/agent/assess/policy/propagator/substitution.rb +32 -22
  77. data/lib/contrast/agent/assess/policy/propagator/trim.rb +64 -45
  78. data/lib/contrast/agent/assess/policy/rewriter_patch.rb +7 -4
  79. data/lib/contrast/agent/assess/policy/source_method.rb +92 -81
  80. data/lib/contrast/agent/assess/policy/source_node.rb +1 -1
  81. data/lib/contrast/agent/assess/policy/source_validation/cross_site_validator.rb +8 -6
  82. data/lib/contrast/agent/assess/policy/source_validation/source_validation.rb +2 -4
  83. data/lib/contrast/agent/assess/policy/trigger/reflected_xss.rb +7 -3
  84. data/lib/contrast/agent/assess/policy/trigger/xpath.rb +7 -8
  85. data/lib/contrast/agent/assess/policy/trigger_method.rb +109 -76
  86. data/lib/contrast/agent/assess/policy/trigger_node.rb +33 -11
  87. data/lib/contrast/agent/assess/policy/trigger_validation/redos_validator.rb +60 -0
  88. data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +3 -5
  89. data/lib/contrast/agent/assess/policy/trigger_validation/trigger_validation.rb +7 -5
  90. data/lib/contrast/agent/assess/policy/trigger_validation/xss_validator.rb +4 -13
  91. data/lib/contrast/agent/assess/properties.rb +1 -3
  92. data/lib/contrast/agent/assess/property/evented.rb +9 -6
  93. data/lib/contrast/agent/assess/property/tagged.rb +38 -20
  94. data/lib/contrast/agent/assess/property/updated.rb +1 -1
  95. data/lib/contrast/agent/assess/rule/provider.rb +1 -1
  96. data/lib/contrast/agent/assess/rule/provider/hardcoded_key.rb +12 -6
  97. data/lib/contrast/agent/assess/rule/provider/hardcoded_password.rb +5 -2
  98. data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +4 -6
  99. data/lib/contrast/agent/assess/tag.rb +1 -1
  100. data/lib/contrast/agent/assess/tracker.rb +2 -2
  101. data/lib/contrast/agent/at_exit_hook.rb +1 -1
  102. data/lib/contrast/agent/class_reopener.rb +4 -2
  103. data/lib/contrast/agent/deadzone/policy/deadzone_node.rb +1 -1
  104. data/lib/contrast/agent/deadzone/policy/policy.rb +7 -3
  105. data/lib/contrast/agent/disable_reaction.rb +2 -4
  106. data/lib/contrast/agent/exclusion_matcher.rb +6 -12
  107. data/lib/contrast/agent/inventory.rb +1 -2
  108. data/lib/contrast/agent/inventory/dependencies.rb +3 -1
  109. data/lib/contrast/agent/inventory/dependency_analysis.rb +1 -1
  110. data/lib/contrast/agent/inventory/dependency_usage_analysis.rb +35 -23
  111. data/lib/contrast/agent/inventory/policy/datastores.rb +1 -1
  112. data/lib/contrast/agent/inventory/policy/policy.rb +1 -1
  113. data/lib/contrast/agent/inventory/policy/trigger_node.rb +1 -1
  114. data/lib/contrast/agent/middleware.rb +111 -110
  115. data/lib/contrast/agent/module_data.rb +4 -4
  116. data/lib/contrast/agent/patching/policy/after_load_patch.rb +1 -1
  117. data/lib/contrast/agent/patching/policy/after_load_patcher.rb +9 -4
  118. data/lib/contrast/agent/patching/policy/method_policy.rb +7 -3
  119. data/lib/contrast/agent/patching/policy/module_policy.rb +15 -8
  120. data/lib/contrast/agent/patching/policy/patch.rb +23 -29
  121. data/lib/contrast/agent/patching/policy/patch_status.rb +8 -9
  122. data/lib/contrast/agent/patching/policy/patcher.rb +72 -64
  123. data/lib/contrast/agent/patching/policy/policy.rb +14 -21
  124. data/lib/contrast/agent/patching/policy/policy_node.rb +15 -5
  125. data/lib/contrast/agent/patching/policy/trigger_node.rb +26 -10
  126. data/lib/contrast/agent/protect/policy/applies_command_injection_rule.rb +2 -2
  127. data/lib/contrast/agent/protect/policy/applies_deserialization_rule.rb +2 -2
  128. data/lib/contrast/agent/protect/policy/applies_no_sqli_rule.rb +2 -2
  129. data/lib/contrast/agent/protect/policy/applies_path_traversal_rule.rb +3 -4
  130. data/lib/contrast/agent/protect/policy/applies_sqli_rule.rb +2 -2
  131. data/lib/contrast/agent/protect/policy/applies_xxe_rule.rb +6 -10
  132. data/lib/contrast/agent/protect/policy/policy.rb +1 -1
  133. data/lib/contrast/agent/protect/policy/rule_applicator.rb +6 -6
  134. data/lib/contrast/agent/protect/policy/trigger_node.rb +1 -1
  135. data/lib/contrast/agent/protect/rule.rb +1 -1
  136. data/lib/contrast/agent/protect/rule/base.rb +19 -33
  137. data/lib/contrast/agent/protect/rule/base_service.rb +10 -6
  138. data/lib/contrast/agent/protect/rule/cmd_injection.rb +15 -19
  139. data/lib/contrast/agent/protect/rule/default_scanner.rb +1 -1
  140. data/lib/contrast/agent/protect/rule/deserialization.rb +7 -14
  141. data/lib/contrast/agent/protect/rule/http_method_tampering.rb +4 -15
  142. data/lib/contrast/agent/protect/rule/no_sqli.rb +7 -3
  143. data/lib/contrast/agent/protect/rule/no_sqli/mongo_no_sql_scanner.rb +2 -4
  144. data/lib/contrast/agent/protect/rule/path_traversal.rb +6 -6
  145. data/lib/contrast/agent/protect/rule/sqli.rb +19 -13
  146. data/lib/contrast/agent/protect/rule/sqli/default_sql_scanner.rb +1 -1
  147. data/lib/contrast/agent/protect/rule/sqli/mysql_sql_scanner.rb +1 -1
  148. data/lib/contrast/agent/protect/rule/sqli/postgres_sql_scanner.rb +2 -2
  149. data/lib/contrast/agent/protect/rule/sqli/sqlite_sql_scanner.rb +1 -1
  150. data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +2 -2
  151. data/lib/contrast/agent/protect/rule/xss.rb +2 -2
  152. data/lib/contrast/agent/protect/rule/xxe.rb +6 -13
  153. data/lib/contrast/agent/protect/rule/xxe/entity_wrapper.rb +2 -3
  154. data/lib/contrast/agent/railtie.rb +1 -1
  155. data/lib/contrast/agent/reaction_processor.rb +12 -11
  156. data/lib/contrast/agent/request.rb +25 -24
  157. data/lib/contrast/agent/request_context.rb +25 -23
  158. data/lib/contrast/agent/request_handler.rb +1 -1
  159. data/lib/contrast/agent/response.rb +1 -1
  160. data/lib/contrast/agent/rewriter.rb +6 -4
  161. data/lib/contrast/agent/rule_set.rb +3 -3
  162. data/lib/contrast/agent/scope.rb +1 -1
  163. data/lib/contrast/agent/service_heartbeat.rb +3 -4
  164. data/lib/contrast/agent/static_analysis.rb +1 -1
  165. data/lib/contrast/agent/thread.rb +2 -2
  166. data/lib/contrast/agent/thread_watcher.rb +21 -6
  167. data/lib/contrast/agent/tracepoint_hook.rb +2 -2
  168. data/lib/contrast/agent/version.rb +2 -2
  169. data/lib/contrast/agent/worker_thread.rb +1 -1
  170. data/lib/contrast/api.rb +1 -1
  171. data/lib/contrast/api/communication.rb +1 -1
  172. data/lib/contrast/api/communication/connection_status.rb +1 -1
  173. data/lib/contrast/api/communication/messaging_queue.rb +19 -22
  174. data/lib/contrast/api/communication/response_processor.rb +13 -8
  175. data/lib/contrast/api/communication/service_lifecycle.rb +5 -3
  176. data/lib/contrast/api/communication/socket.rb +1 -1
  177. data/lib/contrast/api/communication/socket_client.rb +30 -35
  178. data/lib/contrast/api/communication/speedracer.rb +6 -10
  179. data/lib/contrast/api/communication/tcp_socket.rb +1 -1
  180. data/lib/contrast/api/communication/unix_socket.rb +1 -1
  181. data/lib/contrast/api/decorators.rb +3 -1
  182. data/lib/contrast/api/decorators/address.rb +1 -1
  183. data/lib/contrast/api/decorators/agent_startup.rb +58 -0
  184. data/lib/contrast/api/decorators/application_settings.rb +1 -1
  185. data/lib/contrast/api/decorators/application_startup.rb +57 -0
  186. data/lib/contrast/api/decorators/application_update.rb +1 -1
  187. data/lib/contrast/api/decorators/http_request.rb +1 -1
  188. data/lib/contrast/api/decorators/input_analysis.rb +1 -1
  189. data/lib/contrast/api/decorators/instrumentation_mode.rb +37 -0
  190. data/lib/contrast/api/decorators/library.rb +9 -7
  191. data/lib/contrast/api/decorators/library_usage_update.rb +1 -1
  192. data/lib/contrast/api/decorators/message.rb +4 -4
  193. data/lib/contrast/api/decorators/rasp_rule_sample.rb +1 -1
  194. data/lib/contrast/api/decorators/route_coverage.rb +16 -6
  195. data/lib/contrast/api/decorators/server_features.rb +1 -1
  196. data/lib/contrast/api/decorators/trace_event.rb +46 -16
  197. data/lib/contrast/api/decorators/trace_event_object.rb +2 -4
  198. data/lib/contrast/api/decorators/trace_event_signature.rb +1 -1
  199. data/lib/contrast/api/decorators/trace_taint_range.rb +1 -1
  200. data/lib/contrast/api/decorators/trace_taint_range_tags.rb +2 -7
  201. data/lib/contrast/api/decorators/user_input.rb +1 -1
  202. data/lib/contrast/components/agent.rb +16 -15
  203. data/lib/contrast/components/app_context.rb +11 -29
  204. data/lib/contrast/components/assess.rb +6 -11
  205. data/lib/contrast/components/config.rb +3 -2
  206. data/lib/contrast/components/contrast_service.rb +8 -9
  207. data/lib/contrast/components/heap_dump.rb +1 -1
  208. data/lib/contrast/components/interface.rb +4 -3
  209. data/lib/contrast/components/inventory.rb +1 -1
  210. data/lib/contrast/components/logger.rb +1 -1
  211. data/lib/contrast/components/protect.rb +11 -14
  212. data/lib/contrast/components/sampling.rb +55 -7
  213. data/lib/contrast/components/scope.rb +2 -1
  214. data/lib/contrast/components/settings.rb +29 -99
  215. data/lib/contrast/config.rb +1 -1
  216. data/lib/contrast/config/agent_configuration.rb +1 -1
  217. data/lib/contrast/config/application_configuration.rb +1 -1
  218. data/lib/contrast/config/assess_configuration.rb +1 -1
  219. data/lib/contrast/config/assess_rules_configuration.rb +2 -4
  220. data/lib/contrast/config/base_configuration.rb +5 -6
  221. data/lib/contrast/config/default_value.rb +1 -1
  222. data/lib/contrast/config/exception_configuration.rb +2 -6
  223. data/lib/contrast/config/heap_dump_configuration.rb +13 -7
  224. data/lib/contrast/config/inventory_configuration.rb +1 -1
  225. data/lib/contrast/config/logger_configuration.rb +2 -6
  226. data/lib/contrast/config/protect_configuration.rb +1 -1
  227. data/lib/contrast/config/protect_rule_configuration.rb +23 -1
  228. data/lib/contrast/config/protect_rules_configuration.rb +1 -1
  229. data/lib/contrast/config/root_configuration.rb +1 -1
  230. data/lib/contrast/config/ruby_configuration.rb +1 -1
  231. data/lib/contrast/config/sampling_configuration.rb +1 -1
  232. data/lib/contrast/config/server_configuration.rb +1 -1
  233. data/lib/contrast/config/service_configuration.rb +1 -1
  234. data/lib/contrast/configuration.rb +4 -15
  235. data/lib/contrast/delegators/input_analysis.rb +12 -0
  236. data/lib/contrast/extension/assess.rb +1 -1
  237. data/lib/contrast/extension/assess/array.rb +2 -7
  238. data/lib/contrast/extension/assess/erb.rb +2 -8
  239. data/lib/contrast/extension/assess/eval_trigger.rb +3 -11
  240. data/lib/contrast/extension/assess/exec_trigger.rb +4 -14
  241. data/lib/contrast/extension/assess/fiber.rb +3 -13
  242. data/lib/contrast/extension/assess/hash.rb +1 -1
  243. data/lib/contrast/extension/assess/kernel.rb +3 -10
  244. data/lib/contrast/extension/assess/marshal.rb +3 -11
  245. data/lib/contrast/extension/assess/regexp.rb +2 -7
  246. data/lib/contrast/extension/assess/string.rb +4 -2
  247. data/lib/contrast/extension/delegator.rb +1 -1
  248. data/lib/contrast/extension/inventory.rb +1 -1
  249. data/lib/contrast/extension/kernel.rb +5 -3
  250. data/lib/contrast/extension/module.rb +1 -1
  251. data/lib/contrast/extension/protect.rb +1 -1
  252. data/lib/contrast/extension/protect/kernel.rb +1 -1
  253. data/lib/contrast/extension/protect/psych.rb +1 -1
  254. data/lib/contrast/extension/thread.rb +1 -1
  255. data/lib/contrast/framework/base_support.rb +1 -1
  256. data/lib/contrast/framework/manager.rb +14 -17
  257. data/lib/contrast/framework/platform_version.rb +1 -1
  258. data/lib/contrast/framework/rack/patch/session_cookie.rb +6 -19
  259. data/lib/contrast/framework/rack/patch/support.rb +7 -5
  260. data/lib/contrast/framework/rack/support.rb +1 -1
  261. data/lib/contrast/framework/rails/patch/action_controller_live_buffer.rb +1 -1
  262. data/lib/contrast/framework/rails/patch/assess_configuration.rb +8 -3
  263. data/lib/contrast/framework/rails/patch/rails_application_configuration.rb +4 -4
  264. data/lib/contrast/framework/rails/patch/support.rb +5 -3
  265. data/lib/contrast/framework/rails/rewrite/action_controller_railties_helper_inherited.rb +5 -2
  266. data/lib/contrast/framework/rails/rewrite/active_record_attribute_methods_read.rb +3 -1
  267. data/lib/contrast/framework/rails/rewrite/active_record_named.rb +3 -1
  268. data/lib/contrast/framework/rails/rewrite/active_record_time_zone_inherited.rb +3 -1
  269. data/lib/contrast/framework/rails/support.rb +45 -46
  270. data/lib/contrast/framework/sinatra/support.rb +103 -42
  271. data/lib/contrast/funchook/funchook.rb +2 -6
  272. data/lib/contrast/logger/application.rb +13 -10
  273. data/lib/contrast/logger/format.rb +3 -6
  274. data/lib/contrast/logger/log.rb +36 -19
  275. data/lib/contrast/logger/request.rb +2 -3
  276. data/lib/contrast/logger/time.rb +1 -1
  277. data/lib/contrast/security_exception.rb +2 -2
  278. data/lib/contrast/tasks/config.rb +1 -1
  279. data/lib/contrast/tasks/service.rb +6 -2
  280. data/lib/contrast/utils/assess/sampling_util.rb +1 -1
  281. data/lib/contrast/utils/assess/tracking_util.rb +2 -3
  282. data/lib/contrast/utils/class_util.rb +18 -12
  283. data/lib/contrast/utils/duck_utils.rb +1 -1
  284. data/lib/contrast/utils/env_configuration_item.rb +1 -1
  285. data/lib/contrast/utils/hash_digest.rb +16 -24
  286. data/lib/contrast/utils/heap_dump_util.rb +104 -88
  287. data/lib/contrast/utils/invalid_configuration_util.rb +22 -13
  288. data/lib/contrast/utils/inventory_util.rb +1 -1
  289. data/lib/contrast/utils/io_util.rb +2 -2
  290. data/lib/contrast/utils/job_servers_running.rb +10 -5
  291. data/lib/contrast/utils/object_share.rb +1 -1
  292. data/lib/contrast/utils/os.rb +3 -2
  293. data/lib/contrast/utils/preflight_util.rb +1 -1
  294. data/lib/contrast/utils/resource_loader.rb +1 -1
  295. data/lib/contrast/utils/ruby_ast_rewriter.rb +3 -2
  296. data/lib/contrast/utils/sha256_builder.rb +1 -1
  297. data/lib/contrast/utils/stack_trace_utils.rb +1 -1
  298. data/lib/contrast/utils/string_utils.rb +1 -1
  299. data/lib/contrast/utils/tag_util.rb +1 -1
  300. data/lib/contrast/utils/thread_tracker.rb +1 -1
  301. data/lib/contrast/utils/timer.rb +1 -1
  302. data/resources/assess/policy.json +8 -11
  303. data/resources/deadzone/policy.json +7 -17
  304. data/ruby-agent.gemspec +66 -27
  305. data/service_executables/VERSION +1 -1
  306. data/service_executables/linux/contrast-service +0 -0
  307. data/service_executables/mac/contrast-service +0 -0
  308. data/sonar-project.properties +9 -0
  309. metadata +154 -156
  310. data/lib/contrast/agent/assess/rule.rb +0 -18
  311. data/lib/contrast/agent/assess/rule/base.rb +0 -52
  312. data/lib/contrast/agent/assess/rule/redos.rb +0 -67
  313. data/lib/contrast/agent/inventory/gemfile_digest_cache.rb +0 -38
  314. data/lib/contrast/common_agent_configuration.rb +0 -87
  315. data/lib/contrast/framework/sinatra/patch/base.rb +0 -83
  316. data/lib/contrast/framework/sinatra/patch/support.rb +0 -27
  317. data/lib/contrast/utils/prevent_serialization.rb +0 -52
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
1
+ # Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Contrast
@@ -6,11 +6,11 @@ module Contrast
6
6
  # A simple wrapper around a Module and a call to its name, used to avoid
7
7
  # calling the Module#name method and generating extra Strings
8
8
  class ModuleData
9
- attr_reader :mod, :name
9
+ attr_reader :mod, :mod_name
10
10
 
11
- def initialize mod, name = nil
11
+ def initialize mod, mod_name = nil
12
12
  @mod = mod
13
- @name = name || mod.cs__name
13
+ @mod_name = mod_name || mod.cs__name
14
14
  end
15
15
  end
16
16
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
1
+ # Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/components/interface'
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
1
+ # Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/agent/patching/policy/after_load_patch'
@@ -51,10 +51,15 @@ module Contrast
51
51
  next unless after_load_patch.target_defined?
52
52
  next if AGENT.skip_instrumentation?(after_load_patch.module_name)
53
53
 
54
- logger.trace(
55
- 'Catching up on already loaded afterload patch - applying instrumentation',
56
- module: after_load_patch.module_name)
54
+ logger.trace('Catching up on already loaded afterload patch - applying instrumentation',
55
+ module: after_load_patch.module_name)
57
56
  after_load_patch.instrument!
57
+ rescue NameError => e
58
+ logger.error('Method undefined in afterload patch', e, module: after_load_patch.module_name,
59
+ method: after_load_patch.method_to_instrument)
60
+ rescue StandardError => e
61
+ logger.error('Afterload patch failed to apply', e, module: after_load_patch.module_name,
62
+ method: after_load_patch.method_to_instrument)
58
63
  end
59
64
  after_load_patches.delete_if(&:applied?)
60
65
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
1
+ # Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Contrast
@@ -49,7 +49,10 @@ module Contrast
49
49
  private
50
50
 
51
51
  def nodes
52
- @_nodes ||= [source_node, propagation_node, trigger_node, inventory_node, protect_node, deadzone_node].compact
52
+ @_nodes ||= [
53
+ source_node, propagation_node, trigger_node, inventory_node, protect_node,
54
+ deadzone_node
55
+ ].compact
53
56
  end
54
57
 
55
58
  def method_scopes
@@ -76,7 +79,8 @@ module Contrast
76
79
  protect_node = find_method_node(module_policy.protect_nodes, method_name, instance_method)
77
80
  inventory_node = find_method_node(module_policy.inventory_nodes, method_name, instance_method)
78
81
  deadzone_node = find_method_node(module_policy.deadzone_nodes, method_name, instance_method)
79
- method_visibility = find_visibility(source_node, propagation_node, trigger_node, protect_node, inventory_node, deadzone_node)
82
+ method_visibility = find_visibility(source_node, propagation_node, trigger_node, protect_node,
83
+ inventory_node, deadzone_node)
80
84
  MethodPolicy.new(method_name: method_name,
81
85
  method_visibility: method_visibility,
82
86
  instance_method: instance_method,
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
1
+ # Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'contrast/agent/patching/policy/method_policy'
@@ -20,12 +20,18 @@ module Contrast
20
20
  # @return [Contrast::Agent::Patching::Policy::ModulePolicy]
21
21
  def create_module_policy module_name
22
22
  module_policy = Contrast::Agent::Patching::Policy::ModulePolicy.new
23
- module_policy.source_nodes = nodes_for_module(Contrast::Agent::Assess::Policy::Policy.instance.sources, module_name)
24
- module_policy.propagator_nodes = nodes_for_module(Contrast::Agent::Assess::Policy::Policy.instance.propagators, module_name)
25
- module_policy.trigger_nodes = nodes_for_module(Contrast::Agent::Assess::Policy::Policy.instance.triggers, module_name)
26
- module_policy.protect_nodes = nodes_for_module(Contrast::Agent::Protect::Policy::Policy.instance.triggers, module_name)
27
- module_policy.inventory_nodes = nodes_for_module(Contrast::Agent::Inventory::Policy::Policy.instance.triggers, module_name)
28
- module_policy.deadzone_nodes = nodes_for_module(Contrast::Agent::Deadzone::Policy::Policy.instance.deadzones, module_name)
23
+ module_policy.source_nodes = nodes_for_module(
24
+ Contrast::Agent::Assess::Policy::Policy.instance.sources, module_name)
25
+ module_policy.propagator_nodes = nodes_for_module(
26
+ Contrast::Agent::Assess::Policy::Policy.instance.propagators, module_name)
27
+ module_policy.trigger_nodes = nodes_for_module(
28
+ Contrast::Agent::Assess::Policy::Policy.instance.triggers, module_name)
29
+ module_policy.protect_nodes = nodes_for_module(
30
+ Contrast::Agent::Protect::Policy::Policy.instance.triggers, module_name)
31
+ module_policy.inventory_nodes = nodes_for_module(
32
+ Contrast::Agent::Inventory::Policy::Policy.instance.triggers, module_name)
33
+ module_policy.deadzone_nodes = nodes_for_module(
34
+ Contrast::Agent::Deadzone::Policy::Policy.instance.deadzones, module_name)
29
35
  module_policy
30
36
  end
31
37
 
@@ -42,7 +48,8 @@ module Contrast
42
48
  end
43
49
  end
44
50
 
45
- attr_accessor :source_nodes, :propagator_nodes, :trigger_nodes, :inventory_nodes, :protect_nodes, :deadzone_nodes
51
+ attr_accessor :source_nodes, :propagator_nodes, :trigger_nodes, :inventory_nodes, :protect_nodes,
52
+ :deadzone_nodes
46
53
 
47
54
  def empty?
48
55
  return false if source_nodes.any?
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
1
+ # Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'monitor'
@@ -130,11 +130,7 @@ module Contrast
130
130
  return unless AGENT.enabled?
131
131
  return unless PROTECT.enabled?
132
132
 
133
- apply_trigger_only(method_policy&.protect_node,
134
- method,
135
- exception,
136
- object,
137
- args)
133
+ apply_trigger_only(method_policy&.protect_node, method, exception, object, args)
138
134
  end
139
135
 
140
136
  # Apply the Inventory patch which applies to the given method.
@@ -151,11 +147,7 @@ module Contrast
151
147
  def apply_inventory method_policy, method, exception, object, args
152
148
  return unless INVENTORY.enabled?
153
149
 
154
- apply_trigger_only(method_policy&.inventory_node,
155
- method,
156
- exception,
157
- object,
158
- args)
150
+ apply_trigger_only(method_policy&.inventory_node, method, exception, object, args)
159
151
  end
160
152
 
161
153
  # Apply the Assess patches which apply to the given method.
@@ -178,15 +170,18 @@ module Contrast
178
170
  return ret unless method_policy && ASSESS.enabled?
179
171
 
180
172
  current_context = Contrast::Agent::REQUEST_TRACKER.current
181
- return ret unless current_context.analyze_request?
173
+ return ret if current_context && !current_context.analyze_request?
182
174
 
183
175
  trigger_node = method_policy.trigger_node
184
- Contrast::Agent::Assess::Policy::TriggerMethod.apply_trigger_rule(trigger_node, object, ret, args) if trigger_node
176
+ if trigger_node
177
+ Contrast::Agent::Assess::Policy::TriggerMethod.apply_trigger_rule(trigger_node, object, ret, args)
178
+ end
185
179
  if method_policy.source_node
186
180
  # If we were given a frozen return, and it was the target of a
187
181
  # source, and we have frozen sources enabled, we'll need to
188
182
  # replace the return. Note, this is not the default case.
189
- source_ret = Contrast::Agent::Assess::Policy::SourceMethod.source_patchers(method_policy, object, ret, args)
183
+ source_ret = Contrast::Agent::Assess::Policy::SourceMethod.source_patchers(method_policy, object, ret,
184
+ args)
190
185
  end
191
186
  if method_policy.propagation_node
192
187
  propagated_ret = Contrast::Agent::Assess::Policy::PropagationMethod.apply_propagation(
@@ -277,9 +272,9 @@ module Contrast
277
272
  # <method_start>_unbound_<method_name>
278
273
  def build_unbound_method_name patcher_method
279
274
  (Contrast::Utils::ObjectShare::CONTRAST_PATCHED_METHOD_START +
280
- 'unbound' +
281
- Contrast::Utils::ObjectShare::UNDERSCORE +
282
- patcher_method.to_s).to_sym
275
+ 'unbound' +
276
+ Contrast::Utils::ObjectShare::UNDERSCORE +
277
+ patcher_method.to_s).to_sym
283
278
  end
284
279
 
285
280
  # @param mod [Module] the module in which the patch should be
@@ -339,7 +334,7 @@ module Contrast
339
334
  # @return [Symbol] new alias for the underlying method (presumably, so the patched method can call it)
340
335
  def register_c_patch target_module_name, unbound_method, impl = :alias_instance
341
336
  # These could be set as AfterLoadPatches.
342
- method_name = unbound_method.name.to_sym
337
+ method_name = unbound_method.name.to_sym # rubocop:disable Security/Module/Name -- ruby built in attribute.
343
338
  underlying_method_name = build_unbound_method_name(method_name).to_sym
344
339
 
345
340
  target_module = Module.cs__const_get(target_module_name)
@@ -362,29 +357,27 @@ module Contrast
362
357
 
363
358
  case impl
364
359
  when :alias_instance, :alias_singleton
360
+ # Core to patching. Ignore define method usage cop.
361
+ # rubocop:disable Performance/Kernel/DefineMethod
365
362
  unless target_module.instance_methods(false).include? underlying_method_name
366
363
  # alias_method may be private
367
364
  target_module.send(:alias_method, underlying_method_name, method_name)
368
- # TODO: RUBY-1052
369
- # rubocop:disable Performance/Kernel/DefineMethod
370
365
  target_module.send(:define_method, method_name, unbound_method.bind(target_module))
371
- # rubocop:enable Performance/Kernel/DefineMethod
372
366
  end
373
367
  target_module.send(visibility, method_name) # e.g., module.private(:my_method)
374
368
  when :prepend
375
369
  prepending_module = Module.new
376
- # TODO: RUBY-1052
377
- # rubocop:disable Performance/Kernel/DefineMethod
378
370
  prepending_module.send(:define_method, method_name, unbound_method.bind(target_module))
379
- # rubocop:enable Performance/Kernel/DefineMethod
380
371
  prepending_module.send(visibility, method_name)
381
372
  # This prepends to the singleton class (it patches a class method)
382
373
  target_module.prepend prepending_module
374
+ # rubocop:enable Performance/Kernel/DefineMethod
383
375
  end
384
376
  # Ougai::Logger.create_item_with_2args calls Hash#[]=, so we
385
377
  # can't invoke this logging method or we'll seg fault as we'd
386
378
  # change the method definition mid-call
387
- # if method_name != :[]=
379
+ # if method_name != :[]= &&
380
+ # Contrast::Agent::Logger.defined!
388
381
  # logger.trace(
389
382
  # 'Registered C-defined patch',
390
383
  # implementation: impl,
@@ -392,14 +385,15 @@ module Contrast
392
385
  # method: method_name,
393
386
  # visibility: visibility)
394
387
  # end
395
- underlying_method_name.to_sym
388
+ underlying_method_name
396
389
  end
397
390
 
398
391
  # @return [Boolean]
399
392
  def skip_contrast_analysis?
400
393
  return true if in_contrast_scope?
401
- return true unless defined?(Contrast::Agent::REQUEST_TRACKER)
402
- return true unless Contrast::Agent::REQUEST_TRACKER.current&.analyze_request?
394
+ return false unless defined?(Contrast::Agent::REQUEST_TRACKER)
395
+ return false unless Contrast::Agent::REQUEST_TRACKER.current
396
+ return true unless Contrast::Agent::REQUEST_TRACKER.current.analyze_request?
403
397
 
404
398
  false
405
399
  end
@@ -411,7 +405,7 @@ module Contrast
411
405
  def skip_assess_analysis?
412
406
  return true if skip_contrast_analysis?
413
407
 
414
- !ASSESS.enabled?
408
+ !ASSESS&.enabled?
415
409
  end
416
410
  end
417
411
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
1
+ # Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Contrast
@@ -13,7 +13,7 @@ module Contrast
13
13
  # one does not exist.
14
14
  #
15
15
  # @param mod [Module] the Module for which the status is asked
16
- # @return [Contrast::Agent::Patching::Policy::PolicyStatus]
16
+ # @return [Contrast::Agent::Patching::Policy::PatchStatus]
17
17
  def get_status mod
18
18
  if mod.cs__const_defined?(status_key, false)
19
19
  mod.cs__const_get(status_key, false)
@@ -68,7 +68,10 @@ module Contrast
68
68
  def set_info_for mod, method, method_policy, is_instance_method, cs_method
69
69
  mod.instance_variable_set(method_info_key, {}) unless mod.instance_variable_defined?(method_info_key)
70
70
  holder = mod.instance_variable_get(method_info_key)
71
- holder[method_name_key(method, is_instance_method)] = [method_policy, cs_method] unless holder.key?(method)
71
+ # if we already have this information, then we don't need to set it as we'll update the info on access
72
+ return if holder.key?(method)
73
+
74
+ holder[method_name_key(method, is_instance_method)] = [method_policy, cs_method]
72
75
  end
73
76
 
74
77
  private
@@ -153,9 +156,7 @@ module Contrast
153
156
  end
154
157
 
155
158
  def patched?
156
- @patch_status == :PATCHED ||
157
- @patch_status == :NONE ||
158
- @patch_status == :FAILED
159
+ @patch_status == :PATCHED || @patch_status == :NONE || @patch_status == :FAILED
159
160
  end
160
161
 
161
162
  def rewriting!
@@ -179,9 +180,7 @@ module Contrast
179
180
  end
180
181
 
181
182
  def rewritten?
182
- @rewrite_status == :REWRITTEN ||
183
- @rewrite_status == :NO_REWRITE ||
184
- @rewrite_status == :FAILED_REWRITE
183
+ @rewrite_status == :REWRITTEN || @rewrite_status == :NO_REWRITE || @rewrite_status == :FAILED_REWRITE
185
184
  end
186
185
  end
187
186
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
1
+ # Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'monitor'
@@ -13,7 +13,8 @@ require 'contrast/utils/class_util'
13
13
  # assess
14
14
  require 'contrast/agent/assess/policy/policy'
15
15
  require 'contrast/agent/assess/policy/policy_scanner'
16
- require 'contrast/agent/assess/policy/rewriter_patch'
16
+ # TODO: RUBY-714 remove guard w/ EOL of 2.5
17
+ require 'contrast/agent/assess/policy/rewriter_patch' if RUBY_VERSION < '2.6.0'
17
18
  require 'contrast/agent/assess/policy/source_method'
18
19
  require 'contrast/agent/assess/policy/trigger_method'
19
20
 
@@ -52,8 +53,8 @@ module Contrast
52
53
  # startup to catchup on everything we didn't see get loaded
53
54
  def patch
54
55
  catchup_after_load_patches
55
- patch_methods
56
- Contrast::Agent::Assess::Policy::RewriterPatch.rewrite_interpolations
56
+ catchup_loaded_methods
57
+ Contrast::Agent::Assess::Policy::RewriterPatch.rewrite_interpolations if RUBY_VERSION < '2.6.0' # TODO: RUBY-714 remove guard w/ EOL of 2.5
57
58
  end
58
59
 
59
60
  # Hook to only monkeypatch Contrast. This will not trigger any
@@ -62,10 +63,11 @@ module Contrast
62
63
  # where only a subset of the Assess changes are needed.
63
64
  PATCH_MONITOR = Monitor.new
64
65
 
65
- def patch_methods
66
+ # Iterate over and patch those Modules and Methods which were loaded before the Agent was enabled.
67
+ def catchup_loaded_methods
66
68
  PATCH_MONITOR.synchronize do
67
69
  t = Contrast::Agent::Thread.new do
68
- synchronized_patch_methods
70
+ synchronized_catchup_loaded_methods
69
71
  end
70
72
  # aborting on exception makes exceptions propagate.
71
73
  t.abort_on_exception = true
@@ -84,7 +86,7 @@ module Contrast
84
86
 
85
87
  load_patches_for_module(mod_name)
86
88
 
87
- return unless all_module_names.any? { |name| name == mod_name }
89
+ return unless all_module_names.any?(mod_name)
88
90
 
89
91
  module_data = Contrast::Agent::ModuleData.new(mod, mod_name)
90
92
  patch_into_module(module_data)
@@ -100,7 +102,7 @@ module Contrast
100
102
  # @param mod [Module] the module in which the patch should be
101
103
  # placed.
102
104
  # @param methods [Array(Symbol)] all the instance or singleton
103
- # methods in this clazz.
105
+ # methods in this mod.
104
106
  # @param method_policy [Contrast::Agent::Patching::Policy::MethodPolicy]
105
107
  # the policy that applies to the given method_name.
106
108
  # @return [Boolean] if patched, either by this invocation or a
@@ -142,14 +144,15 @@ module Contrast
142
144
  # @return [Array<String>] the names of all the Modules for which
143
145
  # there patches in our policies
144
146
  def all_module_names
145
- @_all_module_names ||= POLICIES.each_with_object(Set.new) { |policy, set| set.merge(policy.instance.module_names) }
147
+ @_all_module_names ||=
148
+ POLICIES.each_with_object(Set.new) { |policy, set| set.merge(policy.instance.module_names) }
146
149
  end
147
150
 
148
151
  # Hook to only monkeypatch Contrast. This will not trigger any
149
152
  # other functions, like rewriting or scanning. This method should
150
153
  # only be invoked by the patch_methods method above in order to
151
154
  # ensure it is wrapped in a synchronize call
152
- def synchronized_patch_methods
155
+ def synchronized_catchup_loaded_methods
153
156
  logger.trace_with_time('Running patching') do
154
157
  patched = []
155
158
  all_module_names.each do |patchable_name|
@@ -166,59 +169,42 @@ module Contrast
166
169
  end
167
170
  end
168
171
 
169
- # Given the patchers that apply to this class that may apply, patch
170
- # Contrast method calls into the methods for which we have rules.
172
+ # Given the patchers that apply to this class that may apply, patch Contrast method calls into the methods
173
+ # for which we have rules.
171
174
  #
172
- # @param module_data [Contrast::Agent::ModuleData] the module, and
173
- # its name, that's being patched into
174
- # @param redo_patch [Boolean] a trigger to force patching
175
- # regardless of the state of the
176
- # Contrast::Agent::Patching::Policy::PatchStatus status on the
177
- # Module
175
+ # @param module_data [Contrast::Agent::ModuleData] the module, and its name, that's being patched into
176
+ # @param redo_patch [Boolean] a trigger to force patching regardless of the state of the
177
+ # Contrast::Agent::Patching::Policy::PatchStatus status on the Module
178
178
  def patch_into_module module_data, redo_patch = false
179
179
  status = status_type.get_status(module_data.mod)
180
180
  return if (status&.patched? || status&.patching?) && !redo_patch
181
181
 
182
- # Begin patching our sources into the given clazz (or module)
183
- # Any patcher that has the name of the clazz will be evaluated for
184
- # patching.
185
- # Find all the patchers that apply to this class, sorted by type.
186
- module_policy = Contrast::Agent::Patching::Policy::ModulePolicy.create_module_policy(module_data.name)
187
-
188
- clazz = module_data.mod
182
+ # Begin patching our sources into the given module. Any patcher that has the name of the module will be
183
+ # evaluated for patching. Find all the patchers that apply to this class, sorted by type.
184
+ module_policy = Contrast::Agent::Patching::Policy::ModulePolicy.create_module_policy(module_data.mod_name)
185
+ # If there's nothing to match, then set that status and exit
186
+ if module_policy.empty?
187
+ status.no_patch!
188
+ return
189
+ end
189
190
 
190
191
  status.patching!
191
- patched = false
192
-
193
- counts = 0
194
- # Monkey patch any methods in this class that have matching nodes in the policy
195
- unless module_policy.empty?
196
- instance_methods = all_instance_methods(clazz, true)
197
- singleton_methods = clazz.singleton_methods(false)
198
- counts += patch_into_methods(clazz, instance_methods, module_policy, true)
199
- counts += patch_into_methods(clazz, singleton_methods, module_policy, false)
200
- counts = module_policy.num_expected_patches if adjust_for_prepend(clazz)
201
- patched = true
202
- end
192
+ num_applied_patches = patch_into_instance_methods(module_data, module_policy)
193
+ num_applied_patches += patch_into_singleton_methods(module_data, module_policy)
194
+ if adjust_for_prepend(module_data) || module_policy.num_expected_patches == num_applied_patches
203
195
 
204
- if patched
205
- if module_policy.num_expected_patches == counts
206
- status.patched!
207
- else
208
- status.partial_patch!
209
- end
196
+ status.patched!
210
197
  else
211
- status.no_patch!
198
+ status.partial_patch!
212
199
  end
213
200
  rescue StandardError => e
214
- status ||= status_type.get_status(module_data.mod)
215
- status.failed_patch!
216
- logger.warn('Patching failed', e, module: module_data.name)
201
+ status&.failed_patch!
202
+ logger.warn('Patching failed', e, module: module_data.mod_name)
217
203
  ensure
218
204
  logger.trace('Patching complete',
219
- module: module_data.name,
220
- result: Contrast::Agent::Patching::Policy::PatchStatus.get_status(
221
- module_data.mod).patch_status)
205
+ module: module_data.mod_name,
206
+ result:
207
+ Contrast::Agent::Patching::Policy::PatchStatus.get_status(module_data.mod).patch_status)
222
208
  end
223
209
 
224
210
  # Get all of the instance methods on the given module, excluding
@@ -249,22 +235,45 @@ module Contrast
249
235
  instance_methods
250
236
  end
251
237
 
238
+ # Patch into the Instance Methods, including private, of the given Module that match the ModulePolicy
239
+ # provided.
240
+ #
241
+ # @param module_data [Contrast::Agent::ModuleData] the module, and its name, that's being patched into
242
+ # @param module_policy [Contrast::Agent::Patching::Policy::ModulePolicy] All the patchers that apply to
243
+ # this module, sorted by type.
244
+ def patch_into_instance_methods module_data, module_policy
245
+ mod = module_data.mod
246
+ methods = all_instance_methods(mod, true)
247
+ patch_into_methods(mod, methods, module_policy, true)
248
+ end
249
+
250
+ # Patch into the Singleton Methods of the given Module that match the ModulePolicy provided.
251
+ #
252
+ # @param module_data [Contrast::Agent::ModuleData] the module, and its name, that's being patched into
253
+ # @param module_policy [Contrast::Agent::Patching::Policy::ModulePolicy] All the patchers that apply to
254
+ # this module, sorted by type.
255
+ def patch_into_singleton_methods module_data, module_policy
256
+ mod = module_data.mod
257
+ methods = mod.singleton_methods(false)
258
+ patch_into_methods(mod, methods, module_policy, false)
259
+ end
260
+
252
261
  # We've found the patchers that apply to this class (or module). Now we'll
253
262
  # filter on the given method.
254
263
  #
255
- # @param mod [Module] The module from which to retrieve instance
256
- # methods.
257
- # @param methods [Array<Symbol>] The names of all the methods in
258
- # in this module
259
- # @param module_policy [Contrast::Agent::Patching::Policy::ModulePolicy]
260
- # All the patchers that apply to this class, sorted by type.
261
- # @param is_instance_method [Boolean] Indicates if these methods
262
- # are the instance or singleton methods for this module.
263
- # @return [Integer] number of methods patched
264
+ # @param mod [Module] The module from which to retrieve instance methods.
265
+ # @param methods [Array<Symbol>] The names of all the methods in in this module
266
+ # @param module_policy [Contrast::Agent::Patching::Policy::ModulePolicy] All the patchers that apply to
267
+ # this class, sorted by type.
268
+ # @param is_instance_method [Boolean] Indicates if these methods are the instance or singleton methods for
269
+ # this module.
270
+ # @return [Integer] number of methods patched.
264
271
  def patch_into_methods mod, methods, module_policy, is_instance_method
265
272
  count = 0
266
273
  methods.each do |method|
267
- method_policy = Contrast::Agent::Patching::Policy::MethodPolicy.build_method_policy(method, module_policy, is_instance_method)
274
+ method_policy = Contrast::Agent::Patching::Policy::MethodPolicy.build_method_policy(method,
275
+ module_policy,
276
+ is_instance_method)
268
277
  next if method_policy.empty?
269
278
 
270
279
  patched = patch_method(mod, methods, method_policy)
@@ -279,11 +288,10 @@ module Contrast
279
288
  # it has to be reapplied.
280
289
  # TODO: RUBY-620 should remove the need for this
281
290
  #
282
- # @param mod[Module] the Module for which a prepend action needs to
283
- # be accounted
291
+ # @param module_data [Contrast::Agent::ModuleData] the module, and its name, that's being patched into
284
292
  # @return [Boolean] if an adjustment was made or not
285
- def adjust_for_prepend mod
286
- return false unless mod.cs__name == 'CGI::Util'
293
+ def adjust_for_prepend module_data
294
+ return false unless module_data.mod.cs__name == 'CGI::Util'
287
295
 
288
296
  CGI.include(CGI::Util)
289
297
  CGI.extend(CGI::Util)