fuzzer: Implement BuildImpl for msl/hlsl Options structs
The default implementation of this was generating random data for
the underlying pointers of std::unordered_map, leading to crashes
when the map was accessed. This CL populates the map in a
structured manner with pseudo-random data.
Bug: chromium:1273001
Change-Id: Ic20ecab85bedba2a59587ebe4a5016be6e53e6f8
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/70701
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/fuzzers/data_builder.h b/fuzzers/data_builder.h
index 39625ef..a931fe0 100644
--- a/fuzzers/data_builder.h
+++ b/fuzzers/data_builder.h
@@ -18,9 +18,12 @@
#include <cassert>
#include <functional>
#include <string>
+#include <unordered_map>
#include <vector>
#include "fuzzers/random_generator.h"
+#include "src/writer/hlsl/generator.h"
+#include "src/writer/msl/generator.h"
namespace tint {
namespace fuzzers {
@@ -106,6 +109,14 @@
generator_.GetNBytes(reinterpret_cast<uint8_t*>(out), n);
}
+ /// Generate pseudo-random data of a specific type into an output var
+ /// @tparam T - type of data to produce
+ /// @param out - output var to generate into
+ template <typename T>
+ void build(T& out) {
+ out = build<T>();
+ }
+
/// Implementation of ::build<T>()
/// @tparam T - type of data to produce
template <typename T>
@@ -145,6 +156,70 @@
/// @returns a boolean with even odds of being true or false
static bool impl(DataBuilder* b) { return b->generator_.GetBool(); }
};
+
+ /// Specialization for writer::msl::Options
+ template <>
+ struct BuildImpl<writer::msl::Options> {
+ /// Generate a pseudo-random writer::msl::Options struct
+ /// @param b - data builder to use
+ /// @returns writer::msl::Options filled with pseudo-random data
+ static writer::msl::Options impl(DataBuilder* b) {
+ writer::msl::Options out{};
+ b->build(out.buffer_size_ubo_index);
+ b->build(out.fixed_sample_mask);
+ b->build(out.emit_vertex_point_size);
+ b->build(out.disable_workgroup_init);
+ b->build(out.array_length_from_uniform);
+ return out;
+ }
+ };
+
+ /// Specialization for writer::hlsl::Options
+ template <>
+ struct BuildImpl<writer::hlsl::Options> {
+ /// Generate a pseudo-random writer::hlsl::Options struct
+ /// @param b - data builder to use
+ /// @returns writer::hlsl::Options filled with pseudo-random data
+ static writer::hlsl::Options impl(DataBuilder* b) {
+ writer::hlsl::Options out{};
+ b->build(out.root_constant_binding_point);
+ b->build(out.disable_workgroup_init);
+ b->build(out.array_length_from_uniform);
+ return out;
+ }
+ };
+
+ /// Specialization for writer::ArrayLengthFromUniformOptions
+ template <>
+ struct BuildImpl<writer::ArrayLengthFromUniformOptions> {
+ /// Generate a pseudo-random writer::ArrayLengthFromUniformOptions struct
+ /// @param b - data builder to use
+ /// @returns writer::ArrayLengthFromUniformOptions filled with pseudo-random
+ /// data
+ static writer::ArrayLengthFromUniformOptions impl(DataBuilder* b) {
+ writer::ArrayLengthFromUniformOptions out{};
+ b->build(out.ubo_binding);
+ b->build(out.bindpoint_to_size_index);
+ return out;
+ }
+ };
+
+ /// Specialization for std::unordered_map<K, V>
+ template <typename K, typename V>
+ struct BuildImpl<std::unordered_map<K, V>> {
+ /// Generate a pseudo-random std::unordered_map<K, V>
+ /// @param b - data builder to use
+ /// @returns std::unordered_map<K, V> filled with
+ /// pseudo-random data
+ static std::unordered_map<K, V> impl(DataBuilder* b) {
+ std::unordered_map<K, V> out;
+ uint8_t count = b->build<uint8_t>();
+ for (uint8_t i = 0; i < count; ++i) {
+ out.emplace(b->build<K>(), b->build<V>());
+ }
+ return out;
+ }
+ };
};
} // namespace fuzzers
diff --git a/src/writer/array_length_from_uniform_options.h b/src/writer/array_length_from_uniform_options.h
index ae92d4f..2c06287 100644
--- a/src/writer/array_length_from_uniform_options.h
+++ b/src/writer/array_length_from_uniform_options.h
@@ -44,6 +44,9 @@
/// The mapping from storage buffer binding points to the index into the
/// uniform buffer where the length of the buffer is stored.
std::unordered_map<sem::BindingPoint, uint32_t> bindpoint_to_size_index;
+
+ // NOTE: Update fuzzers/data_builder.h when adding or changing any struct
+ // members.
};
} // namespace writer
diff --git a/src/writer/hlsl/generator.h b/src/writer/hlsl/generator.h
index 4dacbd4..4013cfa 100644
--- a/src/writer/hlsl/generator.h
+++ b/src/writer/hlsl/generator.h
@@ -56,6 +56,9 @@
/// Options used to specify a mapping of binding points to indices into a UBO
/// from which to load buffer sizes.
ArrayLengthFromUniformOptions array_length_from_uniform = {};
+
+ // NOTE: Update fuzzers/data_builder.h when adding or changing any struct
+ // members.
};
/// The result produced when generating HLSL.
diff --git a/src/writer/msl/generator.h b/src/writer/msl/generator.h
index 63d7939..7f8f92f 100644
--- a/src/writer/msl/generator.h
+++ b/src/writer/msl/generator.h
@@ -64,6 +64,9 @@
/// Options used to specify a mapping of binding points to indices into a UBO
/// from which to load buffer sizes.
ArrayLengthFromUniformOptions array_length_from_uniform = {};
+
+ // NOTE: Update fuzzers/data_builder.h when adding or changing any struct
+ // members.
};
/// The result produced when generating MSL.