nasl-pedant 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/.gitignore +10 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +8 -0
  4. data/bin/pedant +33 -0
  5. data/lib/pedant/check.rb +135 -0
  6. data/lib/pedant/checks/conditional_or_loop_is_empty.rb +70 -0
  7. data/lib/pedant/checks/contains_ip_address_literals.rb +49 -0
  8. data/lib/pedant/checks/contains_no_carriage_returns.rb +48 -0
  9. data/lib/pedant/checks/contains_no_tabs.rb +48 -0
  10. data/lib/pedant/checks/contains_registration_section.rb +107 -0
  11. data/lib/pedant/checks/contains_unreachable_code.rb +68 -0
  12. data/lib/pedant/checks/ends_with_newline.rb +49 -0
  13. data/lib/pedant/checks/files_parse_without_error.rb +101 -0
  14. data/lib/pedant/checks/parse_test_code.rb +63 -0
  15. data/lib/pedant/checks/plugin_type_not_specified.rb +79 -0
  16. data/lib/pedant/cli.rb +82 -0
  17. data/lib/pedant/command.rb +96 -0
  18. data/lib/pedant/commands/check.rb +76 -0
  19. data/lib/pedant/commands/test.rb +37 -0
  20. data/lib/pedant/knowledge_base.rb +42 -0
  21. data/lib/pedant/test.rb +59 -0
  22. data/lib/pedant/version.rb +3 -0
  23. data/lib/pedant.rb +51 -0
  24. data/pedant.gemspec +25 -0
  25. data/test/test_helper.rb +5 -0
  26. data/test/unit/checks/conditional_or_loop_is_empty.rb +125 -0
  27. data/test/unit/checks/contains_ip_address_literals.rb +45 -0
  28. data/test/unit/checks/contains_no_carriage_returns.rb +43 -0
  29. data/test/unit/checks/contains_no_tabs.rb +45 -0
  30. data/test/unit/checks/contains_registration_section.rb +101 -0
  31. data/test/unit/checks/contains_unreachable_code.rb +93 -0
  32. data/test/unit/checks/ends_with_newline.rb +45 -0
  33. data/test/unit/checks/plugin_type_not_specified.rb +72 -0
  34. metadata +123 -0
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ # Ruby gems files.
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
5
+ pkg/*
6
+
7
+ # Editor scratch files.
8
+ \#*
9
+ *~
10
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pedant.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ t.test_files = FileList['test/**/test*.rb']
7
+ t.verbose = true
8
+ end
data/bin/pedant ADDED
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ################################################################################
4
+ # Copyright (c) 2011, Mak Kolybabi
5
+ # All rights reserved.
6
+ #
7
+ # Redistribution and use in source and binary forms, with or without
8
+ # modification, are permitted provided that the following conditions are met:
9
+ #
10
+ # 1. Redistributions of source code must retain the above copyright notice, this
11
+ # list of conditions and the following disclaimer.
12
+ #
13
+ # 2. Redistributions in binary form must reproduce the above copyright notice,
14
+ # this list of conditions and the following disclaimer in the documentation
15
+ # and/or other materials provided with the distribution.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ ################################################################################
28
+
29
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
30
+
31
+ require 'pedant'
32
+
33
+ Pedant::Cli.run
@@ -0,0 +1,135 @@
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 Check
29
+ attr_reader :result
30
+
31
+ @@statuses = {
32
+ :died => 'DIED'.color(:red),
33
+ :fail => 'FAIL'.color(:red),
34
+ :pass => 'PASS'.color(:green),
35
+ :skip => 'SKIP'.color(:green),
36
+ :warn => 'WARN'.color(:yellow),
37
+ :void => 'VOID'.color(:magenta)
38
+ }
39
+
40
+ @@levels = [:error, :warn, :info]
41
+
42
+ def self.initialize!
43
+ Dir.glob(Pedant.lib + 'pedant/checks/*.rb').each { |f| load(f) }
44
+ end
45
+
46
+ def initialize(kb)
47
+ @report = []
48
+ @result = :void
49
+
50
+ @kb = kb
51
+
52
+ # Run all the dependencies for this check if we're in test mode.
53
+ return unless @kb[:test_mode]
54
+ self.class.depends.each do |cls|
55
+ chk = cls.new(@kb)
56
+ chk.run
57
+ end
58
+ end
59
+
60
+ def self.all
61
+ (@_all ||= [])
62
+ end
63
+
64
+ def self.inherited(cls)
65
+ all << cls
66
+ end
67
+
68
+ def self.provides
69
+ return []
70
+ end
71
+
72
+ def self.requires
73
+ return []
74
+ end
75
+
76
+ def self.ready?(kb)
77
+ self.requires.reduce(true) do |stat, req|
78
+ stat && kb.has_key?(req)
79
+ end
80
+ end
81
+
82
+ def self.depends
83
+ keys = self.requires
84
+
85
+ Check.all.reject do |cls|
86
+ (cls.provides & keys).empty?
87
+ end
88
+ end
89
+
90
+ def report(level, text=nil)
91
+ if !text.nil?
92
+ @report << [level, text]
93
+ return
94
+ end
95
+
96
+ # Convert level from symbol to an array index.
97
+ level = @@levels.index(level) if level.is_a?(Symbol)
98
+
99
+ # Format all components of a report at or below the specified level.
100
+ msg = @report.select { |l, t| @@levels.index(l) <= level }.map { |l, t| t }.join("\n")
101
+ msg << "\n" unless msg.empty?
102
+
103
+ # Format the check's result.
104
+ msg = "[#{@@statuses[@result]}] #{self.name}\n#{msg}"
105
+
106
+ return msg
107
+ end
108
+
109
+ def name
110
+ # Mangle the classes name to be more user-friendly.
111
+ self.class.name.gsub(/.*::/, '').gsub(/^Check/, '').gsub(/([A-Z][^A-Z]*)/, ' \1').strip
112
+ end
113
+
114
+ def fail
115
+ @result = :fail
116
+ end
117
+
118
+ def fatal
119
+ report(:error, "This is a fatal error.")
120
+ @result = :died
121
+ end
122
+
123
+ def pass
124
+ @result = :pass
125
+ end
126
+
127
+ def skip
128
+ @result = :skip
129
+ end
130
+
131
+ def warn
132
+ @result = :warn
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,70 @@
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 CheckConditionalOrLoopIsEmpty < Check
29
+ def self.requires
30
+ super + [:trees]
31
+ end
32
+
33
+ def check(file, tree)
34
+ # All of the loops have a body attribute, so they can be checked together.
35
+ [:For, :Foreach, :Repeat, :While].each do |cls|
36
+ tree.all(cls).each do |node|
37
+ next unless node.body.is_a? Nasl::Empty
38
+
39
+ fail
40
+
41
+ report(:error, "#{cls} loop in #{file} has an empty statement as its body.")
42
+ end
43
+ end
44
+
45
+ # An If statement may has two branches, each of which need to be checked.
46
+ # This will not cause false positives on If statements without else
47
+ # clauses, because those branches will be nil.
48
+ tree.all(:If).each do |node|
49
+ [:true, :false].each do |name|
50
+ branch = node.send(name)
51
+
52
+ next if branch.nil?
53
+ next unless branch.is_a? Nasl::Empty
54
+
55
+ fail
56
+
57
+ report(:error, "If statement in #{file} has an empty statement as #{name} branch.")
58
+ end
59
+ end
60
+ end
61
+
62
+ def run
63
+ # This check will pass by default.
64
+ pass
65
+
66
+ # Run this check on the tree from every file.
67
+ @kb[:trees].each { |file, tree| check(file, tree) }
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,49 @@
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 CheckContainsIpAddressLiterals < Check
29
+ def self.requires
30
+ super + [:trees]
31
+ end
32
+
33
+ def check(file, tree)
34
+ return if tree.all(:Ip).empty?
35
+
36
+ warn
37
+ report(:warn, "IP address literals were found in #{file}.")
38
+ tree.all(:Ip).each { |ip| report(:warn, ip.context) }
39
+ end
40
+
41
+ def run
42
+ # This check will pass by default.
43
+ pass
44
+
45
+ # Run this check on the tree of every file.
46
+ @kb[:trees].each { |file, tree| check(file, tree) }
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,48 @@
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 CheckContainsNoCarriageReturns < Check
29
+ def self.requires
30
+ super + [:codes]
31
+ end
32
+
33
+ def check(file, code)
34
+ return unless code =~ /\r/
35
+
36
+ report(:warn, "Carriage returns were found in #{file}.")
37
+ warn
38
+ end
39
+
40
+ def run
41
+ # This check will pass by default.
42
+ pass
43
+
44
+ # Run this check on the code in every file.
45
+ @kb[:codes].each { |file, code| check(file, code) }
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,48 @@
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 CheckContainsNoTabs < Check
29
+ def self.requires
30
+ super + [:codes]
31
+ end
32
+
33
+ def check(file, code)
34
+ return unless code =~ /\t/
35
+
36
+ report(:warn, "Tabs were found in #{file}.")
37
+ warn
38
+ end
39
+
40
+ def run
41
+ # This check will pass by default.
42
+ pass
43
+
44
+ # Run this check on the code in every file.
45
+ @kb[:codes].each { |file, code| check(file, code) }
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,107 @@
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 CheckContainsRegistrationSection < 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
+ # This check will pass by default.
38
+ pass
39
+
40
+ tree = @kb[:trees][@kb[:main]]
41
+
42
+ # Find the registration If statement.
43
+ regs = tree.all(:If).select do |node|
44
+ (node.cond.is_a?(Nasl::Lvalue) && node.cond.ident.name == 'description')
45
+ end
46
+
47
+ # Ensure there's a registration section.
48
+ if regs.empty?
49
+ report(:error, "No registration section was found.")
50
+ report(:error, "This will cause the plugin to be run twice in both Nessus interface and nasl with the -M flag.")
51
+ return fail
52
+ end
53
+
54
+ # Ensure that there is only one registration section.
55
+ unless regs.length == 1
56
+ report(:error, "Multiple registration sections were found.")
57
+ regs.each { |reg| report(:error, reg.context) }
58
+ return fail
59
+ end
60
+
61
+ # Ensure that the registration section is a block.
62
+ reg = regs.first
63
+ branch = reg.true
64
+ unless branch.is_a? Nasl::Block
65
+ report(:error, "The registration section is a #{branch.class.name}, but a Block was expected.")
66
+ report(:error, branch.context(reg))
67
+ return fail
68
+ end
69
+
70
+ # Ensure that the registration section is not empty.
71
+ if branch.body.empty?
72
+ report(:error, "The registration section is empty.")
73
+ report(:error, branch.context(reg))
74
+ return fail
75
+ end
76
+
77
+ # Ensure that the description section ends with a call to exit.
78
+ statement = branch.body.last
79
+ unless statement.is_a? Nasl::Call
80
+ report(:error, "The registration section ends with a #{statement.class.name}, not a Call as expected.")
81
+ report(:error, statement.context(reg))
82
+ return fail
83
+ end
84
+
85
+ unless statement.name.name == 'exit'
86
+ report(:error, "The registration section ends with a call to #{statement.name.name}, not exit as expected.")
87
+ report(:error, statement.context(reg))
88
+ return fail
89
+ end
90
+
91
+ # Ensure that the call to exit is a success without a message.
92
+ args = statement.args
93
+ if args.empty?
94
+ report(:error, "The registration ends with a call to exit with no arguments.")
95
+ report(:error, statement.context)
96
+ return fail
97
+ end
98
+
99
+ arg = args.first
100
+ if args.length != 1 || arg.type != :anonymous || !arg.expr.is_a?(Nasl::Integer) || arg.expr.value != 0
101
+ report(:error, "The registration section does not end with a call to exit(0).")
102
+ report(:error, arg.context(statement))
103
+ return fail
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,68 @@
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 CheckContainsUnreachableCode < Check
29
+ def self.requires
30
+ super + [:trees]
31
+ end
32
+
33
+ def check(file, tree)
34
+ def check_statements(file, list)
35
+ list.each do |node|
36
+ # Check if the Node is capable of jumping out of the Block, without
37
+ # resuming where it left off (i.e., Call). The exception is exit(),
38
+ # which is a builtin Function that terminates execution.
39
+ if node.is_a?(Nasl::Break) || node.is_a?(Nasl::Continue) || node.is_a?(Nasl::Return) || (node.is_a?(Nasl::Call) && node.name.name == 'exit')
40
+ # If this is not the final node in the list, then there is
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
46
+ end
47
+ end
48
+ end
49
+
50
+ # Unreachable statements occur only when there are sequential lists of
51
+ # instructions. In layers deeper than the outermost level of indentation,
52
+ # this only occurs in Blocks.
53
+ tree.all(:Block).each { |blk| check_statements(file, blk.body) }
54
+
55
+ # The main body of a file is not a Block, so it must be considered
56
+ # separately.
57
+ check_statements(file, tree)
58
+ end
59
+
60
+ def run
61
+ # This check will pass by default.
62
+ pass
63
+
64
+ # Run this check on the tree from every file.
65
+ @kb[:trees].each { |file, tree| check(file, tree) }
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,49 @@
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 CheckEndsWithNewline < Check
29
+ def self.requires
30
+ super + [:codes]
31
+ end
32
+
33
+ def check(file, code)
34
+ return if code[-1] == "\n"
35
+
36
+ warn
37
+
38
+ report(:warn, "#{file} does not end with a newline.")
39
+ end
40
+
41
+ def run
42
+ # This check will pass by default.
43
+ pass
44
+
45
+ # Run this check on the code in every file.
46
+ @kb[:codes].each { |file, code| check(file, code) }
47
+ end
48
+ end
49
+ end