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

Avoid index out of range #4176

Merged
merged 1 commit into from
Sep 7, 2024

Conversation

HebaruSan
Copy link
Member

@HebaruSan HebaruSan commented Sep 7, 2024

Problem

Right after #4171, we got a report of an index out of bounds exception in the manage game instances dialog, which was fixed in 2ddf740. Today another came up in a different method of the same class.

Cause

Lines like this cause warnings (which we promote to errors) with nullable reference enabled:

ForgetButton.Enabled = HasSelections && (string)GameInstancesListView.SelectedItems[0].Tag != manager.CurrentInstance?.Name;

We need to check whether GameInstancesListView.SelectedItems[0].Tag is actually a string rather than null before we cast it, so I did that:

if (GameInstancesListView.SelectedItems[0].Tag is string instName)
{
RenameButton.Enabled = SelectButton.Enabled = SetAsDefaultCheckbox.Enabled = CloneGameInstanceMenuItem.Enabled = HasSelections;
ForgetButton.Enabled = HasSelections && instName != manager.CurrentInstance?.Name;
ImportFromSteamMenuItem.Enabled = manager.SteamLibrary.Games.Length > 0;
}

But now we're evaluating GameInstancesListView.SelectedItems[0] before HasSelections runs to confirm that list is non-empty, so when it is empty, it's an array bounds error.

Ideal solution and why we can't do it

C# 11 provides a great way to simplify checking array bounds and eliminate hard coded indexes:

Initially I did a code search to find every instance of a hard coded array index and worked up a set of changes to replace them with list patterns, but I hit a snag when I tried to build it with Mono:

2>CSC : error CS1617: Invalid option '11' for /langversion. Use '/langversion:?' to list supported values.
$ csc /langversion:?
Supported language versions:
default
1
2
3
4
5
6
7.0
7.1
7.2
7.3
8.0
9.0 (default)
latestmajor
preview
latest

So we need a solution that works on C# 9.

Changes

Now every hard coded array index access is replaced by:

  • A comment with a list pattern illustrating the intended behavior
  • A set of explicit, non-list-pattern checks that do exactly the same thing
  • My brief adventure in C# 11 enabled an "unnecessary lambda" message in vscode, so those have been addressed

If we are ever able to migrate to C# 11, we will have the option of switching to the list patterns that are already there in these comments.

@HebaruSan HebaruSan added Bug Something is not working as intended Easy This is easy to fix GUI Issues affecting the interactive GUI Core (ckan.dll) Issues affecting the core part of CKAN labels Sep 7, 2024
@HebaruSan HebaruSan force-pushed the fix/array-out-of-bounds branch from 0d01c4b to 8e7d6c4 Compare September 7, 2024 18:26
@HebaruSan HebaruSan merged commit bc7b390 into KSP-CKAN:master Sep 7, 2024
3 checks passed
@HebaruSan HebaruSan deleted the fix/array-out-of-bounds branch September 7, 2024 18:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something is not working as intended Core (ckan.dll) Issues affecting the core part of CKAN Easy This is easy to fix GUI Issues affecting the interactive GUI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant