summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2024-05-23 16:06:19 -0700
committerGitHub <noreply@github.com>2024-05-23 16:06:19 -0700
commit9b61eb3ab9c9f7d87140acf8a0c43c5b965773dc (patch)
tree32644530f45fedfff39676c5b8e04203f47a7c17 /src
parent06cbe01f2774955ed3f23994b3ea1db58e43a4d8 (diff)
downloadbinaryen-9b61eb3ab9c9f7d87140acf8a0c43c5b965773dc.tar.gz
binaryen-9b61eb3ab9c9f7d87140acf8a0c43c5b965773dc.tar.bz2
binaryen-9b61eb3ab9c9f7d87140acf8a0c43c5b965773dc.zip
Fix fuzzer generation of a DataSegment + add validation that would have caught it (#6626)
The DataSegment was manually added to .dataSegments, but we need to add it using addDataSegment so the maps are updated and getDataSegment(name) works. Also add validation that would have caught this earlier: check that each item in the item lists can be fetched by name.
Diffstat (limited to 'src')
-rw-r--r--src/tools/fuzzing/fuzzing.cpp7
-rw-r--r--src/wasm/wasm-validator.cpp58
2 files changed, 60 insertions, 5 deletions
diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp
index f4f059deb..57c7ec6b0 100644
--- a/src/tools/fuzzing/fuzzing.cpp
+++ b/src/tools/fuzzing/fuzzing.cpp
@@ -224,13 +224,14 @@ void TranslateToFuzzReader::setupMemory() {
auto segment = builder.makeDataSegment();
segment->memory = memory->name;
segment->offset = builder.makeConst(int32_t(0));
- segment->setName(Name::fromInt(0), false);
- wasm.dataSegments.push_back(std::move(segment));
+ segment->setName(Names::getValidDataSegmentName(wasm, Name::fromInt(0)),
+ false);
auto num = upTo(USABLE_MEMORY * 2);
for (size_t i = 0; i < num; i++) {
auto value = upTo(512);
- wasm.dataSegments[0]->data.push_back(value >= 256 ? 0 : (value & 0xff));
+ segment->data.push_back(value >= 256 ? 0 : (value & 0xff));
}
+ wasm.addDataSegment(std::move(segment));
}
}
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index e8a4033ef..689872a19 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -3908,7 +3908,7 @@ static void validateTags(Module& module, ValidationInfo& info) {
}
}
-static void validateModule(Module& module, ValidationInfo& info) {
+static void validateStart(Module& module, ValidationInfo& info) {
// start
if (module.start.is()) {
auto func = module.getFunctionOrNull(module.start);
@@ -3924,6 +3924,59 @@ static void validateModule(Module& module, ValidationInfo& info) {
}
}
+namespace {
+template<typename T, typename U>
+void validateModuleMap(Module& module,
+ ValidationInfo& info,
+ T& list,
+ U getter,
+ const std::string& kind) {
+ // Given a list of module elements (like exports or globals), see that we can
+ // get the items using the getter (getExportorNull, etc.). The getter uses the
+ // lookup map internally, so this validates that they contain all items in
+ // the list.
+ for (auto& item : list) {
+ auto* ptr = (module.*getter)(item->name);
+ if (!ptr) {
+ info.fail(kind + " must be found (use updateMaps)", item->name, nullptr);
+ } else {
+ info.shouldBeEqual(item->name,
+ ptr->name,
+ item->name,
+ "getter must return the correct item");
+ }
+ }
+
+ // TODO: Also check there is nothing extraneous in the map, but that would
+ // require inspecting private fields of Module.
+}
+} // anonymous namespace
+
+static void validateModuleMaps(Module& module, ValidationInfo& info) {
+ // Module maps should be up to date.
+ validateModuleMap(
+ module, info, module.exports, &Module::getExportOrNull, "Export");
+ validateModuleMap(
+ module, info, module.functions, &Module::getFunctionOrNull, "Function");
+ validateModuleMap(
+ module, info, module.globals, &Module::getGlobalOrNull, "Global");
+ validateModuleMap(module, info, module.tags, &Module::getTagOrNull, "Tag");
+ validateModuleMap(module,
+ info,
+ module.elementSegments,
+ &Module::getElementSegmentOrNull,
+ "ElementSegment");
+ validateModuleMap(
+ module, info, module.memories, &Module::getMemoryOrNull, "Memory");
+ validateModuleMap(module,
+ info,
+ module.dataSegments,
+ &Module::getDataSegmentOrNull,
+ "DataSegment");
+ validateModuleMap(
+ module, info, module.tables, &Module::getTableOrNull, "Table");
+}
+
static void validateFeatures(Module& module, ValidationInfo& info) {
if (module.features.hasGC()) {
info.shouldBeTrue(module.features.hasReferenceTypes(),
@@ -4004,7 +4057,8 @@ bool WasmValidator::validate(Module& module, Flags flags) {
validateDataSegments(module, info);
validateTables(module, info);
validateTags(module, info);
- validateModule(module, info);
+ validateStart(module, info);
+ validateModuleMaps(module, info);
validateFeatures(module, info);
if (info.closedWorld) {
validateClosedWorldInterface(module, info);