mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-13 16:45:56 +00:00
Unify fuzzer random number generation into a single class
BUG=tint:1098 Change-Id: I84931804515487d931bbbb5f0d5239d03ca76dfc Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/63300 Auto-Submit: Ryan Harrison <rharrison@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ryan Harrison <rharrison@chromium.org> Reviewed-by: Alastair Donaldson <afdx@google.com>
This commit is contained in:
parent
6a1eb45961
commit
5dc0ea7cce
@ -66,6 +66,8 @@ if (build_with_chromium) {
|
|||||||
]
|
]
|
||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
|
"random_generator.cc",
|
||||||
|
"random_generator.h",
|
||||||
"tint_common_fuzzer.cc",
|
"tint_common_fuzzer.cc",
|
||||||
"tint_common_fuzzer.h",
|
"tint_common_fuzzer.h",
|
||||||
]
|
]
|
||||||
|
@ -17,6 +17,8 @@ function(add_tint_fuzzer NAME)
|
|||||||
${NAME}.cc
|
${NAME}.cc
|
||||||
cli.cc
|
cli.cc
|
||||||
cli.h
|
cli.h
|
||||||
|
random_generator.cc
|
||||||
|
random_generator.h
|
||||||
tint_common_fuzzer.cc
|
tint_common_fuzzer.cc
|
||||||
tint_common_fuzzer.h
|
tint_common_fuzzer.h
|
||||||
tint_init_fuzzer.cc
|
tint_init_fuzzer.cc
|
||||||
|
89
fuzzers/random_generator.cc
Normal file
89
fuzzers/random_generator.cc
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// Copyright 2021 The Tint Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "fuzzers/random_generator.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace fuzzers {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
/// Generate integer from uniform distribution
|
||||||
|
/// @tparam I - integer type
|
||||||
|
/// @param engine - random number engine to use
|
||||||
|
/// @param lower - Lower bound of integer generated
|
||||||
|
/// @param upper - Upper bound of integer generated
|
||||||
|
/// @returns i, where lower <= i < upper
|
||||||
|
template <typename I>
|
||||||
|
I RandomUInt(std::mt19937* engine, I lower, I upper) {
|
||||||
|
assert(lower < upper && "|lower| must be stictly less than |upper|");
|
||||||
|
|
||||||
|
return std::uniform_int_distribution<I>(lower, upper - 1)(*engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
RandomGenerator::RandomGenerator(uint32_t seed) : engine_(seed) {}
|
||||||
|
|
||||||
|
uint32_t RandomGenerator::GetUInt32(uint32_t lower, uint32_t upper) {
|
||||||
|
return RandomUInt(&engine_, lower, upper);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RandomGenerator::GetUInt32(uint32_t bound) {
|
||||||
|
assert(bound > 0 && "|bound| must be greater than 0");
|
||||||
|
return RandomUInt(&engine_, 0u, bound);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t RandomGenerator::GetUInt64(uint64_t lower, uint64_t upper) {
|
||||||
|
return RandomUInt(&engine_, lower, upper);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t RandomGenerator::GetUInt64(uint64_t bound) {
|
||||||
|
assert(bound > 0 && "|bound| must be greater than 0");
|
||||||
|
return RandomUInt(&engine_, static_cast<uint64_t>(0), bound);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t RandomGenerator::GetByte() {
|
||||||
|
return std::independent_bits_engine<std::mt19937, 8, uint8_t>(engine_)();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t RandomGenerator::Get4Bytes() {
|
||||||
|
return std::independent_bits_engine<std::mt19937, 32, uint32_t>(engine_)();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> RandomGenerator::GetNBytes(size_t n) {
|
||||||
|
std::vector<uint8_t> result(n);
|
||||||
|
std::generate(
|
||||||
|
std::begin(result), std::end(result),
|
||||||
|
std::independent_bits_engine<std::mt19937, 8, uint8_t>(engine_));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RandomGenerator::GetBool() {
|
||||||
|
return RandomUInt(&engine_, 0u, 2u);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RandomGenerator::GetWeightedBool(uint32_t percentage) {
|
||||||
|
static const uint32_t kMaxPercentage = 100;
|
||||||
|
assert(percentage <= kMaxPercentage &&
|
||||||
|
"|percentage| needs to be within [0, 100]");
|
||||||
|
return RandomUInt(&engine_, 0u, kMaxPercentage) < percentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace fuzzers
|
||||||
|
} // namespace tint
|
87
fuzzers/random_generator.h
Normal file
87
fuzzers/random_generator.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// Copyright 2021 The Tint Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef FUZZERS_RANDOM_GENERATOR_H_
|
||||||
|
#define FUZZERS_RANDOM_GENERATOR_H_
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace fuzzers {
|
||||||
|
|
||||||
|
/// Pseudo random generator utility class for fuzzing
|
||||||
|
class RandomGenerator {
|
||||||
|
public:
|
||||||
|
/// @brief Initializes the internal engine
|
||||||
|
/// @param seed - seed value passed to engine
|
||||||
|
explicit RandomGenerator(uint32_t seed);
|
||||||
|
~RandomGenerator() {}
|
||||||
|
|
||||||
|
/// Get uint32_t value from uniform distribution.
|
||||||
|
/// @param lower - lower bound of integer generated
|
||||||
|
/// @param upper - upper bound of integer generated
|
||||||
|
/// @returns i, where lower <= i < upper
|
||||||
|
uint32_t GetUInt32(uint32_t lower, uint32_t upper);
|
||||||
|
|
||||||
|
/// Get uint32_t value from uniform distribution.
|
||||||
|
/// @param bound - Upper bound of integer generated
|
||||||
|
/// @returns i, where 0 <= i < bound
|
||||||
|
uint32_t GetUInt32(uint32_t bound);
|
||||||
|
|
||||||
|
/// Get uint32_t value from uniform distribution.
|
||||||
|
/// @param lower - lower bound of integer generated
|
||||||
|
/// @param upper - upper bound of integer generated
|
||||||
|
/// @returns i, where lower <= i < upper
|
||||||
|
uint64_t GetUInt64(uint64_t lower, uint64_t upper);
|
||||||
|
|
||||||
|
/// Get uint64_t value from uniform distribution.
|
||||||
|
/// @param bound - Upper bound of integer generated
|
||||||
|
/// @returns i, where 0 <= i < bound
|
||||||
|
uint64_t GetUInt64(uint64_t bound);
|
||||||
|
|
||||||
|
/// Get 1 byte of pseudo-random data
|
||||||
|
/// Should be more efficient then calling GetNBytes(1);
|
||||||
|
/// @returns 1-byte of random data
|
||||||
|
uint8_t GetByte();
|
||||||
|
|
||||||
|
/// Get 4 bytes of pseudo-random data
|
||||||
|
/// Should be more efficient then calling GetNBytes(4);
|
||||||
|
/// @returns 4-bytes of random data
|
||||||
|
uint32_t Get4Bytes();
|
||||||
|
|
||||||
|
/// Get N bytes of pseudo-random data
|
||||||
|
/// @param n - number of bytes of data to generate
|
||||||
|
/// @returns |N|-bytes of random data as vector
|
||||||
|
std::vector<uint8_t> GetNBytes(size_t n);
|
||||||
|
|
||||||
|
/// Get random bool with even odds
|
||||||
|
/// @returns true 50% of the time and false %50 of time.
|
||||||
|
bool GetBool();
|
||||||
|
|
||||||
|
/// Get random bool with weighted odds
|
||||||
|
/// @param percentage - likelihood of true being returned
|
||||||
|
/// @returns true |percentage|% of the time, and false (100 - |percentage|)%
|
||||||
|
/// of the time.
|
||||||
|
bool GetWeightedBool(uint32_t percentage);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mt19937 engine_;
|
||||||
|
|
||||||
|
}; // class RandomGenerator
|
||||||
|
|
||||||
|
} // namespace fuzzers
|
||||||
|
} // namespace tint
|
||||||
|
|
||||||
|
#endif // FUZZERS_RANDOM_GENERATOR_H_
|
@ -42,8 +42,6 @@ if (build_with_chromium) {
|
|||||||
"cli.cc",
|
"cli.cc",
|
||||||
"cli.h",
|
"cli.h",
|
||||||
"fuzzer.cc",
|
"fuzzer.cc",
|
||||||
"mt_rng.cc",
|
|
||||||
"mt_rng.h",
|
|
||||||
"mutation.cc",
|
"mutation.cc",
|
||||||
"mutation.h",
|
"mutation.h",
|
||||||
"mutation_finder.cc",
|
"mutation_finder.cc",
|
||||||
@ -60,8 +58,6 @@ if (build_with_chromium) {
|
|||||||
"probability_context.cc",
|
"probability_context.cc",
|
||||||
"probability_context.h",
|
"probability_context.h",
|
||||||
"protobufs/tint_ast_fuzzer.h",
|
"protobufs/tint_ast_fuzzer.h",
|
||||||
"random_number_generator.cc",
|
|
||||||
"random_number_generator.h",
|
|
||||||
"util.h",
|
"util.h",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ add_custom_command(
|
|||||||
COMMENT "Generate protobuf sources from proto definition file.")
|
COMMENT "Generate protobuf sources from proto definition file.")
|
||||||
|
|
||||||
set(LIBTINT_AST_FUZZER_SOURCES
|
set(LIBTINT_AST_FUZZER_SOURCES
|
||||||
mt_rng.h
|
../random_generator.h
|
||||||
mutation.h
|
mutation.h
|
||||||
mutation_finder.h
|
mutation_finder.h
|
||||||
mutation_finders/replace_identifiers.h
|
mutation_finders/replace_identifiers.h
|
||||||
@ -44,12 +44,11 @@ set(LIBTINT_AST_FUZZER_SOURCES
|
|||||||
node_id_map.h
|
node_id_map.h
|
||||||
probability_context.h
|
probability_context.h
|
||||||
protobufs/tint_ast_fuzzer.h
|
protobufs/tint_ast_fuzzer.h
|
||||||
random_number_generator.h
|
|
||||||
util.h
|
util.h
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.h)
|
${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.h)
|
||||||
|
|
||||||
set(LIBTINT_AST_FUZZER_SOURCES ${LIBTINT_AST_FUZZER_SOURCES}
|
set(LIBTINT_AST_FUZZER_SOURCES ${LIBTINT_AST_FUZZER_SOURCES}
|
||||||
mt_rng.cc
|
../random_generator.cc
|
||||||
mutation.cc
|
mutation.cc
|
||||||
mutation_finder.cc
|
mutation_finder.cc
|
||||||
mutation_finders/replace_identifiers.cc
|
mutation_finders/replace_identifiers.cc
|
||||||
@ -57,7 +56,6 @@ set(LIBTINT_AST_FUZZER_SOURCES ${LIBTINT_AST_FUZZER_SOURCES}
|
|||||||
mutator.cc
|
mutator.cc
|
||||||
node_id_map.cc
|
node_id_map.cc
|
||||||
probability_context.cc
|
probability_context.cc
|
||||||
random_number_generator.cc
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.cc)
|
${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.cc)
|
||||||
|
|
||||||
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.cc PROPERTIES COMPILE_FLAGS -w)
|
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.cc PROPERTIES COMPILE_FLAGS -w)
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "fuzzers/random_generator.h"
|
||||||
#include "fuzzers/tint_ast_fuzzer/cli.h"
|
#include "fuzzers/tint_ast_fuzzer/cli.h"
|
||||||
#include "fuzzers/tint_ast_fuzzer/mt_rng.h"
|
|
||||||
#include "fuzzers/tint_ast_fuzzer/mutator.h"
|
#include "fuzzers/tint_ast_fuzzer/mutator.h"
|
||||||
#include "fuzzers/tint_ast_fuzzer/override_cli_params.h"
|
#include "fuzzers/tint_ast_fuzzer/override_cli_params.h"
|
||||||
#include "fuzzers/tint_common_fuzzer.h"
|
#include "fuzzers/tint_common_fuzzer.h"
|
||||||
@ -54,8 +54,8 @@ extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run the mutator.
|
// Run the mutator.
|
||||||
MtRng mt_rng(seed);
|
RandomGenerator generator(seed);
|
||||||
ProbabilityContext probability_context(&mt_rng);
|
ProbabilityContext probability_context(&generator);
|
||||||
program = Mutate(std::move(program), &probability_context,
|
program = Mutate(std::move(program), &probability_context,
|
||||||
cli_params.enable_all_mutations,
|
cli_params.enable_all_mutations,
|
||||||
cli_params.mutation_batch_size, nullptr);
|
cli_params.mutation_batch_size, nullptr);
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
// Copyright 2021 The Tint Authors.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "fuzzers/tint_ast_fuzzer/mt_rng.h"
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
namespace tint {
|
|
||||||
namespace fuzzers {
|
|
||||||
namespace ast_fuzzer {
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T RandomUInt(std::mt19937* rng, T bound) {
|
|
||||||
assert(bound > 0 && "`bound` must be positive");
|
|
||||||
return std::uniform_int_distribution<T>(0, bound - 1)(*rng);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
MtRng::MtRng(uint32_t seed) : rng_(seed) {}
|
|
||||||
|
|
||||||
uint32_t MtRng::RandomUint32(uint32_t bound) {
|
|
||||||
return RandomUInt(&rng_, bound);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t MtRng::RandomUint64(uint64_t bound) {
|
|
||||||
return RandomUInt(&rng_, bound);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ast_fuzzer
|
|
||||||
} // namespace fuzzers
|
|
||||||
} // namespace tint
|
|
@ -1,45 +0,0 @@
|
|||||||
// Copyright 2021 The Tint Authors.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#ifndef FUZZERS_TINT_AST_FUZZER_MT_RNG_H_
|
|
||||||
#define FUZZERS_TINT_AST_FUZZER_MT_RNG_H_
|
|
||||||
|
|
||||||
#include <random>
|
|
||||||
|
|
||||||
#include "fuzzers/tint_ast_fuzzer/random_number_generator.h"
|
|
||||||
|
|
||||||
namespace tint {
|
|
||||||
namespace fuzzers {
|
|
||||||
namespace ast_fuzzer {
|
|
||||||
|
|
||||||
/// The random number generator that uses STL's Mersenne Twister (std::mt19937)
|
|
||||||
/// under the hood.
|
|
||||||
class MtRng : public RandomNumberGenerator {
|
|
||||||
public:
|
|
||||||
/// @brief Initializes this RNG with some `seed`.
|
|
||||||
/// @param seed - passed down to the `std::mt19937`.
|
|
||||||
explicit MtRng(uint32_t seed);
|
|
||||||
|
|
||||||
uint32_t RandomUint32(uint32_t bound) override;
|
|
||||||
uint64_t RandomUint64(uint64_t bound) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::mt19937 rng_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ast_fuzzer
|
|
||||||
} // namespace fuzzers
|
|
||||||
} // namespace tint
|
|
||||||
|
|
||||||
#endif // FUZZERS_TINT_AST_FUZZER_MT_RNG_H_
|
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
#include "fuzzers/tint_ast_fuzzer/mt_rng.h"
|
|
||||||
#include "fuzzers/tint_ast_fuzzer/mutations/replace_identifier.h"
|
#include "fuzzers/tint_ast_fuzzer/mutations/replace_identifier.h"
|
||||||
#include "fuzzers/tint_ast_fuzzer/mutator.h"
|
#include "fuzzers/tint_ast_fuzzer/mutator.h"
|
||||||
#include "fuzzers/tint_ast_fuzzer/probability_context.h"
|
#include "fuzzers/tint_ast_fuzzer/probability_context.h"
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#include "fuzzers/tint_ast_fuzzer/node_id_map.h"
|
#include "fuzzers/tint_ast_fuzzer/node_id_map.h"
|
||||||
#include "fuzzers/tint_ast_fuzzer/probability_context.h"
|
#include "fuzzers/tint_ast_fuzzer/probability_context.h"
|
||||||
#include "fuzzers/tint_ast_fuzzer/protobufs/tint_ast_fuzzer.h"
|
#include "fuzzers/tint_ast_fuzzer/protobufs/tint_ast_fuzzer.h"
|
||||||
#include "fuzzers/tint_ast_fuzzer/random_number_generator.h"
|
|
||||||
|
|
||||||
#include "src/program.h"
|
#include "src/program.h"
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
#include "fuzzers/tint_ast_fuzzer/probability_context.h"
|
#include "fuzzers/tint_ast_fuzzer/probability_context.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace fuzzers {
|
namespace fuzzers {
|
||||||
namespace ast_fuzzer {
|
namespace ast_fuzzer {
|
||||||
@ -23,15 +25,18 @@ const std::pair<uint32_t, uint32_t> kChanceOfReplacingIdentifiers = {30, 70};
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ProbabilityContext::ProbabilityContext(RandomNumberGenerator* rng)
|
ProbabilityContext::ProbabilityContext(RandomGenerator* generator)
|
||||||
: rng_(rng),
|
: generator_(generator),
|
||||||
chance_of_replacing_identifiers_(
|
chance_of_replacing_identifiers_(
|
||||||
RandomFromRange(kChanceOfReplacingIdentifiers)) {}
|
RandomFromRange(kChanceOfReplacingIdentifiers)) {
|
||||||
|
assert(generator != nullptr && "generator must not be nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t ProbabilityContext::RandomFromRange(
|
uint32_t ProbabilityContext::RandomFromRange(
|
||||||
std::pair<uint32_t, uint32_t> range) {
|
std::pair<uint32_t, uint32_t> range) {
|
||||||
assert(range.first <= range.second && "Range must be non-decreasing");
|
assert(range.first <= range.second && "Range must be non-decreasing");
|
||||||
return range.first + rng_->RandomUint32(range.second - range.first + 1);
|
return generator_->GetUInt32(
|
||||||
|
range.first, range.second + 1); // + 1 need since range is inclusive.
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ast_fuzzer
|
} // namespace ast_fuzzer
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "fuzzers/tint_ast_fuzzer/random_number_generator.h"
|
#include "fuzzers/random_generator.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace fuzzers {
|
namespace fuzzers {
|
||||||
@ -29,16 +29,21 @@ namespace ast_fuzzer {
|
|||||||
class ProbabilityContext {
|
class ProbabilityContext {
|
||||||
public:
|
public:
|
||||||
/// Initializes this instance with a random number generator.
|
/// Initializes this instance with a random number generator.
|
||||||
/// @param rng - may not be a `nullptr`. Must remain in scope as long as this
|
/// @param generator - must not be a `nullptr`. Must remain in scope as long
|
||||||
|
/// as this
|
||||||
/// instance exists.
|
/// instance exists.
|
||||||
explicit ProbabilityContext(RandomNumberGenerator* rng);
|
explicit ProbabilityContext(RandomGenerator* generator);
|
||||||
|
|
||||||
/// @copydoc RandomNumberGenerator::RandomBool
|
/// Get random bool with even odds
|
||||||
bool RandomBool() { return rng_->RandomBool(); }
|
/// @returns true 50% of the time and false %50 of time.
|
||||||
|
bool RandomBool() { return generator_->GetBool(); }
|
||||||
|
|
||||||
/// @copydoc RandomNumberGenerator::ChoosePercentage
|
/// Get random bool with weighted odds
|
||||||
|
/// @param percentage - likelihood of true being returned
|
||||||
|
/// @returns true |percentage|% of the time, and false (100 - |percentage|)%
|
||||||
|
/// of the time.
|
||||||
bool ChoosePercentage(uint32_t percentage) {
|
bool ChoosePercentage(uint32_t percentage) {
|
||||||
return rng_->ChoosePercentage(percentage);
|
return generator_->GetWeightedBool(percentage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a random value in the range `[0; arr.size())`.
|
/// Returns a random value in the range `[0; arr.size())`.
|
||||||
@ -47,7 +52,7 @@ class ProbabilityContext {
|
|||||||
/// @return the random index in the `arr`.
|
/// @return the random index in the `arr`.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
size_t GetRandomIndex(const std::vector<T>& arr) {
|
size_t GetRandomIndex(const std::vector<T>& arr) {
|
||||||
return static_cast<size_t>(rng_->RandomUint64(arr.size()));
|
return static_cast<size_t>(generator_->GetUInt64(arr.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @return the probability of replacing some identifier with some other one.
|
/// @return the probability of replacing some identifier with some other one.
|
||||||
@ -60,7 +65,7 @@ class ProbabilityContext {
|
|||||||
/// @return an random number in the range `[a; b]`.
|
/// @return an random number in the range `[a; b]`.
|
||||||
uint32_t RandomFromRange(std::pair<uint32_t, uint32_t> range);
|
uint32_t RandomFromRange(std::pair<uint32_t, uint32_t> range);
|
||||||
|
|
||||||
RandomNumberGenerator* rng_;
|
RandomGenerator* generator_;
|
||||||
|
|
||||||
uint32_t chance_of_replacing_identifiers_;
|
uint32_t chance_of_replacing_identifiers_;
|
||||||
};
|
};
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
// Copyright 2021 The Tint Authors.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include "fuzzers/tint_ast_fuzzer/random_number_generator.h"
|
|
||||||
|
|
||||||
namespace tint {
|
|
||||||
namespace fuzzers {
|
|
||||||
namespace ast_fuzzer {
|
|
||||||
|
|
||||||
RandomNumberGenerator::~RandomNumberGenerator() = default;
|
|
||||||
|
|
||||||
bool RandomNumberGenerator::RandomBool() {
|
|
||||||
return RandomUint32(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RandomNumberGenerator::ChoosePercentage(uint32_t percentage) {
|
|
||||||
assert(percentage <= 100 && "|percentage| is invalid");
|
|
||||||
// 100 is used as a bound instead of 101 because otherwise it would be
|
|
||||||
// possible to return `false` when `percentage == 100` holds. This would
|
|
||||||
// happen when the result of `RandomUint32` is 100 as well.
|
|
||||||
return RandomUint32(100) < percentage;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ast_fuzzer
|
|
||||||
} // namespace fuzzers
|
|
||||||
} // namespace tint
|
|
@ -1,57 +0,0 @@
|
|||||||
// Copyright 2021 The Tint Authors.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#ifndef FUZZERS_TINT_AST_FUZZER_RANDOM_NUMBER_GENERATOR_H_
|
|
||||||
#define FUZZERS_TINT_AST_FUZZER_RANDOM_NUMBER_GENERATOR_H_
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace tint {
|
|
||||||
namespace fuzzers {
|
|
||||||
namespace ast_fuzzer {
|
|
||||||
|
|
||||||
/// Abstracts away the underlying algorithm that is used to generate random
|
|
||||||
/// numbers.
|
|
||||||
class RandomNumberGenerator {
|
|
||||||
public:
|
|
||||||
/// Virtual destructor.
|
|
||||||
virtual ~RandomNumberGenerator();
|
|
||||||
|
|
||||||
/// @brief Compute a random `uint32_t` value in the range `[0; bound)`.
|
|
||||||
/// @param bound - the upper exclusive bound for the computed integer
|
|
||||||
/// (must be positive).
|
|
||||||
/// @return the random number.
|
|
||||||
virtual uint32_t RandomUint32(uint32_t bound) = 0;
|
|
||||||
|
|
||||||
/// @brief Compute a random `uint64_t` value in the range `[0; bound)`.
|
|
||||||
/// @param bound - the upper exclusive bound for the computed integer
|
|
||||||
/// (must be positive).
|
|
||||||
/// @return the random number.
|
|
||||||
virtual uint64_t RandomUint64(uint64_t bound) = 0;
|
|
||||||
|
|
||||||
/// @return a randomly generated boolean value.
|
|
||||||
bool RandomBool();
|
|
||||||
|
|
||||||
/// @param percentage - must be in the range `[0; 100]`.
|
|
||||||
/// @return `true` with `percentage` probability.
|
|
||||||
bool ChoosePercentage(uint32_t percentage);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ast_fuzzer
|
|
||||||
} // namespace fuzzers
|
|
||||||
} // namespace tint
|
|
||||||
|
|
||||||
#endif // FUZZERS_TINT_AST_FUZZER_RANDOM_NUMBER_GENERATOR_H_
|
|
@ -21,7 +21,8 @@ function(add_tint_regex_fuzzer NAME)
|
|||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
set(LIBTINT_REGEX_FUZZER_SOURCES
|
set(LIBTINT_REGEX_FUZZER_SOURCES
|
||||||
util.h
|
../random_generator.cc
|
||||||
|
../random_generator.h
|
||||||
wgsl_mutator.cc
|
wgsl_mutator.cc
|
||||||
wgsl_mutator.h)
|
wgsl_mutator.h)
|
||||||
|
|
||||||
|
@ -16,12 +16,11 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "fuzzers/random_generator.h"
|
||||||
#include "fuzzers/tint_common_fuzzer.h"
|
#include "fuzzers/tint_common_fuzzer.h"
|
||||||
#include "fuzzers/tint_regex_fuzzer/cli.h"
|
#include "fuzzers/tint_regex_fuzzer/cli.h"
|
||||||
#include "fuzzers/tint_regex_fuzzer/override_cli_params.h"
|
#include "fuzzers/tint_regex_fuzzer/override_cli_params.h"
|
||||||
#include "fuzzers/tint_regex_fuzzer/util.h"
|
|
||||||
#include "fuzzers/tint_regex_fuzzer/wgsl_mutator.h"
|
#include "fuzzers/tint_regex_fuzzer/wgsl_mutator.h"
|
||||||
|
|
||||||
#include "src/reader/wgsl/parser.h"
|
#include "src/reader/wgsl/parser.h"
|
||||||
#include "src/writer/wgsl/generator.h"
|
#include "src/writer/wgsl/generator.h"
|
||||||
|
|
||||||
@ -57,13 +56,13 @@ extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data,
|
|||||||
unsigned seed) {
|
unsigned seed) {
|
||||||
std::string wgsl_code(data, data + size);
|
std::string wgsl_code(data, data + size);
|
||||||
const std::vector<std::string> delimiters{";"};
|
const std::vector<std::string> delimiters{";"};
|
||||||
std::mt19937 generator(seed);
|
RandomGenerator generator(seed);
|
||||||
|
|
||||||
std::string delimiter =
|
std::string delimiter =
|
||||||
delimiters[GetRandomIntFromRange(0, delimiters.size() - 1, generator)];
|
delimiters[generator.GetUInt64(delimiters.size() - 1u)];
|
||||||
|
|
||||||
MutationKind mutation_kind = static_cast<MutationKind>(GetRandomIntFromRange(
|
MutationKind mutation_kind = static_cast<MutationKind>(generator.GetUInt64(
|
||||||
0, static_cast<size_t>(MutationKind::kNumMutationKinds) - 1, generator));
|
static_cast<size_t>(MutationKind::kNumMutationKinds) - 1u));
|
||||||
|
|
||||||
switch (mutation_kind) {
|
switch (mutation_kind) {
|
||||||
case MutationKind::kSwapIntervals:
|
case MutationKind::kSwapIntervals:
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
// Copyright 2021 The Tint Authors.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#ifndef FUZZERS_TINT_REGEX_FUZZER_UTIL_H_
|
|
||||||
#define FUZZERS_TINT_REGEX_FUZZER_UTIL_H_
|
|
||||||
|
|
||||||
#include <random>
|
|
||||||
|
|
||||||
namespace tint {
|
|
||||||
namespace fuzzers {
|
|
||||||
namespace regex_fuzzer {
|
|
||||||
|
|
||||||
inline size_t GetRandomIntFromRange(size_t lower_bound,
|
|
||||||
size_t upper_bound,
|
|
||||||
std::mt19937& generator) {
|
|
||||||
std::uniform_int_distribution<size_t> dist(lower_bound, upper_bound);
|
|
||||||
return dist(generator);
|
|
||||||
}
|
|
||||||
} // namespace regex_fuzzer
|
|
||||||
} // namespace fuzzers
|
|
||||||
} // namespace tint
|
|
||||||
#endif // FUZZERS_TINT_REGEX_FUZZER_UTIL_H_
|
|
@ -17,13 +17,12 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <random>
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "fuzzers/tint_regex_fuzzer/util.h"
|
#include "fuzzers/random_generator.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace fuzzers {
|
namespace fuzzers {
|
||||||
@ -137,7 +136,7 @@ void ReplaceInterval(size_t start_index,
|
|||||||
|
|
||||||
bool SwapRandomIntervals(const std::string& delimiter,
|
bool SwapRandomIntervals(const std::string& delimiter,
|
||||||
std::string& wgsl_code,
|
std::string& wgsl_code,
|
||||||
std::mt19937& generator) {
|
RandomGenerator& generator) {
|
||||||
std::vector<size_t> delimiter_positions =
|
std::vector<size_t> delimiter_positions =
|
||||||
FindDelimiterIndices(delimiter, wgsl_code);
|
FindDelimiterIndices(delimiter, wgsl_code);
|
||||||
|
|
||||||
@ -148,14 +147,10 @@ bool SwapRandomIntervals(const std::string& delimiter,
|
|||||||
|
|
||||||
// When generating the i-th random number, we should make sure that there are
|
// When generating the i-th random number, we should make sure that there are
|
||||||
// at least (3-i) numbers greater than this number.
|
// at least (3-i) numbers greater than this number.
|
||||||
size_t ind1 =
|
size_t ind1 = generator.GetUInt64(delimiter_positions.size() - 3u);
|
||||||
GetRandomIntFromRange(0, delimiter_positions.size() - 3U, generator);
|
size_t ind2 = generator.GetUInt64(ind1 + 1u, delimiter_positions.size() - 2u);
|
||||||
size_t ind2 = GetRandomIntFromRange(
|
size_t ind3 = generator.GetUInt64(ind2, delimiter_positions.size() - 2u);
|
||||||
ind1 + 1U, delimiter_positions.size() - 2U, generator);
|
size_t ind4 = generator.GetUInt64(ind3 + 1u, delimiter_positions.size() - 1u);
|
||||||
size_t ind3 =
|
|
||||||
GetRandomIntFromRange(ind2, delimiter_positions.size() - 2U, generator);
|
|
||||||
size_t ind4 = GetRandomIntFromRange(
|
|
||||||
ind3 + 1U, delimiter_positions.size() - 1U, generator);
|
|
||||||
|
|
||||||
SwapIntervals(delimiter_positions[ind1],
|
SwapIntervals(delimiter_positions[ind1],
|
||||||
delimiter_positions[ind2] - delimiter_positions[ind1],
|
delimiter_positions[ind2] - delimiter_positions[ind1],
|
||||||
@ -168,7 +163,7 @@ bool SwapRandomIntervals(const std::string& delimiter,
|
|||||||
|
|
||||||
bool DeleteRandomInterval(const std::string& delimiter,
|
bool DeleteRandomInterval(const std::string& delimiter,
|
||||||
std::string& wgsl_code,
|
std::string& wgsl_code,
|
||||||
std::mt19937& generator) {
|
RandomGenerator& generator) {
|
||||||
std::vector<size_t> delimiter_positions =
|
std::vector<size_t> delimiter_positions =
|
||||||
FindDelimiterIndices(delimiter, wgsl_code);
|
FindDelimiterIndices(delimiter, wgsl_code);
|
||||||
|
|
||||||
@ -177,10 +172,8 @@ bool DeleteRandomInterval(const std::string& delimiter,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ind1 =
|
size_t ind1 = generator.GetUInt64(delimiter_positions.size() - 2u);
|
||||||
GetRandomIntFromRange(0, delimiter_positions.size() - 2U, generator);
|
size_t ind2 = generator.GetUInt64(ind1 + 1u, delimiter_positions.size() - 1u);
|
||||||
size_t ind2 = GetRandomIntFromRange(
|
|
||||||
ind1 + 1U, delimiter_positions.size() - 1U, generator);
|
|
||||||
|
|
||||||
DeleteInterval(delimiter_positions[ind1],
|
DeleteInterval(delimiter_positions[ind1],
|
||||||
delimiter_positions[ind2] - delimiter_positions[ind1],
|
delimiter_positions[ind2] - delimiter_positions[ind1],
|
||||||
@ -191,7 +184,7 @@ bool DeleteRandomInterval(const std::string& delimiter,
|
|||||||
|
|
||||||
bool DuplicateRandomInterval(const std::string& delimiter,
|
bool DuplicateRandomInterval(const std::string& delimiter,
|
||||||
std::string& wgsl_code,
|
std::string& wgsl_code,
|
||||||
std::mt19937& generator) {
|
RandomGenerator& generator) {
|
||||||
std::vector<size_t> delimiter_positions =
|
std::vector<size_t> delimiter_positions =
|
||||||
FindDelimiterIndices(delimiter, wgsl_code);
|
FindDelimiterIndices(delimiter, wgsl_code);
|
||||||
|
|
||||||
@ -200,13 +193,9 @@ bool DuplicateRandomInterval(const std::string& delimiter,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ind1 =
|
size_t ind1 = generator.GetUInt64(delimiter_positions.size() - 2u);
|
||||||
GetRandomIntFromRange(0, delimiter_positions.size() - 2U, generator);
|
size_t ind2 = generator.GetUInt64(ind1 + 1u, delimiter_positions.size() - 1u);
|
||||||
size_t ind2 = GetRandomIntFromRange(
|
size_t ind3 = generator.GetUInt64(delimiter_positions.size() - 1u);
|
||||||
ind1 + 1U, delimiter_positions.size() - 1U, generator);
|
|
||||||
|
|
||||||
size_t ind3 =
|
|
||||||
GetRandomIntFromRange(0, delimiter_positions.size() - 1U, generator);
|
|
||||||
|
|
||||||
DuplicateInterval(delimiter_positions[ind1],
|
DuplicateInterval(delimiter_positions[ind1],
|
||||||
delimiter_positions[ind2] - delimiter_positions[ind1],
|
delimiter_positions[ind2] - delimiter_positions[ind1],
|
||||||
@ -215,7 +204,8 @@ bool DuplicateRandomInterval(const std::string& delimiter,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReplaceRandomIdentifier(std::string& wgsl_code, std::mt19937& generator) {
|
bool ReplaceRandomIdentifier(std::string& wgsl_code,
|
||||||
|
RandomGenerator& generator) {
|
||||||
std::vector<std::pair<size_t, size_t>> identifiers =
|
std::vector<std::pair<size_t, size_t>> identifiers =
|
||||||
GetIdentifiers(wgsl_code);
|
GetIdentifiers(wgsl_code);
|
||||||
|
|
||||||
@ -224,15 +214,12 @@ bool ReplaceRandomIdentifier(std::string& wgsl_code, std::mt19937& generator) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t id1_index =
|
size_t id1_index = generator.GetUInt64(identifiers.size() - 1u);
|
||||||
GetRandomIntFromRange(0, identifiers.size() - 1U, generator);
|
size_t id2_index = generator.GetUInt64(identifiers.size() - 1u);
|
||||||
|
|
||||||
size_t id2_index =
|
|
||||||
GetRandomIntFromRange(0, identifiers.size() - 1U, generator);
|
|
||||||
|
|
||||||
// The two identifiers must be different
|
// The two identifiers must be different
|
||||||
while (id1_index == id2_index) {
|
while (id1_index == id2_index) {
|
||||||
id2_index = GetRandomIntFromRange(0, identifiers.size() - 1U, generator);
|
id2_index = generator.GetUInt64(identifiers.size() - 1u);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReplaceRegion(identifiers[id1_index].first, identifiers[id1_index].second,
|
ReplaceRegion(identifiers[id1_index].first, identifiers[id1_index].second,
|
||||||
@ -242,7 +229,8 @@ bool ReplaceRandomIdentifier(std::string& wgsl_code, std::mt19937& generator) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReplaceRandomIntLiteral(std::string& wgsl_code, std::mt19937& generator) {
|
bool ReplaceRandomIntLiteral(std::string& wgsl_code,
|
||||||
|
RandomGenerator& generator) {
|
||||||
std::vector<std::pair<size_t, size_t>> literals = GetIntLiterals(wgsl_code);
|
std::vector<std::pair<size_t, size_t>> literals = GetIntLiterals(wgsl_code);
|
||||||
|
|
||||||
// Need at least one integer literal
|
// Need at least one integer literal
|
||||||
@ -250,14 +238,13 @@ bool ReplaceRandomIntLiteral(std::string& wgsl_code, std::mt19937& generator) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t id1_index = GetRandomIntFromRange(0, literals.size() - 1U, generator);
|
size_t id1_index = generator.GetUInt64(literals.size() - 1u);
|
||||||
|
|
||||||
// INT_MAX = 2147483647, INT_MIN = -2147483648
|
// INT_MAX = 2147483647, INT_MIN = -2147483648
|
||||||
std::vector<std::string> boundary_values = {
|
std::vector<std::string> boundary_values = {
|
||||||
"2147483647", "-2147483648", "1", "-1", "0", "4294967295"};
|
"2147483647", "-2147483648", "1", "-1", "0", "4294967295"};
|
||||||
|
|
||||||
size_t boundary_index =
|
size_t boundary_index = generator.GetUInt64(boundary_values.size() - 1u);
|
||||||
GetRandomIntFromRange(0, boundary_values.size() - 1U, generator);
|
|
||||||
|
|
||||||
ReplaceInterval(literals[id1_index].first, literals[id1_index].second,
|
ReplaceInterval(literals[id1_index].first, literals[id1_index].second,
|
||||||
boundary_values[boundary_index], wgsl_code);
|
boundary_values[boundary_index], wgsl_code);
|
||||||
|
@ -15,11 +15,12 @@
|
|||||||
#ifndef FUZZERS_TINT_REGEX_FUZZER_WGSL_MUTATOR_H_
|
#ifndef FUZZERS_TINT_REGEX_FUZZER_WGSL_MUTATOR_H_
|
||||||
#define FUZZERS_TINT_REGEX_FUZZER_WGSL_MUTATOR_H_
|
#define FUZZERS_TINT_REGEX_FUZZER_WGSL_MUTATOR_H_
|
||||||
|
|
||||||
#include <random>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fuzzers/random_generator.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace fuzzers {
|
namespace fuzzers {
|
||||||
namespace regex_fuzzer {
|
namespace regex_fuzzer {
|
||||||
@ -114,7 +115,7 @@ void ReplaceInterval(size_t start_index,
|
|||||||
/// @return true if a swap happened or false otherwise.
|
/// @return true if a swap happened or false otherwise.
|
||||||
bool SwapRandomIntervals(const std::string& delimiter,
|
bool SwapRandomIntervals(const std::string& delimiter,
|
||||||
std::string& wgsl_code,
|
std::string& wgsl_code,
|
||||||
std::mt19937& generator);
|
RandomGenerator& generator);
|
||||||
|
|
||||||
/// A function that, given a WGSL-like string and a delimiter,
|
/// A function that, given a WGSL-like string and a delimiter,
|
||||||
/// generates another WGSL-like string by deleting a random
|
/// generates another WGSL-like string by deleting a random
|
||||||
@ -125,7 +126,7 @@ bool SwapRandomIntervals(const std::string& delimiter,
|
|||||||
/// @return true if a deletion happened or false otherwise.
|
/// @return true if a deletion happened or false otherwise.
|
||||||
bool DeleteRandomInterval(const std::string& delimiter,
|
bool DeleteRandomInterval(const std::string& delimiter,
|
||||||
std::string& wgsl_code,
|
std::string& wgsl_code,
|
||||||
std::mt19937& generator);
|
RandomGenerator& generator);
|
||||||
|
|
||||||
/// A function that, given a WGSL-like string and a delimiter,
|
/// A function that, given a WGSL-like string and a delimiter,
|
||||||
/// generates another WGSL-like string by duplicating a random
|
/// generates another WGSL-like string by duplicating a random
|
||||||
@ -136,20 +137,22 @@ bool DeleteRandomInterval(const std::string& delimiter,
|
|||||||
/// @return true if a duplication happened or false otherwise.
|
/// @return true if a duplication happened or false otherwise.
|
||||||
bool DuplicateRandomInterval(const std::string& delimiter,
|
bool DuplicateRandomInterval(const std::string& delimiter,
|
||||||
std::string& wgsl_code,
|
std::string& wgsl_code,
|
||||||
std::mt19937& generator);
|
RandomGenerator& generator);
|
||||||
|
|
||||||
/// Replaces a randomly-chosen identifier in wgsl_code.
|
/// Replaces a randomly-chosen identifier in wgsl_code.
|
||||||
/// @param wgsl_code - WGSL-like string where the replacement will occur.
|
/// @param wgsl_code - WGSL-like string where the replacement will occur.
|
||||||
/// @param generator - the random number generator.
|
/// @param generator - the random number generator.
|
||||||
/// @return true if a replacement happened or false otherwise.
|
/// @return true if a replacement happened or false otherwise.
|
||||||
bool ReplaceRandomIdentifier(std::string& wgsl_code, std::mt19937& generator);
|
bool ReplaceRandomIdentifier(std::string& wgsl_code,
|
||||||
|
RandomGenerator& generator);
|
||||||
|
|
||||||
/// Replaces the value of a randomly-chosen integer with one of
|
/// Replaces the value of a randomly-chosen integer with one of
|
||||||
/// the values in the set {INT_MAX, INT_MIN, 0, -1}.
|
/// the values in the set {INT_MAX, INT_MIN, 0, -1}.
|
||||||
/// @param wgsl_code - WGSL-like string where the replacement will occur.
|
/// @param wgsl_code - WGSL-like string where the replacement will occur.
|
||||||
/// @param generator - the random number generator.
|
/// @param generator - the random number generator.
|
||||||
/// @return true if a replacement happened or false otherwise.
|
/// @return true if a replacement happened or false otherwise.
|
||||||
bool ReplaceRandomIntLiteral(std::string& wgsl_code, std::mt19937& generator);
|
bool ReplaceRandomIntLiteral(std::string& wgsl_code,
|
||||||
|
RandomGenerator& generator);
|
||||||
|
|
||||||
} // namespace regex_fuzzer
|
} // namespace regex_fuzzer
|
||||||
} // namespace fuzzers
|
} // namespace fuzzers
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
set(FUZZER_SOURCES
|
set(FUZZER_SOURCES
|
||||||
|
../random_generator.cc
|
||||||
cli.cc
|
cli.cc
|
||||||
fuzzer.cc
|
fuzzer.cc
|
||||||
mutator.cc
|
mutator.cc
|
||||||
@ -23,6 +24,7 @@ set(FUZZER_SOURCES
|
|||||||
util.cc)
|
util.cc)
|
||||||
|
|
||||||
set(FUZZER_SOURCES ${FUZZER_SOURCES}
|
set(FUZZER_SOURCES ${FUZZER_SOURCES}
|
||||||
|
../random_generator.h
|
||||||
cli.h
|
cli.h
|
||||||
mutator.h
|
mutator.h
|
||||||
mutator_cache.h
|
mutator_cache.h
|
||||||
@ -32,8 +34,8 @@ set(FUZZER_SOURCES ${FUZZER_SOURCES}
|
|||||||
util.h)
|
util.h)
|
||||||
|
|
||||||
set(FUZZER_SOURCES ${FUZZER_SOURCES}
|
set(FUZZER_SOURCES ${FUZZER_SOURCES}
|
||||||
../tint_common_fuzzer.h
|
../tint_common_fuzzer.cc
|
||||||
../tint_common_fuzzer.cc)
|
../tint_common_fuzzer.h)
|
||||||
|
|
||||||
function(configure_spirv_tools_fuzzer_target NAME SOURCES)
|
function(configure_spirv_tools_fuzzer_target NAME SOURCES)
|
||||||
add_executable(${NAME} ${SOURCES})
|
add_executable(${NAME} ${SOURCES})
|
||||||
@ -61,6 +63,7 @@ target_compile_definitions(tint_spirv_tools_fuzzer PRIVATE TARGET_FUZZER)
|
|||||||
target_link_libraries(tint_spirv_tools_fuzzer libtint-fuzz)
|
target_link_libraries(tint_spirv_tools_fuzzer libtint-fuzz)
|
||||||
|
|
||||||
set(DEBUGGER_SOURCES
|
set(DEBUGGER_SOURCES
|
||||||
|
../random_generator.cc
|
||||||
cli.cc
|
cli.cc
|
||||||
mutator.cc
|
mutator.cc
|
||||||
mutator_debugger.cc
|
mutator_debugger.cc
|
||||||
@ -70,6 +73,7 @@ set(DEBUGGER_SOURCES
|
|||||||
util.cc)
|
util.cc)
|
||||||
|
|
||||||
set(DEBUGGER_SOURCES ${DEBUGGER_SOURCES}
|
set(DEBUGGER_SOURCES ${DEBUGGER_SOURCES}
|
||||||
|
../random_generator.h
|
||||||
cli.h
|
cli.h
|
||||||
mutator.h
|
mutator.h
|
||||||
spirv_fuzz_mutator.h
|
spirv_fuzz_mutator.h
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <random>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fuzzers/random_generator.h"
|
||||||
#include "fuzzers/tint_common_fuzzer.h"
|
#include "fuzzers/tint_common_fuzzer.h"
|
||||||
#include "fuzzers/tint_spirv_tools_fuzzer/cli.h"
|
#include "fuzzers/tint_spirv_tools_fuzzer/cli.h"
|
||||||
#include "fuzzers/tint_spirv_tools_fuzzer/mutator_cache.h"
|
#include "fuzzers/tint_spirv_tools_fuzzer/mutator_cache.h"
|
||||||
@ -67,9 +67,8 @@ std::unique_ptr<Mutator> CreateMutator(const std::vector<uint32_t>& binary,
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(!types.empty() && "At least one mutator type must be specified");
|
assert(!types.empty() && "At least one mutator type must be specified");
|
||||||
std::mt19937 rng(seed);
|
RandomGenerator generator(seed);
|
||||||
auto mutator_type =
|
auto mutator_type = types[generator.GetUInt64(types.size())];
|
||||||
types[std::uniform_int_distribution<size_t>(0, types.size() - 1)(rng)];
|
|
||||||
|
|
||||||
const auto& mutator_params = context->params.mutator_params;
|
const auto& mutator_params = context->params.mutator_params;
|
||||||
switch (mutator_type) {
|
switch (mutator_type) {
|
||||||
|
@ -66,7 +66,7 @@ SpirvOptMutator::SpirvOptMutator(spv_target_env target_env,
|
|||||||
optimized_binary_(),
|
optimized_binary_(),
|
||||||
validate_after_each_opt_(validate_after_each_opt),
|
validate_after_each_opt_(validate_after_each_opt),
|
||||||
opt_batch_size_(opt_batch_size),
|
opt_batch_size_(opt_batch_size),
|
||||||
rng_(seed) {
|
generator_(seed) {
|
||||||
assert(spvtools::SpirvTools(target_env).Validate(original_binary_) &&
|
assert(spvtools::SpirvTools(target_env).Validate(original_binary_) &&
|
||||||
"Initial binary is invalid");
|
"Initial binary is invalid");
|
||||||
assert(!opt_passes_.empty() && "Must be at least one pass");
|
assert(!opt_passes_.empty() && "Must be at least one pass");
|
||||||
@ -105,8 +105,7 @@ SpirvOptMutator::Result SpirvOptMutator::Mutate() {
|
|||||||
std::vector<std::string> passes;
|
std::vector<std::string> passes;
|
||||||
|
|
||||||
while (passes.size() < num_of_passes) {
|
while (passes.size() < num_of_passes) {
|
||||||
auto idx = std::uniform_int_distribution<size_t>(
|
auto idx = generator_.GetUInt64(opt_passes_.size());
|
||||||
0, opt_passes_.size() - 1)(rng_);
|
|
||||||
passes.push_back(opt_passes_[idx]);
|
passes.push_back(opt_passes_[idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,11 +15,11 @@
|
|||||||
#ifndef FUZZERS_TINT_SPIRV_TOOLS_FUZZER_SPIRV_OPT_MUTATOR_H_
|
#ifndef FUZZERS_TINT_SPIRV_TOOLS_FUZZER_SPIRV_OPT_MUTATOR_H_
|
||||||
#define FUZZERS_TINT_SPIRV_TOOLS_FUZZER_SPIRV_OPT_MUTATOR_H_
|
#define FUZZERS_TINT_SPIRV_TOOLS_FUZZER_SPIRV_OPT_MUTATOR_H_
|
||||||
|
|
||||||
#include <random>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fuzzers/random_generator.h"
|
||||||
#include "fuzzers/tint_spirv_tools_fuzzer/mutator.h"
|
#include "fuzzers/tint_spirv_tools_fuzzer/mutator.h"
|
||||||
#include "spirv-tools/libspirv.h"
|
#include "spirv-tools/libspirv.h"
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ class SpirvOptMutator : public Mutator {
|
|||||||
std::stringstream errors_;
|
std::stringstream errors_;
|
||||||
|
|
||||||
// The random number generator initialized with `seed_`.
|
// The random number generator initialized with `seed_`.
|
||||||
std::mt19937 rng_;
|
RandomGenerator generator_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace spvtools_fuzzer
|
} // namespace spvtools_fuzzer
|
||||||
|
@ -44,7 +44,7 @@ SpirvReduceMutator::SpirvReduceMutator(spv_target_env target_env,
|
|||||||
bool validate_after_each_reduction)
|
bool validate_after_each_reduction)
|
||||||
: ir_context_(nullptr),
|
: ir_context_(nullptr),
|
||||||
finders_(),
|
finders_(),
|
||||||
rng_(seed),
|
generator_(seed),
|
||||||
errors_(),
|
errors_(),
|
||||||
is_valid_(true),
|
is_valid_(true),
|
||||||
reductions_batch_size_(reductions_batch_size),
|
reductions_batch_size_(reductions_batch_size),
|
||||||
|
@ -16,12 +16,12 @@
|
|||||||
#define FUZZERS_TINT_SPIRV_TOOLS_FUZZER_SPIRV_REDUCE_MUTATOR_H_
|
#define FUZZERS_TINT_SPIRV_TOOLS_FUZZER_SPIRV_REDUCE_MUTATOR_H_
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <random>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "fuzzers/random_generator.h"
|
||||||
#include "fuzzers/tint_spirv_tools_fuzzer/mutator.h"
|
#include "fuzzers/tint_spirv_tools_fuzzer/mutator.h"
|
||||||
|
|
||||||
#include "source/reduce/reduction_opportunity_finder.h"
|
#include "source/reduce/reduction_opportunity_finder.h"
|
||||||
@ -65,7 +65,7 @@ class SpirvReduceMutator : public Mutator {
|
|||||||
private:
|
private:
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
void MaybeAddFinder(Args&&... args) {
|
void MaybeAddFinder(Args&&... args) {
|
||||||
if (enable_all_reductions_ || std::uniform_int_distribution<>(0, 1)(rng_)) {
|
if (enable_all_reductions_ || generator_.GetBool()) {
|
||||||
finders_.push_back(std::make_unique<T>(std::forward<Args>(args)...));
|
finders_.push_back(std::make_unique<T>(std::forward<Args>(args)...));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,16 +73,14 @@ class SpirvReduceMutator : public Mutator {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
T* GetRandomElement(std::vector<T>* arr) {
|
T* GetRandomElement(std::vector<T>* arr) {
|
||||||
assert(!arr->empty() && "Can't get random element from an empty vector");
|
assert(!arr->empty() && "Can't get random element from an empty vector");
|
||||||
auto index =
|
auto index = generator_.GetUInt64(arr->size());
|
||||||
std::uniform_int_distribution<size_t>(0, arr->size() - 1)(rng_);
|
|
||||||
return &(*arr)[index];
|
return &(*arr)[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T* GetRandomElement(std::vector<std::unique_ptr<T>>* arr) {
|
T* GetRandomElement(std::vector<std::unique_ptr<T>>* arr) {
|
||||||
assert(!arr->empty() && "Can't get random element from an empty vector");
|
assert(!arr->empty() && "Can't get random element from an empty vector");
|
||||||
auto index =
|
auto index = generator_.GetUInt64(arr->size());
|
||||||
std::uniform_int_distribution<size_t>(0, arr->size() - 1)(rng_);
|
|
||||||
return (*arr)[index].get();
|
return (*arr)[index].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +95,7 @@ class SpirvReduceMutator : public Mutator {
|
|||||||
finders_;
|
finders_;
|
||||||
|
|
||||||
// Random number generator initialized with `seed_`.
|
// Random number generator initialized with `seed_`.
|
||||||
std::mt19937 rng_;
|
RandomGenerator generator_;
|
||||||
|
|
||||||
// All the errors produced by the reducer.
|
// All the errors produced by the reducer.
|
||||||
std::stringstream errors_;
|
std::stringstream errors_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user