nasl-pedant 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c89304bdba6963cc2f97f76b1ebd0c3a2711966c
4
- data.tar.gz: 93ac35fac25ec9d64bc099dbc0babbdc05e2a074
3
+ metadata.gz: 802522146b1d3bb3ba9466e6685d21e4b3d79346
4
+ data.tar.gz: e8253157a6d19177ed45083d7638e1fbb6c097e6
5
5
  SHA512:
6
- metadata.gz: 7cbaf855866862610c321bc4c4044459744e7fb334c443ac8e760b85ea363da2d6625963b1b8af33d2f958a4e9c441933d93f64719d37e12a1a69e7f309c409c
7
- data.tar.gz: 8a1ebefac1023fbd3790075e684bb4044b2c71ca46e8e06f197bdc0e1287cc5d91f029964a45b6a58c3be8e96239bb929a355f489b2175da8ac6ebbde1644f34
6
+ metadata.gz: 12eccd3189ebba43044f772ec4c8384449478fd102b98cc4a894675b2b953ca7c7ca87ac77d5f14ee6582778ae033342c608143208310e74bebb6a07847d0d8d
7
+ data.tar.gz: f619bd12da3a25eba96d6116394c29800bbdb7884cc03bc82d767205f8423a8b24205de722a6f7ba4a9cacbcfb95c38ef682fa0e086429b98375806ee10c1fb2
@@ -33,6 +33,19 @@ module Pedant
33
33
  def check(file, tree)
34
34
  def check_statements(file, list)
35
35
  list.each do |node|
36
+ # Is this an exit() call that's used to deprecate the plugin? If so,
37
+ # we'll ignore it and check the rest of the plugin.
38
+ # These look like:
39
+ # exit(0, "This plugin has been deprecated");
40
+ # Some plugins (like the Slackware plugins) just do: exit(0);
41
+ # But, they are old and have been deprecated forever and will
42
+ # probably never be changed or reenabled.
43
+ next if node.is_a?(Nasl::Call) and
44
+ node.name.ident.name == 'exit' and
45
+ node.args.length == 2 and
46
+ node.args[1].expr.is_a?(Nasl::String) and
47
+ node.args[1].expr.text =~ /plugin has been deprecated|patch has been replaced/i
48
+
36
49
  # Check if the Node is capable of jumping out of the Block, without
37
50
  # resuming where it left off (i.e., Call). The exception is exit(),
38
51
  # which is a builtin Function that terminates execution.
@@ -32,22 +32,44 @@ module Pedant
32
32
 
33
33
  def check(file, tree)
34
34
  def walk(node, root)
35
+ def is_get_kb_item_with_literal? node
36
+ # Is this a call to get_kb_item with just one literal string?
37
+ return true if node.is_a?(Nasl::Call) and
38
+ node.name.ident.name == 'get_kb_item' and
39
+ node.name.indexes == [] and
40
+ node.args.length == 1 and
41
+ node.args.first.expr.is_a?(Nasl::String)
42
+
43
+ return false
44
+ end
35
45
  # Recursively descend into the right-hand and left-hand sides of each expression.
36
46
  if node.is_a? Nasl::Expression
37
47
  [:lhs, :rhs].each { |side| walk(node.send(side), root) }
38
48
 
39
49
  return unless node.op.is_a?(Nasl::Token)
40
50
 
51
+ # We have four operators we examine here:
52
+ # The regex operators, and the substring operators. One operand is the "needle" and the other is the "haystack".
53
+ # For substring (><, >!<), the operands go: "needle" >< "the needle in the haystack"
54
+ # For regex, it's the opposite: "the needle in the haystack" =~ "needle"
55
+ # It's a common error to flip these by accident.
56
+
57
+ # For the regex operators, the left side is what is being tested and
58
+ # the right side is the pattern to match.
41
59
  if ["=~", "!~"].include?(node.op.body)
42
60
  side = :lhs
43
61
  opposite = :rhs
44
62
  end
45
63
 
64
+ # The substring operators have their operands reversed from the regex
65
+ # operators; the right side is the thing we are testing and the left
66
+ # side is the pattern.
46
67
  if ["><", ">!<"].include?(node.op.body)
47
68
  side = :rhs
48
69
  opposite = :lhs
49
70
  end
50
71
 
72
+ # If the operator isn't one of the four we check
51
73
  return if side.nil?
52
74
 
53
75
  # The check for no indexes is to account for this uncommon-but-in-use
@@ -56,7 +78,7 @@ module Pedant
56
78
  #
57
79
  # tolower(xml[index]) >< "abcdefghijklmnopqrstuvwxyz:_"
58
80
  #
59
- if node.send(side).is_a?(Nasl::String) && node.send(opposite).is_a?(Nasl::Lvalue) && node.send(opposite).indexes == []
81
+ if node.send(side).is_a?(Nasl::String) && (node.send(opposite).is_a?(Nasl::Lvalue) && node.send(opposite).indexes == []) or is_get_kb_item_with_literal?(node.send(opposite))
60
82
  warn
61
83
  report(:error, "A '#{node.op.body}' operator has a literal string on the #{if side == :lhs then 'left' else 'right' end}-hand side.")
62
84
  report(:error, "The operands may be accidentally swapped.")
@@ -1,3 +1,3 @@
1
1
  module Pedant
2
- VERSION = '0.1.5'
2
+ VERSION = '0.1.6'
3
3
  end
@@ -48,6 +48,7 @@ Gem::Specification.new do |s|
48
48
  s.require_paths = ['lib']
49
49
 
50
50
  s.add_development_dependency 'rake', '~> 0'
51
+ s.add_development_dependency 'pry', '~> 0'
51
52
 
52
53
  s.add_runtime_dependency 'rainbow', '=2.0.0'
53
54
  s.add_runtime_dependency 'nasl', '~> 0.2', '>= 0.2.0'
@@ -97,6 +97,17 @@ class TestContainsUnreachableCode < Test::Unit::TestCase
97
97
  )
98
98
  end
99
99
 
100
+ # Plugins that are deprecated will have a bit of code inserted to
101
+ # prevent the body of the plugin from running. We should not flag
102
+ # this specific call to exit().
103
+ def test_deprecated_plugin_exit
104
+ check(
105
+ :pass,
106
+ :CheckContainsUnreachableCode,
107
+ %q|{ exit(0, "This plugin has been deprecated"); foo(); }|
108
+ )
109
+ end
110
+
100
111
  # exit() is a special case in this check, because it's a function instead of a
101
112
  # language keyword.
102
113
  def test_indexed_exit
@@ -106,7 +117,7 @@ class TestContainsUnreachableCode < Test::Unit::TestCase
106
117
  %q|{ exit.foo(); foo(); }|
107
118
  )
108
119
  end
109
-
120
+
110
121
  def audit_indexed_exit
111
122
  check(
112
123
  :pass,
@@ -59,6 +59,24 @@ class TestFlippedOperandsOnMatchOrSubstring < Test::Unit::TestCase
59
59
  )
60
60
  end
61
61
 
62
+ # get_kb_item() returns a string and nobody stores regexes or substrings
63
+ # in the KB, so treat this as a special case.
64
+ def test_get_kb_item
65
+ check(
66
+ :warn,
67
+ :CheckFlippedOperandsOnMatchOrSubstring,
68
+ %q|if (get_kb_item("whatever") >< "Windows");|
69
+ )
70
+ end
71
+
72
+ def test_some_other_function
73
+ check(
74
+ :pass,
75
+ :CheckFlippedOperandsOnMatchOrSubstring,
76
+ %q|if (get_substring_for_key("whatever") >< "Windows");|
77
+ )
78
+ end
79
+
62
80
  def test_simple_match
63
81
  check(
64
82
  :warn,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nasl-pedant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mak Kolybabi
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-11-09 00:00:00.000000000 Z
13
+ date: 2017-09-11 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -26,6 +26,20 @@ dependencies:
26
26
  - - "~>"
27
27
  - !ruby/object:Gem::Version
28
28
  version: '0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: pry
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
29
43
  - !ruby/object:Gem::Dependency
30
44
  name: rainbow
31
45
  requirement: !ruby/object:Gem::Requirement