class Pedant::CheckScriptName

Public Class Methods

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

Public Instance Methods

run() click to toggle source
# File lib/pedant/checks/script_name.rb, line 33
def run
  # This check only applies to plugins.
  return skip unless @kb[:main].extname == '.nasl'

  sn_nodes = []
  tree = @kb[:trees][@kb[:main]]

  tree.all(:Call).each do |node|
    next unless node.name.ident.name == 'script_name'
    next unless node.name.indexes == []
    sn_nodes << node
  end

  if sn_nodes.length == 0
    report(:error, "Plugin does not call script_name() in the description.")
    return fail
  elsif sn_nodes.length > 1
    report(:error, "Plugin calls script_name() multiple times:")
    sn_nodes.each { |call| report(:error, call.context()) }
    return fail
  end

  sn_node = sn_nodes.first

  if sn_node.args.empty?
    report(:error, "script_name() was called with no arguments:\n#{sn_node.context()}")
    return fail
  end

  if sn_node.args.length > 1
    report(:error, "script_name() was called with too many arguments:\n#{sn_node.context()}")
    return fail
  end
    
  # Pull out argument
  type = sn_node.args.first.type
  param = sn_node.args.first.name
  arg = sn_node.args.first.expr

  if type == :anonymous
    report(
      :error,
      "script_name() was called using a positional parameter.\n" +
      "It requires using an argument to the 'english' named parameter.\n" +
      arg.context(sn_node)
    )
    return fail
  end

  if param.name != "english"
    report(
      :error,
      "script_name() was called using an invalid named parameter.\n" +
      "The 'english' named parameter must be used.\n" +
      param.context(sn_node)
    )
    return fail
  end
   
  unless arg.is_a? Nasl::String
    report(
      :error,
      "script_name() was called with the wrong type of argument. A string is required.\n" +
      arg.context(sn_node)
    )
    return fail
  end

  if arg.text.length == 0
    report(
      :error,
      "script_name() was called with an empty string.\n" +
      arg.context(sn_node)
    )
    return fail
  end

  if arg.text.slice(0) == " " && arg.text.slice(-1) == " "
    ws_error = "Script name has leading and trailing whitespace:\n"
  elsif arg.text.slice(0) == " "
    ws_error = "Script name has leading whitespace:\n"
  elsif arg.text.slice(-1) == " "
    ws_error = "Script name has trailing whitespace:\n"
  else
    ws_error = nil
  end
 
  unless ws_error.nil?
    report(
      :error,
      ws_error +
      arg.context(sn_node)
    )
    return fail
  end

  report(:info, "Plugin has a script name of '#{arg.text}':\n#{arg.context(sn_node)}")
  pass
end