Module: Bugsnag::Helpers

Defined in:
lib/bugsnag/helpers.rb

Constant Summary collapse

MAX_STRING_LENGTH =
4096

Class Method Summary collapse

Class Method Details

.cleanup_obj(obj, filters = nil, seen = Set.new) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/bugsnag/helpers.rb', line 5

def self.cleanup_obj(obj, filters = nil, seen=Set.new)
  return nil unless obj

  # Protect against recursion of recursable items
  if obj.is_a?(Hash) || obj.is_a?(Array) || obj.is_a?(Set)
    return "[RECURSION]" if seen.include? obj

    # We duplicate the seen set here so that no updates by further cleanup_obj calls
    # are persisted beyond that call.
    seen = seen.dup
    seen << obj
  end

  case obj
  when Hash
    clean_hash = {}
    obj.each do |k,v|
      if filters_match?(k, filters)
        clean_hash[k] = "[FILTERED]"
      else
        clean_obj = cleanup_obj(v, filters, seen)
        clean_hash[k] = clean_obj
      end
    end
    clean_hash
  when Array, Set
    obj.map { |el| cleanup_obj(el, filters, seen) }.compact
  when Numeric
    obj
  when String
    if defined?(obj.encoding) && defined?(Encoding::UTF_8)
      if obj.encoding == Encoding::UTF_8
        obj.valid_encoding? ? obj : obj.encode('utf-16', {:invalid => :replace, :undef => :replace}).encode('utf-8')
      else
        obj.encode('utf-8', {:invalid => :replace, :undef => :replace})
      end
    elsif defined?(Iconv)
      Iconv.conv('UTF-8//IGNORE', 'UTF-8', obj) || obj
    else
      obj
    end
  else
    str = obj.to_s
    # avoid leaking potentially sensitive data from objects' #inspect output
    if str =~ /#<.*>/
      '[OBJECT]'
    else
      str
    end
  end
end

.cleanup_url(url, filters = nil) ⇒ Object



70
71
72
73
74
75
76
# File 'lib/bugsnag/helpers.rb', line 70

def self.cleanup_url(url, filters = nil)
  return url unless filters

  filter_regex = Regexp.new("([?&](?:[^&=]*#{filters.to_a.join('|[^&=]*')}[^&=]*)=)[^&]*")

  url.gsub(filter_regex, '\1[FILTERED]')
end

.dump_json(object, options = {}) ⇒ Object

Helper functions to work around MultiJson changes in 1.3+



107
108
109
110
111
112
113
# File 'lib/bugsnag/helpers.rb', line 107

def self.dump_json(object, options={})
  if MultiJson.respond_to?(:adapter)
    MultiJson.dump(object, options)
  else
    MultiJson.encode(object, options)
  end
end

.filters_match?(object, filters) ⇒ Boolean

Returns:

  • (Boolean)


57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/bugsnag/helpers.rb', line 57

def self.filters_match?(object, filters)
  str = object.to_s

  Array(filters).any? do |f|
    case f
    when Regexp
      str.match(f)
    else
      str.include?(f.to_s)
    end
  end
end

.flatten_meta_data(overrides) ⇒ Object



95
96
97
98
99
100
101
102
103
104
# File 'lib/bugsnag/helpers.rb', line 95

def self.(overrides)
  return nil unless overrides

   = overrides.delete(:meta_data)
  if .is_a?(Hash)
    overrides.merge()
  else
    overrides
  end
end

.load_json(json, options = {}) ⇒ Object



115
116
117
118
119
120
121
# File 'lib/bugsnag/helpers.rb', line 115

def self.load_json(json, options={})
  if MultiJson.respond_to?(:adapter)
    MultiJson.load(json, options)
  else
    MultiJson.decode(json, options)
  end
end

.reduce_hash_size(hash) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/bugsnag/helpers.rb', line 78

def self.reduce_hash_size(hash)
  return {} unless hash.is_a?(Hash)
  hash.inject({}) do |h, (k,v)|
    if v.is_a?(Hash)
      h[k] = reduce_hash_size(v)
    elsif v.is_a?(Array) || v.is_a?(Set)
      h[k] = v.map {|el| reduce_hash_size(el) }
    else
      val = v.to_s
      val = val.slice(0, MAX_STRING_LENGTH) + "[TRUNCATED]" if val.length > MAX_STRING_LENGTH
      h[k] = val
    end

    h
  end
end