Skip to content

fix(avm1): match asfunction: and event: URL prefixes case-insensitively (#23514)#23518

Open
mvanhorn wants to merge 1 commit intoruffle-rs:masterfrom
mvanhorn:osc/23514-asfunction-case-insensitive
Open

fix(avm1): match asfunction: and event: URL prefixes case-insensitively (#23514)#23518
mvanhorn wants to merge 1 commit intoruffle-rs:masterfrom
mvanhorn:osc/23514-asfunction-case-insensitive

Conversation

@mvanhorn
Copy link
Copy Markdown

Closes #23514.

Problem

Submachine HD builds use HREFs like `music: on` for their footer controls. The capital-F `asFunction:` fell through Ruffle's byte-exact `strip_prefix(b"asfunction:")` check and hit the `navigate_to_url` fallback, so clicking "music: on" opened `asFunction:toggle_music` in the user's web browser instead of calling the AVM1 function.

Flash Player matched both `asfunction:` and `event:` case-insensitively.

Fix

In `EditText::open_url`, lowercase the URL head once and strip the prefix against the lowercased variant, then slice the original `url` from the back to preserve the address's original casing for downstream consumers (the function name passed to `execute_avm1_asfunction` and the event text).

Same treatment for `event:` — per the issue author's confirmation in #12812 comments that "the check should probably be made case-insensitive", this is the symmetric fix.

Verification

  • `cargo check -p ruffle_core` — clean
  • `cargo clippy -p ruffle_core -- -D warnings` — clean
  • `cargo fmt --check` — clean

No regression for the existing canonical-case paths; the only behavioural change is that mixed-case variants (`asFunction:`, `ASFUNCTION:`, `Event:`, etc.) now route through the AVM1 / `link` event paths instead of opening a browser.

@kjarosh
Copy link
Copy Markdown
Member

kjarosh commented Apr 23, 2026

Can you add a test for that? Might be also worth testing whether whitespace is stripped around the function, etc.

Please also adhere to the commit message guidelines.

 ruffle-rs#23514)

Submachine HD builds use capital-F `asFunction:` HREFs in their footer
controls. The byte-exact `WStr::strip_prefix` rejected that variant and
fell through to `navigate_to_url`, which opened the function call as
an external URL in the desktop browser.

Flash Player matched both `asfunction:` and `event:` schemes
case-insensitively. Extract a `strip_link_scheme` helper that
lowercases the URL head, strips the scheme from the lowercase copy, and
slices the original `url` from the back to preserve the address's
original casing for downstream consumers (the AVM1 function name and
AVM2 link event text).

Add unit tests covering canonical case, mixed case, upper case, empty
address after scheme, non-matching URLs, and a substring-only match
regression guard.

cargo check -p ruffle_core, cargo clippy -p ruffle_core -- -D warnings,
and cargo fmt --check all pass locally. The 7 new tests pass alongside
the existing 65 ruffle_core unit tests.
@mvanhorn mvanhorn force-pushed the osc/23514-asfunction-case-insensitive branch from 1c733d5 to 9703d25 Compare April 24, 2026 13:31
@mvanhorn
Copy link
Copy Markdown
Author

Thanks @kjarosh - pushed 9703d25. Extracted the prefix-matching into a `strip_link_scheme` helper and added unit tests in `#[cfg(test)] mod tests` at the bottom of edit_text.rs:

  • canonical `asfunction:toggle_music`
  • mixed case `asFunction:ToggleMusic` (preserves address casing)
  • upper case `ASFUNCTION:play`
  • mixed case `Event:clicked`
  • non-matching `https://` URL
  • empty address after `asfunction:`
  • substring-only `asfunctionfoo` (regression guard)

`cargo test -p ruffle_core --lib` passes all 7 new tests alongside the existing 65. `cargo clippy -p ruffle_core -- -D warnings` and `cargo fmt --check` both clean. Also rewrote the commit message to follow the core: <sentence> (close #NNN) format in CONTRIBUTING.md.

For the whitespace-around-function question - that would change observable behavior for existing `asfunction:` args that intentionally include leading/trailing whitespace, so I did not add that in this PR. Happy to open a follow-up if you want it to trim.

@danielhjacobs danielhjacobs added A-core Area: Core player, where no other category fits T-fix Type: Bug fix (in something that's supposed to work already) labels Apr 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-core Area: Core player, where no other category fits T-fix Type: Bug fix (in something that's supposed to work already)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Html HREF buttons tied to actionscript functions are treated as external URLs.

3 participants