nasl-pedant 0.1.5 → 0.1.6

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