nasl-pedant 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/pedant/checks/conditional_contains_assignment.rb +82 -0
- data/lib/pedant/checks/conditional_or_loop_is_empty.rb +2 -0
- data/lib/pedant/checks/confusing_variable_names.rb +104 -0
- data/lib/pedant/checks/contains_unreachable_code.rb +14 -6
- data/lib/pedant/checks/flipped_operands_on_match_or_substring.rb +80 -0
- data/lib/pedant/version.rb +1 -1
- data/test/unit/checks/test_conditional_contains_assignment.rb +93 -0
- data/test/unit/checks/test_confusing_variable_names.rb +113 -0
- data/test/unit/checks/test_flipped_operands_on_match_or_substring.rb +77 -0
- metadata +17 -3
@@ -0,0 +1,82 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2014, Tenable Network Security
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
# list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
16
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
17
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
19
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
21
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
22
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
23
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
24
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
################################################################################
|
26
|
+
|
27
|
+
module Pedant
|
28
|
+
class CheckConditionalContainsAssignment < Check
|
29
|
+
def self.requires
|
30
|
+
super + [:trees]
|
31
|
+
end
|
32
|
+
|
33
|
+
def check(file, tree)
|
34
|
+
def walk(node, root)
|
35
|
+
# Assignments of literals are the most likely to be bugs (determined empiracally).
|
36
|
+
literals = [
|
37
|
+
Nasl::String,
|
38
|
+
Nasl::Integer,
|
39
|
+
Nasl::Identifier,
|
40
|
+
Nasl::Ip,
|
41
|
+
]
|
42
|
+
|
43
|
+
# Recursively descend into the right-hand and left-hand sides of each expression.
|
44
|
+
if node.is_a? Nasl::Expression
|
45
|
+
[:lhs, :rhs].each { |side| walk(node.send(side), root) }
|
46
|
+
end
|
47
|
+
|
48
|
+
if node.is_a?(Nasl::Assignment)
|
49
|
+
# A bit of a kludge, here. Because assignment has such a low precedence, we can see two
|
50
|
+
# different scenarios: the simpler scenario, where the Assignment's expr is the literal
|
51
|
+
# being assigned. Example:
|
52
|
+
# if (a = 5) { ... } -> node.expr == <Nasl::Integer>:5
|
53
|
+
#
|
54
|
+
# In the other scenario, the literal being assigned gets "absorbed" into an Expression
|
55
|
+
# with the higher-precedence operators. Example:
|
56
|
+
# if (a = 5 && foo == bar) { ... } -> node.expr == <Nasl::Expression>
|
57
|
+
# node.expr.lhs == <Nasl::Integer>:5
|
58
|
+
#
|
59
|
+
# In this second case, we can look for the literal in the Expression's left-hand side.
|
60
|
+
if literals.include?(node.expr.class) or
|
61
|
+
node.expr.is_a?(Nasl::Expression) && literals.include?(node.expr.lhs.class)
|
62
|
+
|
63
|
+
fail
|
64
|
+
report(:error, "A conditional statement contains an assignment operation.")
|
65
|
+
report(:error, node.op.context(root))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
cond_stmts = [:For, :Repeat, :While, :If].map { |cls| tree.all(cls) }.flatten
|
71
|
+
cond_stmts.each { |cond_stmt| walk(cond_stmt.cond, cond_stmt) }
|
72
|
+
end
|
73
|
+
|
74
|
+
def run
|
75
|
+
# This check will pass by default.
|
76
|
+
pass
|
77
|
+
|
78
|
+
# Run this check on the tree from every file.
|
79
|
+
@kb[:trees].each { |file, tree| check(file, tree) }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -39,6 +39,7 @@ module Pedant
|
|
39
39
|
fail
|
40
40
|
|
41
41
|
report(:error, "#{cls} loop in #{file} has an empty statement as its body.")
|
42
|
+
report(:error, node.body.context(node))
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
@@ -55,6 +56,7 @@ module Pedant
|
|
55
56
|
fail
|
56
57
|
|
57
58
|
report(:error, "If statement in #{file} has an empty statement as #{name} branch.")
|
59
|
+
report(:error, branch.context(node))
|
58
60
|
end
|
59
61
|
end
|
60
62
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2014, Tenable Network Security
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
# list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
16
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
17
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
19
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
21
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
22
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
23
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
24
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
################################################################################
|
26
|
+
|
27
|
+
require 'set'
|
28
|
+
|
29
|
+
module Pedant
|
30
|
+
class CheckConfusingVariableNames < Check
|
31
|
+
def self.requires
|
32
|
+
super + [:trees]
|
33
|
+
end
|
34
|
+
|
35
|
+
def check(file, tree)
|
36
|
+
# Two identifiers with the same normalization are likely to be confused.
|
37
|
+
# E.g.: CA_list and ca_list, certlist and cert_list
|
38
|
+
def normalize name
|
39
|
+
name.gsub(/_/, '').downcase
|
40
|
+
end
|
41
|
+
|
42
|
+
# Set of all declared and assigned-to names in the source.
|
43
|
+
names = Set.new
|
44
|
+
|
45
|
+
# Handle all local_var and global_var occurrences (both assignments and declarations).
|
46
|
+
(tree.all(:Global) + tree.all(:Local)).each do |decl|
|
47
|
+
decl.idents.each do |node|
|
48
|
+
names << node.name if node.is_a? Nasl::Identifier
|
49
|
+
names << node.lval.name if node.is_a? Nasl::Assignment
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Add every identifier from every assigned-to Nasl::Lvalue to the set of names.
|
54
|
+
tree.all(:Assignment).map(&:lval).each do |lval|
|
55
|
+
# Generate a nested array of Nasl::Identifier, representing the tree structure
|
56
|
+
# of a Nasl::Lvalue.
|
57
|
+
def lval_to_arr(lval)
|
58
|
+
return lval if not lval.is_a?(Nasl::Lvalue)
|
59
|
+
return [lval.ident, lval.indexes.map { |lval| lval_to_arr(lval)} ]
|
60
|
+
end
|
61
|
+
|
62
|
+
if lval.is_a?(Nasl::Lvalue)
|
63
|
+
lval_to_arr(lval).flatten.each do |node|
|
64
|
+
names << node.name if node.is_a?(Nasl::Identifier)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
if lval.is_a?(Nasl::Identifier)
|
69
|
+
names << lval.name
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Group names together that have the same normalized form.
|
74
|
+
confusable_name_groups = {}
|
75
|
+
names.each do |name|
|
76
|
+
key = normalize(name)
|
77
|
+
confusable_name_groups[key] ||= Set.new
|
78
|
+
confusable_name_groups[key] << name
|
79
|
+
end
|
80
|
+
|
81
|
+
# Throw away the normalized forms, all we care about now is the groups.
|
82
|
+
confusable_name_groups = confusable_name_groups.values
|
83
|
+
|
84
|
+
# We only care about groups with more than one name in them.
|
85
|
+
confusable_name_groups.map!(&:to_a).select! { |group| group.length > 1 }
|
86
|
+
|
87
|
+
return if confusable_name_groups.length == 0
|
88
|
+
|
89
|
+
warn
|
90
|
+
report(:error, "These sets of names differ only by capitalization or underscores:")
|
91
|
+
confusable_name_groups.each do |names|
|
92
|
+
report(:error, " #{names.join(', ')}")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def run
|
97
|
+
# This check will pass by default.
|
98
|
+
pass
|
99
|
+
|
100
|
+
# Run this check on the tree from every file.
|
101
|
+
@kb[:trees].each { |file, tree| check(file, tree) }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -39,22 +39,30 @@ module Pedant
|
|
39
39
|
if node.is_a?(Nasl::Break) || node.is_a?(Nasl::Continue) || node.is_a?(Nasl::Return) || (node.is_a?(Nasl::Call) && node.name.ident.name == 'exit' && node.name.indexes == [])
|
40
40
|
# If this is not the final node in the list, then there is
|
41
41
|
# absolutely no way for the later nodes to be accessed.
|
42
|
-
if node != list.last
|
43
|
-
report(:error, "#{file} contains unreachable code.")
|
44
|
-
return fail
|
45
|
-
end
|
42
|
+
return node if node != list.last
|
46
43
|
end
|
47
44
|
end
|
45
|
+
return nil
|
48
46
|
end
|
49
47
|
|
50
48
|
# Unreachable statements occur only when there are sequential lists of
|
51
49
|
# instructions. In layers deeper than the outermost level of indentation,
|
52
50
|
# this only occurs in Blocks.
|
53
|
-
tree.all(:Block).each
|
51
|
+
tree.all(:Block).each do |blk|
|
52
|
+
node = check_statements(file, blk.body)
|
53
|
+
if not node.nil?
|
54
|
+
fail
|
55
|
+
report(:error, node.context(blk))
|
56
|
+
end
|
57
|
+
end
|
54
58
|
|
55
59
|
# The main body of a file is not a Block, so it must be considered
|
56
60
|
# separately.
|
57
|
-
check_statements(file, tree)
|
61
|
+
node = check_statements(file, tree)
|
62
|
+
if not node.nil?
|
63
|
+
fail
|
64
|
+
report(:error, node.context(node))
|
65
|
+
end
|
58
66
|
end
|
59
67
|
|
60
68
|
def run
|
@@ -0,0 +1,80 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2015, Tenable Network Security
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
# list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
16
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
17
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
19
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
21
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
22
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
23
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
24
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
################################################################################
|
26
|
+
|
27
|
+
module Pedant
|
28
|
+
class CheckFlippedOperandsOnMatchOrSubstring < Check
|
29
|
+
def self.requires
|
30
|
+
super + [:trees]
|
31
|
+
end
|
32
|
+
|
33
|
+
def check(file, tree)
|
34
|
+
def walk(node, root)
|
35
|
+
# Recursively descend into the right-hand and left-hand sides of each expression.
|
36
|
+
if node.is_a? Nasl::Expression
|
37
|
+
[:lhs, :rhs].each { |side| walk(node.send(side), root) }
|
38
|
+
|
39
|
+
return unless node.op.is_a?(Nasl::Token)
|
40
|
+
|
41
|
+
if ["=~", "!~"].include?(node.op.body)
|
42
|
+
side = :lhs
|
43
|
+
opposite = :rhs
|
44
|
+
end
|
45
|
+
|
46
|
+
if ["><", ">!<"].include?(node.op.body)
|
47
|
+
side = :rhs
|
48
|
+
opposite = :lhs
|
49
|
+
end
|
50
|
+
|
51
|
+
return if side.nil?
|
52
|
+
|
53
|
+
# The check for no indexes is to account for this uncommon-but-in-use
|
54
|
+
# pattern, to check that a character falls into a certain subset of
|
55
|
+
# acceptable characters:
|
56
|
+
#
|
57
|
+
# tolower(xml[index]) >< "abcdefghijklmnopqrstuvwxyz:_"
|
58
|
+
#
|
59
|
+
if node.send(side).is_a?(Nasl::String) && node.send(opposite).is_a?(Nasl::Lvalue) && node.send(opposite).indexes == []
|
60
|
+
warn
|
61
|
+
report(:error, "A '#{node.op.body}' operator has a literal string on the #{if side == :lhs then 'left' else 'right' end}-hand side.")
|
62
|
+
report(:error, "The operands may be accidentally swapped.")
|
63
|
+
report(:error, node.send(side).context(node))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
cond_stmts = [:For, :Repeat, :While, :If].map { |cls| tree.all(cls) }.flatten
|
69
|
+
cond_stmts.each { |cond_stmt| walk(cond_stmt.cond, cond_stmt) }
|
70
|
+
end
|
71
|
+
|
72
|
+
def run
|
73
|
+
# This check will pass by default.
|
74
|
+
pass
|
75
|
+
|
76
|
+
# Run this check on the tree from every file.
|
77
|
+
@kb[:trees].each { |file, tree| check(file, tree) }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/pedant/version.rb
CHANGED
@@ -0,0 +1,93 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2014, Tenable Network Security
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
# list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
16
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
17
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
19
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
21
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
22
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
23
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
24
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
################################################################################
|
26
|
+
|
27
|
+
class TestConditionalContainsAssignment < Test::Unit::TestCase
|
28
|
+
include Pedant::Test
|
29
|
+
|
30
|
+
def test_none
|
31
|
+
check(
|
32
|
+
:pass,
|
33
|
+
:CheckConditionalContainsAssignment,
|
34
|
+
%q||
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_literal_integer
|
39
|
+
check(
|
40
|
+
:fail,
|
41
|
+
:CheckConditionalContainsAssignment,
|
42
|
+
%q|if (a = 5) { exit(); }|
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_literal_integer_while
|
47
|
+
check(
|
48
|
+
:fail,
|
49
|
+
:CheckConditionalContainsAssignment,
|
50
|
+
%q|while (a = 5) { exit(); }|
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_literal_string
|
55
|
+
check(
|
56
|
+
:fail,
|
57
|
+
:CheckConditionalContainsAssignment,
|
58
|
+
%q|if (a = "foo") { exit(); }|
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_complex_literal_rhs
|
63
|
+
check(
|
64
|
+
:fail,
|
65
|
+
:CheckConditionalContainsAssignment,
|
66
|
+
%q|if (((foobar > 2 && (a = 1 && b < 2)) && foo.bar == bar.foo) && baz == 2) { exit(); }|
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_complex_literal_lhs
|
71
|
+
check(
|
72
|
+
:fail,
|
73
|
+
:CheckConditionalContainsAssignment,
|
74
|
+
%q|if (((foobar > 2 && (c == 2 && a = 1 && b < 2)) && foo.bar == bar.foo) && baz == 2) { exit(); }|
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_complex_non_literal
|
79
|
+
check(
|
80
|
+
:pass,
|
81
|
+
:CheckConditionalContainsAssignment,
|
82
|
+
%q|if (((foobar > 2 && (a = one && b < 2)) && foo.bar == bar.foo) && baz == 2) { exit(); }|
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_non_literal
|
87
|
+
check(
|
88
|
+
:pass,
|
89
|
+
:CheckConditionalContainsAssignment,
|
90
|
+
%q|if ((a = get_oracle_homes()) == "somestring") { exit(); }|
|
91
|
+
)
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2014, Tenable Network Security
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
# list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
16
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
17
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
19
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
21
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
22
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
23
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
24
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
################################################################################
|
26
|
+
|
27
|
+
class TestConfusingVariableNames < Test::Unit::TestCase
|
28
|
+
include Pedant::Test
|
29
|
+
|
30
|
+
def test_does
|
31
|
+
check(
|
32
|
+
:pass,
|
33
|
+
:CheckConfusingVariableNames,
|
34
|
+
%q||
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_does_not
|
39
|
+
check(
|
40
|
+
:warn,
|
41
|
+
:CheckConfusingVariableNames,
|
42
|
+
%q|local_var CA_list; calist = 1;|
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_var_types
|
47
|
+
check(
|
48
|
+
:warn,
|
49
|
+
:CheckConfusingVariableNames,
|
50
|
+
%q|local_var ca_list; CA_list = 1;|
|
51
|
+
)
|
52
|
+
|
53
|
+
check(
|
54
|
+
:warn,
|
55
|
+
:CheckConfusingVariableNames,
|
56
|
+
%q|global_var ca_list; CA_list = 1;|
|
57
|
+
)
|
58
|
+
|
59
|
+
check(
|
60
|
+
:warn,
|
61
|
+
:CheckConfusingVariableNames,
|
62
|
+
%q|global_var ca_list; function foo() { local_var CA_list; }|
|
63
|
+
)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_underscores
|
67
|
+
check(
|
68
|
+
:warn,
|
69
|
+
:CheckConfusingVariableNames,
|
70
|
+
%q|global_var ca_list; calist = 1;|
|
71
|
+
)
|
72
|
+
|
73
|
+
check(
|
74
|
+
:warn,
|
75
|
+
:CheckConfusingVariableNames,
|
76
|
+
%q|global_var ca__list; calist = 1;|
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_capitalization
|
81
|
+
check(
|
82
|
+
:warn,
|
83
|
+
:CheckConfusingVariableNames,
|
84
|
+
%q|global_var calist; CAlist = 1;|
|
85
|
+
)
|
86
|
+
|
87
|
+
check(
|
88
|
+
:warn,
|
89
|
+
:CheckConfusingVariableNames,
|
90
|
+
%q|global_var CA_list; ca_list = 1;|
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_lvalue_idents
|
95
|
+
check(
|
96
|
+
:warn,
|
97
|
+
:CheckConfusingVariableNames,
|
98
|
+
%q|ca_list.CA_list = 1;|
|
99
|
+
)
|
100
|
+
|
101
|
+
check(
|
102
|
+
:warn,
|
103
|
+
:CheckConfusingVariableNames,
|
104
|
+
%q|ca_list[foo.bar[CA_list]] = 1;|
|
105
|
+
)
|
106
|
+
|
107
|
+
check(
|
108
|
+
:warn,
|
109
|
+
:CheckConfusingVariableNames,
|
110
|
+
%q|ca_list[foo.CA_list[10 + "woo"]] = 1;|
|
111
|
+
)
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2015, Tenable Network Security
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# 1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
# list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
16
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
17
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
19
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
20
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
21
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
22
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
23
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
24
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
25
|
+
################################################################################
|
26
|
+
|
27
|
+
class TestFlippedOperandsOnMatchOrSubstring < Test::Unit::TestCase
|
28
|
+
include Pedant::Test
|
29
|
+
|
30
|
+
def test_none
|
31
|
+
check(
|
32
|
+
:pass,
|
33
|
+
:CheckFlippedOperandsOnMatchOrSubstring,
|
34
|
+
%q||
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_no_op
|
39
|
+
check(
|
40
|
+
:pass,
|
41
|
+
:CheckFlippedOperandsOnMatchOrSubstring,
|
42
|
+
%q|if (a == b) exit(0);|
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_simple_substring
|
47
|
+
check(
|
48
|
+
:warn,
|
49
|
+
:CheckFlippedOperandsOnMatchOrSubstring,
|
50
|
+
%q|if (a >< 'woo') exit(0);|
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_simple_substring_indexed
|
55
|
+
check(
|
56
|
+
:pass,
|
57
|
+
:CheckFlippedOperandsOnMatchOrSubstring,
|
58
|
+
%q|if (a[i] >< 'woo') exit(0);|
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_simple_match
|
63
|
+
check(
|
64
|
+
:warn,
|
65
|
+
:CheckFlippedOperandsOnMatchOrSubstring,
|
66
|
+
%q|if ('woo' =~ a) exit(0);|
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_complex_match
|
71
|
+
check(
|
72
|
+
:warn,
|
73
|
+
:CheckFlippedOperandsOnMatchOrSubstring,
|
74
|
+
%q|if ('woo' >< a && 'woo' =~ a) exit(0);|
|
75
|
+
)
|
76
|
+
end
|
77
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nasl-pedant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2015-03-02 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rake
|
@@ -83,7 +83,9 @@ files:
|
|
83
83
|
- bin/pedant
|
84
84
|
- lib/pedant.rb
|
85
85
|
- lib/pedant/check.rb
|
86
|
+
- lib/pedant/checks/conditional_contains_assignment.rb
|
86
87
|
- lib/pedant/checks/conditional_or_loop_is_empty.rb
|
88
|
+
- lib/pedant/checks/confusing_variable_names.rb
|
87
89
|
- lib/pedant/checks/contains_ip_address_literals.rb
|
88
90
|
- lib/pedant/checks/contains_no_carriage_returns.rb
|
89
91
|
- lib/pedant/checks/contains_no_tabs.rb
|
@@ -91,6 +93,7 @@ files:
|
|
91
93
|
- lib/pedant/checks/contains_unreachable_code.rb
|
92
94
|
- lib/pedant/checks/ends_with_newline.rb
|
93
95
|
- lib/pedant/checks/files_parse_without_errors.rb
|
96
|
+
- lib/pedant/checks/flipped_operands_on_match_or_substring.rb
|
94
97
|
- lib/pedant/checks/local_variable_unused.rb
|
95
98
|
- lib/pedant/checks/parse_test_code.rb
|
96
99
|
- lib/pedant/checks/plugin_type_not_specified.rb
|
@@ -108,13 +111,16 @@ files:
|
|
108
111
|
- lib/pedant/version.rb
|
109
112
|
- pedant.gemspec
|
110
113
|
- test/test_helper.rb
|
114
|
+
- test/unit/checks/test_conditional_contains_assignment.rb
|
111
115
|
- test/unit/checks/test_conditional_or_loop_is_empty.rb
|
116
|
+
- test/unit/checks/test_confusing_variable_names.rb
|
112
117
|
- test/unit/checks/test_contains_ip_address_literals.rb
|
113
118
|
- test/unit/checks/test_contains_no_carriage_returns.rb
|
114
119
|
- test/unit/checks/test_contains_no_tabs.rb
|
115
120
|
- test/unit/checks/test_contains_registration_section.rb
|
116
121
|
- test/unit/checks/test_contains_unreachable_code.rb
|
117
122
|
- test/unit/checks/test_ends_with_newline.rb
|
123
|
+
- test/unit/checks/test_flipped_operands_on_match_or_substring.rb
|
118
124
|
- test/unit/checks/test_plugin_type_not_specified.rb
|
119
125
|
- test/unit/checks/test_script_family_not_specified.rb
|
120
126
|
homepage: http://github.com/tenable/pedant
|
@@ -130,12 +136,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
130
136
|
- - ! '>='
|
131
137
|
- !ruby/object:Gem::Version
|
132
138
|
version: '0'
|
139
|
+
segments:
|
140
|
+
- 0
|
141
|
+
hash: 333689523
|
133
142
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
143
|
none: false
|
135
144
|
requirements:
|
136
145
|
- - ! '>='
|
137
146
|
- !ruby/object:Gem::Version
|
138
147
|
version: '0'
|
148
|
+
segments:
|
149
|
+
- 0
|
150
|
+
hash: 333689523
|
139
151
|
requirements: []
|
140
152
|
rubyforge_project: nasl-pedant
|
141
153
|
rubygems_version: 1.8.23
|
@@ -144,13 +156,15 @@ specification_version: 3
|
|
144
156
|
summary: A framework for the Nessus Attack Scripting Language.
|
145
157
|
test_files:
|
146
158
|
- test/test_helper.rb
|
159
|
+
- test/unit/checks/test_conditional_contains_assignment.rb
|
147
160
|
- test/unit/checks/test_conditional_or_loop_is_empty.rb
|
161
|
+
- test/unit/checks/test_confusing_variable_names.rb
|
148
162
|
- test/unit/checks/test_contains_ip_address_literals.rb
|
149
163
|
- test/unit/checks/test_contains_no_carriage_returns.rb
|
150
164
|
- test/unit/checks/test_contains_no_tabs.rb
|
151
165
|
- test/unit/checks/test_contains_registration_section.rb
|
152
166
|
- test/unit/checks/test_contains_unreachable_code.rb
|
153
167
|
- test/unit/checks/test_ends_with_newline.rb
|
168
|
+
- test/unit/checks/test_flipped_operands_on_match_or_substring.rb
|
154
169
|
- test/unit/checks/test_plugin_type_not_specified.rb
|
155
170
|
- test/unit/checks/test_script_family_not_specified.rb
|
156
|
-
has_rdoc:
|