sqreen 1.18.2-java → 1.19.0-java
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/CHANGELOG.md +35 -0
- data/LICENSE +3 -0
- data/lib/sqreen.rb +2 -0
- data/lib/sqreen/actions.rb +13 -337
- data/lib/sqreen/actions/actions_index.rb +16 -0
- data/lib/sqreen/actions/base.rb +104 -0
- data/lib/sqreen/actions/block_ip.rb +34 -0
- data/lib/sqreen/actions/block_user.rb +46 -0
- data/lib/sqreen/actions/ip_range_indexed_action_class.rb +16 -0
- data/lib/sqreen/actions/ip_ranges_index.rb +57 -0
- data/lib/sqreen/actions/redirect_ip.rb +42 -0
- data/lib/sqreen/actions/redirect_user.rb +47 -0
- data/lib/sqreen/actions/repository.rb +43 -0
- data/lib/sqreen/actions/unknown_action_type.rb +20 -0
- data/lib/sqreen/actions/user_action_class.rb +16 -0
- data/lib/sqreen/actions/users_index.rb +35 -0
- data/lib/sqreen/agent.rb +6 -2
- data/lib/sqreen/attack_blocked.rb +19 -0
- data/lib/sqreen/backport.rb +2 -0
- data/lib/sqreen/backport/clock_gettime.rb +74 -0
- data/lib/sqreen/backport/original_name.rb +2 -0
- data/lib/sqreen/binding_accessor.rb +11 -102
- data/lib/sqreen/binding_accessor/path_elem.rb +10 -0
- data/lib/sqreen/binding_accessor/transforms.rb +114 -0
- data/lib/sqreen/call_countable.rb +2 -0
- data/lib/sqreen/capped_queue.rb +4 -0
- data/lib/sqreen/{callbacks.rb → cb.rb} +3 -53
- data/lib/sqreen/{callback_tree.rb → cb_tree.rb} +4 -2
- data/lib/sqreen/condition_evaluator.rb +24 -5
- data/lib/sqreen/conditionable.rb +2 -0
- data/lib/sqreen/configuration.rb +19 -0
- data/lib/sqreen/context.rb +2 -0
- data/lib/sqreen/default_cb.rb +22 -0
- data/lib/sqreen/deferred_logger.rb +65 -0
- data/lib/sqreen/deliveries.rb +12 -0
- data/lib/sqreen/deliveries/batch.rb +9 -1
- data/lib/sqreen/deliveries/simple.rb +7 -0
- data/lib/sqreen/dependency.rb +3 -1
- data/lib/sqreen/dependency/detector.rb +22 -14
- data/lib/sqreen/dependency/libsqreen.rb +32 -0
- data/lib/sqreen/dependency/new_relic.rb +2 -0
- data/lib/sqreen/dependency/rack.rb +10 -5
- data/lib/sqreen/dependency/rails.rb +8 -0
- data/lib/sqreen/dependency/sentry.rb +2 -0
- data/lib/sqreen/dependency/sinatra.rb +58 -14
- data/lib/sqreen/encoding_sanitizer.rb +2 -0
- data/lib/sqreen/error_handling_middleware.rb +32 -0
- data/lib/sqreen/event.rb +4 -0
- data/lib/sqreen/events/attack.rb +4 -0
- data/lib/sqreen/events/remote_exception.rb +2 -0
- data/lib/sqreen/events/request_record.rb +13 -56
- data/lib/sqreen/exception.rb +11 -40
- data/lib/sqreen/formatter_with_tid.rb +47 -0
- data/lib/sqreen/framework_cb.rb +30 -0
- data/lib/sqreen/frameworks.rb +9 -0
- data/lib/sqreen/frameworks/generic.rb +22 -2
- data/lib/sqreen/frameworks/rails.rb +3 -0
- data/lib/sqreen/frameworks/rails3.rb +2 -0
- data/lib/sqreen/frameworks/request_recorder.rb +5 -0
- data/lib/sqreen/frameworks/sinatra.rb +4 -0
- data/lib/sqreen/frameworks/sqreen_test.rb +4 -0
- data/lib/sqreen/graft.rb +12 -0
- data/lib/sqreen/graft/call.rb +150 -0
- data/lib/sqreen/{dependency → graft}/callback.rb +12 -4
- data/lib/sqreen/graft/hook.rb +316 -0
- data/lib/sqreen/{dependency → graft}/hook_point.rb +152 -33
- data/lib/sqreen/graft/hook_point_error.rb +10 -0
- data/lib/sqreen/invalid_signature_exception.rb +10 -0
- data/lib/sqreen/js.rb +11 -0
- data/lib/sqreen/js/call_context.rb +12 -0
- data/lib/sqreen/js/context_pool.rb +62 -0
- data/lib/sqreen/js/exec_js_runnable.rb +22 -0
- data/lib/sqreen/js/execjs_adapter.rb +8 -47
- data/lib/sqreen/js/executable_js.rb +14 -0
- data/lib/sqreen/js/js_service.rb +4 -22
- data/lib/sqreen/js/js_service_adapter.rb +20 -0
- data/lib/sqreen/js/mini_racer_adapter.rb +8 -180
- data/lib/sqreen/js/mini_racer_executable_js.rb +144 -0
- data/lib/sqreen/js/thread_local_exec_js_runnable.rb +49 -0
- data/lib/{sqreen-alt.rb → sqreen/legacy.rb} +5 -1
- data/lib/sqreen/{instrumentation.rb → legacy/instrumentation.rb} +44 -15
- data/lib/sqreen/log.rb +10 -188
- data/lib/sqreen/log/loggable.rb +28 -0
- data/lib/sqreen/logger.rb +85 -0
- data/lib/sqreen/metrics.rb +2 -0
- data/lib/sqreen/metrics/average.rb +2 -0
- data/lib/sqreen/metrics/base.rb +2 -0
- data/lib/sqreen/metrics/binning.rb +2 -0
- data/lib/sqreen/metrics/collect.rb +2 -0
- data/lib/sqreen/metrics/sum.rb +2 -0
- data/lib/sqreen/metrics_store.rb +5 -11
- data/lib/sqreen/metrics_store/already_registered_metric.rb +13 -0
- data/lib/sqreen/metrics_store/unknown_metric.rb +13 -0
- data/lib/sqreen/metrics_store/unregistered_metric.rb +13 -0
- data/lib/sqreen/middleware.rb +2 -34
- data/lib/sqreen/mono_time.rb +4 -0
- data/lib/sqreen/node.rb +46 -0
- data/lib/sqreen/not_implemented_yet.rb +10 -0
- data/lib/sqreen/null_logger.rb +26 -0
- data/lib/sqreen/payload_creator.rb +4 -19
- data/lib/sqreen/payload_creator/header_section.rb +30 -0
- data/lib/sqreen/performance_notifications.rb +2 -0
- data/lib/sqreen/performance_notifications/binned_metrics.rb +2 -0
- data/lib/sqreen/performance_notifications/log.rb +2 -0
- data/lib/sqreen/performance_notifications/log_performance.rb +2 -0
- data/lib/sqreen/performance_notifications/metrics.rb +2 -0
- data/lib/sqreen/performance_notifications/newrelic.rb +2 -0
- data/lib/sqreen/prefix.rb +35 -0
- data/lib/sqreen/rails_middleware.rb +16 -0
- data/lib/sqreen/remote_command.rb +3 -8
- data/lib/sqreen/remote_command/failure_output.rb +16 -0
- data/lib/sqreen/rules.rb +34 -2
- data/lib/sqreen/{rule_attributes.rb → rules/attrs.rb} +2 -0
- data/lib/sqreen/{rules_callbacks/sdk_auth_track.rb → rules/auth_track_cb.rb} +4 -2
- data/lib/sqreen/{rules_callbacks/binding_accessor_matcher.rb → rules/binding_accessor_matcher_cb.rb} +6 -8
- data/lib/sqreen/{rules_callbacks → rules}/binding_accessor_metrics.rb +3 -1
- data/lib/sqreen/{rules_callbacks/blacklist_ips.rb → rules/blacklist_ips_cb.rb} +5 -2
- data/lib/sqreen/{rules_callbacks → rules}/count_http_codes.rb +4 -2
- data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches.rb → rules/crawler_user_agent_matches_cb.rb} +3 -1
- data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches_metrics.rb → rules/crawler_user_agent_matches_metrics_cb.rb} +3 -1
- data/lib/sqreen/{rules_callbacks/custom_error.rb → rules/custom_error_cb.rb} +3 -1
- data/lib/sqreen/{rules_callbacks/devise_auth_track.rb → rules/devise_auth_track_cb.rb} +4 -2
- data/lib/sqreen/{rules_callbacks/devise_signup_track.rb → rules/devise_signup_track_cb.rb} +4 -2
- data/lib/sqreen/{rules_callbacks/execjs.rb → rules/execjs_cb.rb} +51 -50
- data/lib/sqreen/{rules_callbacks/headers_insert.rb → rules/headers_insert_cb.rb} +8 -1
- data/lib/sqreen/{rules_callbacks → rules}/matcher_rule.rb +4 -2
- data/lib/sqreen/{rules_callbacks/not_found.rb → rules/not_found_cb.rb} +7 -2
- data/lib/sqreen/{rules_callbacks/rails_parameters.rb → rules/rails_parameters_cb.rb} +3 -1
- data/lib/sqreen/{rules_callbacks → rules}/record_request_context.rb +3 -1
- data/lib/sqreen/{rules_callbacks/regexp_rule.rb → rules/regexp_rule_cb.rb} +3 -1
- data/lib/sqreen/{rule_callback.rb → rules/rule_cb.rb} +4 -2
- data/lib/sqreen/{rules_callbacks → rules}/run_req_start_actions.rb +7 -3
- data/lib/sqreen/{rules_callbacks → rules}/run_user_actions.rb +4 -2
- data/lib/sqreen/{rules_callbacks/shell_env.rb → rules/shell_env_cb.rb} +3 -1
- data/lib/sqreen/{rules_callbacks/sdk_signup_track.rb → rules/signup_track_cb.rb} +4 -2
- data/lib/sqreen/rules/update_request_context.rb +22 -0
- data/lib/sqreen/{rules_callbacks/url_matches.rb → rules/url_matches_cb.rb} +3 -1
- data/lib/sqreen/{rules_callbacks/user_agent_matches.rb → rules/user_agent_matches_cb.rb} +3 -1
- data/lib/sqreen/{rules_callbacks/waf.rb → rules/waf_cb.rb} +41 -21
- data/lib/sqreen/{rules_callbacks/reflected_xss.rb → rules/xss_cb.rb} +12 -7
- data/lib/sqreen/run_when_called_cb.rb +23 -0
- data/lib/sqreen/runner.rb +25 -7
- data/lib/sqreen/runtime_infos.rb +4 -9
- data/lib/sqreen/safe_json.rb +2 -0
- data/lib/sqreen/sdk.rb +4 -0
- data/lib/sqreen/sensitive_data_redactor.rb +113 -0
- data/lib/sqreen/serializer.rb +2 -0
- data/lib/sqreen/session.rb +2 -0
- data/lib/sqreen/shared_storage.rb +2 -0
- data/lib/sqreen/shared_storage23.rb +2 -0
- data/lib/sqreen/shrink_wrap.rb +16 -0
- data/lib/sqreen/signature_verifier.rb +22 -0
- data/lib/sqreen/sinatra_middleware.rb +16 -0
- data/lib/sqreen/{rules_signature.rb → sqreen_signed_verifier.rb} +7 -17
- data/lib/sqreen/token_invalid_exception.rb +10 -0
- data/lib/sqreen/token_not_found_exception.rb +11 -0
- data/lib/sqreen/trie.rb +5 -64
- data/lib/sqreen/unauthorized.rb +10 -0
- data/lib/sqreen/util.rb +7 -0
- data/lib/sqreen/util/capped_array.rb +35 -0
- data/lib/sqreen/util/capped_hash.rb +41 -0
- data/lib/sqreen/util/capped_string.rb +26 -0
- data/lib/sqreen/util/capper.rb +67 -0
- data/lib/sqreen/version.rb +3 -1
- data/lib/sqreen/waf_error.rb +20 -0
- data/lib/sqreen/weave.rb +12 -0
- data/lib/sqreen/weave/hardcoded.rb +19 -0
- data/lib/sqreen/weave/instrumentor.rb +48 -0
- data/lib/sqreen/weave/legacy.rb +12 -0
- data/lib/sqreen/weave/legacy/instrumentation.rb +406 -0
- data/lib/sqreen/web_server.rb +2 -0
- data/lib/sqreen/web_server/generic.rb +2 -0
- data/lib/sqreen/web_server/passenger.rb +2 -0
- data/lib/sqreen/web_server/puma.rb +2 -0
- data/lib/sqreen/web_server/rainbows.rb +2 -0
- data/lib/sqreen/web_server/thin.rb +2 -0
- data/lib/sqreen/web_server/unicorn.rb +2 -0
- data/lib/sqreen/web_server/webrick.rb +2 -0
- data/lib/sqreen/worker.rb +2 -0
- metadata +105 -39
- data/lib/sqreen/dependency/hook.rb +0 -102
- data/lib/sqreen/rules_callbacks.rb +0 -35
- data/lib/sqreen/rules_callbacks/inspect_rule.rb +0 -25
|
@@ -1,12 +1,26 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
|
|
1
3
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
2
4
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
3
5
|
|
|
4
6
|
require 'sqreen/dependency'
|
|
5
7
|
require 'sqreen/backport/original_name'
|
|
8
|
+
require 'sqreen/graft'
|
|
9
|
+
require 'sqreen/graft/hook_point_error'
|
|
6
10
|
|
|
7
11
|
module Sqreen
|
|
8
|
-
module
|
|
9
|
-
class
|
|
12
|
+
module Graft
|
|
13
|
+
class HookSpot < Module
|
|
14
|
+
def initialize(key)
|
|
15
|
+
@key = key
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
attr_reader :key
|
|
19
|
+
|
|
20
|
+
def inspect
|
|
21
|
+
"#<#{self.class.name}: #{@key.inspect}>"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
10
24
|
|
|
11
25
|
class HookPoint
|
|
12
26
|
def self.parse(hook_point)
|
|
@@ -22,8 +36,9 @@ module Sqreen
|
|
|
22
36
|
|
|
23
37
|
attr_reader :klass_name, :method_kind, :method_name
|
|
24
38
|
|
|
25
|
-
def initialize(hook_point)
|
|
26
|
-
@klass_name, @method_kind, @method_name = Sqreen::
|
|
39
|
+
def initialize(hook_point, strategy = :chain)
|
|
40
|
+
@klass_name, @method_kind, @method_name = Sqreen::Graft::HookPoint.parse(hook_point)
|
|
41
|
+
@strategy = strategy
|
|
27
42
|
end
|
|
28
43
|
|
|
29
44
|
def to_s
|
|
@@ -34,11 +49,12 @@ module Sqreen
|
|
|
34
49
|
return false unless Sqreen::Dependency.const_exist?(@klass_name)
|
|
35
50
|
|
|
36
51
|
if klass_method?
|
|
37
|
-
(klass.
|
|
52
|
+
(klass.singleton_class.public_instance_methods(false) + klass.singleton_class.protected_instance_methods(false) + klass.singleton_class.private_instance_methods(false)).include?(@method_name)
|
|
38
53
|
elsif instance_method?
|
|
39
|
-
(klass.
|
|
54
|
+
(klass.public_instance_methods(false) + klass.protected_instance_methods(false) + klass.private_instance_methods(false)).include?(@method_name)
|
|
40
55
|
else
|
|
41
|
-
|
|
56
|
+
Sqreen::Graft.logger.error { "[#{Process.pid}] #{self} unknown hook point kind" }
|
|
57
|
+
raise HookPointError, "#{self} unknown hook point kind"
|
|
42
58
|
end
|
|
43
59
|
end
|
|
44
60
|
|
|
@@ -56,7 +72,8 @@ module Sqreen
|
|
|
56
72
|
elsif instance_method?
|
|
57
73
|
klass.private_instance_methods.include?(@method_name)
|
|
58
74
|
else
|
|
59
|
-
|
|
75
|
+
Sqreen::Graft.logger.error { "[#{Process.pid}] #{self} unknown hook point kind" }
|
|
76
|
+
raise HookPointError, "#{self} unknown hook point kind"
|
|
60
77
|
end
|
|
61
78
|
end
|
|
62
79
|
|
|
@@ -66,7 +83,8 @@ module Sqreen
|
|
|
66
83
|
elsif instance_method?
|
|
67
84
|
klass.protected_instance_methods.include?(@method_name)
|
|
68
85
|
else
|
|
69
|
-
|
|
86
|
+
Sqreen::Graft.logger.error { "[#{Process.pid}] #{self} unknown hook point kind" }
|
|
87
|
+
raise HookPointError, "#{self} unknown hook point kind"
|
|
70
88
|
end
|
|
71
89
|
end
|
|
72
90
|
|
|
@@ -74,58 +92,159 @@ module Sqreen
|
|
|
74
92
|
@method_kind == :instance_method
|
|
75
93
|
end
|
|
76
94
|
|
|
77
|
-
def installed?(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
(klass.instance_methods + klass.protected_instance_methods + klass.private_instance_methods).include?(:"#{method_name}_with_#{suffix}")
|
|
82
|
-
else
|
|
83
|
-
raise HookPointError, 'unknown hook point kind'
|
|
95
|
+
def installed?(key)
|
|
96
|
+
case @strategy
|
|
97
|
+
when :chain then defined(key)
|
|
98
|
+
when :prepend then prepended?(key) && overridden?(key)
|
|
84
99
|
end
|
|
85
100
|
end
|
|
86
101
|
|
|
102
|
+
def super?
|
|
103
|
+
@strategy == :prepend
|
|
104
|
+
end
|
|
105
|
+
|
|
87
106
|
def apply(obj, suffix, *args, &block)
|
|
107
|
+
raise 'use super' if super?
|
|
108
|
+
|
|
88
109
|
obj.send("#{method_name}_without_#{suffix}", *args, &block)
|
|
89
110
|
end
|
|
90
111
|
|
|
91
|
-
def install(
|
|
92
|
-
if installed?(
|
|
93
|
-
Sqreen.
|
|
112
|
+
def install(key, &block)
|
|
113
|
+
if installed?(key)
|
|
114
|
+
Sqreen::Graft.logger.debug { "[#{Process.pid}] #{self} already installed" }
|
|
115
|
+
return
|
|
94
116
|
end
|
|
95
117
|
unless exist?
|
|
96
|
-
Sqreen.
|
|
118
|
+
Sqreen::Graft.logger.debug { "[#{Process.pid}] #{self} hook point not found" }
|
|
119
|
+
return
|
|
97
120
|
end
|
|
98
121
|
|
|
99
|
-
|
|
100
|
-
|
|
122
|
+
case @strategy
|
|
123
|
+
when :chain
|
|
124
|
+
define(key, &block)
|
|
125
|
+
chain(key)
|
|
126
|
+
when :prepend
|
|
127
|
+
prepend(key)
|
|
128
|
+
override(key, &block)
|
|
129
|
+
end
|
|
101
130
|
end
|
|
102
131
|
|
|
103
|
-
def uninstall(
|
|
104
|
-
|
|
105
|
-
|
|
132
|
+
def uninstall(key)
|
|
133
|
+
unless installed?(key)
|
|
134
|
+
Sqreen::Graft.logger.debug { "[#{Process.pid}] #{self} not installed" }
|
|
135
|
+
return
|
|
136
|
+
end
|
|
137
|
+
unless exist?
|
|
138
|
+
Sqreen::Graft.logger.debug { "[#{Process.pid}] #{self} hook point not found" }
|
|
139
|
+
return
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
case @strategy
|
|
143
|
+
when :chain
|
|
144
|
+
disable(key)
|
|
145
|
+
remove(key)
|
|
146
|
+
when :prepend
|
|
147
|
+
unoverride(key) if overridden?(key)
|
|
148
|
+
end
|
|
106
149
|
end
|
|
107
150
|
|
|
108
|
-
def enable(
|
|
109
|
-
|
|
151
|
+
def enable(key)
|
|
152
|
+
case @strategy
|
|
153
|
+
when :chain
|
|
154
|
+
chain(key)
|
|
155
|
+
when :prepend
|
|
156
|
+
raise HookPointError, "enable called on prepend mode"
|
|
157
|
+
end
|
|
110
158
|
end
|
|
111
159
|
|
|
112
|
-
def disable(
|
|
113
|
-
|
|
160
|
+
def disable(key)
|
|
161
|
+
case @strategy
|
|
162
|
+
when :chain
|
|
163
|
+
unchain(key)
|
|
164
|
+
when :prepend
|
|
165
|
+
unoverride(key)
|
|
166
|
+
end
|
|
114
167
|
end
|
|
115
168
|
|
|
116
|
-
def disabled?(
|
|
117
|
-
|
|
169
|
+
def disabled?(key)
|
|
170
|
+
case @strategy
|
|
171
|
+
when :chain
|
|
172
|
+
!chained?(key)
|
|
173
|
+
when :prepend
|
|
174
|
+
!overridden?(key)
|
|
175
|
+
end
|
|
118
176
|
end
|
|
119
177
|
|
|
120
178
|
private
|
|
121
179
|
|
|
180
|
+
def prepend(key)
|
|
181
|
+
target = klass_method? ? klass.singleton_class : klass
|
|
182
|
+
mod = target.ancestors.each { |e| break if e == target; break(e) if e.class == HookSpot && e.key == key }
|
|
183
|
+
mod ||= HookSpot.new(key)
|
|
184
|
+
target.instance_eval { prepend(mod) }
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def prepended?(key)
|
|
188
|
+
target = klass_method? ? klass.singleton_class : klass
|
|
189
|
+
mod = target.ancestors.each { |e| break if e == target; break(e) if e.class == HookSpot && e.key == key }
|
|
190
|
+
|
|
191
|
+
mod != nil
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def overridden?(key)
|
|
195
|
+
target = klass_method? ? klass.singleton_class : klass
|
|
196
|
+
mod = target.ancestors.each { |e| break if e == target; break(e) if e.class == HookSpot && e.key == key }
|
|
197
|
+
|
|
198
|
+
(mod.instance_methods(false) + mod.protected_instance_methods(false) + mod.private_instance_methods(false)).include?(method_name)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def override(key, &block)
|
|
202
|
+
hook_point = self
|
|
203
|
+
method_name = @method_name
|
|
204
|
+
|
|
205
|
+
target = klass_method? ? klass.singleton_class : klass
|
|
206
|
+
mod = target.ancestors.each { |e| break if e == target; break(e) if e.class == HookSpot && e.key == key }
|
|
207
|
+
|
|
208
|
+
mod.instance_eval do
|
|
209
|
+
if hook_point.private_method?
|
|
210
|
+
private
|
|
211
|
+
elsif hook_point.protected_method?
|
|
212
|
+
protected
|
|
213
|
+
else
|
|
214
|
+
public
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
define_method(:"#{method_name}", &block)
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def unoverride(key)
|
|
222
|
+
method_name = @method_name
|
|
223
|
+
|
|
224
|
+
target = klass_method? ? klass.singleton_class : klass
|
|
225
|
+
mod = target.ancestors.each { |e| break if e == target; break(e) if e.class == HookSpot && e.key == key }
|
|
226
|
+
|
|
227
|
+
mod.instance_eval { remove_method(method_name) }
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def defined(suffix)
|
|
231
|
+
if klass_method?
|
|
232
|
+
(klass.methods + klass.protected_methods + klass.private_methods).include?(:"#{method_name}_with_#{suffix}")
|
|
233
|
+
elsif instance_method?
|
|
234
|
+
(klass.instance_methods + klass.protected_instance_methods + klass.private_instance_methods).include?(:"#{method_name}_with_#{suffix}")
|
|
235
|
+
else
|
|
236
|
+
Sqreen::Graft.logger.error { "[#{Process.pid}] #{self} unknown hook point kind" }
|
|
237
|
+
raise HookPointError, "#{self} unknown hook point kind"
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
122
241
|
def define(suffix, &block)
|
|
123
242
|
hook_point = self
|
|
124
243
|
method_name = @method_name
|
|
125
244
|
|
|
126
245
|
if klass_method?
|
|
127
246
|
klass.singleton_class.instance_eval do
|
|
128
|
-
if hook_point.
|
|
247
|
+
if hook_point.private_method?
|
|
129
248
|
private
|
|
130
249
|
elsif hook_point.protected_method?
|
|
131
250
|
protected
|
|
@@ -137,7 +256,7 @@ module Sqreen
|
|
|
137
256
|
end
|
|
138
257
|
elsif instance_method?
|
|
139
258
|
klass.class_eval do
|
|
140
|
-
if hook_point.
|
|
259
|
+
if hook_point.private_method?
|
|
141
260
|
private
|
|
142
261
|
elsif hook_point.protected_method?
|
|
143
262
|
protected
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
4
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
5
|
+
|
|
6
|
+
require 'sqreen/exception'
|
|
7
|
+
|
|
8
|
+
module Sqreen
|
|
9
|
+
class InvalidSignatureException < Sqreen::Exception; end
|
|
10
|
+
end
|
data/lib/sqreen/js.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
4
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
5
|
+
|
|
6
|
+
# TODO: useless?
|
|
7
|
+
|
|
8
|
+
module Sqreen
|
|
9
|
+
module Js
|
|
10
|
+
CallContext = Struct.new(:inst, :args, :rv)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# typed: ignore
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
4
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
5
|
+
|
|
6
|
+
# TODO: => Sqreen::JS:MiniRacer ?
|
|
7
|
+
|
|
8
|
+
module Sqreen
|
|
9
|
+
module Js
|
|
10
|
+
class ContextPool
|
|
11
|
+
def initialize
|
|
12
|
+
@mutex = Mutex.new
|
|
13
|
+
@total_ctxs = 0
|
|
14
|
+
@contexts = []
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def with_context(&block)
|
|
18
|
+
isolate = context
|
|
19
|
+
begin
|
|
20
|
+
block[isolate]
|
|
21
|
+
ensure
|
|
22
|
+
give_back_context isolate
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def context
|
|
29
|
+
@mutex.synchronize do
|
|
30
|
+
if @contexts.empty?
|
|
31
|
+
@total_ctxs += 1
|
|
32
|
+
Sqreen.log.debug "Creating new V8 context (#{@total_ctxs})"
|
|
33
|
+
SqreenContext.new
|
|
34
|
+
else
|
|
35
|
+
@contexts.pop
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def give_back_context(context)
|
|
41
|
+
context.possibly_gc
|
|
42
|
+
|
|
43
|
+
if context.gc_load > 30
|
|
44
|
+
if context.gc_threshold_in_bytes == DEFAULT_GC_THRESHOLD
|
|
45
|
+
context.gc_threshold_in_bytes *= 2
|
|
46
|
+
Sqreen.log.warn("Context #{context} had too many close garbage " \
|
|
47
|
+
'collections; doubling the threshold to ' \
|
|
48
|
+
"#{context.gc_threshold_in_bytes} bytes")
|
|
49
|
+
context.gc_load = 0
|
|
50
|
+
else
|
|
51
|
+
Sqreen.log.warn("Context #{context} had too many close garbage " \
|
|
52
|
+
'collections; discarding it')
|
|
53
|
+
context.dispose
|
|
54
|
+
return
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
@mutex.synchronize { @contexts.push(context); }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
4
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
5
|
+
|
|
6
|
+
# TODO: => Sqreen::JS:ExecJS
|
|
7
|
+
|
|
8
|
+
require 'sqreen/js/executable_js'
|
|
9
|
+
|
|
10
|
+
module Sqreen
|
|
11
|
+
module Js
|
|
12
|
+
class ExecJsRunnable < ExecutableJs
|
|
13
|
+
def initialize(compiled)
|
|
14
|
+
@compiled = compiled
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def run_js_cb(cbname, _budget, arguments)
|
|
18
|
+
@compiled.call(cbname, *arguments)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
|
|
1
3
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
|
2
4
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
|
3
5
|
|
|
6
|
+
# TODO: => Sqreen::JS:ExecJS
|
|
7
|
+
|
|
4
8
|
require 'execjs'
|
|
5
9
|
require 'weakref'
|
|
10
|
+
require 'sqreen/js/executable_js'
|
|
11
|
+
require 'sqreen/js/js_service_adapter'
|
|
12
|
+
require 'sqreen/js/exec_js_runnable'
|
|
13
|
+
require 'sqreen/js/thread_local_exec_js_runnable'
|
|
6
14
|
|
|
7
15
|
module Sqreen
|
|
8
16
|
module Js
|
|
@@ -25,52 +33,5 @@ module Sqreen
|
|
|
25
33
|
ExecJS.runtime.name != 'therubyrhino (Rhino)'
|
|
26
34
|
end
|
|
27
35
|
end
|
|
28
|
-
|
|
29
|
-
class ExecJsRunnable < ExecutableJs
|
|
30
|
-
def initialize(compiled)
|
|
31
|
-
@compiled = compiled
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def run_js_cb(cbname, _budget, arguments)
|
|
35
|
-
@compiled.call(cbname, *arguments)
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
class ThreadLocalExecJsRunnable < ExecutableJs
|
|
40
|
-
def initialize(code)
|
|
41
|
-
@code = code
|
|
42
|
-
@tl_key = "SQREEN_EXECJS_CONTEXT_#{object_id}".freeze
|
|
43
|
-
@runtimes = [] # place where to keep strong references
|
|
44
|
-
@runtimes_mutex = Mutex.new
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def run_js_cb(cbname, _budget, arguments)
|
|
48
|
-
tl_exec_js_runnable.call(cbname, *arguments)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def with_runtimes_mutex
|
|
52
|
-
@runtimes_mutex.synchronize { yield }
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
private
|
|
56
|
-
|
|
57
|
-
def dispose_from_dead_threads
|
|
58
|
-
with_runtimes_mutex do
|
|
59
|
-
@runtimes.delete_if { |th, _runtime| !th.alive? }
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def tl_exec_js_runnable
|
|
64
|
-
runnable = Thread.current[@tl_key]
|
|
65
|
-
return runnable if runnable && runnable.weakref_alive?
|
|
66
|
-
|
|
67
|
-
dispose_from_dead_threads
|
|
68
|
-
runtime = ExecJS.compile(@code)
|
|
69
|
-
with_runtimes_mutex do
|
|
70
|
-
@runtimes << [Thread.current, runtime]
|
|
71
|
-
end
|
|
72
|
-
Thread.current[@tl_key] = WeakRef.new(runtime)
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
36
|
end
|
|
76
37
|
end
|