Class: RuboCop::Cop::Security::CompoundHash
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::Security::CompoundHash
show all
- Defined in:
- lib/rubocop/cop/security/compound_hash.rb
Overview
Checks for implementations of the ‘hash` method which combine values using custom logic instead of delegating to `Array#hash`.
Manually combining hashes is error prone and hard to follow, especially when there are many values. Poor implementations may also introduce performance or security concerns if they are prone to collisions. Delegating to ‘Array#hash` is clearer and safer, although it might be slower depending on the use case.
Constant Summary
collapse
- COMBINATOR_IN_HASH_MSG =
'Use `[...].hash` instead of combining hash values manually.'
- MONUPLE_HASH_MSG =
'Delegate hash directly without wrapping in an array when only using a single value.'
- REDUNDANT_HASH_MSG =
'Calling .hash on elements of a hashed array is redundant.'
- RESTRICT_ON_SEND =
%i[hash ^ + * |].freeze
Instance Attribute Summary
Attributes inherited from Base
#config, #processed_source
Instance Method Summary
collapse
Methods inherited from Base
#active_support_extensions_enabled?, #add_global_offense, #add_offense, #always_autocorrect?, autocorrect_incompatible_with, badge, #begin_investigation, #callbacks_needed, callbacks_needed, #config_to_allow_offenses, #config_to_allow_offenses=, #contextual_autocorrect?, #cop_config, cop_name, #cop_name, department, documentation_url, exclude_from_registry, #excluded_file?, #external_dependency_checksum, inherited, #initialize, #inspect, joining_forces, lint?, match?, #message, #offenses, #on_investigation_end, #on_new_investigation, #on_other_file, #parse, #parser_engine, #ready, #relevant_file?, requires_gem, #string_literals_frozen_by_default?, support_autocorrect?, support_multiple_source?, #target_rails_version, #target_ruby_version
#exclude_limit
#autocorrect?, #autocorrect_enabled?, #autocorrect_requested?, #autocorrect_with_disable_uncorrectable?, #correctable?, #disable_uncorrectable?, #safe_autocorrect?
#ignore_node, #ignored_node?, #part_of_ignored_node?
Methods included from Util
silence_warnings
Instance Method Details
#bad_hash_combinator?(node) ⇒ Object
59
60
61
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 59
def_node_matcher :bad_hash_combinator?, <<~PATTERN
({send | op-asgn} _ {:^ | :+ | :* | :|} _)
PATTERN
|
#contained_in_hash_method?(node, &block) ⇒ Boolean
76
77
78
79
80
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 76
def contained_in_hash_method?(node, &block)
node.each_ancestor.any? do |ancestor|
hash_method_definition?(ancestor, &block)
end
end
|
#dynamic_hash_method_definition?(node) ⇒ Object
43
44
45
46
47
48
49
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 43
def_node_matcher :dynamic_hash_method_definition?, <<~PATTERN
(block
(send _ {:define_method | :define_singleton_method}
(sym :hash))
(args)
_)
PATTERN
|
#hash_method_definition?(node) ⇒ Object
38
39
40
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 38
def_node_matcher :hash_method_definition?, <<~PATTERN
{#static_hash_method_definition? | #dynamic_hash_method_definition?}
PATTERN
|
#monuple_hash?(node) ⇒ Object
64
65
66
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 64
def_node_matcher :monuple_hash?, <<~PATTERN
(send (array _) :hash)
PATTERN
|
#on_send(node) ⇒ Object
Also known as:
on_op_asgn
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 88
def on_send(node)
outer_bad_hash_combinator?(node) do
contained_in_hash_method?(node) do
add_offense(node, message: COMBINATOR_IN_HASH_MSG)
end
end
monuple_hash?(node) do
add_offense(node, message: MONUPLE_HASH_MSG)
end
redundant_hash?(node) do
add_offense(node, message: REDUNDANT_HASH_MSG)
end
end
|
#outer_bad_hash_combinator?(node) ⇒ Boolean
82
83
84
85
86
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 82
def outer_bad_hash_combinator?(node)
bad_hash_combinator?(node) do
yield true if node.each_ancestor.none? { |ancestor| bad_hash_combinator?(ancestor) }
end
end
|
#redundant_hash?(node) ⇒ Object
69
70
71
72
73
74
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 69
def_node_matcher :redundant_hash?, <<~PATTERN
(
^^(send array ... :hash)
_ :hash
)
PATTERN
|
#static_hash_method_definition?(node) ⇒ Object
52
53
54
55
56
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 52
def_node_matcher :static_hash_method_definition?, <<~PATTERN
({def | defs _} :hash
(args)
_)
PATTERN
|