Skip to content

Commit f4a0b18

Browse files
authored
Disallow exact references in public types (#7554)
When custom descriptors are disabled, validate that public types do not contain exact references. If they did, we would drop the exactness and change the identity of the public type during binary writing, which would be incorrect. This still allows internal usage of exact types without custom descriptors enabled, and it is up to the individual passes to ensure that the eventual erasing of exactness does not cause any problems.
1 parent 20e7058 commit f4a0b18

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

src/wasm/wasm-validator.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3970,6 +3970,34 @@ static void validateBinaryenIR(Module& wasm, ValidationInfo& info) {
39703970

39713971
// Main validator class
39723972

3973+
static void validateTypes(Module& module, ValidationInfo& info) {
3974+
// Check that public types do not contain any exact references if custom
3975+
// descriptors is not enabled. If they did, we would erase the exactness
3976+
// during binary writing and change the public type identities.
3977+
if (module.features.hasCustomDescriptors()) {
3978+
return;
3979+
}
3980+
3981+
for (auto type : ModuleUtils::getPublicHeapTypes(module)) {
3982+
for (auto child : type.getTypeChildren()) {
3983+
if (child.isExact()) {
3984+
std::string typeName;
3985+
if (auto it = module.typeNames.find(type);
3986+
it != module.typeNames.end()) {
3987+
typeName = '$' + it->second.name.toString();
3988+
} else {
3989+
typeName = type.toString();
3990+
}
3991+
info.fail("Exact reference in public type not allowed without custom "
3992+
"descriptors [--enable-custom-descriptors]",
3993+
typeName,
3994+
nullptr);
3995+
break;
3996+
}
3997+
}
3998+
}
3999+
}
4000+
39734001
static void validateImports(Module& module, ValidationInfo& info) {
39744002
ModuleUtils::iterImportedFunctions(module, [&](Function* curr) {
39754003
if (curr->getResults().isTuple()) {
@@ -4439,6 +4467,7 @@ bool WasmValidator::validate(Module& module, Flags flags) {
44394467

44404468
// Validate globally.
44414469
if (info.validateGlobally) {
4470+
validateTypes(module, info);
44424471
validateImports(module, info);
44434472
validateExports(module, info);
44444473
validateGlobals(module, info);

test/lit/validation/public-exact.wast

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
;; Test that exact references in public types are disallowed without custom descriptors
2+
3+
;; RUN: not wasm-opt %s -all --disable-custom-descriptors 2>&1 | filecheck %s
4+
;; RUN: wasm-opt %s -all -S -o - | filecheck %s --check-prefix=NOERR
5+
6+
;; CHECK: [wasm-validator error in module] Exact reference in public type not allowed without custom descriptors [--enable-custom-descriptors], on
7+
;; CHECK-NEXT: $struct
8+
;; CHECK-NEXT: [wasm-validator error in module] Exact reference in public type not allowed without custom descriptors [--enable-custom-descriptors], on
9+
;; CHECK-NEXT: $array
10+
;; CHECK-NEXT: [wasm-validator error in module] Exact reference in public type not allowed without custom descriptors [--enable-custom-descriptors], on
11+
;; CHECK-NEXT: $func
12+
13+
;; NOERR: (module
14+
15+
(module
16+
(type $struct (struct (field (ref null (exact $struct)))))
17+
(type $array (array (field (ref (exact $struct)))))
18+
(type $func (func (param (ref null (exact $struct))) (result (ref (exact $array)))))
19+
20+
(import "" "struct" (global $struct (ref $struct)))
21+
(import "" "array" (global $array (ref $array)))
22+
(import "" "func" (global $func (ref $func)))
23+
)

0 commit comments

Comments
 (0)