Skip to content

Commit

Permalink
[interpreter] add new assertions for custom sections (#19)
Browse files Browse the repository at this point in the history
* [interpreter] add new assertions for custom sections

assert_malformed and assert_invalid now have a _custom variant, for
asserting custom section/annotation errors.

The js implementation is a no-op, since no JS engine currently support
any kind of diagnostic for custom sections.

* Update interpreter/script/run.ml

Co-authored-by: Andreas Rossberg <rossberg@mpi-sws.org>

* Update interpreter/script/run.ml

Co-authored-by: Andreas Rossberg <rossberg@mpi-sws.org>

* revert check_module change

* add custom assertions in the test harness

---------

Co-authored-by: Andreas Rossberg <rossberg@mpi-sws.org>
  • Loading branch information
yuri91 and rossberg authored Nov 8, 2023
1 parent eeb243b commit 755cb78
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 19 deletions.
12 changes: 12 additions & 0 deletions interpreter/script/js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,21 @@ function assert_malformed(bytes) {
throw new Error("Wasm decoding failure expected");
}

function assert_malformed_custom(bytes) {
return;
}

function assert_invalid(bytes) {
try { module(bytes, false) } catch (e) {
if (e instanceof WebAssembly.CompileError) return;
}
throw new Error("Wasm validation failure expected");
}

function assert_invalid_custom(bytes) {
return;
}

function assert_unlinkable(bytes) {
let mod = module(bytes);
try { new WebAssembly.Instance(mod, registry) } catch (e) {
Expand Down Expand Up @@ -571,8 +579,12 @@ let of_assertion mods ass =
match ass.it with
| AssertMalformed (def, _) ->
"assert_malformed(" ^ of_definition def ^ ");"
| AssertMalformedCustom (def, _) ->
"assert_malformed_custom(" ^ of_definition def ^ ");"
| AssertInvalid (def, _) ->
"assert_invalid(" ^ of_definition def ^ ");"
| AssertInvalidCustom (def, _) ->
"assert_invalid_custom(" ^ of_definition def ^ ");"
| AssertUnlinkable (def, _) ->
"assert_unlinkable(" ^ of_definition def ^ ");"
| AssertUninstantiable (def, _) ->
Expand Down
19 changes: 17 additions & 2 deletions interpreter/script/run.ml
Original file line number Diff line number Diff line change
Expand Up @@ -450,9 +450,15 @@ let run_assertion ass =
(match ignore (run_definition def) with
| exception Decode.Code (_, msg) -> assert_message ass.at "decoding" msg re
| exception Parse.Syntax (_, msg) -> assert_message ass.at "parsing" msg re
| _ -> Assert.error ass.at "expected decoding/parsing error"
)

| AssertMalformedCustom (def, re) ->
trace "Asserting malformed custom...";
(match ignore (run_definition def) with
| exception Custom.Syntax (_, msg) ->
assert_message ass.at "annotation parsing" msg re
| _ -> Assert.error ass.at "expected decoding/parsing error"
| _ -> Assert.error ass.at "expected custom decoding/parsing error"
)

| AssertInvalid (def, re) ->
Expand All @@ -463,9 +469,18 @@ let run_assertion ass =
with
| exception Valid.Invalid (_, msg) ->
assert_message ass.at "validation" msg re
| _ -> Assert.error ass.at "expected validation error"
)

| AssertInvalidCustom (def, re) ->
trace "Asserting invalid custom...";
(match
let m, cs = run_definition def in
Valid.check_module_with_custom (m, cs)
with
| exception Custom.Invalid (_, msg) ->
assert_message ass.at "custom validation" msg re
| _ -> Assert.error ass.at "expected validation error"
| _ -> Assert.error ass.at "expected custom validation error"
)

| AssertUnlinkable (def, re) ->
Expand Down
2 changes: 2 additions & 0 deletions interpreter/script/script.ml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ and result' =
type assertion = assertion' Source.phrase
and assertion' =
| AssertMalformed of definition * string
| AssertMalformedCustom of definition * string
| AssertInvalid of definition * string
| AssertInvalidCustom of definition * string
| AssertUnlinkable of definition * string
| AssertUninstantiable of definition * string
| AssertReturn of action * result list
Expand Down
8 changes: 8 additions & 0 deletions interpreter/text/arrange.ml
Original file line number Diff line number Diff line change
Expand Up @@ -758,8 +758,16 @@ let assertion mode ass =
| _ ->
[Node ("assert_malformed", [definition `Original None def; Atom (string re)])]
)
| AssertMalformedCustom (def, re) ->
(match mode, def.it with
| `Binary, Quoted _ -> []
| _ ->
[Node ("assert_malformed_custom", [definition `Original None def; Atom (string re)])]
)
| AssertInvalid (def, re) ->
[Node ("assert_invalid", [definition mode None def; Atom (string re)])]
| AssertInvalidCustom (def, re) ->
[Node ("assert_invalid_custom", [definition mode None def; Atom (string re)])]
| AssertUnlinkable (def, re) ->
[Node ("assert_unlinkable", [definition mode None def; Atom (string re)])]
| AssertUninstantiable (def, re) ->
Expand Down
2 changes: 2 additions & 0 deletions interpreter/text/lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,8 @@ rule token = parse
| "get" -> GET
| "assert_malformed" -> ASSERT_MALFORMED
| "assert_invalid" -> ASSERT_INVALID
| "assert_malformed_custom" -> ASSERT_MALFORMED_CUSTOM
| "assert_invalid_custom" -> ASSERT_INVALID_CUSTOM
| "assert_unlinkable" -> ASSERT_UNLINKABLE
| "assert_return" -> ASSERT_RETURN
| "assert_trap" -> ASSERT_TRAP
Expand Down
5 changes: 5 additions & 0 deletions interpreter/text/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ let parse_annots (m : module_) : Custom.section list =
%token MODULE BIN QUOTE
%token SCRIPT REGISTER INVOKE GET
%token ASSERT_MALFORMED ASSERT_INVALID ASSERT_UNLINKABLE
%token ASSERT_MALFORMED_CUSTOM ASSERT_INVALID_CUSTOM
%token ASSERT_RETURN ASSERT_TRAP ASSERT_EXHAUSTION
%token<Script.nan> NAN
%token INPUT OUTPUT
Expand Down Expand Up @@ -1062,6 +1063,10 @@ assertion :
{ AssertMalformed (snd $3, $4) @@ at () }
| LPAR ASSERT_INVALID script_module STRING RPAR
{ AssertInvalid (snd $3, $4) @@ at () }
| LPAR ASSERT_MALFORMED_CUSTOM script_module STRING RPAR
{ AssertMalformedCustom (snd $3, $4) @@ at () }
| LPAR ASSERT_INVALID_CUSTOM script_module STRING RPAR
{ AssertInvalidCustom (snd $3, $4) @@ at () }
| LPAR ASSERT_UNLINKABLE script_module STRING RPAR
{ AssertUnlinkable (snd $3, $4) @@ at () }
| LPAR ASSERT_TRAP script_module STRING RPAR
Expand Down
28 changes: 14 additions & 14 deletions test/custom/custom/custom_annot.wast
Original file line number Diff line number Diff line change
Expand Up @@ -22,78 +22,78 @@

;; Malformed name

(assert_malformed
(assert_malformed_custom
(module quote "(@custom)")
"@custom annotation: missing section name"
)

(assert_malformed
(assert_malformed_custom
(module quote "(@custom 4)")
"@custom annotation: missing section name"
)

(assert_malformed
(assert_malformed_custom
(module quote "(@custom bla)")
"@custom annotation: missing section name"
)

(assert_malformed
(assert_malformed_custom
(module quote "(@custom \"\\df\")")
"@custom annotation: malformed UTF-8 encoding"
)


;; Malformed placement

(assert_malformed
(assert_malformed_custom
(module quote "(@custom \"bla\" here)")
"@custom annotation: unexpected token"
)

(assert_malformed
(assert_malformed_custom
(module quote "(@custom \"bla\" after)")
"@custom annotation: unexpected token"
)

(assert_malformed
(assert_malformed_custom
(module quote "(@custom \"bla\" (after))")
"@custom annotation: malformed section kind"
)

(assert_malformed
(assert_malformed_custom
(module quote "(@custom \"bla\" (type))")
"@custom annotation: malformed placement"
)

(assert_malformed
(assert_malformed_custom
(module quote "(@custom \"bla\" (aft type))")
"@custom annotation: malformed placement"
)

(assert_malformed
(assert_malformed_custom
(module quote "(@custom \"bla\" (before types))")
"@custom annotation: malformed section kind"
)


;; Misplaced

(assert_malformed
(assert_malformed_custom
(module quote "(type (@custom \"bla\") $t (func))")
"misplaced @custom annotation"
)

(assert_malformed
(assert_malformed_custom
(module quote "(func (@custom \"bla\"))")
"misplaced @custom annotation"
)

(assert_malformed
(assert_malformed_custom
(module quote "(func (block (@custom \"bla\")))")
"misplaced @custom annotation"
)

(assert_malformed
(assert_malformed_custom
(module quote "(func (nop (@custom \"bla\")))")
"misplaced @custom annotation"
)
6 changes: 3 additions & 3 deletions test/custom/name/name_annot.wast
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@

(module $moduel (@name "Modül"))

(assert_malformed
(assert_malformed_custom
(module quote "(module (@name \"M1\") (@name \"M2\"))")
"@name annotation: multiple module"
)

(assert_malformed
(assert_malformed_custom
(module quote "(module (func) (@name \"M\"))")
"misplaced @name annotation"
)

(assert_malformed
(assert_malformed_custom
(module quote "(module (start $f (@name \"M\")) (func $f))")
"misplaced @name annotation"
)
6 changes: 6 additions & 0 deletions test/harness/async_index.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@ function assert_invalid(bytes) {

const assert_malformed = assert_invalid;

function assert_invalid_custom(bytes) {
module(bytes);
}

const assert_malformed_custom = assert_invalid_custom;

function instance(bytes, imports, valid = true) {
const test = valid
? "Test that WebAssembly instantiation succeeds"
Expand Down
12 changes: 12 additions & 0 deletions test/harness/sync_index.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,18 @@ function assert_invalid(bytes) {

const assert_malformed = assert_invalid;

function assert_invalid_custom(bytes) {
uniqueTest(() => {
try {
module(bytes, /* valid */ true);
} catch(e) {
throw new Error('failed on custom section error');
}
}, "A wast module that should have an invalid or malformed custom section.");
}

const assert_malformed_custom = assert_invalid_custom;

function instance(bytes, imports = registry, valid = true) {
if (imports instanceof Result) {
if (imports.isError())
Expand Down

0 comments on commit 755cb78

Please sign in to comment.