nasl-pedant 0.1.4 → 0.1.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.
- 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
|