nasl-pedant 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/pedant/checks/contains_no_duplicate_words.rb +81 -0
- data/lib/pedant/checks/contains_no_tabs.rb +27 -1
- data/lib/pedant/checks/files_parse_without_errors.rb +3 -3
- data/lib/pedant/checks/plugin_type_not_specified.rb +13 -2
- data/lib/pedant/version.rb +1 -1
- data/test/unit/checks/test_contains_no_tabs.rb +22 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c89304bdba6963cc2f97f76b1ebd0c3a2711966c
|
4
|
+
data.tar.gz: 93ac35fac25ec9d64bc099dbc0babbdc05e2a074
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7cbaf855866862610c321bc4c4044459744e7fb334c443ac8e760b85ea363da2d6625963b1b8af33d2f958a4e9c441933d93f64719d37e12a1a69e7f309c409c
|
7
|
+
data.tar.gz: 8a1ebefac1023fbd3790075e684bb4044b2c71ca46e8e06f197bdc0e1287cc5d91f029964a45b6a58c3be8e96239bb929a355f489b2175da8ac6ebbde1644f34
|
@@ -0,0 +1,81 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2016, 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 CheckContainsNoDuplicateWords < Check
|
29
|
+
def self.requires
|
30
|
+
# Don't run on local checks, since those are auto-generated and their text
|
31
|
+
# is beyond our direct control.
|
32
|
+
super + [:trees, :plugin_type_remote]
|
33
|
+
end
|
34
|
+
|
35
|
+
def check(file, tree)
|
36
|
+
def check_string(s)
|
37
|
+
# Clone the string so we don't alter the original.
|
38
|
+
text = String.new(s.text)
|
39
|
+
|
40
|
+
# Remove extra whitespace, including newlines.
|
41
|
+
text.gsub!(/\s+/, " ")
|
42
|
+
|
43
|
+
# Other removals may be good here, but they'll need large scale testing
|
44
|
+
# to avoid false alarms.
|
45
|
+
|
46
|
+
# Check for any words that are duplicated.
|
47
|
+
text.match(/\b(\w+)\b \b\1\b/) do |phrase|
|
48
|
+
word = phrase[1]
|
49
|
+
|
50
|
+
# Numbers are tricky to reason about, ignore them.
|
51
|
+
next if word =~ /^\d+$/
|
52
|
+
|
53
|
+
# Next we need to find the original phrase in the original text.
|
54
|
+
# This needs to be able to jump across whitespace and newlines.
|
55
|
+
real_phrase = s.text.match(/#{word}\s+#{word}/m)
|
56
|
+
next if not real_phrase
|
57
|
+
|
58
|
+
# Access the context object for this code.
|
59
|
+
ctx = s.ctx
|
60
|
+
|
61
|
+
# Calculate the region the phrase spans, for the message.
|
62
|
+
loc = s.region.begin + real_phrase.begin(0) .. s.region.begin + real_phrase.end(0) + 1
|
63
|
+
bol = ctx.bol(s.region.begin + real_phrase.begin(0))
|
64
|
+
eol = ctx.eol(s.region.begin + real_phrase.end(0))
|
65
|
+
report(:error, "Phrase with repeated word found: #{ctx.context(loc, bol..eol)}")
|
66
|
+
fail
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
tree.all(:String).each { |s| check_string(s) }
|
71
|
+
end
|
72
|
+
|
73
|
+
def run
|
74
|
+
# This check will pass by default.
|
75
|
+
pass
|
76
|
+
|
77
|
+
# Run this check on the tree of every file.
|
78
|
+
@kb[:trees].each { |file, tree| check(file, tree) }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -40,7 +40,16 @@ module Pedant
|
|
40
40
|
|
41
41
|
return if tab_lines.length == 0
|
42
42
|
|
43
|
-
|
43
|
+
# Make the consecutive sequences friendlier to read
|
44
|
+
ranges = self.class.chunk_while(tab_lines.keys.sort) { |i, j| i + 1 == j }.map do |group|
|
45
|
+
if group.length == 1
|
46
|
+
group.first.to_s
|
47
|
+
else
|
48
|
+
"#{group.first.to_s}-#{group.last.to_s}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
report(:warn, "Tabs were found in #{file}, on these lines: #{ranges.join(', ')}")
|
44
53
|
report(:warn, "Showing up to five lines:")
|
45
54
|
tab_lines.keys.sort.first(5).each do |linenum|
|
46
55
|
report(:warn, "#{linenum}: #{tab_lines[linenum].gsub(/\t/, Rainbow(" ").background(:red))}")
|
@@ -56,5 +65,22 @@ module Pedant
|
|
56
65
|
# Run this check on the code in every file.
|
57
66
|
@kb[:codes].each { |file, code| check(file, code) }
|
58
67
|
end
|
68
|
+
|
69
|
+
# Enumerable#chunk_while in Ruby 2.3 would remove the need for this
|
70
|
+
def self.chunk_while enumerable
|
71
|
+
# If we're passed an array or something...
|
72
|
+
enumerable = enumerable.to_enum unless enumerable.respond_to? :next
|
73
|
+
|
74
|
+
chunks = [[enumerable.next]] rescue [[]]
|
75
|
+
loop do
|
76
|
+
elem = enumerable.next
|
77
|
+
if yield chunks.last.last, elem
|
78
|
+
chunks[-1] << elem
|
79
|
+
else
|
80
|
+
chunks << [elem]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
return chunks
|
84
|
+
end
|
59
85
|
end
|
60
86
|
end
|
@@ -62,10 +62,10 @@ module Pedant
|
|
62
62
|
tree = Nasl::Parser.new.parse(contents, path)
|
63
63
|
@kb[:trees][file] = tree
|
64
64
|
report(:info, "Parsed contents of #{path}.")
|
65
|
-
rescue Nasl::ParseException, Nasl::TokenException
|
66
|
-
# XXX-MAK: Incorporate the error from the parser, as it gives full,
|
67
|
-
# coloured context.
|
65
|
+
rescue Nasl::ParseException, Nasl::TokenException => e
|
68
66
|
report(:error, "Failed to parse #{path}.")
|
67
|
+
report(:error, e.message)
|
68
|
+
report(:error, e.backtrace)
|
69
69
|
return fatal
|
70
70
|
end
|
71
71
|
end
|
@@ -26,10 +26,17 @@
|
|
26
26
|
|
27
27
|
module Pedant
|
28
28
|
class CheckPluginTypeNotSpecified < Check
|
29
|
+
|
30
|
+
@@valid_types = ['combined', 'local', 'reputation', 'remote', 'settings', 'summary', 'thirdparty']
|
31
|
+
|
29
32
|
def self.requires
|
30
33
|
super + [:main, :trees]
|
31
34
|
end
|
32
35
|
|
36
|
+
def self.provides
|
37
|
+
super + @@valid_types.map {|t| "plugin_type_#{t}".to_sym}
|
38
|
+
end
|
39
|
+
|
33
40
|
def run
|
34
41
|
# This check only applies to plugins.
|
35
42
|
return skip unless @kb[:main].extname == '.nasl'
|
@@ -53,11 +60,15 @@ module Pedant
|
|
53
60
|
next if !arg.is_a? Nasl::String
|
54
61
|
|
55
62
|
# Ensure that the plugin type is valid.
|
56
|
-
|
57
|
-
|
63
|
+
type = arg.text
|
64
|
+
unless @@valid_types.include? type
|
65
|
+
report(:info, "Plugin is of unknown type #{type}:\n#{arg.context(node)}")
|
58
66
|
return fail
|
59
67
|
end
|
60
68
|
|
69
|
+
# Turn the plugin type into a symbol on which other checks can depend.
|
70
|
+
@kb["plugin_type_#{type}".to_sym] = true
|
71
|
+
|
61
72
|
args << [arg, node]
|
62
73
|
end
|
63
74
|
|
data/lib/pedant/version.rb
CHANGED
@@ -42,4 +42,26 @@ class TestContainsNoTabs < Test::Unit::TestCase
|
|
42
42
|
%Q|\t|
|
43
43
|
)
|
44
44
|
end
|
45
|
+
|
46
|
+
def test_line_squashing
|
47
|
+
assert_equal(
|
48
|
+
Pedant::CheckContainsNoTabs.chunk_while([1, 2, 3, 5, 6]) { |i, j| i + 1 == j },
|
49
|
+
[[1, 2, 3], [5, 6]]
|
50
|
+
)
|
51
|
+
|
52
|
+
assert_equal(
|
53
|
+
Pedant::CheckContainsNoTabs.chunk_while([1, 3, 5]) { |i, j| i + 1 == j },
|
54
|
+
[[1], [3], [5]]
|
55
|
+
)
|
56
|
+
|
57
|
+
assert_equal(
|
58
|
+
Pedant::CheckContainsNoTabs.chunk_while([1]) { |i, j| i + 1 == j },
|
59
|
+
[[1]]
|
60
|
+
)
|
61
|
+
|
62
|
+
assert_equal(
|
63
|
+
Pedant::CheckContainsNoTabs.chunk_while([]) { |i, j| i + 1 == j },
|
64
|
+
[[]]
|
65
|
+
)
|
66
|
+
end
|
45
67
|
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.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mak Kolybabi
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-
|
13
|
+
date: 2016-11-09 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rake
|
@@ -98,6 +98,7 @@ files:
|
|
98
98
|
- lib/pedant/checks/contains_display.rb
|
99
99
|
- lib/pedant/checks/contains_ip_address_literals.rb
|
100
100
|
- lib/pedant/checks/contains_no_carriage_returns.rb
|
101
|
+
- lib/pedant/checks/contains_no_duplicate_words.rb
|
101
102
|
- lib/pedant/checks/contains_no_tabs.rb
|
102
103
|
- lib/pedant/checks/contains_registration_section.rb
|
103
104
|
- lib/pedant/checks/contains_unreachable_code.rb
|