Skip to content

avm2: Treat hasnext2/nextname/nextvalue index as u32 - #24166

Draft
SuchAFuriousDeath wants to merge 2 commits into
ruffle-rs:masterfrom
SuchAFuriousDeath:avm2-enumeration-u32-index
Draft

avm2: Treat hasnext2/nextname/nextvalue index as u32#24166
SuchAFuriousDeath wants to merge 2 commits into
ruffle-rs:masterfrom
SuchAFuriousDeath:avm2-enumeration-u32-index

Conversation

@SuchAFuriousDeath

Copy link
Copy Markdown
Collaborator

Description

Fixes #11181.

The hasnext2, nextname, and nextvalue opcodes coerced their enumeration cookie to i32 and treated negative values as end-of-iteration. ArrayStorage::Sparse::get_next_enumerant returns key + 1 as the cookie, so
as soon as the enumeration reached a sparse index >= 2^31, the cookie wrapped to a negative i32 and iteration terminated. Callers ended up with null in the middle of the enumerated sequence and every key past that
point was lost.

Boxhead the Nightmare (issue #11181) writes a SharedObject whose objects field is a sparse Array keyed by 32-bit hashTag values. Restoring that save into Ruffle dropped every key >= 2^31; FDataFields/set objects()
then walked the array and hit TypeError #1009 accessing field: hashTag, aborting boot.

This restores the pre-e7ee3d3e1 (#18958) u32 semantics, which match avmplus. op_has_next is left as-is — the legacy hasnext opcode is not covered by the new test and modern ASC only emits hasnext2. Someone can flip
it in a follow-up.

Checklist

  • I, a human, have self-reviewed this PR and fully understand the changes within.
  • I have made or updated tests where possible.
  • All of my commits are properly scoped, compile successfully, and pass all tests.
  • This PR does not make sense to split up into smaller PRs.
  • An LLM was involved in the authoring of this code.

@SuchAFuriousDeath SuchAFuriousDeath changed the title Avm2 enumeration u32 index avm2: Treat hasnext2/nextname/nextvalue index as u32 Jul 10, 2026
Comment thread tests/tests/swfs/avm2/array_enumeration_high_index/Test.as
@SuchAFuriousDeath
SuchAFuriousDeath force-pushed the avm2-enumeration-u32-index branch from 37e208d to 91dfe81 Compare July 10, 2026 11:31

@kjarosh kjarosh 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, but would be nice if @Lord-McSweeney or @adrian17 took a look as well

@kjarosh
kjarosh requested a review from Lord-McSweeney July 10, 2026 18:24

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

From its source, avmplus always coerces the index passed to nextname, nextvalue, and hasnext(2) to an int. Is there some evidence suggesting otherwise?

@kjarosh

kjarosh commented Jul 10, 2026

Copy link
Copy Markdown
Member

Does the test fail without changes from this PR?

@SuchAFuriousDeath

Copy link
Copy Markdown
Collaborator Author

Does the test fail without changes from this PR?

Yes

@SuchAFuriousDeath

Copy link
Copy Markdown
Collaborator Author

From its source, avmplus always coerces the index passed to nextname, nextvalue, and hasnext(2) to an int. Is there some evidence suggesting otherwise?

The game not working as well as the test.

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

As mentioned on Discord,

ArrayStorage::Sparse::get_next_enumerant returns key + 1 as the cookie

This is the root cause, not the fact that we stop iteration for negative int values. Sadly, those indices are untested in ruffle that's why the tests pass here.

@SuchAFuriousDeath
SuchAFuriousDeath marked this pull request as draft July 14, 2026 12:37
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.

Error on https://www.crazymonkeygames.com/Boxhead-the-Nightmare.html

3 participants