Module: Contrast::Utils::Patching::PatchUtils
- Included in:
- Agent::Patching::Policy::Patch
- Defined in:
- lib/contrast/utils/patching/policy/patch_utils.rb
Overview
This module will include all methods for different patch applies from Patch module and some other module methods from the same place, so we can ease the main module
Instance Method Summary collapse
-
#apply_assess(method_policy, preshift, object, ret, args, block) ⇒ Object
Apply the Assess patches which apply to the given method.
-
#apply_inventory(method_policy, method, exception, object, args) ⇒ Object
Apply the Inventory patch which applies to the given method.
-
#apply_post_patch(method_policy, preshift, object, ret, args, block) ⇒ Object
THIS IS CALLED FROM C.
-
#apply_pre_patch(method_policy, method, exception, object, args) ⇒ Object
PATCH APPLIERS ===== THIS IS CALLED FROM C.
-
#apply_protect(method_policy, method, exception, object, args) ⇒ Object
Apply the Protect patch which applies to the given method.
-
#apply_trigger_only(trigger_node, method, exception, object, args) ⇒ Object
Generic invocation of the Inventory or Protect patch which apply to the given method.
-
#build_method_name(patched_class, patched_method) ⇒ Symbol
Given a module and method, construct an expected name for the alias by which Contrast will reference the original.
-
#build_unbound_method_name(patcher_method) ⇒ Object
Given a method, return a symbol in the format <method_start>unbound<method_name>.
Instance Method Details
#apply_assess(method_policy, preshift, object, ret, args, block) ⇒ Object
Apply the Assess patches which apply to the given method.
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/contrast/utils/patching/policy/patch_utils.rb', line 113 def apply_assess method_policy, preshift, object, ret, args, block return ret unless method_policy && ::Contrast::ASSESS.enabled? current_context = Contrast::Agent::REQUEST_TRACKER.current return ret if current_context && !current_context.analyze_request? trigger_node = method_policy.trigger_node if trigger_node && !trigger_node.nil? Contrast::Agent::Assess::Policy::TriggerMethod.apply_trigger_rule(trigger_node, object, ret, args) end if method_policy.source_node Contrast::Agent::Assess::Policy::SourceMethod.apply_source(method_policy, object, ret, args) end if method_policy.propagation_node Contrast::Agent::Assess::Policy::PropagationMethod.apply_propagation( method_policy, preshift, object, ret, args, block) end rescue StandardError => e logger.error('Unable to assess method call.', e) rescue Exception => e # rubocop:disable Lint/RescueException logger.error('Unable to assess method call due to exception.', e) raise(e) ensure ret.rewind if Contrast::Utils::IOUtil.should_rewind?(ret) end |
#apply_inventory(method_policy, method, exception, object, args) ⇒ Object
Apply the Inventory patch which applies to the given method.
97 98 99 100 101 |
# File 'lib/contrast/utils/patching/policy/patch_utils.rb', line 97 def apply_inventory method_policy, method, exception, object, args return unless ::Contrast::INVENTORY.enable apply_trigger_only(method_policy&.inventory_node, method, exception, object, args) end |
#apply_post_patch(method_policy, preshift, object, ret, args, block) ⇒ Object
THIS IS CALLED FROM C. Do not change the signature lightly.
This method functions to call the infilter methods from our patches, allowing for analysis and reporting at the point just after the patched code is invoked
68 69 70 71 72 |
# File 'lib/contrast/utils/patching/policy/patch_utils.rb', line 68 def apply_post_patch method_policy, preshift, object, ret, args, block apply_assess(method_policy, preshift, object, ret, args, block) rescue StandardError => e logger.error('Unable to apply post patch to method.', e) end |
#apply_pre_patch(method_policy, method, exception, object, args) ⇒ Object
PATCH APPLIERS =====
THIS IS CALLED FROM C. Do not change the signature lightly.
This method functions to call the infilter methods from our patches, allowing for analysis and reporting at the point just before the patched code is invoked.
43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/contrast/utils/patching/policy/patch_utils.rb', line 43 def apply_pre_patch method_policy, method, exception, object, args apply_protect(method_policy, method, exception, object, args) apply_inventory(method_policy, method, exception, object, args) rescue Contrast::SecurityException => e # We were told to block something, so we gotta. Don't catch this one, let it get back to our Middleware or # even all the way out to the framework raise(e) rescue StandardError => e # Anything else was our bad and we gotta catch that to allow for normal application flow logger.error('Unable to apply pre patch to method.', e) end |
#apply_protect(method_policy, method, exception, object, args) ⇒ Object
Apply the Protect patch which applies to the given method.
82 83 84 85 86 87 |
# File 'lib/contrast/utils/patching/policy/patch_utils.rb', line 82 def apply_protect method_policy, method, exception, object, args return unless ::Contrast::AGENT.enabled? return unless ::Contrast::PROTECT.enabled? apply_trigger_only(method_policy&.protect_node, method, exception, object, args) end |
#apply_trigger_only(trigger_node, method, exception, object, args) ⇒ Object
Generic invocation of the Inventory or Protect patch which apply to the given method.
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/contrast/utils/patching/policy/patch_utils.rb', line 153 def apply_trigger_only trigger_node, method, exception, object, args return unless trigger_node # If that rule only applies in the case of an exception being thrown and there's no exception here, move # along, or vice versa return if trigger_node.on_exception && !exception return if !trigger_node.on_exception && exception # Each patch has an applicator that handles logic for it. Think of this as being similar to propagator # actions, most closely resembling CUSTOM - they all have a common interface but their own logic based on # what's in the method(s) they've been patched into. # Each patch also knows the method of its applicator. Some things, like AppliesXxeRule, have different # methods depending on the library patched. This lets us handle the boilerplate of patching while still # allowing for custom handling of the methods. applicator_method = trigger_node.applicator_method # By calling send like this, we can reuse all the patching. We `send` to the given method of the given class # (applicator) since they all accept the same inputs trigger_node.applicator.send(applicator_method, method, exception, trigger_node.properties, object, args) end |
#build_method_name(patched_class, patched_method) ⇒ Symbol
Given a module and method, construct an expected name for the alias by which Contrast will reference the original.
16 17 18 19 20 21 |
# File 'lib/contrast/utils/patching/policy/patch_utils.rb', line 16 def build_method_name patched_class, patched_method (Contrast::Utils::ObjectShare::CONTRAST_PATCHED_METHOD_START + patched_class.cs__name.gsub('::', '_').downcase + Contrast::Utils::ObjectShare::UNDERSCORE + patched_method.to_s).to_sym end |
#build_unbound_method_name(patcher_method) ⇒ Object
Given a method, return a symbol in the format <method_start>unbound<method_name>
25 26 27 28 29 |
# File 'lib/contrast/utils/patching/policy/patch_utils.rb', line 25 def build_unbound_method_name patcher_method "#{ Contrast::Utils::ObjectShare::CONTRAST_PATCHED_METHOD_START }unbound" \ "#{ Contrast::Utils::ObjectShare::UNDERSCORE }" \ "#{ patcher_method }".to_sym end |