class Pedant::CheckFilesParseWithoutErrors

Public Class Methods

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

Public Instance Methods

import(path) click to toggle source
# File lib/pedant/checks/files_parse_without_errors.rb, line 38
def import(path)
  # All files should be relative to the main file's base in practice.
  path = @kb[:base] + path

  # Since there are potentially several ways to write the path leading to
  # a file, we'll use the basename as the key for hashes. This will
  # prevent parsing the same file multiple times.
  file = path.basename

  # Mark a placeholder key in the KB for this file. This will prevent us
  # from trying to parse a library more than once if there is a failure.
  @kb[:codes][file] = :pending
  @kb[:trees][file] = :pending

  begin
    contents = File.open(path, "rb").read
    @kb[:codes][file] = contents
    report(:info, "Read contents of #{path}.")
  rescue
    report(:error, "Failed to read contents of #{path}.")
    return fatal
  end

  begin
    tree = Nasl::Parser.new.parse(contents, path)
    @kb[:trees][file] = tree
    report(:info, "Parsed contents of #{path}.")
  rescue Nasl::ParseException, Nasl::TokenException => e
    report(:error, "Failed to parse #{path}.")
    report(:error, e.message)
    report(:error, e.backtrace)
    return fatal
  end
end
run() click to toggle source
# File lib/pedant/checks/files_parse_without_errors.rb, line 37
def run
  def import(path)
    # All files should be relative to the main file's base in practice.
    path = @kb[:base] + path

    # Since there are potentially several ways to write the path leading to
    # a file, we'll use the basename as the key for hashes. This will
    # prevent parsing the same file multiple times.
    file = path.basename

    # Mark a placeholder key in the KB for this file. This will prevent us
    # from trying to parse a library more than once if there is a failure.
    @kb[:codes][file] = :pending
    @kb[:trees][file] = :pending

    begin
      contents = File.open(path, "rb").read
      @kb[:codes][file] = contents
      report(:info, "Read contents of #{path}.")
    rescue
      report(:error, "Failed to read contents of #{path}.")
      return fatal
    end

    begin
      tree = Nasl::Parser.new.parse(contents, path)
      @kb[:trees][file] = tree
      report(:info, "Parsed contents of #{path}.")
    rescue Nasl::ParseException, Nasl::TokenException => e
      report(:error, "Failed to parse #{path}.")
      report(:error, e.message)
      report(:error, e.backtrace)
      return fatal
    end
  end

  # This check will pass by default.
  pass

  # Initialize the keys written by this check.
  @kb[:codes] = {}
  @kb[:trees] = {}

  # Load up the main file.
  import(@kb[:main])

  return

  while true
    # Get the list of all Includes, and prune any that have already had the
    # files they reference parsed.
    libs = Nasl::Include.all.map do |inc|
      (@kb[:base] + inc.filename.text).basename
    end

    libs.delete_if { |lib| lib == @kb[:main] || @kb[:trees].has_key?(lib) }

    break if libs.empty?

    # Try and parse each library, continuing on failures.
    libs.each { |lib| import(lib) }
  end
end