nasl-pedant 0.0.1
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/.gitignore +10 -0
- data/Gemfile +4 -0
- data/Rakefile +8 -0
- data/bin/pedant +33 -0
- data/lib/pedant/check.rb +135 -0
- data/lib/pedant/checks/conditional_or_loop_is_empty.rb +70 -0
- data/lib/pedant/checks/contains_ip_address_literals.rb +49 -0
- data/lib/pedant/checks/contains_no_carriage_returns.rb +48 -0
- data/lib/pedant/checks/contains_no_tabs.rb +48 -0
- data/lib/pedant/checks/contains_registration_section.rb +107 -0
- data/lib/pedant/checks/contains_unreachable_code.rb +68 -0
- data/lib/pedant/checks/ends_with_newline.rb +49 -0
- data/lib/pedant/checks/files_parse_without_error.rb +101 -0
- data/lib/pedant/checks/parse_test_code.rb +63 -0
- data/lib/pedant/checks/plugin_type_not_specified.rb +79 -0
- data/lib/pedant/cli.rb +82 -0
- data/lib/pedant/command.rb +96 -0
- data/lib/pedant/commands/check.rb +76 -0
- data/lib/pedant/commands/test.rb +37 -0
- data/lib/pedant/knowledge_base.rb +42 -0
- data/lib/pedant/test.rb +59 -0
- data/lib/pedant/version.rb +3 -0
- data/lib/pedant.rb +51 -0
- data/pedant.gemspec +25 -0
- data/test/test_helper.rb +5 -0
- data/test/unit/checks/conditional_or_loop_is_empty.rb +125 -0
- data/test/unit/checks/contains_ip_address_literals.rb +45 -0
- data/test/unit/checks/contains_no_carriage_returns.rb +43 -0
- data/test/unit/checks/contains_no_tabs.rb +45 -0
- data/test/unit/checks/contains_registration_section.rb +101 -0
- data/test/unit/checks/contains_unreachable_code.rb +93 -0
- data/test/unit/checks/ends_with_newline.rb +45 -0
- data/test/unit/checks/plugin_type_not_specified.rb +72 -0
- metadata +123 -0
@@ -0,0 +1,101 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2011, Mak Kolybabi
|
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 CheckFilesParseWithoutErrors < Check
|
29
|
+
def self.requires
|
30
|
+
super + [:file_mode, :base, :main]
|
31
|
+
end
|
32
|
+
|
33
|
+
def provides
|
34
|
+
super + [:codes, :trees]
|
35
|
+
end
|
36
|
+
|
37
|
+
def run
|
38
|
+
def import(path)
|
39
|
+
# All files should be relative to the main file's base in practice.
|
40
|
+
path = @kb[:base] + path
|
41
|
+
|
42
|
+
# Since there are potentially several ways to write the path leading to
|
43
|
+
# a file, we'll use the basename as the key for hashes. This will
|
44
|
+
# prevent parsing the same file multiple times.
|
45
|
+
file = path.basename
|
46
|
+
|
47
|
+
# Mark a placeholder key in the KB for this file. This will prevent us
|
48
|
+
# from trying to parse a library more than once if there is a failure.
|
49
|
+
@kb[:codes][file] = :pending
|
50
|
+
@kb[:trees][file] = :pending
|
51
|
+
|
52
|
+
begin
|
53
|
+
contents = File.open(path, "rb").read
|
54
|
+
@kb[:codes][file] = contents
|
55
|
+
report(:info, "Read contents of #{path}.")
|
56
|
+
rescue
|
57
|
+
report(:error, "Failed to read contents #{path}.")
|
58
|
+
return fatal
|
59
|
+
end
|
60
|
+
|
61
|
+
begin
|
62
|
+
tree = Nasl::Parser.new.parse(contents, path)
|
63
|
+
@kb[:trees][file] = tree
|
64
|
+
report(:info, "Parsed contents of #{path}.")
|
65
|
+
rescue
|
66
|
+
# XXX-MAK: Incorporate the error from the parser, as it gives full,
|
67
|
+
# coloured context.
|
68
|
+
report(:error, "Failed to parse #{path}.")
|
69
|
+
return fatal
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# This check will pass by default.
|
74
|
+
pass
|
75
|
+
|
76
|
+
# Initialize the keys written by this check.
|
77
|
+
@kb[:codes] = {}
|
78
|
+
@kb[:trees] = {}
|
79
|
+
|
80
|
+
# Load up the main file.
|
81
|
+
import(@kb[:main])
|
82
|
+
|
83
|
+
return
|
84
|
+
|
85
|
+
while true
|
86
|
+
# Get the list of all Includes, and prune any that have already had the
|
87
|
+
# files they reference parsed.
|
88
|
+
libs = Nasl::Include.all.map do |inc|
|
89
|
+
(@kb[:base] + inc.filename.text).basename
|
90
|
+
end
|
91
|
+
|
92
|
+
libs.delete_if { |lib| lib == @kb[:main] || @kb[:trees].has_key?(lib) }
|
93
|
+
|
94
|
+
break if libs.empty?
|
95
|
+
|
96
|
+
# Try and parse each library, continuing on failures.
|
97
|
+
libs.each { |lib| import(lib) }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2011, Mak Kolybabi
|
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 CheckParseTestCode < Check
|
29
|
+
def self.requires
|
30
|
+
super + [:codes, :main, :test_mode]
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.provides
|
34
|
+
super + [:trees]
|
35
|
+
end
|
36
|
+
|
37
|
+
def run
|
38
|
+
def import(path)
|
39
|
+
# Since there are potentially several ways to write the path leading to
|
40
|
+
# a file, we'll use the basename as the key for hashes. This will
|
41
|
+
# prevent parsing the same file multiple times.
|
42
|
+
file = path.basename
|
43
|
+
|
44
|
+
# Mark a placeholder key in the KB for this file. This will prevent us
|
45
|
+
# from trying to parse a library more than once if there is a failure.
|
46
|
+
@kb[:trees][file] = :pending
|
47
|
+
|
48
|
+
tree = Nasl::Parser.new.parse(@kb[:codes][file], path)
|
49
|
+
@kb[:trees][file] = tree
|
50
|
+
report(:info, "Parsed contents of #{path}.")
|
51
|
+
end
|
52
|
+
|
53
|
+
# This check will pass by default.
|
54
|
+
pass
|
55
|
+
|
56
|
+
# Initialize the keys written by this check.
|
57
|
+
@kb[:trees] = {}
|
58
|
+
|
59
|
+
# Load up the main file.
|
60
|
+
import(@kb[:main])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2011, Mak Kolybabi
|
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 CheckPluginTypeNotSpecified < Check
|
29
|
+
def self.requires
|
30
|
+
super + [:main, :trees]
|
31
|
+
end
|
32
|
+
|
33
|
+
def run
|
34
|
+
# This check only applies to plugins.
|
35
|
+
return skip unless @kb[:main].extname == '.nasl'
|
36
|
+
|
37
|
+
args = []
|
38
|
+
|
39
|
+
tree = @kb[:trees][@kb[:main]]
|
40
|
+
|
41
|
+
tree.all(:Call).each do |node|
|
42
|
+
next unless node.name.name == 'script_set_attribute'
|
43
|
+
next unless node.arg.has_key? 'attribute'
|
44
|
+
|
45
|
+
# Pull out the attribute argument.
|
46
|
+
arg = node.arg['attribute']
|
47
|
+
next if !arg.is_a? Nasl::String
|
48
|
+
next if arg.text != 'plugin_type'
|
49
|
+
|
50
|
+
# Pull out the value argument.
|
51
|
+
arg = node.arg['value']
|
52
|
+
next if !arg.is_a? Nasl::String
|
53
|
+
|
54
|
+
# Ensure that the plugin type is valid.
|
55
|
+
unless ['combined', 'local', 'remote'].include? arg.text
|
56
|
+
report(:info, "Plugin is of unknown type #{arg.text}:\n#{arg.context(node)}")
|
57
|
+
return fail
|
58
|
+
end
|
59
|
+
|
60
|
+
args << [arg, node]
|
61
|
+
end
|
62
|
+
|
63
|
+
case args.length
|
64
|
+
when 0
|
65
|
+
report(:error, "Plugin does not specify a type.")
|
66
|
+
fail
|
67
|
+
when 1
|
68
|
+
arg = args.first[0]
|
69
|
+
call = args.first[1]
|
70
|
+
report(:info, "Plugin is of type #{arg.text}:\n#{arg.context(call)}")
|
71
|
+
pass
|
72
|
+
else
|
73
|
+
report(:error, "Plugin specifies multiple types.")
|
74
|
+
args.each { |arg, call| report(:error, arg.context(call)) }
|
75
|
+
fail
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/pedant/cli.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2011, Mak Kolybabi
|
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 'optparse'
|
28
|
+
|
29
|
+
module Pedant
|
30
|
+
class Cli
|
31
|
+
def self.run
|
32
|
+
cfg = {}
|
33
|
+
|
34
|
+
Command.initialize!
|
35
|
+
|
36
|
+
optparse = OptionParser.new do |opts|
|
37
|
+
opts.banner = "Usage: pedant [options] [command [args]]"
|
38
|
+
|
39
|
+
cfg[:verbose] = 0
|
40
|
+
opts.on('-v', '--verbose', 'Output more information') do
|
41
|
+
cfg[:verbose] += 1
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
optparse.parse!
|
46
|
+
|
47
|
+
# Sanity check the command line arguments.
|
48
|
+
if ARGV.empty?
|
49
|
+
puts "No command was specified."
|
50
|
+
puts
|
51
|
+
usage
|
52
|
+
exit 1
|
53
|
+
end
|
54
|
+
|
55
|
+
cmd = ARGV.shift
|
56
|
+
cls = Command.find(cmd)
|
57
|
+
if cls.nil? then
|
58
|
+
puts "Command '#{cmd}' not supported."
|
59
|
+
puts
|
60
|
+
usage
|
61
|
+
exit 1
|
62
|
+
end
|
63
|
+
|
64
|
+
# Run the command.
|
65
|
+
cls.run(cfg, ARGV)
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.usage
|
69
|
+
puts "For the moment, you have to run Pedant from its top-level directory."
|
70
|
+
puts
|
71
|
+
puts "./bin/pedant [flags] [command] [filename ...]"
|
72
|
+
puts
|
73
|
+
puts "Flags:"
|
74
|
+
puts " -v Display more verbose (warning) messages. "
|
75
|
+
puts " -vv Display more verbose (informational) messages. "
|
76
|
+
puts
|
77
|
+
puts "Commands:"
|
78
|
+
puts " check Runs all included checks against the specified plugin(s)."
|
79
|
+
puts " test Runs the specified unit tests, all are selected by default."
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2011, Mak Kolybabi
|
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 Command
|
29
|
+
def self.initialize!
|
30
|
+
Dir.glob(Pedant.lib + 'pedant/commands/*.rb').each {|f| load(f)}
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.all
|
34
|
+
(@_all ||= [])
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.inherited(cls)
|
38
|
+
all << cls
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.find(cmd)
|
42
|
+
all.each do |cls|
|
43
|
+
return cls if cls.binding == cmd
|
44
|
+
end
|
45
|
+
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.banner(title, width=80)
|
50
|
+
# Create center of banner.
|
51
|
+
middle = "[ #{title} ]"
|
52
|
+
|
53
|
+
# Make sure width is a float.
|
54
|
+
width = width.to_f
|
55
|
+
|
56
|
+
# Create bars on either side.
|
57
|
+
leftover = (width - middle.length) / 2
|
58
|
+
left = '-' * leftover.floor
|
59
|
+
right = '-' * leftover.ceil
|
60
|
+
|
61
|
+
left + middle + right
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.run(cfg, args)
|
65
|
+
# Separate plugins and libraries from the rest of the arguments.
|
66
|
+
paths = args.select { |arg| arg =~ /(\/|\.(inc|nasl))$/ }
|
67
|
+
args -= paths
|
68
|
+
|
69
|
+
# If we have no paths to process, there's a problem. Special purpose
|
70
|
+
# commands that don't require files to be declared should override this
|
71
|
+
# method.
|
72
|
+
if paths.empty?
|
73
|
+
puts "No directories (/), libraries (.inc), or plugins (.nasl) were specified."
|
74
|
+
exit 1
|
75
|
+
end
|
76
|
+
|
77
|
+
# Collect all the paths together, recursively.
|
78
|
+
dirents = []
|
79
|
+
paths.each do |path|
|
80
|
+
Pathname.new(path).find do |dirent|
|
81
|
+
if dirent.file? && dirent.extname =~ /inc|nasl/
|
82
|
+
dirents << dirent
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# If the command is capable of handling all the paths at once, send them
|
88
|
+
# in a group, otherwise send them individually.
|
89
|
+
if self.respond_to? :analyze_all then
|
90
|
+
analyze_all(cfg, dirents, args)
|
91
|
+
else
|
92
|
+
dirents.each { |d| analyze(cfg, d, args) }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2011, Mak Kolybabi
|
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 CommandCheck < Command
|
29
|
+
def self.binding
|
30
|
+
'check'
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.analyze(cfg, path, args)
|
34
|
+
Check.initialize!
|
35
|
+
|
36
|
+
# Get a list of every existing check.
|
37
|
+
pending = Check.all
|
38
|
+
|
39
|
+
# Initialize the knowledge base where checks can store information for
|
40
|
+
# other checks.
|
41
|
+
kb = KnowledgeBase.new(:file_mode, path)
|
42
|
+
|
43
|
+
# Try to run each pending check, until we've run all our checks or
|
44
|
+
# deadlocked.
|
45
|
+
fatal = false
|
46
|
+
until pending.empty? || fatal
|
47
|
+
# Find all of the checks that can run right now.
|
48
|
+
ready = pending.select { |cls| cls.ready?(kb) }
|
49
|
+
break if ready.empty?
|
50
|
+
|
51
|
+
# Run all of the checks that are ready.
|
52
|
+
ready.each do |cls|
|
53
|
+
# Create a new check instance.
|
54
|
+
chk = cls.new(kb)
|
55
|
+
pending.delete(cls)
|
56
|
+
|
57
|
+
chk.run
|
58
|
+
|
59
|
+
# Fatal errors mean that no further checks should be processed.
|
60
|
+
if chk.result == :fatal
|
61
|
+
fatal = true
|
62
|
+
break
|
63
|
+
end
|
64
|
+
|
65
|
+
# Display the results of the check.
|
66
|
+
puts chk.report(cfg[:verbose])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Notify the user if any checks did not run due to unsatisfied
|
71
|
+
# dependencies or a fatal error occurring before they had the chance to
|
72
|
+
# run.
|
73
|
+
pending.each { |cls| puts cls.new(kb).report(cfg[:verbose]) }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2011, Mak Kolybabi
|
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 CommandTest < Command
|
29
|
+
def self.binding
|
30
|
+
'test'
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.run(cfg, args)
|
34
|
+
Test.initialize!(args)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2011, Mak Kolybabi
|
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 KnowledgeBase < Hash
|
29
|
+
def initialize(mode, path=nil)
|
30
|
+
self[mode] = true
|
31
|
+
|
32
|
+
case mode
|
33
|
+
when :file_mode
|
34
|
+
self[:base] = path.dirname
|
35
|
+
self[:main] = path.basename
|
36
|
+
when :test_mode
|
37
|
+
self[:base] = Pathname.new('/var/empty')
|
38
|
+
self[:main] = Pathname.new('test.nasl')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/pedant/test.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright (c) 2011, Mak Kolybabi
|
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 'test/unit'
|
28
|
+
|
29
|
+
module Pedant
|
30
|
+
module Test
|
31
|
+
def self.initialize!(args)
|
32
|
+
# Run all tests by default.
|
33
|
+
args = ['unit/*', 'unit/*/*'] if args.empty?
|
34
|
+
|
35
|
+
# Run each test or category of tests specified on the command line.
|
36
|
+
args.each do |test|
|
37
|
+
Dir.glob(Pedant.test + (test + '.rb')).each { |f| load(f) }
|
38
|
+
end
|
39
|
+
|
40
|
+
Check.initialize!
|
41
|
+
end
|
42
|
+
|
43
|
+
def check(result, cls, code)
|
44
|
+
# Create a knowledge base.
|
45
|
+
kb = KnowledgeBase.new(:test_mode)
|
46
|
+
|
47
|
+
# Put test code into the knowledge base.
|
48
|
+
kb[:codes] = {}
|
49
|
+
kb[:codes][kb[:main]] = code
|
50
|
+
|
51
|
+
# Create a new instance of the check, which will execute all dependencies.
|
52
|
+
chk = Pedant.const_get(cls).new(kb)
|
53
|
+
|
54
|
+
# Run the test and ensure we got the expected result.
|
55
|
+
chk.run
|
56
|
+
assert_equal(result, chk.result)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|