diff --git a/src/Runner.Common/HostContext.cs b/src/Runner.Common/HostContext.cs index 4a78da83f..4d9ff24c5 100644 --- a/src/Runner.Common/HostContext.cs +++ b/src/Runner.Common/HostContext.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; @@ -220,7 +220,7 @@ namespace GitHub.Runner.Common var runnerFile = GetConfigFile(WellKnownConfigFile.Runner); if (File.Exists(runnerFile)) { - var runnerSettings = IOUtil.LoadObject(runnerFile); + var runnerSettings = IOUtil.LoadObject(runnerFile, true); _userAgents.Add(new ProductInfoHeaderValue("RunnerId", runnerSettings.AgentId.ToString(CultureInfo.InvariantCulture))); _userAgents.Add(new ProductInfoHeaderValue("GroupId", runnerSettings.PoolId.ToString(CultureInfo.InvariantCulture))); } diff --git a/src/Runner.Sdk/Util/IOUtil.cs b/src/Runner.Sdk/Util/IOUtil.cs index d95698819..2ecca6787 100644 --- a/src/Runner.Sdk/Util/IOUtil.cs +++ b/src/Runner.Sdk/Util/IOUtil.cs @@ -40,10 +40,19 @@ namespace GitHub.Runner.Sdk File.WriteAllText(path, StringUtil.ConvertToJson(obj), Encoding.UTF8); } - public static T LoadObject(string path) + public static T LoadObject(string path, bool required = false) { string json = File.ReadAllText(path, Encoding.UTF8); - return StringUtil.ConvertFromJson(json); + if (required && string.IsNullOrEmpty(json)) + { + throw new ArgumentNullException($"File {path} is empty"); + } + T result = StringUtil.ConvertFromJson(json); + if (required && result == null) + { + throw new ArgumentException("Converting json to object resulted in a null value"); + } + return result; } public static string GetSha256Hash(string path) diff --git a/src/Test/L0/Util/IOUtilL0.cs b/src/Test/L0/Util/IOUtilL0.cs index 6a504d192..a3901c90d 100644 --- a/src/Test/L0/Util/IOUtilL0.cs +++ b/src/Test/L0/Util/IOUtilL0.cs @@ -1,4 +1,3 @@ -using GitHub.Runner.Common.Util; using GitHub.Runner.Sdk; using System; using System.IO; @@ -931,6 +930,36 @@ namespace GitHub.Runner.Common.Tests.Util } } + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Common")] + public void LoadObject_ThrowsOnRequiredLoadObject() + { + using (TestHostContext hc = new(this)) + { + Tracing trace = hc.GetTrace(); + + // Arrange: Create a directory with a file. + string directory = Path.Combine(hc.GetDirectory(WellKnownDirectory.Bin), Path.GetRandomFileName()); + + string file = Path.Combine(directory, "empty file"); + Directory.CreateDirectory(directory); + + File.WriteAllText(path: file, contents: ""); + Assert.Throws(() => IOUtil.LoadObject(file, true)); + + file = Path.Combine(directory, "invalid type file"); + File.WriteAllText(path: file, contents: " "); + Assert.Throws(() => IOUtil.LoadObject(file, true)); + + // Cleanup. + if (Directory.Exists(directory)) + { + Directory.Delete(directory, recursive: true); + } + } + } + private static async Task CreateDirectoryReparsePoint(IHostContext context, string link, string target) { #if OS_WINDOWS