Class: Necropsy::Analyzers::Dynamic::RedisInputLimits

Inherits:
Object
  • Object
show all
Defined in:
lib/necropsy/analyzers/dynamic/redis_input_limits.rb

Constant Summary collapse

DEFAULTS =
{
  'connect_timeout' => 5.0,
  'read_timeout' => 5.0,
  'total_timeout' => 15.0,
  'max_response_bytes' => 16 * 1024 * 1024,
  'max_bulk_bytes' => 8 * 1024 * 1024,
  'max_array_elements' => 100_000,
  'max_resp_depth' => 16,
  'max_keys' => 1_000,
  'max_payload_depth' => 64
}.freeze
TIMEOUT_KEYS =
%w[connect_timeout read_timeout total_timeout].freeze
INTEGER_KEYS =
(DEFAULTS.keys - TIMEOUT_KEYS).freeze

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ RedisInputLimits

Returns a new instance of RedisInputLimits.



25
26
27
28
# File 'lib/necropsy/analyzers/dynamic/redis_input_limits.rb', line 25

def initialize(config)
  TIMEOUT_KEYS.each { |key| instance_variable_set("@#{key}", positive_float(config, key)) }
  INTEGER_KEYS.each { |key| instance_variable_set("@#{key}", positive_integer(config, key)) }
end

Instance Method Details

#validate_payload!(payload) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/necropsy/analyzers/dynamic/redis_input_limits.rb', line 30

def validate_payload!(payload)
  stack = [[payload, 0]]
  until stack.empty?
    value, depth = stack.pop
    raise Error, 'Redis coverage payload exceeds maximum nesting depth' if depth > max_payload_depth
    if (value.is_a?(Hash) || value.is_a?(Array)) && value.length > max_array_elements
      raise Error, 'Redis coverage payload exceeds maximum collection size'
    end

    children = value.is_a?(Hash) ? value.flat_map { |key, child| [key, child] } : Array(value)
    stack.concat(children.map { |child| [child, depth + 1] }) if value.is_a?(Hash) || value.is_a?(Array)
  end
  payload
end