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_gem_version, #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
permalink
#bad_hash_combinator?(node) ⇒ Object
[View source]
59
60
61
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 59
def_node_matcher :bad_hash_combinator?, <<~PATTERN
({send | op-asgn} _ {:^ | :+ | :* | :|} _)
PATTERN
|
permalink
#contained_in_hash_method?(node, &block) ⇒ Boolean
[View source]
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
|
permalink
#dynamic_hash_method_definition?(node) ⇒ Object
[View source]
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
|
permalink
#hash_method_definition?(node) ⇒ Object
[View source]
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
|
permalink
#monuple_hash?(node) ⇒ Object
[View source]
64
65
66
|
# File 'lib/rubocop/cop/security/compound_hash.rb', line 64
def_node_matcher :monuple_hash?, <<~PATTERN
(send (array _) :hash)
PATTERN
|
permalink
#on_send(node) ⇒ Object
Also known as:
on_csend, on_op_asgn
[View source]
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
|
permalink
#outer_bad_hash_combinator?(node) ⇒ Boolean
[View source]
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
|
permalink
#redundant_hash?(node) ⇒ Object
[View source]
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
|
permalink
#static_hash_method_definition?(node) ⇒ Object
[View source]
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
|