sqreen 1.18.2-java → 1.18.3-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.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/LICENSE +3 -0
  4. data/lib/sqreen/actions.rb +11 -337
  5. data/lib/sqreen/actions/base.rb +110 -0
  6. data/lib/sqreen/actions/block_ip.rb +32 -0
  7. data/lib/sqreen/actions/block_user.rb +44 -0
  8. data/lib/sqreen/actions/ip_range_indexed_action_class.rb +36 -0
  9. data/lib/sqreen/actions/ip_ranges_index.rb +36 -0
  10. data/lib/sqreen/actions/redirect_ip.rb +40 -0
  11. data/lib/sqreen/actions/redirect_user.rb +45 -0
  12. data/lib/sqreen/actions/repository.rb +24 -0
  13. data/lib/sqreen/actions/unknown_action_type.rb +16 -0
  14. data/lib/sqreen/actions/user_action_class.rb +41 -0
  15. data/lib/sqreen/agent.rb +4 -1
  16. data/lib/sqreen/attack_blocked.rb +17 -0
  17. data/lib/sqreen/binding_accessor.rb +9 -102
  18. data/lib/sqreen/binding_accessor/path_elem.rb +8 -0
  19. data/lib/sqreen/binding_accessor/transforms.rb +107 -0
  20. data/lib/sqreen/capped_queue.rb +2 -0
  21. data/lib/sqreen/{callbacks.rb → cb.rb} +1 -53
  22. data/lib/sqreen/{callback_tree.rb → cb_tree.rb} +2 -2
  23. data/lib/sqreen/condition_evaluator.rb +22 -5
  24. data/lib/sqreen/configuration.rb +5 -0
  25. data/lib/sqreen/default_cb.rb +20 -0
  26. data/lib/sqreen/deferred_logger.rb +63 -0
  27. data/lib/sqreen/deliveries.rb +10 -0
  28. data/lib/sqreen/deliveries/batch.rb +7 -1
  29. data/lib/sqreen/deliveries/simple.rb +5 -0
  30. data/lib/sqreen/dependency/detector.rb +1 -1
  31. data/lib/sqreen/dependency/libsqreen.rb +28 -0
  32. data/lib/sqreen/dependency/rails.rb +4 -0
  33. data/lib/sqreen/dependency/sinatra.rb +47 -14
  34. data/lib/sqreen/error_handling_middleware.rb +30 -0
  35. data/lib/sqreen/event.rb +2 -0
  36. data/lib/sqreen/events/attack.rb +2 -0
  37. data/lib/sqreen/events/request_record.rb +11 -56
  38. data/lib/sqreen/exception.rb +9 -40
  39. data/lib/sqreen/formatter_with_tid.rb +45 -0
  40. data/lib/sqreen/framework_cb.rb +28 -0
  41. data/lib/sqreen/frameworks.rb +7 -0
  42. data/lib/sqreen/frameworks/generic.rb +20 -2
  43. data/lib/sqreen/frameworks/rails.rb +2 -0
  44. data/lib/sqreen/frameworks/request_recorder.rb +3 -0
  45. data/lib/sqreen/frameworks/sinatra.rb +2 -0
  46. data/lib/sqreen/frameworks/sqreen_test.rb +2 -0
  47. data/lib/sqreen/instrumentation.rb +5 -5
  48. data/lib/sqreen/invalid_signature_exception.rb +8 -0
  49. data/lib/{sqreen-alt.rb → sqreen/js.rb} +6 -1
  50. data/lib/sqreen/js/call_context.rb +10 -0
  51. data/lib/sqreen/js/context_pool.rb +60 -0
  52. data/lib/sqreen/js/exec_js_runnable.rb +20 -0
  53. data/lib/sqreen/js/execjs_adapter.rb +6 -47
  54. data/lib/sqreen/js/executable_js.rb +12 -0
  55. data/lib/sqreen/js/js_service.rb +2 -22
  56. data/lib/sqreen/js/js_service_adapter.rb +18 -0
  57. data/lib/sqreen/js/mini_racer_adapter.rb +6 -180
  58. data/lib/sqreen/js/mini_racer_executable_js.rb +142 -0
  59. data/lib/sqreen/js/thread_local_exec_js_runnable.rb +47 -0
  60. data/lib/sqreen/log.rb +8 -188
  61. data/lib/sqreen/logger.rb +83 -0
  62. data/lib/sqreen/metrics_store.rb +3 -11
  63. data/lib/sqreen/metrics_store/already_registered_metric.rb +11 -0
  64. data/lib/sqreen/metrics_store/unknown_metric.rb +11 -0
  65. data/lib/sqreen/metrics_store/unregistered_metric.rb +11 -0
  66. data/lib/sqreen/middleware.rb +0 -34
  67. data/lib/sqreen/mono_time.rb +2 -0
  68. data/lib/sqreen/node.rb +44 -0
  69. data/lib/sqreen/not_implemented_yet.rb +8 -0
  70. data/lib/sqreen/null_logger.rb +24 -0
  71. data/lib/sqreen/payload_creator.rb +2 -19
  72. data/lib/sqreen/payload_creator/header_section.rb +28 -0
  73. data/lib/sqreen/prefix.rb +33 -0
  74. data/lib/sqreen/rails_middleware.rb +14 -0
  75. data/lib/sqreen/remote_command.rb +1 -8
  76. data/lib/sqreen/remote_command/failure_output.rb +11 -0
  77. data/lib/sqreen/rules.rb +32 -2
  78. data/lib/sqreen/{rule_attributes.rb → rules/attrs.rb} +0 -0
  79. data/lib/sqreen/{rules_callbacks/sdk_auth_track.rb → rules/auth_track_cb.rb} +2 -2
  80. data/lib/sqreen/{rules_callbacks/binding_accessor_matcher.rb → rules/binding_accessor_matcher_cb.rb} +4 -8
  81. data/lib/sqreen/{rules_callbacks → rules}/binding_accessor_metrics.rb +1 -1
  82. data/lib/sqreen/{rules_callbacks/blacklist_ips.rb → rules/blacklist_ips_cb.rb} +3 -2
  83. data/lib/sqreen/{rules_callbacks → rules}/count_http_codes.rb +2 -2
  84. data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches.rb → rules/crawler_user_agent_matches_cb.rb} +1 -1
  85. data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches_metrics.rb → rules/crawler_user_agent_matches_metrics_cb.rb} +1 -1
  86. data/lib/sqreen/{rules_callbacks/custom_error.rb → rules/custom_error_cb.rb} +1 -1
  87. data/lib/sqreen/{rules_callbacks/devise_auth_track.rb → rules/devise_auth_track_cb.rb} +2 -2
  88. data/lib/sqreen/{rules_callbacks/devise_signup_track.rb → rules/devise_signup_track_cb.rb} +2 -2
  89. data/lib/sqreen/{rules_callbacks/execjs.rb → rules/execjs_cb.rb} +49 -50
  90. data/lib/sqreen/{rules_callbacks/headers_insert.rb → rules/headers_insert_cb.rb} +1 -1
  91. data/lib/sqreen/{rules_callbacks → rules}/matcher_rule.rb +2 -2
  92. data/lib/sqreen/{rules_callbacks/not_found.rb → rules/not_found_cb.rb} +2 -2
  93. data/lib/sqreen/{rules_callbacks/rails_parameters.rb → rules/rails_parameters_cb.rb} +1 -1
  94. data/lib/sqreen/{rules_callbacks → rules}/record_request_context.rb +1 -1
  95. data/lib/sqreen/{rules_callbacks/regexp_rule.rb → rules/regexp_rule_cb.rb} +1 -1
  96. data/lib/sqreen/{rule_callback.rb → rules/rule_cb.rb} +2 -2
  97. data/lib/sqreen/{rules_callbacks → rules}/run_req_start_actions.rb +4 -2
  98. data/lib/sqreen/{rules_callbacks → rules}/run_user_actions.rb +1 -1
  99. data/lib/sqreen/{rules_callbacks/shell_env.rb → rules/shell_env_cb.rb} +1 -1
  100. data/lib/sqreen/{rules_callbacks/sdk_signup_track.rb → rules/signup_track_cb.rb} +2 -2
  101. data/lib/sqreen/rules/update_request_context.rb +20 -0
  102. data/lib/sqreen/{rules_callbacks/url_matches.rb → rules/url_matches_cb.rb} +1 -1
  103. data/lib/sqreen/{rules_callbacks/user_agent_matches.rb → rules/user_agent_matches_cb.rb} +1 -1
  104. data/lib/sqreen/{rules_callbacks/waf.rb → rules/waf_cb.rb} +10 -14
  105. data/lib/sqreen/{rules_callbacks/reflected_xss.rb → rules/xss_cb.rb} +10 -7
  106. data/lib/sqreen/run_when_called_cb.rb +21 -0
  107. data/lib/sqreen/runtime_infos.rb +2 -9
  108. data/lib/sqreen/sensitive_data_redactor.rb +111 -0
  109. data/lib/sqreen/signature_verifier.rb +20 -0
  110. data/lib/sqreen/sinatra_middleware.rb +14 -0
  111. data/lib/sqreen/{rules_signature.rb → sqreen_signed_verifier.rb} +5 -17
  112. data/lib/sqreen/token_invalid_exception.rb +8 -0
  113. data/lib/sqreen/token_not_found_exception.rb +9 -0
  114. data/lib/sqreen/trie.rb +3 -64
  115. data/lib/sqreen/unauthorized.rb +8 -0
  116. data/lib/sqreen/util.rb +2 -0
  117. data/lib/sqreen/util/capped_array.rb +33 -0
  118. data/lib/sqreen/util/capped_hash.rb +39 -0
  119. data/lib/sqreen/util/capped_string.rb +24 -0
  120. data/lib/sqreen/util/capper.rb +65 -0
  121. data/lib/sqreen/version.rb +1 -1
  122. data/lib/sqreen/waf_error.rb +18 -0
  123. metadata +87 -35
  124. data/lib/sqreen/rules_callbacks.rb +0 -35
  125. data/lib/sqreen/rules_callbacks/inspect_rule.rb +0 -25
@@ -5,6 +5,8 @@
5
5
 
6
6
  require 'sqreen/frameworks/generic'
7
7
  require 'sqreen/middleware'
8
+ require 'sqreen/error_handling_middleware'
9
+ require 'sqreen/rails_middleware'
8
10
 
9
11
  module Sqreen
10
12
  module Frameworks
@@ -1,6 +1,9 @@
1
1
  # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
2
  # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
3
 
4
+ # TODO: Sqreen::Framework::RequestRecorder misnamed/misplaced?
5
+ # TODO: deps?
6
+
4
7
  require 'set'
5
8
  require 'sqreen/shared_storage'
6
9
  require 'sqreen/events/request_record'
@@ -3,6 +3,8 @@
3
3
 
4
4
  require 'sqreen/frameworks/generic'
5
5
  require 'sqreen/middleware'
6
+ require 'sqreen/error_handling_middleware'
7
+ require 'sqreen/sinatra_middleware'
6
8
 
7
9
  module Sqreen
8
10
  module Frameworks
@@ -1,6 +1,8 @@
1
1
  # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
2
  # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
3
 
4
+ # TODO: drop
5
+
4
6
  require 'sqreen/frameworks/generic'
5
7
 
6
8
  module Sqreen
@@ -1,17 +1,17 @@
1
1
  # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
2
  # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
3
 
4
- require 'sqreen/callback_tree'
4
+ require 'sqreen/cb_tree'
5
5
  require 'sqreen/log'
6
6
  require 'sqreen/exception'
7
7
  require 'sqreen/performance_notifications'
8
8
  require 'sqreen/call_countable'
9
9
  require 'sqreen/events/remote_exception'
10
- require 'sqreen/rules_signature'
10
+ require 'sqreen/sqreen_signed_verifier'
11
11
  require 'sqreen/shared_storage'
12
- require 'sqreen/rules_callbacks/record_request_context'
13
- require 'sqreen/rules_callbacks/run_req_start_actions'
14
- require 'sqreen/rules_callbacks/run_user_actions'
12
+ require 'sqreen/rules/record_request_context'
13
+ require 'sqreen/rules/run_req_start_actions'
14
+ require 'sqreen/rules/run_user_actions'
15
15
  require 'sqreen/mono_time'
16
16
  require 'set'
17
17
 
@@ -0,0 +1,8 @@
1
+ # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
+ # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
+
4
+ require 'sqreen/exception'
5
+
6
+ module Sqreen
7
+ class InvalidSignatureException < Sqreen::Exception; end
8
+ end
@@ -1,4 +1,9 @@
1
1
  # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
2
  # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
3
 
4
- require "sqreen"
4
+ # TODO: case JS/Js?
5
+
6
+ module Sqreen
7
+ module Js
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
+ # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
+
4
+ # TODO: useless?
5
+
6
+ module Sqreen
7
+ module Js
8
+ CallContext = Struct.new(:inst, :args, :rv)
9
+ end
10
+ end
@@ -0,0 +1,60 @@
1
+ # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
+ # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
+
4
+ # TODO: => Sqreen::JS:MiniRacer ?
5
+
6
+ module Sqreen
7
+ module Js
8
+ class ContextPool
9
+ def initialize
10
+ @mutex = Mutex.new
11
+ @total_ctxs = 0
12
+ @contexts = []
13
+ end
14
+
15
+ def with_context(&block)
16
+ isolate = context
17
+ begin
18
+ block[isolate]
19
+ ensure
20
+ give_back_context isolate
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def context
27
+ @mutex.synchronize do
28
+ if @contexts.empty?
29
+ @total_ctxs += 1
30
+ Sqreen.log.debug "Creating new V8 context (#{@total_ctxs})"
31
+ SqreenContext.new
32
+ else
33
+ @contexts.pop
34
+ end
35
+ end
36
+ end
37
+
38
+ def give_back_context(context)
39
+ context.possibly_gc
40
+
41
+ if context.gc_load > 30
42
+ if context.gc_threshold_in_bytes == DEFAULT_GC_THRESHOLD
43
+ context.gc_threshold_in_bytes *= 2
44
+ Sqreen.log.warn("Context #{context} had too many close garbage " \
45
+ 'collections; doubling the threshold to ' \
46
+ "#{context.gc_threshold_in_bytes} bytes")
47
+ context.gc_load = 0
48
+ else
49
+ Sqreen.log.warn("Context #{context} had too many close garbage " \
50
+ 'collections; discarding it')
51
+ context.dispose
52
+ return
53
+ end
54
+ end
55
+
56
+ @mutex.synchronize { @contexts.push(context); }
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,20 @@
1
+ # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
+ # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
+
4
+ # TODO: => Sqreen::JS:ExecJS
5
+
6
+ require 'sqreen/js/executable_js'
7
+
8
+ module Sqreen
9
+ module Js
10
+ class ExecJsRunnable < ExecutableJs
11
+ def initialize(compiled)
12
+ @compiled = compiled
13
+ end
14
+
15
+ def run_js_cb(cbname, _budget, arguments)
16
+ @compiled.call(cbname, *arguments)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,8 +1,14 @@
1
1
  # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
2
  # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
3
 
4
+ # TODO: => Sqreen::JS:ExecJS
5
+
4
6
  require 'execjs'
5
7
  require 'weakref'
8
+ require 'sqreen/js/executable_js'
9
+ require 'sqreen/js/js_service_adapter'
10
+ require 'sqreen/js/exec_js_runnable'
11
+ require 'sqreen/js/thread_local_exec_js_runnable'
6
12
 
7
13
  module Sqreen
8
14
  module Js
@@ -25,52 +31,5 @@ module Sqreen
25
31
  ExecJS.runtime.name != 'therubyrhino (Rhino)'
26
32
  end
27
33
  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
34
  end
76
35
  end
@@ -0,0 +1,12 @@
1
+ # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
+ # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
+
4
+ module Sqreen
5
+ module Js
6
+ class ExecutableJs
7
+ def run_js_cb(_cb_name, _budget, _arguments)
8
+ raise Sqreen::NotImplementedYet
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,12 +1,12 @@
1
1
  # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
2
  # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
3
 
4
+ require 'sqreen/log'
4
5
  require 'sqreen/exception'
6
+ require 'singleton'
5
7
 
6
8
  module Sqreen
7
9
  module Js
8
- # start public interface
9
-
10
10
  class JsService
11
11
  include ::Singleton
12
12
 
@@ -66,25 +66,5 @@ module Sqreen
66
66
  false
67
67
  end
68
68
  end
69
-
70
- CallContext = Struct.new(:inst, :args, :rv)
71
-
72
- class ExecutableJs
73
- def run_js_cb(_cb_name, _budget, _arguments)
74
- raise Sqreen::NotImplementedYet
75
- end
76
- end
77
-
78
- # end public interface
79
-
80
- class JsServiceAdapter
81
- def preprocess(rule_name, code)
82
- raise Sqreen::NotImplementedYet
83
- end
84
-
85
- def variant_name
86
- 'unspecified'
87
- end
88
- end
89
69
  end
90
70
  end
@@ -0,0 +1,18 @@
1
+ # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
+ # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
+
4
+ require 'sqreen/exception'
5
+
6
+ module Sqreen
7
+ module Js
8
+ class JsServiceAdapter
9
+ def preprocess(_rule_name, _code)
10
+ raise Sqreen::NotImplementedYet
11
+ end
12
+
13
+ def variant_name
14
+ 'unspecified'
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,14 +1,19 @@
1
1
  # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
2
  # Please refer to our terms for more information: https://www.sqreen.com/terms.html
3
3
 
4
+ # TODO: => Sqreen::JS:MiniRacer
5
+
4
6
  require 'digest'
5
7
  require 'json'
8
+ require 'sqreen/js/executable_js'
9
+ require 'sqreen/js/js_service_adapter'
10
+ require 'sqreen/js/context_pool'
11
+ require 'sqreen/js/mini_racer_executable_js'
6
12
 
7
13
  module Sqreen
8
14
  module Js
9
15
  DEFAULT_GC_THRESHOLD = 15000000 # 15 MB
10
16
 
11
-
12
17
  class MiniRacerAdapter < JsServiceAdapter
13
18
  def initialize(vendored = false)
14
19
  @vendored = vendored
@@ -30,184 +35,5 @@ module Sqreen
30
35
  @done_static_init = true
31
36
  end
32
37
  end
33
-
34
- # Auxiliary classes
35
-
36
- class ContextPool
37
- def initialize
38
- @mutex = Mutex.new
39
- @total_ctxs = 0
40
- @contexts = []
41
- end
42
-
43
- def with_context(&block)
44
- isolate = get_context
45
- begin
46
- block[isolate]
47
- ensure
48
- give_back_context isolate
49
- end
50
- end
51
-
52
- private
53
-
54
- def get_context
55
- @mutex.synchronize do
56
- if @contexts.empty?
57
- @total_ctxs += 1
58
- Sqreen.log.debug "Creating new V8 context (#{@total_ctxs})"
59
- SqreenContext.new
60
- else
61
- @contexts.pop
62
- end
63
- end
64
- end
65
-
66
- def give_back_context(context)
67
- context.possibly_gc
68
-
69
- if context.gc_load > 30
70
- if context.gc_threshold_in_bytes == DEFAULT_GC_THRESHOLD
71
- context.gc_threshold_in_bytes *= 2
72
- Sqreen.log.warn("Context #{context} had too many close garbage " \
73
- 'collections; doubling the threshold to ' \
74
- "#{context.gc_threshold_in_bytes} bytes")
75
- context.gc_load = 0
76
- else
77
- Sqreen.log.warn("Context #{context} had too many close garbage " \
78
- 'collections; discarding it')
79
- context.dispose
80
- return
81
- end
82
- end
83
-
84
- @mutex.synchronize { @contexts.push(context); }
85
- end
86
- end
87
-
88
- class MiniRacerExecutableJs < ExecutableJs
89
- @@ctx_defined = false
90
-
91
- def initialize(pool, code, vendored)
92
- @pool = pool
93
- @code = code
94
- @code_id = self.class.code_id(code)
95
-
96
- @module = vendored ? Sqreen::MiniRacer : MiniRacer
97
-
98
- mod = vendored ? Sqreen::MiniRacer : MiniRacer
99
- unless @@ctx_defined
100
- self.class.define_sqreen_context(mod)
101
- @@ctx_defined = true
102
- end
103
- end
104
-
105
- def run_js_cb(cb_name, budget, arguments)
106
- @pool.with_context do |ctx|
107
- if ctx.code_failed?(@code_id)
108
- Sqreen.log.debug do
109
- "Skipping execution of callback #{cb_name} (code md5 #{@code_id})" \
110
- " due to prev failure of definition evaluation"
111
- end
112
- return nil
113
- end
114
-
115
- ctx.add_code(@code_id, @code) unless ctx.has_code?(@code_id)
116
-
117
- # mini_racer expects timeout to be in ms
118
- ctx.timeout = budget ? budget * 1000.0 : nil
119
- begin
120
- ctx.call("sqreen_#{@code_id}_#{cb_name}", *arguments)
121
- rescue @module::ScriptTerminatedError
122
- Sqreen.log.debug "ScriptTerminatedError/#{cb_name}"
123
- nil
124
- end
125
- end
126
- end
127
-
128
- def self.code_id(code)
129
- Digest::MD5.hexdigest(code)
130
- end
131
-
132
- private
133
-
134
- class << self
135
- def define_sqreen_context(modoole)
136
- # Context specialized for Sqreen usage
137
- Sqreen::Js.const_set 'SqreenContext', Class.new(modoole.const_get('Context'))
138
- SqreenContext.class_eval do
139
- attr_accessor :gc_threshold_in_bytes
140
- attr_accessor :gc_load
141
- attr_writer :timeout
142
-
143
- def has_code?(code_id)
144
- return false unless @code_ids
145
- @code_ids.include?(code_id)
146
- end
147
-
148
- def code_failed?(code_id)
149
- return false unless @failed_code_ids
150
- @failed_code_ids.include?(code_id)
151
- end
152
-
153
- def add_code(code_id, code)
154
- # It's important that the definition is run in its own scope (by executing it inside an anonymous function)
155
- # Otherwise some auxiliary functions that the backend server sends will collide the name
156
- # Because they're defined with `var`, running the definitions inside a function is enough
157
- eval_unsafe "(function() { #{code} })()"
158
- transf_global_funcs code_id
159
- @code_ids ||= Set.new
160
- @code_ids << code_id
161
- rescue
162
- @failed_code_ids ||= Set.new
163
- @failed_code_ids << code_id
164
- raise
165
- end
166
-
167
- def eval_unsafe(str, filename = nil, timeoutv = nil)
168
- # Beware, timeout could be kept in the context
169
- # if perf cap is removed after having been activated
170
- # As it's unused by execjscb we are not cleaning it
171
- return super(str, filename) if timeoutv.nil?
172
- return if timeoutv <= 0.0
173
- timeoutv *= 1000 # Timeout are currently expressed in seconds
174
- @timeout = timeoutv
175
- @eval_thread = Thread.current
176
- timeout do
177
- super(str, filename)
178
- end
179
- end
180
-
181
- def possibly_gc
182
- @gc_threshold_in_bytes ||= DEFAULT_GC_THRESHOLD
183
- @gc_load ||= 0
184
-
185
- # garbage collections max 1 in every 4 calls (avg)
186
- if heap_stats[:total_heap_size] > @gc_threshold_in_bytes
187
- low_memory_notification
188
- @gc_load += 4
189
- else
190
- @gc_load = [0, @gc_load - 1].max
191
- end
192
- end
193
-
194
- private
195
-
196
- def transf_global_funcs(code_id)
197
- # Multiple callbacks may share the same name. In order to avoid collisions, we rename them here.
198
- eval_unsafe <<EOD
199
- Object.keys(this).forEach(name => {
200
- if (typeof this[name] === "function" && !name.startsWith("sqreen_")) {
201
- this['sqreen_#{code_id}_' + name] = this[name];
202
- this[name] = undefined;
203
- }
204
- });
205
- EOD
206
-
207
- end
208
- end
209
- end
210
- end
211
- end
212
38
  end
213
39
  end