sqreen 1.10.3 → 1.10.4

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 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