Class: Ibex::Fuzz

Inherits:
Object
  • Object
show all
Defined in:
lib/ibex/fuzz.rb

Overview

Bounded grammar-derived differential fuzzing without semantic execution.

Defined Under Namespace

Classes: BudgetExceeded, Mismatch

Constant Summary collapse

ALGORITHMS =

: Array

%i[slr lalr ielr lr1].freeze
DEFAULT_MAX_ACTIONS =

: Integer

100_000
DEFAULT_MAX_STACK =

: Integer

10_000

Instance Method Summary collapse

Constructor Details

#initialize(grammar, seed: 0, count: 100, max_tokens: 32, max_depth: 16, max_expansions: Samples::DEFAULT_MAX_EXPANSIONS, max_actions: DEFAULT_MAX_ACTIONS, max_stack: DEFAULT_MAX_STACK, coverage_guided: false, path_length: 2, algorithms: ALGORITHMS, ielr_strategy: :partition, automata: nil, against: nil, against_description: nil) ⇒ Fuzz

rubocop:disable Metrics/ParameterLists

Raises:

  • (ArgumentError)


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/ibex/fuzz.rb', line 57

def initialize(grammar, seed: 0, count: 100, max_tokens: 32, max_depth: 16,
               max_expansions: Samples::DEFAULT_MAX_EXPANSIONS, max_actions: DEFAULT_MAX_ACTIONS,
               max_stack: DEFAULT_MAX_STACK, coverage_guided: false, path_length: 2,
               algorithms: ALGORITHMS, ielr_strategy: :partition, automata: nil,
               against: nil, against_description: nil)
  raise ArgumentError, "count must be positive" unless count.positive?
  raise ArgumentError, "algorithms must not be empty" if algorithms.empty?
  unless LALR::Builder::IELR_STRATEGIES.include?(ielr_strategy.to_sym)
    raise ArgumentError, "unknown IELR construction strategy #{ielr_strategy.inspect}"
  end

  @grammar = grammar
  @seed = seed
  @count = count
  @random = Random.new(seed ^ 0x1BE)
  @max_tokens = max_tokens
  @max_depth = max_depth
  @max_expansions = max_expansions
  @max_actions = max_actions
  @max_stack = max_stack
  @coverage_guided = coverage_guided
  @path_length = path_length
  @algorithms = algorithms.map(&:to_sym).freeze
  @ielr_strategy = ielr_strategy.to_sym
  @automata = automata || build_automata
  @against = against
  @against_description = against_description
end

Instance Method Details

#minimize(mismatch, max_trials: 1_000) ⇒ Object

Minimize one observed mismatch without changing its kind or outcomes.



110
111
112
113
114
115
116
117
118
119
# File 'lib/ibex/fuzz.rb', line 110

def minimize(mismatch, max_trials: 1_000)
  details = mismatch.details
  original = details[:tokens]
  kind = details[:kind].to_sym
  sentence = details[:sentence]
  outcomes = details[:outcomes]
  DeltaReducer.new(max_trials: max_trials).minimize(original) do |candidate|
    mismatch_reproduced?(candidate, kind: kind, sentence: sentence, outcomes: outcomes)
  end
end

#runObject



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/ibex/fuzz.rb', line 88

def run
  sentences = generate_sentences
  mutation_count = 0
  sentences.each_with_index do |tokens, index|
    compare!(tokens, kind: :generated, sentence: index)
    mutations(tokens).each do |mutation|
      compare!(mutation, kind: :mutation, sentence: index)
      mutation_count += 1
    end
  end
  successful_report(sentences.length, mutation_count)
rescue Ibex::Error => e
  raise if e.is_a?(Mismatch) || e.is_a?(BudgetExceeded) || !budget_error?(e)

  raise BudgetExceeded.new(
    message: e.message,
    bounds: { max_expansions: @max_expansions, max_actions: @max_actions, max_stack: @max_stack }
  )
end