You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[4.0.7/4.0.8] Deterministic boot panic at addition.rs:425 — duplicate path within one add_files_to_directory batch dereferences its own future FileInfoIdx
#647
Deterministic panic on every boot at src/replacement/addition.rs:425:31 — index out of bounds — reproduced on both v4.0.8 and v4.0.7, Smash 13.0.4, Skyline beta, all support plugins current. This appears to be the same panic as closed issue #607 (which was on real hardware, FW 19.0.1 / Atmosphere), so the mechanism is not emulator-specific; analysis below is platform-independent.
Trigger mod: "MicroMoveset Little Mac c100 ~ Broly DBS" by Mastaklo (reported to the author separately). With the mod installed the panic fires 100% of boots at the splash screen; removing it boots clean.
Root cause (from reading add_files_to_directory, v4.0.8)
For each incoming file processed in the second loop, the function rewrites its lookup entry to a future table position: ctx.file_info_indices[...].file_info_index = FileInfoIdx((ctx.file_infos.len() + file_infos.len()) as u32) — a position that only becomes valid when ctx.file_infos.extend_from_slice(&file_infos) runs at the end of the call.
contained_files only guards against files already in the target directory (populated in the first loop). The incoming files slice is never checked for internal duplicates.
Therefore, if the same path occurs twice in one batch: the first occurrence is pushed and its file_info_index now points past the current end of ctx.file_infos; the second occurrence passes the contained_files check, get_path_idx succeeds, and line 425 (ctx.file_infos[usize::from(...file_info_index)]) reads the not-yet-materialized index → panic. The overshoot equals the number of pushes between the two occurrences.
Supporting measurements
len 633302 / index 633652 (overshoot 350). Removing exactly 2 files the mod shipped in the batch region (Windows build junk) → len 633300 / index 633648 (overshoot 348).
Adding 35 unrelated files to the mod → len 633335 / index 633683: length grew by exactly 35, overshoot unchanged at 348 — consistent with a fixed duplicate-pair distance in the plugin-built batch, independent of surrounding files.
The batch appears to be built by the mod's plugin.nro, whose strings show it iterates all eight colors (c00_index…c07_index, characall_label_c00…c07) while the mod ships a single added slot — a plausible duplicate factory.
Suggested hardening
Insert each processed file's hash into contained_files inside the second loop (or dedupe the incoming slice up front), so a duplicated path is skipped like an already-present file instead of dereferencing a future FileInfoIdx. That one change turns this class of malformed plugin batch from a boot-killing panic into a logged skip.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Summary
Deterministic panic on every boot at
src/replacement/addition.rs:425:31—index out of bounds— reproduced on both v4.0.8 and v4.0.7, Smash 13.0.4, Skyline beta, all support plugins current. This appears to be the same panic as closed issue #607 (which was on real hardware, FW 19.0.1 / Atmosphere), so the mechanism is not emulator-specific; analysis below is platform-independent.Trigger mod: "MicroMoveset Little Mac c100 ~ Broly DBS" by Mastaklo (reported to the author separately). With the mod installed the panic fires 100% of boots at the splash screen; removing it boots clean.
Root cause (from reading
add_files_to_directory, v4.0.8)ctx.file_info_indices[...].file_info_index = FileInfoIdx((ctx.file_infos.len() + file_infos.len()) as u32)— a position that only becomes valid whenctx.file_infos.extend_from_slice(&file_infos)runs at the end of the call.contained_filesonly guards against files already in the target directory (populated in the first loop). The incomingfilesslice is never checked for internal duplicates.file_info_indexnow points past the current end ofctx.file_infos; the second occurrence passes thecontained_filescheck,get_path_idxsucceeds, and line 425 (ctx.file_infos[usize::from(...file_info_index)]) reads the not-yet-materialized index → panic. The overshoot equals the number of pushes between the two occurrences.Supporting measurements
len 633302 / index 633652(overshoot 350). Removing exactly 2 files the mod shipped in the batch region (Windows build junk) →len 633300 / index 633648(overshoot 348).len 633335 / index 633683: length grew by exactly 35, overshoot unchanged at 348 — consistent with a fixed duplicate-pair distance in the plugin-built batch, independent of surrounding files.plugin.nro, whose strings show it iterates all eight colors (c00_index…c07_index,characall_label_c00…c07) while the mod ships a single added slot — a plausible duplicate factory.Suggested hardening
Insert each processed file's hash into
contained_filesinside the second loop (or dedupe the incoming slice up front), so a duplicated path is skipped like an already-present file instead of dereferencing a futureFileInfoIdx. That one change turns this class of malformed plugin batch from a boot-killing panic into a logged skip.Happy to provide full logs or run test builds.
All reactions