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.
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