Skip to content

Handle parentheses inside strings in lit check updater - #9372

Open
Blue1977 wants to merge 1 commit into
WebAssembly:mainfrom
Blue1977:fix-parentheses-strings
Open

Blue1977 wants to merge 1 commit into
WebAssembly:mainfrom
Blue1977:fix-parentheses-strings

Conversation

@Blue1977

@Blue1977 Blue1977 commented Nov 9, 2026

Copy link
Copy Markdown

Description

This PR fixes an issue in scripts/update_lit_checks.py where the lit check updater incorrectly counts unbalanced parentheses inside strings (such as "hello(" or "hello)") as part of the WebAssembly syntax structure. This bug causes CHECK assertions to map incorrectly to subsequent functions inside data segments.

Solution

Modified find_end to handle string boundaries and escaped characters by implementing in_string and escaped state tracking. Parentheses inside string literals are now successfully skipped, ensuring accurate structure parsing.

Validation Results (WSL Ubuntu)

Local regression test suite executed using test/unit/test_update_lit_checks_strings.py:

  • before log status: 5 expected subcase failures detected (string='hello(', hello)', hello((), hello\"(, hello\\().
  • after log status: OK (Ran 1 test containing all subcases successfully).

No issues or PR numbers are linked as this stems from an internal code FIXME.

@Blue1977
Blue1977 requested a review from a team as a code owner November 9, 2026 06:13
@tlively
tlively requested review from tlively and removed request for a team November 9, 2026 06:13

@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 updates scripts/update_lit_checks.py to correctly handle parentheses nested inside string literals, including escaped quotes and backslashes, and adds a comprehensive unit test suite to verify this behavior. A review comment identifies an off-by-one bug in the loop termination logic of find_end that could truncate the closing parenthesis if it is the last character in the string, and provides a suggestion to fix it.

Comment on lines 140 to 156
for end in range(start + 1, len(module)):
if depth == 0:
break
if in_string:
if escaped:
escaped = False
elif module[end] == '\\':
escaped = True
elif module[end] == '"':
in_string = False
elif module[end] == '"':
in_string = True
elif module[end] == '(':
depth += 1
elif module[end] == ')':
depth -= 1
return end

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

There is an off-by-one bug in the loop termination logic. If the matching closing parenthesis is the very last character of the module string, the loop terminates naturally without executing the next iteration where depth == 0 is checked. As a result, end is returned as len(module) - 1 instead of len(module), which incorrectly truncates the closing parenthesis when slicing.

We can fix this and simplify the logic by checking if depth == 0 immediately after decrementing it, and returning end + 1 directly from within the loop.

Suggested change
for end in range(start + 1, len(module)):
if depth == 0:
break
if in_string:
if escaped:
escaped = False
elif module[end] == '\\':
escaped = True
elif module[end] == '"':
in_string = False
elif module[end] == '"':
in_string = True
elif module[end] == '(':
depth += 1
elif module[end] == ')':
depth -= 1
return end
for end in range(start + 1, len(module)):
if in_string:
if escaped:
escaped = False
elif module[end] == '\\':
escaped = True
elif module[end] == '"':
in_string = False
elif module[end] == '"':
in_string = True
elif module[end] == '(':
depth += 1
elif module[end] == ')':
depth -= 1
if depth == 0:
return end + 1
return len(module)

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.

Sounds like it's worth fixing this at the same time.

@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.

Thanks for the PR!

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.

Rather than a Python unit test, let's just have a small .wast lit test that contains parens inside strings and make sure that the auto-update script can properly generate output for it.

Comment on lines 140 to 156
for end in range(start + 1, len(module)):
if depth == 0:
break
if in_string:
if escaped:
escaped = False
elif module[end] == '\\':
escaped = True
elif module[end] == '"':
in_string = False
elif module[end] == '"':
in_string = True
elif module[end] == '(':
depth += 1
elif module[end] == ')':
depth -= 1
return end

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.

Sounds like it's worth fixing this at the same time.

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