sqreen 1.10.3 → 1.10.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 294bf474df4e1beb0533d87876a9b27e984d47ab332482aab2485fee862de414
4
- data.tar.gz: 6a4b0f5c640371ad280c0412c5b3c58f73d921df69f767522659e5c90d4ee663
3
+ metadata.gz: bdd2b054367e611564274927940b2cbc1f7d52c160b6288079a839da5a07c73a
4
+ data.tar.gz: 163fa3ce8ae72fe25635c1943eea48d00e5f54b6dfd222f66051ce2032f5763d
5
5
  SHA512:
6
- metadata.gz: bb633499e38e67c6768ac77bbdedccd83710708abe7b2422bfb0f3e4f4a2797b532b35203c97fbdf445ea205fe5e63cb5a1613e4ea8237b74330111410065ddb
7
- data.tar.gz: 8bf22330ac83b3c9133a96127f358e34f27fe3dd504985832fb8825a19cfcfbafa82a9a3db25284e4c460c76587a92923c331cac7a584c7e8e396e4145ff2070
6
+ metadata.gz: 6b142290e1c3f3f20d9a5a37da34c906f8ad3f3da4328d16f9354a9ba15bec6e0f9997eeb9837b6584fb6bf0e58f0118b2b38ac2c58641a2df376131373607b2
7
+ data.tar.gz: 2f8e8d35f50b9f4f1ef79fa7a7c695b3e816be16c422a65b21e55649991ecbd20a3f2781b891533af107e4027615f62368d609545e6a258e02b397511e0b910b
@@ -176,10 +176,29 @@ module Sqreen
176
176
  end
177
177
  end
178
178
 
179
+ def self.guard_multi_call(instance, method, original_method, args, block)
180
+ @sqreen_multi_instr ||= nil
181
+ key = [method]
182
+ Instrumentation.guard_call(nil, :guard_multi_call) do
183
+ args.each{|e| key.push(e.object_id)}
184
+ end
185
+ if key && @sqreen_multi_instr && @sqreen_multi_instr[instance.object_id].member?(key)
186
+ return instance.send(original_method, *args, &block)
187
+ end
188
+ @sqreen_multi_instr ||= Hash.new {|h, k| h[k]=Set.new } # TODO this should probably be a thread local
189
+ @sqreen_multi_instr[instance.object_id].add(key)
190
+ r = yield
191
+ return r
192
+ ensure
193
+ if @sqreen_multi_instr && @sqreen_multi_instr[instance.object_id] && @sqreen_multi_instr[instance.object_id].delete(key).empty?
194
+ @sqreen_multi_instr.delete(instance.object_id)
195
+ end
196
+ end
197
+
179
198
  def self.guard_call(method, retval)
180
199
  @sqreen_in_instr ||= nil
181
200
  return retval if @sqreen_in_instr && @sqreen_in_instr.member?(method)
182
- @sqreen_in_instr ||= Set.new
201
+ @sqreen_in_instr ||= Set.new # TODO this should probably be a thread local
183
202
  @sqreen_in_instr.add(method)
184
203
  r = yield
185
204
  @sqreen_in_instr.delete(method)
@@ -197,6 +216,7 @@ module Sqreen
197
216
  end
198
217
  return send(original_meth, *args, &block)
199
218
  end
219
+ Instrumentation.guard_multi_call(self, meth, original_meth, args, block) do
200
220
  Sqreen.stats.callbacks_calls += 1
201
221
 
202
222
  skip = false
@@ -271,6 +291,7 @@ module Sqreen
271
291
  result
272
292
  end
273
293
  end
294
+ end
274
295
  end
275
296
 
276
297
  def override_class_method(klass, meth)
@@ -325,8 +346,8 @@ module Sqreen
325
346
  end
326
347
  end
327
348
 
328
- def get_saved_method_name(meth)
329
- "#{meth}_not_modified".to_sym
349
+ def get_saved_method_name(meth, suffix=nil)
350
+ "#{meth}_sq#{suffix}_not_modified".to_sym
330
351
  end
331
352
 
332
353
  def override_instance_method(klass_name, meth)
@@ -403,6 +424,30 @@ module Sqreen
403
424
  is_instance_method?(obj, method)
404
425
  end
405
426
 
427
+ # Override a singleton method on an instance
428
+ def override_singleton_method(instance, klass_name, meth)
429
+ saved_meth_name = get_saved_method_name(meth, 'singleton')
430
+ if instance.respond_to?(saved_meth_name, true)
431
+ Sqreen.log.debug { "#{saved_meth_name} found #{instance.class}##{instance.object_id} already instrumented" }
432
+ return nil
433
+ elsif instance.frozen?
434
+ Sqreen.log.debug { "#{instance.class}##{instance.object_id} is frozen, not reinstrumenting" }
435
+ return nil
436
+ end
437
+ raise Sqreen::NotImplementedYet, "#{instance.inspect} doesn't respond to define_singleton_method" unless instance.respond_to?(:define_singleton_method)
438
+ p = Instrumentation.define_callback_method(meth, saved_meth_name,
439
+ klass_name)
440
+ instance.define_singleton_method(saved_meth_name, instance.method(meth))
441
+ instance.define_singleton_method(meth, p)
442
+ # Hide saved method (its only available in this syntax)
443
+ eval <<-RUBY, binding, __FILE__, __LINE__ + 1
444
+ class << instance
445
+ private :#{saved_meth_name}
446
+ end
447
+ saved_meth_name
448
+ RUBY
449
+ end
450
+
406
451
  def add_callback(cb)
407
452
  @@override_semaphore.synchronize do
408
453
  klass = cb.klass
@@ -427,7 +472,7 @@ module Sqreen
427
472
  # - method_missing
428
473
  # ...
429
474
  #
430
- msg = "#{cb} is neither singleton or instance"
475
+ msg = "#{cb} is neither class or instance"
431
476
  raise Sqreen::NotImplementedYet, msg
432
477
  end
433
478
 
@@ -436,6 +481,18 @@ module Sqreen
436
481
  Sqreen.log.debug "#{key} was already overriden"
437
482
  end
438
483
 
484
+ if klass != Object && klass != Kernel && !Sqreen.features['instrument_all_instances'] && !defined?(::JRUBY_VERSION)
485
+ insts = 0
486
+ ObjectSpace.each_object(klass) do |e|
487
+ next if e.is_a?(Class) || e.is_a?(Module)
488
+ next unless e.singleton_methods.include?(method.to_sym)
489
+ insts += 1 if override_singleton_method(e, klass, method)
490
+ end
491
+ if insts > 0
492
+ Sqreen.log.debug { "Reinstrumented #{insts} instances of #{klass}" }
493
+ end
494
+ end
495
+
439
496
  @@registered_callbacks.add(cb)
440
497
  @@instrumented_pid = Process.pid
441
498
  end
@@ -7,6 +7,16 @@ require 'set'
7
7
  require 'openssl'
8
8
  require 'base64'
9
9
  require 'json'
10
+ if defined?(::JRUBY_VERSION)
11
+ OJ_LOADED = false
12
+ else
13
+ begin
14
+ require "oj"
15
+ OJ_LOADED = true
16
+ rescue LoadError
17
+ OJ_LOADED = false
18
+ end
19
+ end
10
20
 
11
21
  ## Rules signature
12
22
  module Sqreen
@@ -25,7 +35,7 @@ module Sqreen
25
35
 
26
36
  # Normalize and verify a rule
27
37
  class SqreenSignedVerifier
28
- REQUIRED_SIGNED_KEYS = %w(hookpoint name callbacks conditions).freeze
38
+ REQUIRED_SIGNED_KEYS = %w[hookpoint name callbacks conditions].freeze
29
39
  SIGNATURE_KEY = 'signature'.freeze
30
40
  SIGNATURE_VALUE_KEY = 'value'.freeze
31
41
  SIGNED_KEYS_KEY = 'keys'.freeze
@@ -42,12 +52,14 @@ module Sqreen
42
52
  attr_accessor :pub_key
43
53
  attr_accessor :required_signed_keys
44
54
  attr_accessor :digest
55
+ attr_accessor :use_oj
45
56
 
46
57
  def initialize(required_keys = REQUIRED_SIGNED_KEYS,
47
58
  public_key = PUBLIC_KEY,
48
- digest = OpenSSL::Digest::SHA512.new)
59
+ digest = OpenSSL::Digest::SHA512.new, use_oj_gem = nil)
49
60
  @required_signed_keys = required_keys
50
61
  @signature_verifier = SignatureVerifier.new(public_key, digest)
62
+ @use_oj = use_oj_gem.nil? ? OJ_LOADED : use_oj_gem
51
63
  end
52
64
 
53
65
  def normalize_val(val, level)
@@ -62,6 +74,7 @@ module Sqreen
62
74
  end
63
75
  "[#{ary.join(',')}]"
64
76
  when String, Integer
77
+ return Oj.dump(val, :mode => :compat, :escape_mode => :json) if use_oj
65
78
  begin
66
79
  JSON.dump(val)
67
80
  rescue JSON::GeneratorError
@@ -76,6 +89,7 @@ module Sqreen
76
89
  def normalize_key(key)
77
90
  case key
78
91
  when String, Integer
92
+ return Oj.dump(key, :mode => :compat, :escape_mode => :json) if use_oj
79
93
  begin
80
94
  JSON.dump(key)
81
95
  rescue JSON::GeneratorError
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2015 Sqreen. All Rights Reserved.
2
2
  # Please refer to our terms for more information: https://www.sqreen.io/terms.html
3
3
  module Sqreen
4
- VERSION = '1.10.3'.freeze
4
+ VERSION = '1.10.4'.freeze
5
5
  end
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.10.3
4
+ version: 1.10.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sqreen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-15 00:00:00.000000000 Z
11
+ date: 2018-02-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: execjs