Skip to content

Add missing string validation and fix test - #9295

Open
kripken wants to merge 2 commits into
WebAssembly:mainfrom
kripken:str.val
Open

kripken wants to merge 2 commits into
WebAssembly:mainfrom
kripken:str.val

Conversation

@kripken

@kripken kripken commented Oct 22, 2026

Copy link
Copy Markdown
Member

No description provided.

@kripken
kripken requested a review from tlively October 22, 2026 20:10
@kripken
kripken requested a review from a team as a code owner October 22, 2026 20:10

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request adds type validation checks for various WebAssembly string operations (such as string.measure, string.concat, string.eq, string.test, string.wtf16_get, and string.slice_wtf) in wasm-validator.cpp, ensuring inputs are subtypes of externref and index arguments are i32. It also updates associated tests to use noextern instead of none. The reviewer identified that validation for string.compare is missing and should be added. Additionally, the reviewer suggested simplifying redundant Type(Type::i32) constructor calls to Type::i32 in visitStringWTF16Get and visitStringSliceWTF for better readability.

Comment on lines +4440 to +4447
shouldBeSubTypeIgnoringShared(curr->left->type,
Type(HeapType::ext, Nullable),
curr,
"string.eq left should be an externref");
shouldBeSubTypeIgnoringShared(curr->right->type,
Type(HeapType::ext, Nullable),
curr,
"string.eq right should be an externref");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

It appears that visitStringCompare is missing from both the FunctionValidator class declaration and its implementation. Since string.compare is a standard string operation (and is used in the tests), it should be validated similarly to string.eq to ensure that the strings feature is enabled and that both operands are subtypes of externref (or stringref). Please add the declaration to FunctionValidator and implement visitStringCompare.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

StringCompare does not exist in the IR, so visitStringCompare is irrelevant. It is implemented as a StringEq opcode.

Comment on lines +4469 to +4472
shouldBeSubType(curr->pos->type,
Type(Type::i32),
curr,
"string.wtf16_get pos should be an i32");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The explicit construction Type(Type::i32) is redundant here. Type::i32 is an unscoped enum value that is implicitly convertible to Type and is already used directly elsewhere in this file (e.g., in ref.i31 validation). Simplifying it to Type::i32 improves readability.

Suggested change
shouldBeSubType(curr->pos->type,
Type(Type::i32),
curr,
"string.wtf16_get pos should be an i32");
shouldBeSubType(curr->pos->type,
Type::i32,
curr,
"string.wtf16_get pos should be an i32");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is not the case due to C++ type conversion shenanigans.

Comment on lines +4484 to +4491
shouldBeSubType(curr->start->type,
Type(Type::i32),
curr,
"string.slice_wtf start should be an i32");
shouldBeSubType(curr->end->type,
Type(Type::i32),
curr,
"string.slice_wtf end should be an i32");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The explicit construction Type(Type::i32) is redundant here. Simplifying it to Type::i32 improves readability and maintains consistency with other parts of the validator.

Suggested change
shouldBeSubType(curr->start->type,
Type(Type::i32),
curr,
"string.slice_wtf start should be an i32");
shouldBeSubType(curr->end->type,
Type(Type::i32),
curr,
"string.slice_wtf end should be an i32");
shouldBeSubType(curr->start->type,
Type::i32,
curr,
"string.slice_wtf start should be an i32");
shouldBeSubType(curr->end->type,
Type::i32,
curr,
"string.slice_wtf end should be an i32");

@tlively tlively left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM % comments.

Comment on lines +4430 to +4433
shouldBeSubTypeIgnoringShared(curr->right->type,
Type(HeapType::ext, Nullable),
curr,
"string.concat right should be an externref");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should check that the LHS and RHS sharedness match as well. Same for StringEq below.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done.

Comment on lines +4469 to +4472
shouldBeSubType(curr->pos->type,
Type(Type::i32),
curr,
"string.wtf16_get pos should be an i32");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is not the case due to C++ type conversion shenanigans.

This branch has not been deployed

No deployments
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