Skip to content

Commit 19ee909

Browse files
koicbbatsov
authored andcommitted
[Fix #13556] Fix false positives for Style/FileNull
Fixes #13556. This PR fixes false positives for `Style/FileNull` when using `'nul'` string. This PR ensures only files that use the string `'/dev/null'` are targeted for detection. This is because the string `'nul'` is not limited to the null device. This behavior results in false negatives when the `'/dev/null'` string is not used, but it is a trade-off to avoid false positives.
1 parent fd13dab commit 19ee909

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#13556](https://github.com/rubocop/rubocop/issues/13556): Fix false positives for `Style/FileNull` when using `'nul'` string. ([@koic][])

lib/rubocop/cop/style/file_null.rb

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ module Style
88
# Only looks for full string matches, substrings within a longer string are not
99
# considered.
1010
#
11+
# However, only files that use the string `'/dev/null'` are targeted for detection.
12+
# This is because the string `'NUL'` is not limited to the null device.
13+
# This behavior results in false negatives when the `'/dev/null'` string is not used,
14+
# but it is a trade-off to avoid false positives. `NULL:`
15+
# Unlike `'NUL'`, `'NUL:'` is regarded as something like `C:` and is always detected.
16+
#
1117
# NOTE: Uses inside arrays and hashes are ignored.
1218
#
1319
# @safety
@@ -42,11 +48,21 @@ class FileNull < Base
4248
REGEXP = %r{\A(/dev/null|NUL:?)\z}i.freeze
4349
MSG = 'Use `File::NULL` instead of `%<source>s`.'
4450

51+
def on_new_investigation
52+
return unless (ast = processed_source.ast)
53+
54+
@contain_dev_null_string_in_file = ast.each_descendant(:str).any? do |str|
55+
content = str.str_content
56+
57+
valid_string?(content) && content.downcase == '/dev/null' # rubocop:disable Style/FileNull
58+
end
59+
end
60+
4561
def on_str(node)
4662
value = node.value
47-
48-
return if invalid_string?(value)
63+
return unless valid_string?(value)
4964
return if acceptable?(node)
65+
return if value.downcase == 'nul' && !@contain_dev_null_string_in_file # rubocop:disable Style/FileNull
5066
return unless REGEXP.match?(value)
5167

5268
add_offense(node, message: format(MSG, source: value)) do |corrector|
@@ -56,8 +72,8 @@ def on_str(node)
5672

5773
private
5874

59-
def invalid_string?(value)
60-
value.empty? || !value.valid_encoding?
75+
def valid_string?(value)
76+
!value.empty? && value.valid_encoding?
6177
end
6278

6379
def acceptable?(node)

spec/rubocop/cop/style/file_null_spec.rb

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,40 @@
2424
RUBY
2525
end
2626

27-
it 'registers an offense and corrects when the entire string is `NUL`' do
27+
it "registers an offense and corrects when the entire string is `NUL` or '/dev/null'" do
2828
expect_offense(<<~RUBY)
29+
CONST = '/dev/null'
30+
^^^^^^^^^^^ Use `File::NULL` instead of `/dev/null`.
2931
path = 'NUL'
3032
^^^^^ Use `File::NULL` instead of `NUL`.
3133
RUBY
3234

3335
expect_correction(<<~RUBY)
36+
CONST = File::NULL
3437
path = File::NULL
3538
RUBY
3639
end
3740

38-
it 'registers an offense and corrects when the entire string is `NUL:`' do
41+
it "does not register an offense when the entire string is `NUL` without '/dev/null'" do
42+
expect_no_offenses(<<~RUBY)
43+
path = 'NUL'
44+
RUBY
45+
end
46+
47+
it "registers an offense and corrects when the entire string is `NUL:` or '/dev/null'" do
48+
expect_offense(<<~RUBY)
49+
path = cond ? '/dev/null' : 'NUL:'
50+
^^^^^^^^^^^ Use `File::NULL` instead of `/dev/null`.
51+
^^^^^^ Use `File::NULL` instead of `NUL:`.
52+
RUBY
53+
54+
# Different cops will detect duplication of the branch bodies.
55+
expect_correction(<<~RUBY)
56+
path = cond ? File::NULL : File::NULL
57+
RUBY
58+
end
59+
60+
it "registers an offense when the entire string is `NUL:` without '/dev/null'" do
3961
expect_offense(<<~RUBY)
4062
path = 'NUL:'
4163
^^^^^^ Use `File::NULL` instead of `NUL:`.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy