sqreen 1.14.2 → 1.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/sqreen/js/mini_racer_adapter.rb +94 -64
- data/lib/sqreen/metrics/binning.rb +1 -0
- data/lib/sqreen/rules.rb +2 -2
- data/lib/sqreen/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59d80d2fe6c9c0bd343380d867b4c1b7f878a42890e3cbe5ab005e4e32507abc
|
4
|
+
data.tar.gz: 1e7c0ee1ef948048fb020b3b64377a1476f2b000aaf22df683b5aec38658895e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b26544a382b1ef480be8bd92593187584efa7c0b63a05d366f4d53083d6d2f3e71acb168c216985d649281b6004f5bb31ed068b688062531a77cfe0ead4d0e0
|
7
|
+
data.tar.gz: 6331863e48ce18d812ed294b9d1a6fef01a1a805ca2dbab1a20bd76d5837b983bcd022572d751f1e006a68e34a5cf0db2b32a4fc4e7eaf598bf6cd9f7c269ee2
|
@@ -1,5 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require 'sqreen/runner' # for Sqreen.on_forked_worker?
|
1
|
+
require 'digest'
|
3
2
|
|
4
3
|
module Sqreen
|
5
4
|
module Js
|
@@ -8,11 +7,12 @@ module Sqreen
|
|
8
7
|
class MiniRacerAdapter < JsServiceAdapter
|
9
8
|
def initialize(vendored = false)
|
10
9
|
@vendored = vendored
|
10
|
+
@pool = ContextPool.new
|
11
11
|
self.class.static_init
|
12
12
|
end
|
13
13
|
|
14
14
|
def preprocess(_rule_name, code)
|
15
|
-
MiniRacerExecutableJs.new(code, @vendored)
|
15
|
+
MiniRacerExecutableJs.new(@pool, code, @vendored)
|
16
16
|
end
|
17
17
|
|
18
18
|
def variant_name
|
@@ -28,48 +28,74 @@ module Sqreen
|
|
28
28
|
|
29
29
|
# Auxiliary classes
|
30
30
|
|
31
|
+
class ContextPool
|
32
|
+
def initialize
|
33
|
+
@mutex = Mutex.new
|
34
|
+
@total_ctxs = 0
|
35
|
+
@contexts = []
|
36
|
+
end
|
37
|
+
|
38
|
+
def with_context(&block)
|
39
|
+
isolate = get_context
|
40
|
+
begin
|
41
|
+
block[isolate]
|
42
|
+
ensure
|
43
|
+
give_back_context isolate
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def get_context
|
50
|
+
@mutex.synchronize do
|
51
|
+
if @contexts.empty?
|
52
|
+
@total_ctxs += 1
|
53
|
+
Sqreen.log.debug "Creating new V8 context (#{@total_ctxs})"
|
54
|
+
SqreenContext.new
|
55
|
+
else
|
56
|
+
@contexts.pop
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def give_back_context(isolate)
|
62
|
+
@mutex.synchronize { @contexts.push(isolate); }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
31
66
|
class MiniRacerExecutableJs < ExecutableJs
|
32
67
|
@@ctx_defined = false
|
33
68
|
|
34
|
-
def initialize(
|
69
|
+
def initialize(pool, code, vendored)
|
70
|
+
@pool = pool
|
71
|
+
@code = code
|
72
|
+
@code_id = self.class.code_id(code)
|
73
|
+
|
35
74
|
@module = vendored ? Sqreen::MiniRacer : MiniRacer
|
36
|
-
|
37
|
-
|
38
|
-
@runtimes = []
|
39
|
-
@tl_key = "SQREEN_MINI_RACER_CONTEXT_#{object_id}".freeze
|
40
|
-
snapshot if Sqreen.on_forked_worker? # called to eagerly initialize snapshot
|
75
|
+
|
76
|
+
mod = vendored ? Sqreen::MiniRacer : MiniRacer
|
41
77
|
unless @@ctx_defined
|
42
|
-
self.class.define_sqreen_context(
|
78
|
+
self.class.define_sqreen_context(mod)
|
43
79
|
@@ctx_defined = true
|
44
80
|
end
|
45
81
|
end
|
46
82
|
|
47
83
|
def run_js_cb(cb_name, budget, arguments)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
mini_racer_context = {
|
59
|
-
:c => 0,
|
60
|
-
:r => WeakCtx.new(new_runtime),
|
61
|
-
}
|
62
|
-
Thread.current[@tl_key] = mini_racer_context
|
84
|
+
@pool.with_context do |ctx|
|
85
|
+
ctx.add_code(@code_id, @code) unless ctx.has_code?(@code_id)
|
86
|
+
|
87
|
+
begin
|
88
|
+
json_args = "[#{arguments.map(&method(:fixup_bad_encoding)).map(&:to_json).join(',')}]"
|
89
|
+
ctx.eval_unsafe(
|
90
|
+
"sqreen_data['#{@code_id}']['#{cb_name}'].apply(this, #{json_args})", nil, budget)
|
91
|
+
rescue @module::ScriptTerminatedError
|
92
|
+
nil
|
93
|
+
end
|
63
94
|
end
|
95
|
+
end
|
64
96
|
|
65
|
-
|
66
|
-
|
67
|
-
json_args = "[#{arguments.map(&method(:fixup_bad_encoding)).map(&:to_json).join(',')}]"
|
68
|
-
mini_racer_context[:r].eval_unsafe(
|
69
|
-
"#{cb_name}.apply(this, #{json_args})", nil, budget)
|
70
|
-
rescue @module::ScriptTerminatedError
|
71
|
-
nil
|
72
|
-
end
|
97
|
+
def self.code_id(code)
|
98
|
+
Digest::MD5.base64digest(code)
|
73
99
|
end
|
74
100
|
|
75
101
|
private
|
@@ -91,29 +117,25 @@ module Sqreen
|
|
91
117
|
end
|
92
118
|
end
|
93
119
|
|
94
|
-
def snapshot
|
95
|
-
@snapshot ||= @module::Snapshot.new(@source)
|
96
|
-
end
|
97
|
-
|
98
|
-
def push_runtime(runtime)
|
99
|
-
@runtimes.delete_if do |th, runt, _thid|
|
100
|
-
del = th.nil? || !th.weakref_alive? || !th.alive?
|
101
|
-
runt.dispose if del
|
102
|
-
del
|
103
|
-
end
|
104
|
-
@runtimes.push [WeakRef.new(Thread.current), runtime, Thread.current.object_id]
|
105
|
-
end
|
106
|
-
|
107
|
-
def dispose_runtime(runtime)
|
108
|
-
@runtimes.delete_if { |_th, _runt, thid| thid == Thread.current.object_id }
|
109
|
-
runtime.dispose
|
110
|
-
end
|
111
|
-
|
112
120
|
class << self
|
113
121
|
def define_sqreen_context(modoole)
|
114
122
|
# Context specialized for Sqreen usage
|
115
123
|
Sqreen::Js.const_set 'SqreenContext', Class.new(modoole.const_get('Context'))
|
116
124
|
SqreenContext.class_eval do
|
125
|
+
def has_code?(code_id)
|
126
|
+
return false unless @code_ids
|
127
|
+
@code_ids.include?(code_id)
|
128
|
+
end
|
129
|
+
|
130
|
+
def add_code(code_id, code)
|
131
|
+
@code_ids ||= Set.new
|
132
|
+
# if it fails, we don't try again
|
133
|
+
@code_ids << code_id
|
134
|
+
|
135
|
+
eval_unsafe code
|
136
|
+
transf_global_funcs code_id
|
137
|
+
end
|
138
|
+
|
117
139
|
def eval_unsafe(str, filename = nil, timeoutv = nil)
|
118
140
|
# Beware, timeout could be kept in the context
|
119
141
|
# if perf cap is removed after having been activated
|
@@ -127,21 +149,29 @@ module Sqreen
|
|
127
149
|
super(str, filename)
|
128
150
|
end
|
129
151
|
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
134
152
|
|
153
|
+
private
|
154
|
+
|
155
|
+
def transf_global_funcs(code_id)
|
156
|
+
eval_unsafe <<EOD
|
157
|
+
if (typeof sqreen_data === 'undefined') {
|
158
|
+
sqreen_data = {};
|
159
|
+
}
|
160
|
+
|
161
|
+
group = {};
|
162
|
+
Object.keys(this).forEach(name => {
|
163
|
+
if (typeof this[name] === "function") {
|
164
|
+
group[name] = this[name];
|
165
|
+
this[name] = undefined;
|
166
|
+
}
|
167
|
+
});
|
168
|
+
sqreen_data['#{code_id}'] = group
|
169
|
+
delete group;
|
170
|
+
EOD
|
135
171
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
def initialize(*args)
|
140
|
-
super(*args)
|
141
|
-
end
|
142
|
-
|
143
|
-
def eval_unsafe(str, filename, timeoutv)
|
144
|
-
__getobj__.eval_unsafe(str, filename, timeoutv)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
145
175
|
end
|
146
176
|
end
|
147
177
|
end
|
data/lib/sqreen/rules.rb
CHANGED
@@ -77,8 +77,8 @@ module Sqreen
|
|
77
77
|
js = hash_rule[Attrs::CALLBACKS]
|
78
78
|
|
79
79
|
if js && !Sqreen::Js::JsService.instance.online?
|
80
|
-
unless
|
81
|
-
|
80
|
+
unless @issue_nojs_warn
|
81
|
+
@issue_nojs_warn = true
|
82
82
|
Sqreen.log.warn('No JavaScript engine is available. ' \
|
83
83
|
'JavaScript callbacks will be ignored')
|
84
84
|
end
|
data/lib/sqreen/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sqreen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sqreen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-10-
|
11
|
+
date: 2018-10-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sq_mini_racer
|