class Arachni::Data::Issues

Stores and provides access to all logged {Issue}s.

@author Tasos “Zapotek” Laskos <tasos.laskos@arachni-scanner.com>

Attributes

collection[R]

@return [Hash{Integer=>Issue}]

Issues by their {Issue#digest}.
digests[R]

@return [Set<Integer>]

{Issue#digest}s.

Public Class Methods

load( directory ) click to toggle source
# File lib/arachni/data/issues.rb, line 181
def self.load( directory )
    issues = new

    Dir["#{directory}/issue_*"].each do |issue_file|
        issue = Marshal.load( IO.binread( issue_file ) )
        issues.collection[issue.digest] = issue
    end

    issues.digests.merge Marshal.load( IO.binread( "#{directory}/digests" ) )

    issues
end
new() click to toggle source
# File lib/arachni/data/issues.rb, line 34
def initialize
    super

    # Stores all issues with Issue#digest as the key as a way to deduplicate.
    @collection = {}

    # We also use this Set for deduplication in case #do_not_store has been
    # called.
    @digests = Set.new

    store
end

Public Instance Methods

<<( issue ) click to toggle source

@note Will deduplicate issues.

@param [Issue] issue

Issue to push to the collection.

@return [Issues]

`self`
# File lib/arachni/data/issues.rb, line 119
def <<( issue )
    notify_on_new_pre_deduplication( issue )

    return self if include?( issue )

    digest = issue.digest
    @digests << digest

    synchronize do
        notify_on_new( issue )

        if store?
            @collection[digest] = issue
        end
    end

    self
end
==( other ) click to toggle source
# File lib/arachni/data/issues.rb, line 194
def ==( other )
    hash == other.hash
end
[]( digest ) click to toggle source

@param [Integer] digest

{Issue#digest}

@return [Issue]

# File lib/arachni/data/issues.rb, line 141
def []( digest )
    @collection[digest]
end
all() click to toggle source

@return [Array<Issue>]

All logged issues.
# File lib/arachni/data/issues.rb, line 95
def all
    @collection.values
end
any?() click to toggle source
# File lib/arachni/data/issues.rb, line 159
def any?
    @collection.any?
end
clear() click to toggle source
# File lib/arachni/data/issues.rb, line 202
def clear
    @digests.clear
    @collection.clear
    clear_observers
end
do_not_store() click to toggle source

Disables issue storage via {#<<}.

@see store? @see <<

# File lib/arachni/data/issues.rb, line 88
def do_not_store
    @store = false
    self
end
dump( directory ) click to toggle source
# File lib/arachni/data/issues.rb, line 171
def dump( directory )
    FileUtils.mkdir_p( directory )

    @collection.each do |digest, issue|
        IO.binwrite( "#{directory}/issue_#{digest}", Marshal.dump( issue ) )
    end

    IO.binwrite( "#{directory}/digests", Marshal.dump( digests ) )
end
each( &block ) click to toggle source
# File lib/arachni/data/issues.rb, line 99
def each( &block )
    all.each( &block )
end
empty?() click to toggle source
# File lib/arachni/data/issues.rb, line 163
def empty?
    !any?
end
first() click to toggle source
# File lib/arachni/data/issues.rb, line 151
def first
    all.first
end
hash() click to toggle source
# File lib/arachni/data/issues.rb, line 198
def hash
    @digests.hash
end
include?( issue ) click to toggle source

@return [Bool]

`true` if `issue` is
# File lib/arachni/data/issues.rb, line 109
def include?( issue )
    @digests.include? issue.digest
end
last() click to toggle source
# File lib/arachni/data/issues.rb, line 155
def last
    all.last
end
map( &block ) click to toggle source
# File lib/arachni/data/issues.rb, line 103
def map( &block )
    all.map( &block )
end
size() click to toggle source
# File lib/arachni/data/issues.rb, line 167
def size
    @collection.size
end
sort() click to toggle source

@return [Array<Issue>]

Sorted array of {Issue}s.
# File lib/arachni/data/issues.rb, line 147
def sort
    all.sort_by(&:severity).reverse
end
statistics() click to toggle source
# File lib/arachni/data/issues.rb, line 47
def statistics
    by_severity = Hash.new(0)
    each { |issue| by_severity[issue.severity.to_sym] += 1 }

    by_type = Hash.new(0)
    each { |issue| by_type[issue.name] += 1 }

    by_check = Hash.new(0)
    each { |issue| by_check[issue.check[:shortname]] += 1 }

    {
        total:       size,
        by_severity: by_severity,
        by_type:     by_type,
        by_check:    by_check
    }
end
store() click to toggle source

Enables issue storage via {#<<}.

@see store? @see <<

# File lib/arachni/data/issues.rb, line 79
def store
    @store = true
    self
end
store?() click to toggle source

@note Defaults to ‘true`.

@return [Bool]

`true` if {#<<} is configured to store issues, `false` otherwise.

@see <<

# File lib/arachni/data/issues.rb, line 71
def store?
    @store
end