From beee0b01f35798cdc3f45d60efb9e38d84d5d2a5 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Wed, 29 Jan 2025 18:26:01 -0800 Subject: [PATCH] Fix a text parser assertion on bad immediates We previously asserted that the end of a nested expression is the same when we parse it with a null context just to find its children and when we parse it for real. It turns out that it is possible for the two end positions to be different when the instruction is invalid in a way that only the real parse catches. Return a normal error instead of asserting because it is possible for invalid input to trigger this condition. Fixes #7251. --- src/parser/parsers.h | 7 +++++++ test/lit/parse-bad-optional-memidx.wast | 17 +++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 test/lit/parse-bad-optional-memidx.wast diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 48f65c497e0..c90e2c01d1f 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -1005,6 +1005,13 @@ template MaybeResult<> foldedinstr(Ctx& ctx) { auto inst = plaininstr(ctx, std::move(info.annotations)); assert(inst && "unexpectedly failed to parse instruction"); CHECK_ERR(inst); + // We have already parsed the instruction, so we generally know where it + // ends. But there may have been some invalid extra immediates (e.g. + // invalid memory indices) that we only realize are invalid now that we've + // parsed the instruction for real. + if (ctx.in.getPos() != *info.end) { + return ctx.in.err("expected end of instruction"); + } assert(ctx.in.getPos() == *info.end && "expected end of instruction"); continue; } diff --git a/test/lit/parse-bad-optional-memidx.wast b/test/lit/parse-bad-optional-memidx.wast new file mode 100644 index 00000000000..57438d6d2fd --- /dev/null +++ b/test/lit/parse-bad-optional-memidx.wast @@ -0,0 +1,17 @@ +;; Regression test for a parser bug where the invalid memory index followed by +;; another immediate caused an assertion failure. + +;; RUN: not wasm-opt -all %s 2>&1 | filecheck %s + +;; CHECK: Fatal: 12:22: error: expected end of instruction + +(module + (memory 1 1) + + (func $v128.load16_lane1 (param $0 i32) (param $1 v128) (result v128) + (v128.load16_lane 1 0 ;; invalid memory index + (local.get $0) + (local.get $1) + ) + ) +) \ No newline at end of file