class Honeybadger::Util::Sanitizer
Sanitizer
sanitizes data for sending to Honeybadger’s API. The filters are based on Rails’ HTTP
parameter filter.
Constants
- BASIC_OBJECT
- COOKIE_PAIRS
- COOKIE_PAIR_SEP
- COOKIE_SEP
- DEPTH
- ENCODE_OPTS
- FILTERED
- IMMUTABLE
- MAX_STRING_SIZE
- RAISED
- RECURSION
- TRUNCATED
- VALID_ENCODINGS
Attributes
blocks[R]
deep_regexps[R]
max_depth[R]
regexps[R]
Public Class Methods
new(max_depth: 20, filters: [])
click to toggle source
# File lib/honeybadger/util/sanitizer.rb, line 35 def initialize(max_depth: 20, filters: []) @filters = !filters.empty? @max_depth = max_depth strings, @regexps, @blocks = [], [], [] filters.each do |item| case item when Proc @blocks << item when Regexp @regexps << item else strings << Regexp.escape(item.to_s) end end @deep_regexps, @regexps = @regexps.partition { |r| r.to_s.include?('\\.'.freeze) } deep_strings, @strings = strings.partition { |s| s.include?('\\.'.freeze) } @regexps << Regexp.new(strings.join('|'.freeze), true) unless strings.empty? @deep_regexps << Regexp.new(deep_strings.join('|'.freeze), true) unless deep_strings.empty? end
sanitize(data)
click to toggle source
# File lib/honeybadger/util/sanitizer.rb, line 30 def self.sanitize(data) @sanitizer ||= new @sanitizer.sanitize(data) end
Public Instance Methods
filter_url(url)
click to toggle source
# File lib/honeybadger/util/sanitizer.rb, line 147 def filter_url(url) return url unless filters? filtered_url = url.to_s.dup filtered_url.scan(/(?:^|&|\?)([^=?&]+)=([^&]+)/).each do |m| next unless filter_key?(m[0]) filtered_url.gsub!(/#{Regexp.escape(m[1])}/, FILTERED) end filtered_url end
sanitize(data, depth = 0, stack = nil, parents = [])
click to toggle source
# File lib/honeybadger/util/sanitizer.rb, line 59 def sanitize(data, depth = 0, stack = nil, parents = []) return BASIC_OBJECT if basic_object?(data) if recursive?(data) return RECURSION if stack && stack.include?(data.object_id) stack = stack ? stack.dup : Set.new stack << data.object_id end case data when Hash return DEPTH if depth >= max_depth hash = data.to_hash new_hash = {} hash.each_pair do |key, value| parents.push(key) if deep_regexps key = key.kind_of?(Symbol) ? key : sanitize(key, depth+1, stack, parents) if filter_key?(key, parents) new_hash[key] = FILTERED else value = sanitize(value, depth+1, stack, parents) if blocks.any? && !recursive?(value) key = key.dup if can_dup?(key) value = value.dup if can_dup?(value) blocks.each { |b| b.call(key, value) } end new_hash[key] = value end parents.pop if deep_regexps end new_hash when Array, Set return DEPTH if depth >= max_depth data.to_a.map do |value| sanitize(value, depth+1, stack, parents) end when Numeric, TrueClass, FalseClass, NilClass data when String sanitize_string(data) when -> (d) { d.respond_to?(:to_honeybadger) } return DEPTH if depth >= max_depth begin data = data.to_honeybadger rescue return RAISED end sanitize(data, depth+1, stack, parents) else # all other objects klass = data.class begin data = String(data) rescue return RAISED end return "#<#{klass.name}>" if inspected?(data) sanitize_string(data) end end
Private Instance Methods
basic_object?(object)
click to toggle source
# File lib/honeybadger/util/sanitizer.rb, line 197 def basic_object?(object) object.respond_to?(:to_s) false rescue # BasicObject doesn't respond to `#respond_to?`. true end
can_dup?(obj)
click to toggle source
# File lib/honeybadger/util/sanitizer.rb, line 205 def can_dup?(obj) !IMMUTABLE.any? {|k| obj.kind_of?(k) } end
filter_key?(key, parents = nil)
click to toggle source
# File lib/honeybadger/util/sanitizer.rb, line 168 def filter_key?(key, parents = nil) return false unless filters? return true if key.respond_to?(:=~) && regexps.any? { |r| key =~ r } return true if deep_regexps && parents && (joined = parents.join(".")) && deep_regexps.any? { |r| joined =~ r } false end
filters?()
click to toggle source
# File lib/honeybadger/util/sanitizer.rb, line 164 def filters? !!@filters end
inspected?(string)
click to toggle source
# File lib/honeybadger/util/sanitizer.rb, line 209 def inspected?(string) String(string) =~ /#<.*>/ end
recursive?(data)
click to toggle source
# File lib/honeybadger/util/sanitizer.rb, line 193 def recursive?(data) data.is_a?(Hash) || data.is_a?(Array) || data.is_a?(Set) || data.respond_to?(:to_honeybadger) end
sanitize_string(string)
click to toggle source
# File lib/honeybadger/util/sanitizer.rb, line 175 def sanitize_string(string) string = valid_encoding(string) return string unless string.respond_to?(:size) && string.size > MAX_STRING_SIZE string[0...MAX_STRING_SIZE] + TRUNCATED end
valid_encoding(string)
click to toggle source
# File lib/honeybadger/util/sanitizer.rb, line 188 def valid_encoding(string) return string if valid_encoding?(string) string.encode(Encoding::UTF_8, **ENCODE_OPTS) end
valid_encoding?(string)
click to toggle source
# File lib/honeybadger/util/sanitizer.rb, line 181 def valid_encoding?(string) string.valid_encoding? && ( VALID_ENCODINGS.include?(string.encoding) || VALID_ENCODINGS.include?(Encoding.compatible?(''.freeze, string)) ) end