From f86d28d62cd99a3aaebe894e539df4460001f68f Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Thu, 20 May 2021 17:34:37 -0500 Subject: [PATCH] Attempt to heal settings files damaged by #9962 The bug that caused #9962 resulted in folks getting profiles written to their settings that didn't contain any identifying information (name or guid), sometimes multiple times. These profiles look (somewhat) like this: ```json { "colorScheme": "Campbell" }, {}, ``` An empty profile serves no purpose -- it shows up in the list as being named "Default", and it only launches CMD (unless the commandline is the thing that the user successfully changed.) We can heal the settings file by simply ignoring those profiles that have *no identifying information* (a guid or a name that can be converted into a guid). Validation ---------- I created a number of profiles that fit this format and made sure that they were ignored on load and destroyed on save. --- .../CascadiaSettingsSerialization.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp b/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp index 65b6d0acfde..c39e00ff15e 100644 --- a/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp +++ b/src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp @@ -795,6 +795,18 @@ bool CascadiaSettings::_AppendDynamicProfilesToUserSettings() return changedFile; } +// Function Description: +// - Given a json serialization of a profile, this function will determine +// whether it is "well-formed". We introduced a bug (GH#9962, fixed in GH#9964) +// that would result in one or more nameless, guid-less profiles being emitted +// into the user's settings file. Those profiles would show up in the list as +// "Default" later. +static bool _IsValidProfileObject(const Json::Value& profileJson) +{ + return profileJson.isMember(&*NameKey.begin(), &*NameKey.end()) || // has a name (can generate a guid) + profileJson.isMember(&*GuidKey.begin(), &*GuidKey.end()); // or has a guid +} + // Method Description: // - Create a new instance of this class from a serialized JsonObject. // Arguments: @@ -837,7 +849,7 @@ void CascadiaSettings::LayerJson(const Json::Value& json) for (auto profileJson : _GetProfilesJsonObject(json)) { - if (profileJson.isObject()) + if (profileJson.isObject() && _IsValidProfileObject(profileJson)) { _LayerOrCreateProfile(profileJson); }