Skip to content

SaveLoad: validate save data before applying it - #81

Open
Goober5000 wants to merge 2 commits into
FSO-Scripters:masterfrom
Goober5000:fix/saveload_robustness
Open

SaveLoad: validate save data before applying it#81
Goober5000 wants to merge 2 commits into
FSO-Scripters:masterfrom
Goober5000:fix/saveload_robustness

Conversation

@Goober5000

@Goober5000 Goober5000 commented Sep 5, 2026

Copy link
Copy Markdown
Contributor
  • SaveLoad: validate save data before applying it

The save format is positional, so a truncated or hand-edited line used to
cause nil arithmetic inside the splitters. They now log the problem and
return nil, and shipdataset skips the ship. An empty weapon class name is
not an error: it means the bank was empty when the ship was saved.

Saved names are checked before use, since a failed table lookup yields an
invalid handle rather than nil. Whatever depends on a name that no longer
resolves is skipped rather than applied to the wrong target: an unusable
ship class skips the subsystem and weapon sections, which are indexed by
position within that class, and an unusable weapon class skips the
ammunition, which is scaled by the mounted weapon's cargo size.

shipdatacollect consults mn.ShipRegistry first, so an unknown name is
skipped instead of reaching the SEXP parser. Every isValid() call site
uses the "x and x:isValid()" form, for mods that make invalid handles nil.

  • SaveLoad: treat a ship that has not arrived as a no-op

The save format is positional, so a truncated or hand-edited line used to
cause nil arithmetic inside the splitters. They now log the problem and
return nil, and shipdataset skips the ship. An empty weapon class name is
not an error: it means the bank was empty when the ship was saved.

Saved names are checked before use, since a failed table lookup yields an
invalid handle rather than nil. Whatever depends on a name that no longer
resolves is skipped rather than applied to the wrong target: an unusable
ship class skips the subsystem and weapon sections, which are indexed by
position within that class, and an unusable weapon class skips the
ammunition, which is scaled by the mounted weapon's cargo size.

shipdatacollect consults mn.ShipRegistry first, so an unknown name is
skipped instead of reaching the SEXP parser. Every isValid() call site
uses the "x and x:isValid()" form, for mods that make invalid handles nil.

@Goober5000 Goober5000 added fix A fix for a bug, mistake, or oversight cleanup Polishing, rather than fixes or features labels Sep 5, 2026
Goober5000 and others added 2 commits September 5, 2026 02:47
The save format is positional, so a truncated or hand-edited line used to
cause nil arithmetic inside the splitters.  They now log the problem and
return nil, and shipdataset skips the ship.  An empty weapon class name is
not an error: it means the bank was empty when the ship was saved.

Saved names are checked before use, since a failed table lookup yields an
invalid handle rather than nil.  Whatever depends on a name that no longer
resolves is skipped rather than applied to the wrong target: an unusable
ship class skips the subsystem and weapon sections, which are indexed by
position within that class, and an unusable weapon class skips the
ammunition, which is scaled by the mounted weapon's cargo size.

shipdatacollect consults mn.ShipRegistry first, so an unknown name is
skipped instead of reaching the SEXP parser.  Every isValid() call site
uses the "x and x:isValid()" form, for mods that make invalid handles nil.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Such a ship still has exactly its mission file attributes, so there is
nothing to save or restore.  It could not be represented either: only live
ship handles are read, so it fell through both status probes and was saved
as vanished, which vanished it on load if it had arrived by then.
lua-spawn-and-load-ship hit this every time, making the ship arrive and
then immediately vanishing it.

shipdatacollect now returns nothing for a not-yet-present registry entry,
and load_ship says so when a ship has no saved data.  A file written
before this change may still hold the vanished status for such a ship, and
will still vanish it.

The status enum is read through its FSO 26.0 name where the build has one,
since the old name raises an error in a mod that targets 26.0 or later.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Goober5000
Goober5000 force-pushed the fix/saveload_robustness branch 3 times, most recently from c773837 to 29f76ce Compare September 5, 2026 07:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cleanup Polishing, rather than fixes or features fix A fix for a bug, mistake, or oversight

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant