nasl-pedant 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|