Guard watchers against invalid settings (#8857)

This commit is contained in:
Travis Ralston 2022-06-16 23:15:02 -06:00 committed by GitHub
parent 4faacdaec0
commit 4653394a1f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -174,6 +174,14 @@ export default class SettingsStore {
const watcherId = `${new Date().getTime()}_${SettingsStore.watcherCount++}_${settingName}_${roomId}`;
const localizedCallback = (changedInRoomId: string | null, atLevel: SettingLevel, newValAtLevel: any) => {
if (!SettingsStore.doesSettingSupportLevel(originalSettingName, atLevel)) {
logger.warn(
`Setting handler notified for an update of an invalid setting level: ` +
`${originalSettingName}@${atLevel} - this likely means a weird setting value ` +
`made it into the level's storage. The notification will be ignored.`,
);
return;
}
const newValue = SettingsStore.getValue(originalSettingName);
const newValueAtLevel = SettingsStore.getValueAt(atLevel, originalSettingName) ?? newValAtLevel;
callbackFn(originalSettingName, changedInRoomId, atLevel, newValueAtLevel, newValue);
@ -516,6 +524,23 @@ export default class SettingsStore {
return LEVEL_HANDLERS[level].isSupported();
}
/**
* Determines if a setting supports a particular level.
* @param settingName The setting name.
* @param level The level.
* @returns True if supported, false otherwise. Note that this will not check to see if
* the level itself can be supported by the runtime (ie: you will need to call #isLevelSupported()
* on your own).
*/
public static doesSettingSupportLevel(settingName: string, level: SettingLevel): boolean {
const setting = SETTINGS[settingName];
if (!setting) {
throw new Error("Setting '" + settingName + "' does not appear to be a setting.");
}
return level === SettingLevel.DEFAULT || (setting.supportedLevels.includes(level));
}
/**
* Determines the first supported level out of all the levels that can be used for a
* specific setting.