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.'
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
#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
58
59
60
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 58
def_node_matcher :bad_hash_combinator?, <<~PATTERN
({send | op-asgn} _ {:^ | :+ | :* | :|} _)
PATTERN
|
#contained_in_hash_method?(node, &block) ⇒ Boolean
75
76
77
78
79
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 75
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
42
43
44
45
46
47
48
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 42
def_node_matcher :dynamic_hash_method_definition?, <<~PATTERN
(block
(send _ {:define_method | :define_singleton_method}
(sym :hash))
(args)
_)
PATTERN
|
#hash_method_definition?(node) ⇒ Object
37
38
39
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 37
def_node_matcher :hash_method_definition?, <<~PATTERN
{#static_hash_method_definition? | #dynamic_hash_method_definition?}
PATTERN
|
#monuple_hash?(node) ⇒ Object
63
64
65
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 63
def_node_matcher :monuple_hash?, <<~PATTERN
(send (array _) :hash)
PATTERN
|
#on_send(node) ⇒ Object
Also known as:
on_op_asgn
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 87
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
81
82
83
84
85
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 81
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
68
69
70
71
72
73
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 68
def_node_matcher :redundant_hash?, <<~PATTERN
(
^^(send array ... :hash)
_ :hash
)
PATTERN
|
#static_hash_method_definition?(node) ⇒ Object
51
52
53
54
55
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 51
def_node_matcher :static_hash_method_definition?, <<~PATTERN
({def | defs _} :hash
(args)
_)
PATTERN
|