class Pedant::CheckNonsenseComparison

Public Class Methods

requires() click to toggle source
Calls superclass method Pedant::Check::requires
# File lib/pedant/checks/nonsense_comparison.rb, line 31
def self.requires
  super + [:trees]
end

Public Instance Methods

check(file, tree) click to toggle source
# File lib/pedant/checks/nonsense_comparison.rb, line 35
def check(file, tree)
  literals = Set.new [
    Nasl::Array,
    Nasl::List,
    Nasl::Integer,
    Nasl::String,
    Nasl::Ip
  ]

  comparisons = Set.new [ "==", "!=", "=~", "!~", "><", ">!<", "<", ">", "<=", ">=" ]

  # isnull() with a literal (never FALSE).
  tree.all(:Call).each do |call|
    next if call.name.ident.name != "isnull"
    next if call.name.indexes != []
    next if call.args.length != 1
    next if not literals.include? call.args.first.expr.class
    fail
    report(:error, "isnull() is called with a literal, which can never be FALSE.")
    report(:error, call.args.first.context(call))
  end

  # Comparing a literal to another literal (either TRUE or FALSE, but pointless).
  tree.all(:Expression).each do |expr|
    next if not literals.include? expr.lhs.class
    next if not literals.include? expr.rhs.class
    next if not comparisons.include? expr.op.to_s
    fail
    report(:error, "Comparing two literals is always TRUE or FALSE.")
    report(:error, expr.op.context(expr))
  end

  # Comparing something against itself.
  tree.all(:Expression).each do |expr|
    next if not comparisons.include? expr.op.to_s
    next if not expr.lhs.is_a? Nasl::Lvalue
    next if not expr.rhs.is_a? Nasl::Lvalue
    # Compare the XML representations of the two Lvalues.
    # Handles integer keys nicely, so these two are the same: a[0x01] == a[1]
    xmls = [:lhs, :rhs].map do |side|
      expr.send(side).to_xml(Builder::XmlMarkup.new)
    end
    next if xmls[0] != xmls[1]
    fail
    report(:error, "Comparing two identical Lvalues. This will always be TRUE.")
    report(:error, expr.op.context(expr))
  end
end
run() click to toggle source
# File lib/pedant/checks/nonsense_comparison.rb, line 84
def run
  # This check will pass by default.
  pass

  # Run this check on the tree from every file.
  @kb[:trees].each { |file, tree| check(file, tree) }
end