Showing 1,430 of 1,430 total issues
Prefer using YAML.safe_load
over YAML.load
. Open
input = YAML.load(fd)
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for the use of YAML class methods which have potential security issues leading to remote code execution when loading from an untrusted source.
NOTE: Ruby 3.1+ (Psych 4) uses Psych.load
as Psych.safe_load
by default.
Safety:
The behavior of the code might change depending on what was
in the YAML payload, since YAML.safe_load
is more restrictive.
Example:
# bad
YAML.load("--- !ruby/object:Foo {}") # Psych 3 is unsafe by default
# good
YAML.safe_load("--- !ruby/object:Foo {}", [Foo]) # Ruby 2.5 (Psych 3)
YAML.safe_load("--- !ruby/object:Foo {}", permitted_classes: [Foo]) # Ruby 3.0- (Psych 3)
YAML.load("--- !ruby/object:Foo {}", permitted_classes: [Foo]) # Ruby 3.1+ (Psych 4)
YAML.dump(foo)
Avoid more than 3 levels of block nesting. Open
if key.nil?
_log.warn("No value was found for the key [#{key_name}] in section [#{section}] for record [#{id}]")
next
elsif result_section.key?(key)
_log.warn("A duplicate key value [#{key}] for the key [#{key_name}] was found in section [#{section}] for record [#{id}]")
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for excessive nesting of conditional and looping constructs.
You can configure if blocks are considered using the CountBlocks
option. When set to false
(the default) blocks are not counted
towards the nesting level. Set to true
to count blocks as well.
The maximum level of nesting allowed is configurable.
Use filter_map
instead. Open
tag.split("/").map { |x| x.split("|").second }.compact.join(" -> ")
- Create a ticketCreate a ticket
- Exclude checks
Use match?
instead of match
when MatchData
is not used. Open
rec_model = "Vm" if rec_model.downcase.match("template")
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
In Ruby 2.4, String#match?
, Regexp#match?
and Symbol#match?
have been added. The methods are faster than match
.
Because the methods avoid creating a MatchData
object or saving
backref.
So, when MatchData
is not used, use match?
instead of match
.
Example:
# bad
def foo
if x =~ /re/
do_something
end
end
# bad
def foo
if x.match(/re/)
do_something
end
end
# bad
def foo
if /re/ === x
do_something
end
end
# good
def foo
if x.match?(/re/)
do_something
end
end
# good
def foo
if x =~ /re/
do_something(Regexp.last_match)
end
end
# good
def foo
if x.match(/re/)
do_something($~)
end
end
# good
def foo
if /re/ === x
do_something($~)
end
end
Use filter_map
instead. Open
@values[:src_vm_nics] = vm.hardware && vm.hardware.nics.collect(&:device_name).compact
- Create a ticketCreate a ticket
- Exclude checks
Avoid immutable Array literals in loops. It is better to extract it into a local variable or a constant. Open
if ["y", "c"].include?(group) && !sortby.nil? && save_val != d.data[sortby[0]].to_s
- Create a ticketCreate a ticket
- Exclude checks
Use filter_map
instead. Open
when :date then @table.data.collect { |d| d.data[sb] }.compact.max.try(:+, 1)
- Create a ticketCreate a ticket
- Exclude checks
Avoid immutable Array literals in loops. It is better to extract it into a local variable or a constant. Open
%w[reports compare].flat_map { |dir| Dir.glob(plugin.root.join("content", dir, "**", "*.yaml")).sort }
- Create a ticketCreate a ticket
- Exclude checks
Wrap expressions with varying precedence with parentheses to avoid ambiguity. Open
hdr << "@page{@bottom-right{font-size: 75%;content: '" + _("Page %{page_number} of %{total_pages}") % {:page_number => " ' counter(page) '", :total_pages => " ' counter(pages)}}"}
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Looks for expressions containing multiple binary operators
where precedence is ambiguous due to lack of parentheses. For example,
in 1 + 2 * 3
, the multiplication will happen before the addition, but
lexically it appears that the addition will happen first.
The cop does not consider unary operators (ie. !a
or -b
) or comparison
operators (ie. a =~ b
) because those are not ambiguous.
NOTE: Ranges are handled by Lint/AmbiguousRange
.
Example:
# bad
a + b * c
a || b && c
a ** b + c
# good (different precedence)
a + (b * c)
a || (b && c)
(a ** b) + c
# good (same precedence)
a + b + c
a * b / c % d
Avoid more than 3 levels of block nesting. Open
[set_value, field_values[set_value]] if field_values.key?(set_value)
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for excessive nesting of conditional and looping constructs.
You can configure if blocks are considered using the CountBlocks
option. When set to false
(the default) blocks are not counted
towards the nesting level. Set to true
to count blocks as well.
The maximum level of nesting allowed is configurable.
Use filter_map
instead. Open
datacenters = sources.collect do |h|
rails_logger("host_to_folder for host #{h.name}", 0)
result = find_datacenter_for_ci(h)
rails_logger("host_to_folder for host #{h.name}", 1)
result
- Create a ticketCreate a ticket
- Exclude checks
Do not return
in begin..end
blocks in assignment contexts. Open
return if email.blank?
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for the presence of a return
inside a begin..end
block
in assignment contexts.
In this situation, the return
will result in an exit from the current
method, possibly leading to unexpected behavior.
Example:
# bad
@some_variable ||= begin
return some_value if some_condition_is_met
do_something
end
Example:
# good
@some_variable ||= begin
if some_condition_is_met
some_value
else
do_something
end
end
# good
some_variable = if some_condition_is_met
return if another_condition_is_met
some_value
else
do_something
end
Redundant safe navigation detected. Open
export_attributes['filter'] = MiqExpression.new(export_attributes["filter"].exp) if export_attributes["filter"]&.kind_of?(MiqExpression)
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for redundant safe navigation calls.
instance_of?
, kind_of?
, is_a?
, eql?
, respond_to?
, and equal?
methods
are checked by default. These are customizable with AllowedMethods
option.
The AllowedMethods
option specifies nil-safe methods,
in other words, it is a method that is allowed to skip safe navigation.
Note that the AllowedMethod
option is not an option that specifies methods
for which to suppress (allow) this cop's check.
In the example below, the safe navigation operator (&.
) is unnecessary
because NilClass
has methods like respond_to?
and is_a?
.
Safety:
This cop is unsafe, because autocorrection can change the return type of
the expression. An offending expression that previously could return nil
will be autocorrected to never return nil
.
Example:
# bad
do_something if attrs&.respond_to?(:[])
# good
do_something if attrs.respond_to?(:[])
# bad
while node&.is_a?(BeginNode)
node = node.parent
end
# good
while node.is_a?(BeginNode)
node = node.parent
end
# good - without `&.` this will always return `true`
foo&.respond_to?(:to_a)
Example: AllowedMethods: [nilsafemethod]
# bad
do_something if attrs&.nil_safe_method(:[])
# good
do_something if attrs.nil_safe_method(:[])
do_something if attrs&.not_nil_safe_method(:[])
self
used in void context. Open
self
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for operators, variables, literals, lambda, proc and nonmutating methods used in void context.
Example: CheckForMethodsWithNoSideEffects: false (default)
# bad
def some_method
some_num * 10
do_something
end
def some_method(some_var)
some_var
do_something
end
Example: CheckForMethodsWithNoSideEffects: true
# bad
def some_method(some_array)
some_array.sort
do_something(some_array)
end
# good
def some_method
do_something
some_num * 10
end
def some_method(some_var)
do_something
some_var
end
def some_method(some_array)
some_array.sort!
do_something(some_array)
end
Useless private
access modifier. Open
private
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for redundant access modifiers, including those with no
code, those which are repeated, and leading public
modifiers in a
class or module body. Conditionally-defined methods are considered as
always being defined, and thus access modifiers guarding such methods
are not redundant.
This cop has ContextCreatingMethods
option. The default setting value
is an empty array that means no method is specified.
This setting is an array of methods which, when called, are known to
create its own context in the module's current access context.
It also has MethodCreatingMethods
option. The default setting value
is an empty array that means no method is specified.
This setting is an array of methods which, when called, are known to
create other methods in the module's current access context.
Example:
# bad
class Foo
public # this is redundant (default access is public)
def method
end
end
# bad
class Foo
# The following is redundant (methods defined on the class'
# singleton class are not affected by the private modifier)
private
def self.method3
end
end
# bad
class Foo
protected
define_method(:method2) do
end
protected # this is redundant (repeated from previous modifier)
[1,2,3].each do |i|
define_method("foo#{i}") do
end
end
end
# bad
class Foo
private # this is redundant (no following methods are defined)
end
# good
class Foo
private # this is not redundant (a method is defined)
def method2
end
end
# good
class Foo
# The following is not redundant (conditionally defined methods are
# considered as always defining a method)
private
if condition?
def method
end
end
end
# good
class Foo
protected # this is not redundant (a method is defined)
define_method(:method2) do
end
end
Example: ContextCreatingMethods: concerning
# Lint/UselessAccessModifier:
# ContextCreatingMethods:
# - concerning
# good
require 'active_support/concern'
class Foo
concerning :Bar do
def some_public_method
end
private
def some_private_method
end
end
# this is not redundant because `concerning` created its own context
private
def some_other_private_method
end
end
Example: MethodCreatingMethods: delegate
# Lint/UselessAccessModifier:
# MethodCreatingMethods:
# - delegate
# good
require 'active_support/core_ext/module/delegation'
class Foo
# this is not redundant because `delegate` creates methods
private
delegate :method_a, to: :method_b
end
Duplicate branch body detected. Open
else value # Ignore
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks that there are no repeated bodies
within if/unless
, case-when
, case-in
and rescue
constructs.
With IgnoreLiteralBranches: true
, branches are not registered
as offenses if they return a basic literal value (string, symbol,
integer, float, rational, complex, true
, false
, or nil
), or
return an array, hash, regexp or range that only contains one of
the above basic literal values.
With IgnoreConstantBranches: true
, branches are not registered
as offenses if they return a constant value.
Example:
# bad
if foo
do_foo
do_something_else
elsif bar
do_foo
do_something_else
end
# good
if foo || bar
do_foo
do_something_else
end
# bad
case x
when foo
do_foo
when bar
do_foo
else
do_something_else
end
# good
case x
when foo, bar
do_foo
else
do_something_else
end
# bad
begin
do_something
rescue FooError
handle_error
rescue BarError
handle_error
end
# good
begin
do_something
rescue FooError, BarError
handle_error
end
Example: IgnoreLiteralBranches: true
# good
case size
when "small" then 100
when "medium" then 250
when "large" then 1000
else 250
end
Example: IgnoreConstantBranches: true
# good
case size
when "small" then SMALL_SIZE
when "medium" then MEDIUM_SIZE
when "large" then LARGE_SIZE
else MEDIUM_SIZE
end
Avoid more than 3 levels of block nesting. Open
unless f[:values].blank?
sorted_values = f[:values].sort
selected_key = sorted_values.first.first
end
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for excessive nesting of conditional and looping constructs.
You can configure if blocks are considered using the CountBlocks
option. When set to false
(the default) blocks are not counted
towards the nesting level. Set to true
to count blocks as well.
The maximum level of nesting allowed is configurable.
Avoid rescuing the Exception
class. Perhaps you meant to rescue StandardError
? Open
rescue Exception => err
msg = "Error adjusting schedules: #{err.message}"
_log.error(msg)
_log.log_backtrace(err)
do_exit("#{msg}. Restarting.", 1)
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for rescue
blocks targeting the Exception class.
Example:
# bad
begin
do_something
rescue Exception
handle_exception
end
Example:
# good
begin
do_something
rescue ArgumentError
handle_exception
end
Avoid more than 3 levels of block nesting. Open
if j.tags.any? { |t| t.to_s.starts_with?("miq_schedules_") }
_log.info("Removing user schedule with Tags: #{j.tags.inspect}")
end
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for excessive nesting of conditional and looping constructs.
You can configure if blocks are considered using the CountBlocks
option. When set to false
(the default) blocks are not counted
towards the nesting level. Set to true
to count blocks as well.
The maximum level of nesting allowed is configurable.
Variable roles
used in void context. Open
roles
- Read upRead up
- Create a ticketCreate a ticket
- Exclude checks
Checks for operators, variables, literals, lambda, proc and nonmutating methods used in void context.
Example: CheckForMethodsWithNoSideEffects: false (default)
# bad
def some_method
some_num * 10
do_something
end
def some_method(some_var)
some_var
do_something
end
Example: CheckForMethodsWithNoSideEffects: true
# bad
def some_method(some_array)
some_array.sort
do_something(some_array)
end
# good
def some_method
do_something
some_num * 10
end
def some_method(some_var)
do_something
some_var
end
def some_method(some_array)
some_array.sort!
do_something(some_array)
end