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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions AutoUpdate/CKAN-autoupdate.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<PackageReference Include="Nullable" Version="1.3.1" PrivateAssets="all" />
<PackageReference Include="IndexRange" Version="1.0.3" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\_build\meta\GlobalAssemblyVersionInfo.cs">
Expand Down
22 changes: 13 additions & 9 deletions AutoUpdate/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,22 @@ public static int Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionEventHandler;

if (args.Length != 4)
if (//args is not [string pid_str,
// string local_path,
// string updated_path,
// string launch and ("launch" or "nolaunch")]
args.Length < 4
|| args[0] is not string pid_str
|| args[1] is not string local_path
|| args[2] is not string updated_path
|| args[3] is not (string launch and ("launch" or "nolaunch")))
{
ReportError("{0}: AutoUpdater.exe pid oldPath newPath [no]launch", Properties.Resources.Usage);
ReportError("{0}: AutoUpdater.exe pid oldPath newPath [no]launch",
Properties.Resources.Usage);
return ExitBADOPT;
}

// Yes, it's a global variable, but we're an ephemeral singleton so :shrug:
fromGui = (args[3] == "launch");

int pid = int.Parse(args[0]);
string local_path = args[1];
string updated_path = args[2];
int pid = int.Parse(pid_str);
fromGui = (launch == "launch");

if (!File.Exists(updated_path))
{
Expand Down
2 changes: 1 addition & 1 deletion Cmdline/Action/Import.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public int RunCommand(CKAN.GameInstance instance, object options)
var toInstall = new List<CkanModule>();
var installer = new ModuleInstaller(instance, manager.Cache, user);
var regMgr = RegistryManager.Instance(instance, repoData);
installer.ImportFiles(toImport, user, mod => toInstall.Add(mod), regMgr.registry, !opts?.Headless ?? false);
installer.ImportFiles(toImport, user, toInstall.Add, regMgr.registry, !opts?.Headless ?? false);
if (toInstall.Count > 0)
{
HashSet<string>? possibleConfigOnlyDirs = null;
Expand Down
53 changes: 26 additions & 27 deletions Cmdline/Action/Show.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,15 @@ public int RunCommand(CKAN.GameInstance instance, object raw_options)
user.RaiseMessage("");
continue;
}
else if (matches.Count() == 1)
else if (//matches is [CkanModule oneMod]
matches.Count == 1
&& matches[0] is CkanModule oneMod)
{
// If there is only 1 match, display it.
user.RaiseMessage(Properties.Resources.ShowFoundOne, matches[0].name);
user.RaiseMessage(Properties.Resources.ShowFoundOne, oneMod.name);
user.RaiseMessage("");

moduleToShow = matches[0];
moduleToShow = oneMod;
}
else
{
Expand Down Expand Up @@ -281,10 +283,14 @@ private int ShowMod(CkanModule module, ShowOptions opts)
module.resources.remoteSWInfo);
}

if (!opts.without_files && !module.IsDLC)
if (!opts.without_files && !module.IsDLC
//&& module.download is [Uri url, ..]
&& module.download != null
&& module.download.Count > 0
&& module.download[0] is Uri url)
{
// Compute the CKAN filename.
string file_uri_hash = NetFileCache.CreateURLHash(module.download?[0]);
string file_uri_hash = NetFileCache.CreateURLHash(url);
string file_name = CkanModule.StandardName(module.identifier, module.version);

user.RaiseMessage("");
Expand Down Expand Up @@ -313,35 +319,28 @@ private void ShowVersionTable(CKAN.GameInstance inst, List<CkanModule> modules)
var versions = modules.Select(m => m.version.ToString()).ToList();
var gameVersions = modules.Select(m =>
{
CkanModule.GetMinMaxVersions(new List<CkanModule>() { m }, out _, out _, out GameVersion? minKsp, out GameVersion? maxKsp);
CkanModule.GetMinMaxVersions(new List<CkanModule>() { m }, out _, out _,
out GameVersion? minKsp, out GameVersion? maxKsp);
return GameVersionRange.VersionSpan(inst.game,
minKsp ?? GameVersion.Any,
maxKsp ?? GameVersion.Any);
}).ToList();
string[] headers = new string[] {
Properties.Resources.ShowVersionHeader,
Properties.Resources.ShowGameVersionsHeader
};
int versionLength = Math.Max(headers[0].Length, versions.Max(v => v.Length));
int gameVersionLength = Math.Max(headers[1].Length, gameVersions.Max(v => v.Length));
int versionLength = Math.Max(Properties.Resources.ShowVersionHeader.Length,
versions.Max(v => v.Length));
int gameVersionLength = Math.Max(Properties.Resources.ShowGameVersionsHeader.Length,
gameVersions.Max(v => v.Length));
user.RaiseMessage("");
user.RaiseMessage(
"{0} {1}",
headers[0].PadRight(versionLength),
headers[1].PadRight(gameVersionLength)
);
user.RaiseMessage(
"{0} {1}",
new string('-', versionLength),
new string('-', gameVersionLength)
);
user.RaiseMessage("{0} {1}",
Properties.Resources.ShowVersionHeader.PadRight(versionLength),
Properties.Resources.ShowGameVersionsHeader.PadRight(gameVersionLength));
user.RaiseMessage("{0} {1}",
new string('-', versionLength),
new string('-', gameVersionLength));
for (int row = 0; row < versions.Count; ++row)
{
user.RaiseMessage(
"{0} {1}",
versions[row].PadRight(versionLength),
gameVersions[row].PadRight(gameVersionLength)
);
user.RaiseMessage("{0} {1}",
versions[row].PadRight(versionLength),
gameVersions[row].PadRight(gameVersionLength));
}
}

Expand Down
9 changes: 7 additions & 2 deletions Cmdline/Action/Upgrade.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,12 @@ public int RunCommand(CKAN.GameInstance instance, object raw_options)
return Exit.BADOPT;
}

if (!options.upgrade_all && options.modules?[0] == "ckan" && AutoUpdate.CanUpdate)
if (!options.upgrade_all
//&& options.modules is ["ckan"]
&& options.modules != null
&& options.modules.Count > 0
&& options.modules[0] is "ckan"
&& AutoUpdate.CanUpdate)
{
if (options.dev_build && options.stable_release)
{
Expand Down Expand Up @@ -196,7 +201,7 @@ private void UpgradeModules(NetModuleCache cache,
installer.Upgrade(modules, downloader,
ref possibleConfigOnlyDirs,
regMgr, true, true, true),
m => modules.Add(m));
modules.Add);
}

/// <summary>
Expand Down
4 changes: 3 additions & 1 deletion Cmdline/ConsoleUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ public int RaiseSelectionDialog(string message, params object[] args)
// Check if we have a default selection.
int defaultSelection = -1;

if (args[0] is int v)
if (//args is [int v, ..]
args.Length > 0
&& args[0] is int v)
{
// Check that the default selection makes sense.
defaultSelection = v;
Expand Down
37 changes: 20 additions & 17 deletions Cmdline/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,32 +87,35 @@ public static int Execute(GameInstanceManager? manager, CommonOptions? opts, str
// It breaks command-specific help, for starters.
try
{
switch (args[0])
if (args.Length > 0)
{
case "repair":
return (new Repair(repoData)).RunSubCommand(manager, opts, new SubCommandOptions(args));
switch (args[0])
{
case "repair":
return (new Repair(repoData)).RunSubCommand(manager, opts, new SubCommandOptions(args));

case "instance":
return (new GameInstance()).RunSubCommand(manager, opts, new SubCommandOptions(args));
case "instance":
return (new GameInstance()).RunSubCommand(manager, opts, new SubCommandOptions(args));

case "compat":
return (new Compat()).RunSubCommand(manager, opts, new SubCommandOptions(args));
case "compat":
return (new Compat()).RunSubCommand(manager, opts, new SubCommandOptions(args));

case "repo":
return (new Repo(repoData)).RunSubCommand(manager, opts, new SubCommandOptions(args));
case "repo":
return (new Repo(repoData)).RunSubCommand(manager, opts, new SubCommandOptions(args));

case "authtoken":
return (new AuthToken()).RunSubCommand(manager, opts, new SubCommandOptions(args));
case "authtoken":
return (new AuthToken()).RunSubCommand(manager, opts, new SubCommandOptions(args));

case "cache":
return (new Cache()).RunSubCommand(manager, opts, new SubCommandOptions(args));
case "cache":
return (new Cache()).RunSubCommand(manager, opts, new SubCommandOptions(args));

case "mark":
return (new Mark(repoData)).RunSubCommand(manager, opts, new SubCommandOptions(args));
case "mark":
return (new Mark(repoData)).RunSubCommand(manager, opts, new SubCommandOptions(args));

case "filter":
return (new Filter()).RunSubCommand(manager, opts, new SubCommandOptions(args));
case "filter":
return (new Filter()).RunSubCommand(manager, opts, new SubCommandOptions(args));

}
}
}
catch (NoGameInstanceKraken)
Expand Down
2 changes: 1 addition & 1 deletion ConsoleUI/Toolkit/ConsoleFileMultiSelectDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public ConsoleFileMultiSelectDialog(ConsoleTheme theme,
getRowName, compareNames, null),
new ConsoleListBoxColumn<FileSystemInfo>(
Properties.Resources.FileSelectSizeHeader,
(FileSystemInfo fi) => getLength(fi),
getLength,
(a, b) => {
var fb = b as FileInfo;
return a is not FileInfo fa
Expand Down
7 changes: 6 additions & 1 deletion ConsoleUI/Toolkit/Symbols.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,12 @@ private static Encoding GetCodePage(int which)
/// </summary>
public static readonly char leftHalfBlock = cp437c(0xdd);

private static char cp437c(byte num) => dosCodePage.GetChars(new byte[] {num})[0];
private static char cp437c(byte num) => //dosCodePage.GetChars(new byte[] {num}) is [char val]
dosCodePage.GetChars(new byte[] {num}) is char[] chars
&& chars.Length > 0
&& chars[0] is char val
? val
: (char)0;
private static string cp437s(byte num) => $"{cp437c(num)}";
}

Expand Down
17 changes: 15 additions & 2 deletions Core/AutoUpdate/GithubReleaseCkanUpdate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,21 @@ internal static string ExtractReleaseNotes(string releaseBody)
{
const string divider = "\r\n---\r\n";
// Get at most two pieces, the first is the image, the second is the release notes
string[] notesArray = releaseBody.Split(new string[] { divider }, 2, StringSplitOptions.None);
return notesArray.Length > 1 ? notesArray[1] : notesArray[0];
//return releaseBody.Split(new string[] { divider },
// 2, StringSplitOptions.None) switch {
// [_, string val, ..] => val,
// [string val] => val,
// _ => "",
//};
var array = releaseBody.Split(new string[] { divider },
2, StringSplitOptions.None);
return array.Length > 1
&& array[1] is string val
? val
: array.Length == 1
&& array[0] is string val2
? val2
: "";
}

private static readonly Uri latestCKANReleaseApiUrl =
Expand Down
8 changes: 6 additions & 2 deletions Core/Converters/JsonSingleOrArrayConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@ public class JsonSingleOrArrayConverter<T> : JsonConverter

public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
var list = value as List<T>;
serializer.Serialize(writer, list?.Count == 1 ? list[0] : value);
serializer.Serialize(writer, //value is List<T> and [T val]
value is List<T> list
&& list.Count == 1
&& list[0] is T val
? val
: value);
}

/// <summary>
Expand Down
7 changes: 5 additions & 2 deletions Core/Converters/JsonToGamesDictionaryConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,11 @@ public class JsonToGamesDictionaryConverter : JsonConverter
{
return token.ToObject(objectType);
}
var valueType = objectType.GetGenericArguments()[1];
if (Activator.CreateInstance(objectType) is IDictionary obj
if (//objectType.GetGenericArguments() is [_, var valueType, ..]
objectType.GetGenericArguments() is Type[] types
&& types.Length > 0
&& types[1] is var valueType
&& Activator.CreateInstance(objectType) is IDictionary obj
&& !IsTokenEmpty(token))
{
foreach (var gameName in KnownGames.AllGameShortNames())
Expand Down
16 changes: 12 additions & 4 deletions Core/Exporters/DelimiterSeparatedValueExporter.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;

namespace CKAN.Exporters
{
Expand Down Expand Up @@ -53,7 +54,7 @@ public void Export(RegistryManager manager, IRegistryQuerier registry, Stream st
QuoteIfNecessary(mod.Module.description),
QuoteIfNecessary(mod.Module.author == null ? "" : string.Join(";", mod.Module.author)),
QuoteIfNecessary(mod.Module.kind),
WriteUri(mod.Module.download?[0]),
WriteUri(mod.Module.download),
mod.Module.download_size,
mod.Module.ksp_version,
mod.Module.ksp_version_min,
Expand All @@ -71,9 +72,16 @@ public void Export(RegistryManager manager, IRegistryQuerier registry, Stream st
}

private string WriteUri(Uri? uri)
=> uri != null
? QuoteIfNecessary(uri.ToString())
: string.Empty;
=> uri != null ? QuoteIfNecessary(uri.ToString())
: string.Empty;

private string WriteUri(List<Uri>? uris)
=> WriteUri(//uris is [Uri uri, ..]
uris != null
&& uris.Count > 0
&& uris[0] is Uri uri
? uri
: null);

private string WriteRepository(ResourcesDescriptor? resources)
=> resources != null && resources.repository != null
Expand Down
2 changes: 1 addition & 1 deletion Core/Extensions/DictionaryExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public static bool DictionaryEquals<K, V>(this IDictionary<K, V>? a,
IDictionary<K, V>? b)
=> a == null ? b == null
: b != null && a.Count == b.Count
&& a.Keys.All(k => b.ContainsKey(k))
&& a.Keys.All(b.ContainsKey)
&& b.Keys.All(k => a.ContainsKey(k)
&& EqualityComparer<V>.Default.Equals(a[k], b[k]));

Expand Down
2 changes: 1 addition & 1 deletion Core/Extensions/EnumExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public static class EnumExtensions
{

public static bool HasAnyFlag(this Enum val, params Enum[] flags)
=> flags.Any(f => val.HasFlag(f));
=> flags.Any(val.HasFlag);

}
}
Loading