/*
* Copyright 2016 The Android Open Source Project
*
* 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 __VTS_PROTO_FUZZER_MUTATOR_H_
#define __VTS_PROTO_FUZZER_MUTATOR_H_
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
#include "ProtoFuzzerRunner.h"
#include "ProtoFuzzerUtils.h"
namespace android {
namespace vts {
namespace fuzzer {
using BiasedRandomScalarGen = std::function<uint64_t(Random &rand)>;
using Odds = std::pair<uint64_t, uint64_t>;
using VarMutateFn = std::function<VarInstance(const VarInstance &)>;
using VarRandomGenFn = std::function<VarInstance(const VarSpec &)>;
using VarTransformFn = std::function<VariableSpecificationMessage(
const VariableSpecificationMessage &)>;
// Encapsulates heuristic strategy for biased mutation/random generation.
struct ProtoFuzzerMutatorConfig {
// Generates biased random scalars.
BiasedRandomScalarGen scalar_bias_ = [](Random &rand) { return rand.Rand(); };
// Used to decide if enum will be mutated/generated like a scalar.
Odds enum_bias_ = {0, 1};
// Odds that a function in an execution is mutated rather than regenerated.
Odds func_mutated_ = {100, 1};
// Default size used to randomly generate a vector.
size_t default_vector_size_ = 64;
// Default size used to randomly generate a string.
size_t default_string_size_ = 16;
};
// Provides methods for mutation or random generation.
class ProtoFuzzerMutator {
public:
ProtoFuzzerMutator(Random &, std::unordered_map<std::string, TypeSpec>,
ProtoFuzzerMutatorConfig);
// Generates a random ExecSpec.
ExecSpec RandomGen(const IfaceDescTbl &, size_t);
// Mutates in-place an ExecSpec.
void Mutate(const IfaceDescTbl &, ExecSpec *);
// Generates a random FuncSpec.
FuncSpec RandomGen(const FuncSpec &);
// Mutates a FuncSpec.
FuncSpec Mutate(const FuncSpec &);
// Generates a random VarInstance.
VarInstance RandomGen(const VarSpec &);
// Mutates a VarInstance.
VarInstance Mutate(const VarInstance &);
private:
// Randomly selects an interface.
const CompSpec *RandomSelectIface(const IfaceDescTbl &);
// Used for mutation/random generation of VarInstance.
VarInstance ArrayRandomGen(const VarSpec &);
VarInstance ArrayMutate(const VarInstance &);
VarInstance EnumRandomGen(const VarSpec &);
VarInstance EnumMutate(const VarInstance &);
VarInstance ScalarRandomGen(const VarSpec &);
VarInstance ScalarMutate(const VarInstance &);
VarInstance StringRandomGen(const VarSpec &);
VarInstance StringMutate(const VarInstance &);
VarInstance StructRandomGen(const VarSpec &);
VarInstance StructMutate(const VarInstance &);
VarInstance UnionRandomGen(const VarSpec &);
VarInstance UnionMutate(const VarInstance &);
VarInstance VectorRandomGen(const VarSpec &);
VarInstance VectorMutate(const VarInstance &);
// Used for mutation/random generation of ScalarData.
ScalarData RandomGen(const ScalarData &, const std::string &);
ScalarData Mutate(const ScalarData &, const string &);
// Used for mutation/random generation of variables of fundamental data types
// e.g. char, int, double.
template <typename T>
T RandomGen(T);
template <typename T>
T Mutate(T);
bool RandomGen(bool);
bool Mutate(bool);
float Mutate(float);
double Mutate(double);
// Generates a random ASCII character.
char RandomAsciiChar();
// Looks up predefined type by name.
const TypeSpec &FindPredefinedType(std::string);
// 64-bit random number generator.
Random &rand_;
// Used to look up definition of a predefined type by its name.
std::unordered_map<std::string, TypeSpec> predefined_types_;
// Used to delegate mutation/random generation of VariableSpecifationMessage
// of different VariableType to mutation/random delegation function for that
// VariableType.
std::unordered_map<VariableType, VarMutateFn> mutate_fns_;
std::unordered_map<VariableType, VarRandomGenFn> random_gen_fns_;
// Used for biased mutation/random generation of variables.
ProtoFuzzerMutatorConfig mutator_config_;
};
} // namespace fuzzer
} // namespace vts
} // namespace android
#endif // __VTS_PROTO_FUZZER_MUTATOR__