bugsnag 6.13.0 → 6.13.1

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: 2298a07774ef42fb825c7ae6aa9722c9da1234617789236a442cd0d888a4e486
4
- data.tar.gz: f4882c3be40fe0e4d6582ec24e00751257ab5f5926866c0317a7d6d0ae3aa129
3
+ metadata.gz: 25dcf74c356f7025c163ad055ddb01ecb27b46ddf31b746f87b8753d9c1899ca
4
+ data.tar.gz: fab1845fb7b1165caa97a88561bdc49230603e7d8d9e218a55c0cf52af2da640
5
5
  SHA512:
6
- metadata.gz: 129a9b9cf9411234935f4d49be119596e55475d31ff68e943e978f14ca95d17f2418c37fffa6190f25b03301fd408d5c0d4719c11807934982d3cd6f4d1c52ff
7
- data.tar.gz: 6dae71c25d20bb071104e07608e51b33e4ab2deaaa0a7bf2bab06694f850d20823d2afde37c1edebd105b8e190b0d22baf61da8d16925b84f3fb5ec757cf6cbf
6
+ metadata.gz: d103cd0a9df8e2d02fd98a10f9b24ef706dc93c8266f148d480076c1ee2d2d06114de0c60983ca5c3275804271c9f664cdc64ddffdbc19fda1f787afb6d49e24
7
+ data.tar.gz: 6d85db5571b16d3de7c23baf7c932536c08fdd9261557bbb2f59e4436981caf02177fb5b91fb7cb4adbbc62d5c6f42f610128890f7414eda85aa1e1c21248ba2
@@ -1,6 +1,16 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## 6.13.1 (11 May 2020)
5
+
6
+ ### Fixes
7
+
8
+ * Only call custom diagnostic data methods once
9
+ | [#586](https://github.com/bugsnag/bugsnag-ruby/pull/586)
10
+ | [stoivo](https://github.com/stoivo)
11
+ * Guard against exceptions in to_s when cleaning objects
12
+ | [#591](https://github.com/bugsnag/bugsnag-ruby/pull/591)
13
+
4
14
  ## 6.13.0 (30 Jan 2020)
5
15
 
6
16
  ### Enhancements
data/VERSION CHANGED
@@ -1 +1 @@
1
- 6.13.0
1
+ 6.13.1
@@ -29,10 +29,19 @@ module Bugsnag
29
29
  when Hash
30
30
  clean_hash = {}
31
31
  obj.each do |k,v|
32
- if filters_match_deeply?(k, scope)
33
- clean_hash[k] = FILTERED
34
- else
35
- clean_hash[k] = traverse_object(v, seen, [scope, k].compact.join('.'))
32
+ begin
33
+ if filters_match_deeply?(k, scope)
34
+ clean_hash[k] = FILTERED
35
+ else
36
+ clean_hash[k] = traverse_object(v, seen, [scope, k].compact.join('.'))
37
+ end
38
+ # If we get an error here, we assume the key needs to be filtered
39
+ # to avoid leaking things we shouldn't. We also remove the key itself
40
+ # because it may cause issues later e.g. when being converted to JSON
41
+ rescue StandardError
42
+ clean_hash[RAISED] = FILTERED
43
+ rescue SystemStackError
44
+ clean_hash[RECURSION] = FILTERED
36
45
  end
37
46
  end
38
47
  clean_hash
@@ -43,7 +52,15 @@ module Bugsnag
43
52
  when String
44
53
  clean_string(obj)
45
54
  else
46
- str = obj.to_s rescue RAISED
55
+ # guard against objects that raise or blow the stack when stringified
56
+ begin
57
+ str = obj.to_s
58
+ rescue StandardError
59
+ str = RAISED
60
+ rescue SystemStackError
61
+ str = RECURSION
62
+ end
63
+
47
64
  # avoid leaking potentially sensitive data from objects' #inspect output
48
65
  if str =~ /#<.*>/
49
66
  OBJECT
@@ -9,21 +9,27 @@ module Bugsnag::Middleware
9
9
  def call(report)
10
10
  # Apply the user's information attached to the exceptions
11
11
  report.raw_exceptions.each do |exception|
12
- if exception.respond_to?(:bugsnag_user_id) && exception.bugsnag_user_id.is_a?(String)
13
- report.user = {id: exception.bugsnag_user_id}
12
+ if exception.respond_to?(:bugsnag_user_id)
13
+ user_id = exception.bugsnag_user_id
14
+ report.user = {id: user_id} if user_id.is_a?(String)
14
15
  end
15
16
 
16
- if exception.respond_to?(:bugsnag_context) && exception.bugsnag_context.is_a?(String)
17
- report.context = exception.bugsnag_context
17
+ if exception.respond_to?(:bugsnag_context)
18
+ context = exception.bugsnag_context
19
+ report.context = context if context.is_a?(String)
18
20
  end
19
21
 
20
- if exception.respond_to?(:bugsnag_grouping_hash) && exception.bugsnag_grouping_hash.is_a?(String)
21
- report.grouping_hash = exception.bugsnag_grouping_hash
22
+ if exception.respond_to?(:bugsnag_grouping_hash)
23
+ group_hash = exception.bugsnag_grouping_hash
24
+ report.grouping_hash = group_hash if group_hash.is_a?(String)
22
25
  end
23
26
 
24
- if exception.respond_to?(:bugsnag_meta_data) && exception.bugsnag_meta_data.is_a?(Hash)
25
- exception.bugsnag_meta_data.each do |key, value|
26
- report.add_tab key, value
27
+ if exception.respond_to?(:bugsnag_meta_data)
28
+ meta_data = exception.bugsnag_meta_data
29
+ if meta_data.is_a?(Hash)
30
+ meta_data.each do |key, value|
31
+ report.add_tab key, value
32
+ end
27
33
  end
28
34
  end
29
35
  end
@@ -6,12 +6,84 @@ describe Bugsnag::Cleaner do
6
6
  subject { described_class.new(nil) }
7
7
 
8
8
  describe "#clean_object" do
9
+ is_jruby = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
10
+
9
11
  it "cleans up recursive hashes" do
10
12
  a = {:a => {}}
11
13
  a[:a][:b] = a
12
14
  expect(subject.clean_object(a)).to eq({:a => {:b => "[RECURSION]"}})
13
15
  end
14
16
 
17
+ it "cleans up hashes when keys infinitely recurse in to_s" do
18
+ skip "JRuby doesn't allow recovery from SystemStackErrors" if is_jruby
19
+
20
+ class RecursiveHashKey
21
+ def to_s
22
+ to_s
23
+ end
24
+ end
25
+
26
+ key = RecursiveHashKey.new
27
+
28
+ a = {}
29
+ a[key] = 1
30
+
31
+ expect(subject.clean_object(a)).to eq({ "[RECURSION]" => "[FILTERED]" })
32
+ end
33
+
34
+ it "cleans up hashes when a nested key infinitely recurse in to_s" do
35
+ skip "JRuby doesn't allow recovery from SystemStackErrors" if is_jruby
36
+
37
+ class RecursiveHashKey
38
+ def to_s
39
+ to_s
40
+ end
41
+ end
42
+
43
+ key = RecursiveHashKey.new
44
+
45
+ a = {}
46
+ a[:b] = {}
47
+ a[:b][key] = 1
48
+
49
+ expected = { :b => { "[RECURSION]" => "[FILTERED]" } }
50
+
51
+ expect(subject.clean_object(a)).to eq(expected)
52
+ end
53
+
54
+ it "cleans up hashes when keys raise in to_s" do
55
+ class RaisingHashKey
56
+ def to_s
57
+ raise "hey!"
58
+ end
59
+ end
60
+
61
+ key = RaisingHashKey.new
62
+
63
+ a = {}
64
+ a[key] = 1
65
+
66
+ expect(subject.clean_object(a)).to eq({ "[RAISED]" => "[FILTERED]" })
67
+ end
68
+
69
+ it "cleans up hashes when nested keys raise in to_s" do
70
+ class RaisingHashKey
71
+ def to_s
72
+ raise "hey!"
73
+ end
74
+ end
75
+
76
+ key = RaisingHashKey.new
77
+
78
+ a = {}
79
+ a[:b] = {}
80
+ a[:b][key] = 1
81
+
82
+ expected = { :b => { "[RAISED]" => "[FILTERED]" } }
83
+
84
+ expect(subject.clean_object(a)).to eq(expected)
85
+ end
86
+
15
87
  it "cleans up recursive arrays" do
16
88
  a = []
17
89
  a << a
@@ -48,6 +120,20 @@ describe Bugsnag::Cleaner do
48
120
  expect(subject.clean_object(a)).to eq('[OBJECT]')
49
121
  end
50
122
 
123
+ it "cleans custom objects when they infinitely recurse" do
124
+ skip "JRuby doesn't allow recovery from SystemStackErrors" if is_jruby
125
+
126
+ class RecursiveObject
127
+ def to_s
128
+ to_s
129
+ end
130
+ end
131
+
132
+ object = RecursiveObject.new
133
+
134
+ expect(subject.clean_object(object)).to eq("[RECURSION]")
135
+ end
136
+
51
137
  it "cleans up binary strings properly" do
52
138
  if RUBY_VERSION > "1.9"
53
139
  obj = "Andr\xc7\xff"
@@ -50,6 +50,61 @@ describe Bugsnag::Helpers do
50
50
  value = Bugsnag::Helpers.trim_if_needed([1, 3, StringRaiser.new])
51
51
  expect(value[2]).to eq "[RAISED]"
52
52
  end
53
+
54
+ it "replaces hash key with '[RAISED]'" do
55
+ a = {}
56
+ a[StringRaiser.new] = 1
57
+
58
+ value = Bugsnag::Helpers.trim_if_needed(a)
59
+ expect(value).to eq({ "[RAISED]" => "[FILTERED]" })
60
+ end
61
+
62
+ it "uses a single '[RAISED]'key when multiple keys raise" do
63
+ a = {}
64
+ a[StringRaiser.new] = 1
65
+ a[StringRaiser.new] = 2
66
+
67
+ value = Bugsnag::Helpers.trim_if_needed(a)
68
+ expect(value).to eq({ "[RAISED]" => "[FILTERED]" })
69
+ end
70
+ end
71
+
72
+ context "an object will infinitely recurse if `to_s` is called" do
73
+ is_jruby = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
74
+
75
+ class StringRecurser
76
+ def to_s
77
+ to_s
78
+ end
79
+ end
80
+
81
+ it "uses the string '[RECURSION]' instead" do
82
+ skip "JRuby doesn't allow recovery from SystemStackErrors" if is_jruby
83
+
84
+ value = Bugsnag::Helpers.trim_if_needed([1, 3, StringRecurser.new])
85
+ expect(value[2]).to eq "[RECURSION]"
86
+ end
87
+
88
+ it "replaces hash key with '[RECURSION]'" do
89
+ skip "JRuby doesn't allow recovery from SystemStackErrors" if is_jruby
90
+
91
+ a = {}
92
+ a[StringRecurser.new] = 1
93
+
94
+ value = Bugsnag::Helpers.trim_if_needed(a)
95
+ expect(value).to eq({ "[RECURSION]" => "[FILTERED]" })
96
+ end
97
+
98
+ it "uses a single '[RECURSION]'key when multiple keys recurse" do
99
+ skip "JRuby doesn't allow recovery from SystemStackErrors" if is_jruby
100
+
101
+ a = {}
102
+ a[StringRecurser.new] = 1
103
+ a[StringRecurser.new] = 2
104
+
105
+ value = Bugsnag::Helpers.trim_if_needed(a)
106
+ expect(value).to eq({ "[RECURSION]" => "[FILTERED]" })
107
+ end
53
108
  end
54
109
 
55
110
  context "payload length is less than allowed" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bugsnag
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.13.0
4
+ version: 6.13.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Smith
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-30 00:00:00.000000000 Z
11
+ date: 2020-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -722,8 +722,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
722
722
  - !ruby/object:Gem::Version
723
723
  version: '0'
724
724
  requirements: []
725
- rubyforge_project:
726
- rubygems_version: 2.7.6.2
725
+ rubygems_version: 3.1.2
727
726
  signing_key:
728
727
  specification_version: 4
729
728
  summary: Ruby notifier for bugsnag.com