Skip to content

feat: allow reviving user types from saves without eval#388

Open
io-spectre wants to merge 2 commits intotmedwards:developfrom
io-spectre:dev/no-save-xss
Open

feat: allow reviving user types from saves without eval#388
io-spectre wants to merge 2 commits intotmedwards:developfrom
io-spectre:dev/no-save-xss

Conversation

@io-spectre
Copy link
Copy Markdown

@io-spectre io-spectre commented Dec 27, 2025

It is quite common for authors to accept (or even require) save files for bug reports. Therefore we should allow authors to completely opt-out of executing arbitrary code on save load. This is implemented here by introducing Config.saves.isEvalEnabled (which currently defaults to true).

I've implemented a simple somewhat-more-explicit method for reviving user types which does not need eval-like powers by using a registry-based dispatch mechanism:1

// Assume that you have a custom class named `Character` that you wish to
// register with the serializer. Note that the class doesn't need to be in the
// global scope for this to work.
class Character {
	static serialId = 'Character'; // unique identifier for this class, could also be a UUID
	constructor(data) {
		// initialize the instance with the given data...
	}
	// class implementation...
	toJSON() {
		return Serial.createRegisteredReviver(Character.serialId, /* own data chunk */);
	}
	// more class implementation...
}
// Register the `Character` class with the serializer.
Serial.registerUserType(Character.serialId, {
	revive : (data) => {
		return new Character(data);
	}
});

I'm open to bike-shedding and if I've violated some sort of style guide, please let me know. I'll fix it asap.

Resolves #390

Footnotes

  1. The mechanism could be extended to automatically detect a registered serializer based on the prototype, etc. but I thought this minimal equivalent feature set to be less controversial.

Add a replacement for `Serial.createReviver()` which does not evaluate
code contained in a save file.
@io-spectre
Copy link
Copy Markdown
Author

btw. why is there support for Infinity but not Number.NEGATIVE_INFINITY or Number.NaN?

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.

Add an Option to disable the execution of JavaScript contained in saves

1 participant