Commit 6fa656fd authored by clemensh's avatar clemensh Committed by Commit bot

[wasm] Check for duplicate export names

Without this check, instantiation of the wasm module would fail on
DefineOwnProperty on the exports object for the duplicate export.
Now we detect this as validation error.

R=rossberg@chromium.org, titzer@chromium.org, ahaas@chromium.org

Review-Url: https://codereview.chromium.org/2065043002
Cr-Commit-Position: refs/heads/master@{#37038}
parent 93e26314
......@@ -360,6 +360,32 @@ class ModuleDecoder : public Decoder {
exp->func_index = consume_func_index(module, &func);
exp->name_offset = consume_string(&exp->name_length, true);
}
// Check for duplicate exports.
if (ok() && module->export_table.size() > 1) {
std::vector<WasmExport> sorted_exports(module->export_table);
const byte* base = start_;
auto cmp_less = [base](const WasmExport& a, const WasmExport& b) {
// Return true if a < b.
uint32_t len = a.name_length;
if (len != b.name_length) return len < b.name_length;
return memcmp(base + a.name_offset, base + b.name_offset, len) <
0;
};
std::stable_sort(sorted_exports.begin(), sorted_exports.end(),
cmp_less);
auto it = sorted_exports.begin();
WasmExport* last = &*it++;
for (auto end = sorted_exports.end(); it != end; last = &*it++) {
DCHECK(!cmp_less(*it, *last)); // Vector must be sorted.
if (!cmp_less(*last, *it)) {
const byte* pc = start_ + it->name_offset;
error(pc, pc,
"Duplicate export name '%.*s' for functions %d and %d",
it->name_length, pc, last->func_index, it->func_index);
break;
}
}
}
break;
}
case WasmSection::Code::Max:
......
......@@ -72,3 +72,18 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
assertEquals(kReturnValue, module.exports["0"]());
})();
(function testExportNameClash() {
var builder = new WasmModuleBuilder();
builder.addFunction("one", kSig_v_v).addBody([kExprNop]).exportAs("main");
builder.addFunction("two", kSig_v_v).addBody([kExprNop]).exportAs("other");
builder.addFunction("three", kSig_v_v).addBody([kExprNop]).exportAs("main");
try {
builder.instantiate();
assertUnreachable("should have thrown an exception");
} catch (e) {
assertContains("Duplicate export", e.toString());
}
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment