forked from rubocop/rubocop
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Fix rubocop#5973] Add Style/IpAddresses cop
- Loading branch information
Showing
9 changed files
with
215 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'resolv' | ||
|
||
module RuboCop | ||
module Cop | ||
module Style | ||
# This cop checks for hardcoded IP addresses, which can make code | ||
# brittle. IP addresses are likely to need to be changed when code | ||
# is deployed to a different server or environment, which may break | ||
# a deployment if forgotten. Prefer setting IP addresses in ENV or | ||
# other configuration. | ||
# | ||
# @example | ||
# | ||
# # bad | ||
# ip_address = '127.59.241.29' | ||
# | ||
# # good | ||
# ip_address = ENV['DEPLOYMENT_IP_ADDRESS'] | ||
class IpAddresses < Cop | ||
include StringHelp | ||
|
||
IPV6_MAX_SIZE = 45 # IPv4-mapped IPv6 is the longest | ||
MSG = 'Do not hardcode IP addresses.'.freeze | ||
|
||
def offense?(node) | ||
contents = node.source[1...-1] | ||
|
||
return false if whitelist.include?(contents.downcase) | ||
|
||
# To try to avoid doing two regex checks on every string, | ||
# shortcut out if the string does not look like an IP address | ||
return false unless could_be_ip?(contents) | ||
|
||
contents =~ ::Resolv::IPv4::Regex || contents =~ ::Resolv::IPv6::Regex | ||
end | ||
|
||
# Dummy implementation of method in ConfigurableEnforcedStyle that is | ||
# called from StringHelp. | ||
def opposite_style_detected; end | ||
|
||
# Dummy implementation of method in ConfigurableEnforcedStyle that is | ||
# called from StringHelp. | ||
def correct_style_detected; end | ||
|
||
private | ||
|
||
def whitelist | ||
whitelist = cop_config['Whitelist'] | ||
Array(whitelist).map(&:downcase) | ||
end | ||
|
||
def could_be_ip?(str) | ||
# If the string is too long, it can't be an IP | ||
return false if too_long?(str) | ||
|
||
# If the string doesn't start with a colon or hexadecimal char, | ||
# we know it's not an IP address | ||
starts_with_hex_or_colon?(str) | ||
end | ||
|
||
def too_long?(str) | ||
str.size > IPV6_MAX_SIZE | ||
end | ||
|
||
def starts_with_hex_or_colon?(str) | ||
first_char = str[0].ord | ||
(48..58).cover?(first_char) || (65..70).cover?(first_char) || | ||
(97..102).cover?(first_char) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
# frozen_string_literal: true | ||
|
||
RSpec.describe RuboCop::Cop::Style::IpAddresses, :config do | ||
subject(:cop) { described_class.new(config) } | ||
|
||
let(:cop_config) { {} } | ||
|
||
context 'IPv4' do | ||
it 'registers an offense for a valid address' do | ||
expect_offense(<<-RUBY.strip_indent) | ||
'255.255.255.255' | ||
^^^^^^^^^^^^^^^^^ Do not hardcode IP addresses. | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense for an invalid address' do | ||
expect_no_offenses('"578.194.591.059"') | ||
end | ||
|
||
it 'does not register an offense for an address inside larger text' do | ||
expect_no_offenses('"My IP is 192.168.1.1"') | ||
end | ||
end | ||
|
||
context 'IPv6' do | ||
it 'registers an offense for a valid address' do | ||
expect_offense(<<-RUBY.strip_indent) | ||
'2001:0db8:85a3:0000:0000:8a2e:0370:7334' | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not hardcode IP addresses. | ||
RUBY | ||
end | ||
|
||
it 'registers an offense for an address with 0s collapsed' do | ||
expect_offense(<<-RUBY.strip_indent) | ||
'2001:db8:85a3::8a2e:370:7334' | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not hardcode IP addresses. | ||
RUBY | ||
end | ||
|
||
it 'registers an offense for a shortened address' do | ||
expect_offense(<<-RUBY.strip_indent) | ||
'2001:db8::1' | ||
^^^^^^^^^^^^^ Do not hardcode IP addresses. | ||
RUBY | ||
end | ||
|
||
it 'registers an offense for a very short address' do | ||
expect_offense(<<-RUBY.strip_indent) | ||
'1::' | ||
^^^^^ Do not hardcode IP addresses. | ||
RUBY | ||
end | ||
|
||
it 'registers an offense for the loopback address' do | ||
expect_offense(<<-RUBY.strip_indent) | ||
'::1' | ||
^^^^^ Do not hardcode IP addresses. | ||
RUBY | ||
end | ||
|
||
it 'does not register an offense for an invalid address' do | ||
expect_no_offenses('"2001:db8::1xyz"') | ||
end | ||
|
||
context 'the unspecified address :: (shortform of 0:0:0:0:0:0:0:0)' do | ||
it 'does not register an offense' do | ||
expect_no_offenses('"::"') | ||
end | ||
|
||
context 'when it is removed from the whitelist' do | ||
let(:cop_config) { { 'Whitelist' => [] } } | ||
|
||
it 'registers an offense' do | ||
expect_offense(<<-RUBY.strip_indent) | ||
'::' | ||
^^^^ Do not hardcode IP addresses. | ||
RUBY | ||
end | ||
end | ||
end | ||
end | ||
|
||
context 'with whitelist' do | ||
let(:cop_config) { { 'Whitelist' => ['a::b'] } } | ||
|
||
it 'does not register an offense for a whitelisted address' do | ||
expect_no_offenses('"a::b"') | ||
end | ||
|
||
it 'does not register an offense if the case differs' do | ||
expect_no_offenses('"A::B"') | ||
end | ||
end | ||
end |