mirror of
https://github.com/claunia/flac.git
synced 2025-12-16 18:54:26 +00:00
oss-fuzz: Add fuzzing headers
These includes header files were taken from:
https://github.com/guidovranken/fuzzing-headers.git
with some minor changes required to make them compile cleanly
with the extra compiler warning flags used by the FLAC build
system.
This commit is contained in:
167
oss-fuzz/fuzzing/datasource/datasource.hpp
Normal file
167
oss-fuzz/fuzzing/datasource/datasource.hpp
Normal file
@@ -0,0 +1,167 @@
|
||||
#pragma once
|
||||
|
||||
#include <fuzzing/exception.hpp>
|
||||
#include <fuzzing/types.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace fuzzing {
|
||||
namespace datasource {
|
||||
|
||||
class Base
|
||||
{
|
||||
protected:
|
||||
virtual std::vector<uint8_t> get(const size_t min, const size_t max, const uint64_t id = 0) = 0;
|
||||
public:
|
||||
Base(void) = default;
|
||||
virtual ~Base(void) = default;
|
||||
|
||||
template<class T> T Get(const uint64_t id = 0);
|
||||
uint16_t GetChoice(const uint64_t id = 0);
|
||||
std::vector<uint8_t> GetData(const uint64_t id, const size_t min = 0, const size_t max = 0);
|
||||
template <class T> std::vector<T> GetVector(const uint64_t id = 0);
|
||||
|
||||
class OutOfData : public fuzzing::exception::FlowException {
|
||||
public:
|
||||
OutOfData() = default;
|
||||
};
|
||||
|
||||
class DeserializationFailure : public fuzzing::exception::FlowException {
|
||||
public:
|
||||
DeserializationFailure() = default;
|
||||
};
|
||||
};
|
||||
|
||||
#ifndef FUZZING_HEADERS_NO_IMPL
|
||||
template<class T> T Base::Get(const uint64_t id)
|
||||
{
|
||||
T ret;
|
||||
const auto v = get(sizeof(ret), sizeof(ret), id);
|
||||
memcpy(&ret, v.data(), sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <> bool Base::Get<bool>(const uint64_t id)
|
||||
{
|
||||
uint8_t ret;
|
||||
const auto v = get(sizeof(ret), sizeof(ret), id);
|
||||
memcpy(&ret, v.data(), sizeof(ret));
|
||||
return (ret % 2) ? true : false;
|
||||
}
|
||||
|
||||
template <> std::string Base::Get<std::string>(const uint64_t id)
|
||||
{
|
||||
auto data = GetData(id);
|
||||
return std::string(data.data(), data.data() + data.size());
|
||||
}
|
||||
|
||||
template <> std::vector<std::string> Base::Get<std::vector<std::string>>(const uint64_t id)
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
while ( true ) {
|
||||
auto data = GetData(id);
|
||||
ret.push_back( std::string(data.data(), data.data() + data.size()) );
|
||||
if ( Get<bool>(id) == false ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint16_t Base::GetChoice(const uint64_t id)
|
||||
{
|
||||
return Get<uint16_t>(id);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Base::GetData(const uint64_t id, const size_t min, const size_t max)
|
||||
{
|
||||
return get(min, max, id);
|
||||
}
|
||||
|
||||
|
||||
template <> types::String<> Base::Get<types::String<>>(const uint64_t id) {
|
||||
const auto data = GetData(id);
|
||||
types::String<> ret(data.data(), data.size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <> types::Data<> Base::Get<types::Data<>>(const uint64_t id) {
|
||||
const auto data = GetData(id);
|
||||
types::Data<> ret(data.data(), data.size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::vector<T> Base::GetVector(const uint64_t id) {
|
||||
std::vector<T> ret;
|
||||
|
||||
while ( Get<bool>(id) == true ) {
|
||||
ret.push_back( Get<T>(id) );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
class Datasource : public Base
|
||||
{
|
||||
private:
|
||||
const uint8_t* data;
|
||||
const size_t size;
|
||||
size_t idx;
|
||||
size_t left;
|
||||
std::vector<uint8_t> get(const size_t min, const size_t max, const uint64_t id = 0) override;
|
||||
|
||||
// Make copy constructor and assignment opertator private.
|
||||
Datasource(const Datasource &) : data(0), size(0), idx(0), left(0) {}
|
||||
Datasource& operator=(const Datasource &) { return *this; }
|
||||
public:
|
||||
Datasource(const uint8_t* _data, const size_t _size);
|
||||
};
|
||||
|
||||
#ifndef FUZZING_HEADERS_NO_IMPL
|
||||
Datasource::Datasource(const uint8_t* _data, const size_t _size) :
|
||||
Base(), data(_data), size(_size), idx(0), left(size)
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Datasource::get(const size_t min, const size_t max, const uint64_t id) {
|
||||
(void)id;
|
||||
|
||||
uint32_t getSize;
|
||||
if ( left < sizeof(getSize) ) {
|
||||
throw OutOfData();
|
||||
}
|
||||
memcpy(&getSize, data + idx, sizeof(getSize));
|
||||
idx += sizeof(getSize);
|
||||
left -= sizeof(getSize);
|
||||
|
||||
if ( getSize < min ) {
|
||||
getSize = min;
|
||||
}
|
||||
if ( max && getSize > max ) {
|
||||
getSize = max;
|
||||
}
|
||||
|
||||
if ( left < getSize ) {
|
||||
throw OutOfData();
|
||||
}
|
||||
|
||||
std::vector<uint8_t> ret(getSize);
|
||||
|
||||
if ( getSize > 0 ) {
|
||||
memcpy(ret.data(), data + idx, getSize);
|
||||
}
|
||||
idx += getSize;
|
||||
left -= getSize;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
} /* namespace datasource */
|
||||
} /* namespace fuzzing */
|
||||
52
oss-fuzz/fuzzing/datasource/id.hpp
Normal file
52
oss-fuzz/fuzzing/datasource/id.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <utility>
|
||||
#include <map>
|
||||
|
||||
namespace fuzzing {
|
||||
namespace datasource {
|
||||
|
||||
/* From: https://gist.github.com/underscorediscovery/81308642d0325fd386237cfa3b44785c */
|
||||
inline uint64_t hash_64_fnv1a(const void* key, const uint64_t len) {
|
||||
|
||||
const char* data = (char*)key;
|
||||
uint64_t hash = 0xcbf29ce484222325;
|
||||
uint64_t prime = 0x100000001b3;
|
||||
|
||||
for(uint64_t i = 0; i < len; ++i) {
|
||||
uint8_t value = data[i];
|
||||
hash = hash ^ value;
|
||||
hash *= prime;
|
||||
}
|
||||
|
||||
return hash;
|
||||
|
||||
} //hash_64_fnv1a
|
||||
|
||||
// FNV1a c++11 constexpr compile time hash functions, 32 and 64 bit
|
||||
// str should be a null terminated string literal, value should be left out
|
||||
// e.g hash_32_fnv1a_const("example")
|
||||
// code license: public domain or equivalent
|
||||
// post: https://notes.underscorediscovery.com/constexpr-fnv1a/
|
||||
|
||||
constexpr uint32_t val_32_const = 0x811c9dc5;
|
||||
constexpr uint32_t prime_32_const = 0x1000193;
|
||||
constexpr uint64_t val_64_const = 0xcbf29ce484222325;
|
||||
constexpr uint64_t prime_64_const = 0x100000001b3;
|
||||
|
||||
|
||||
inline constexpr uint64_t ID(const char* const str, const uint64_t value = val_64_const) noexcept {
|
||||
auto ret = (str[0] == '\0') ? value : ID(&str[1], (value ^ uint64_t(str[0])) * prime_64_const);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline constexpr std::pair<const char*, uint64_t> IDPair(const char* const str, const uint64_t value = val_64_const) noexcept {
|
||||
return {str, ID(str, value)};
|
||||
}
|
||||
|
||||
using IDMap = std::map<const char*, uint64_t>;
|
||||
|
||||
} /* namespace datasource */
|
||||
} /* namespace fuzzing */
|
||||
Reference in New Issue
Block a user