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
This cop 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, faster, and safer.
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'
Constants inherited
from Base
Base::RESTRICT_ON_SEND
Instance Attribute Summary
Attributes inherited from Base
#config, #processed_source
Instance Method Summary
collapse
Methods inherited from Base
#add_global_offense, #add_offense, autocorrect_incompatible_with, badge, callbacks_needed, #callbacks_needed, #config_to_allow_offenses, #config_to_allow_offenses=, #cop_config, #cop_name, cop_name, department, documentation_url, exclude_from_registry, #excluded_file?, #external_dependency_checksum, inherited, #initialize, joining_forces, lint?, match?, #message, #offenses, #on_investigation_end, #on_new_investigation, #on_other_file, #parse, #ready, #relevant_file?, 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
57
58
59
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 57
def_node_matcher :bad_hash_combinator?, <<~PATTERN
({send | op-asgn} _ {:^ | :+ | :* | :|} _)
PATTERN
|
#contained_in_hash_method?(node, &block) ⇒ Boolean
74
75
76
77
78
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 74
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
41
42
43
44
45
46
47
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 41
def_node_matcher :dynamic_hash_method_definition?, <<~PATTERN
(block
(send _ {:define_method | :define_singleton_method}
(sym :hash))
(args)
_)
PATTERN
|
#hash_method_definition?(node) ⇒ Object
36
37
38
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 36
def_node_matcher :hash_method_definition?, <<~PATTERN
{#static_hash_method_definition? | #dynamic_hash_method_definition?}
PATTERN
|
#monuple_hash?(node) ⇒ Object
62
63
64
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 62
def_node_matcher :monuple_hash?, <<~PATTERN
(send (array _) :hash)
PATTERN
|
#on_send(node) ⇒ Object
Also known as:
on_op_asgn
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 86
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
80
81
82
83
84
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 80
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
67
68
69
70
71
72
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 67
def_node_matcher :redundant_hash?, <<~PATTERN
(
^^(send array ... :hash)
_ :hash
)
PATTERN
|
#static_hash_method_definition?(node) ⇒ Object
50
51
52
53
54
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 50
def_node_matcher :static_hash_method_definition?, <<~PATTERN
({def | defs _} :hash
(args)
_)
PATTERN
|