Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix handling of empty builds.json file #3733

Merged
merged 1 commit into from Dec 4, 2022

Conversation

HebaruSan
Copy link
Member

@HebaruSan HebaruSan commented Dec 3, 2022

Problem

If your %LOCALAPPDATA%\CKAN\builds.json file is empty (zero bytes), CKAN throws an exception at startup:

Unhandled exception:
System.TypeInitializationException: The type initializer for 'CKAN.Versioning.GameVersion' threw an exception. ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at CKAN.GameVersionProviders.KspBuildMap.get_KnownVersions()
   at CKAN.Versioning.GameVersion..cctor()
   --- End of inner exception stack trace ---
   at CKAN.Versioning.GameVersion.op_Equality(GameVersion v1, GameVersion v2)
   at CKAN.GameInstance.Version()
   at CKAN.GUI.ManageGameInstancesDialog.<>c.<UpdateInstancesList>b__8_2(KeyValuePair`2 instance)
   at System.Linq.EnumerableSorter`2.ComputeKeys(TElement[] elements, Int32 count)
   at System.Linq.EnumerableSorter`1.Sort(TElement[] elements, Int32 count)
   at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__1.MoveNext()
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at CKAN.GUI.ManageGameInstancesDialog.UpdateInstancesList()
   at CKAN.GUI.ManageGameInstancesDialog..ctor(Boolean centerScreen, IUser user)
   at CKAN.GUI.Main.InstancePromptAtStart()
   at CKAN.GUI.Main..ctor(String[] cmdlineArgs, GameInstanceManager mgr, Boolean showConsole)
   at CKAN.GUI.GUI.Main_(String[] args, GameInstanceManager manager, Boolean showConsole)
   at CKAN.CmdLine.MainClass.Gui(GameInstanceManager manager, GuiOptions options, String[] args)
   at CKAN.CmdLine.MainClass.RunSimpleAction(Options cmdline, CommonOptions options, String[] args, IUser user, GameInstanceManager manager)
   at CKAN.CmdLine.MainClass.Execute(GameInstanceManager manager, CommonOptions opts, String[] args)
   at CKAN.CmdLine.MainClass.Main(String[] args) 

Originally reported by Discord user Krhank, and probably confirmed by Discord user Netuno.

Cause

KspBuildMap.TrySetBuildMap is supposed to return true if it successfully sets the build map and false if it fails, so the calling code can fall back to other sources, and it assumes that JsonConvert.DeserializeObject will throw an exception if there are any problems parsing the input:

private bool TrySetBuildMap(string buildMapJson)
{
try
{
_jBuilds = JsonConvert.DeserializeObject<JBuilds>(buildMapJson);
return true;
}
catch (Exception e)
{
Log.WarnFormat("Could not parse build map");
Log.DebugFormat("{0}\n{1}", buildMapJson, e);
return false;
}
}

However, if %LOCALAPPDATA%\CKAN\builds.json is empty, then buildMapJson will be the empty string, which parses to null without throwing an exception! KspBuildMap.TrySetBuildMap then returns true even though _jBuilds is null. This prevents KspBuildMap from falling back to other sources like the embedded build map, and any subsequent attempt to access the build map will throw null reference exceptions. (We've had this break things before in other places where we parse JSON.)

(Caching of this data in a local file was new in #3624, but the parsing logic had this flaw before that.)

Changes

Now KspBuildMap.TrySetBuildMap only returns true if _jBuilds is non-null. This way a null value will be detected as a failure, allowing fallback sources to be checked.

We also now only save the file to disk if the parse succeeds, so empty files should be much less likely.

@HebaruSan HebaruSan merged commit bb56dbe into KSP-CKAN:master Dec 4, 2022
@HebaruSan HebaruSan deleted the fix/bad-build-cache branch December 4, 2022 14:15
@AnonymousDevPerson
Copy link

how do i fix?

@HebaruSan
Copy link
Member Author

how do i fix?

You can work around this by deleting %LOCALAPPDATA%\CKAN\builds.json.

@HebaruSan HebaruSan mentioned this pull request Mar 23, 2023
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Core (ckan.dll) Issues affecting the core part of CKAN
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants