Skip to content

Replace assert statements used for argument validation - #118

Merged
andreaTP merged 2 commits into
bytecodealliance:mainfrom
Marcono1234:assert
Aug 10, 2026
Merged

Replace assert statements used for argument validation#118
andreaTP merged 2 commits into
bytecodealliance:mainfrom
Marcono1234:assert

Conversation

@Marcono1234

Copy link
Copy Markdown
Contributor

Instead of an Exception they cause an AssertionError (an Error), or worse when assertions are disabled at runtime execution just continues despite the program being in an invalid state.

Some of these were found during the fuzzing of #98.

This does not replace all assert calls. To me it looks like the remaining ones are not actually used for argument / state validation.

@Marcono1234
Marcono1234 requested a review from andreaTP as a code owner July 25, 2026 10:22
Comment thread wasm/src/main/java/run/endive/wasm/types/Value.java Outdated
@Marcono1234

Copy link
Copy Markdown
Contributor Author

CI failure seems to be unrelated, see #121

@andreaTP andreaTP left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for submitting this one, a couple of notes, but all the rest lgtm!

/**
* Builds the instance.
*
* <p>When running in 'runtime compilation' mode, invalid or unsupported Wasm code might already cause an

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick - I'm a bit confused about this comment, it requires a good understanding of how things are working under the curtains to be able to action it, and usage of the word "might" doesn't help less experienced folks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. My goal was to tell users "expect this to throw any RuntimeException" but without making any guarantees about the details, which seem to be implementation details (?).
But also make it clear that for interpreter mode, this Builder#build() does not (always?) throw an exception for invalid Wasm code but instead that occurs later during the actual execution (at least that is what I experienced).

case IF:
case TRY_TABLE:
assert (scope.isPresent());
if (scope.isEmpty()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the records: those were asserts in first place as they would detect bugs in the calculation/labelling of the Control Flow instructions.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean all of the asserts? Because during fuzzing I encountered a case where assert (labelFalse.isEmpty()); failed. Here is the reproducer (unfortunately not minimal):

AnnotatedInstruction.class.getClassLoader().setDefaultAssertionStatus(true);
byte[] bytes = Base64.getDecoder().decode("AGFzbQEAAAABGAJgB39/f39/f38Bf2AIf39/f39/f38BfwMEAwAAAQcFAQFmAAAKSgMSACAAIAEgAiADIAQgBSAGEAELGwAgACABIAIgA0EfcUGAAXJBACAEUwUgBhICCxkAIAAgAWogApogA2ogBGogBWogBmogB2oL");
Parser.parse(bytes);

I guess the Wasm code is invalid, wasm2wat fails for it, but it should nonetheless not cause an AssertionError.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For that reproducer, maybe the problem is here:

case ELSE:
{
currentControlFlow
.instruction()
.withLabelFalse(instructions.size() + 1);
currentControlFlow.addCallback(instruction::withLabelTrue);
break;
}

It seems for ELSE it just assumes that the currentControlFlow is the corresponding IF (or are there other cases where ELSE is valid?) without actually checking it. But for the reproducer above currentControlFlow is actually LOCAL_GET (the first instruction).

Comment thread wasm/src/main/java/run/endive/wasm/types/Value.java Outdated

@andreaTP andreaTP left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I took over the last few refinements

Marcono1234 and others added 2 commits August 10, 2026 13:25
Instead of an Exception they cause an AssertionError (an Error), or
worse when assertions are disabled at runtime execution just continues
despite the program being in an invalid state.
…e#139

- Value.toString(): use safe non-throwing default instead of RuntimeException
- Instance.build(): drop confusing Javadoc about interpreter vs compiler modes
- Generator: use MalformedException instead of bare RuntimeException
- Parser: remove vague class-level Javadoc addition
- Emitters.assertTempSlotInRange: replace assert with WasmEngineException
@andreaTP
andreaTP merged commit 877bdda into bytecodealliance:main Aug 10, 2026
27 checks passed
@Marcono1234

Copy link
Copy Markdown
Contributor Author

Thanks! Regarding #118 (comment); if I see it correctly you completely removed these Javadoc changes again. Are you planning on adding different Javadoc, or will you leave it as it is for now?

@Marcono1234
Marcono1234 deleted the assert branch August 10, 2026 14:53
@andreaTP

Copy link
Copy Markdown
Contributor

Are you planning on adding different Javadoc, or will you leave it as it is for now?

My bad, would you mind sending them back in another PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants