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