Skip to content

Commit 3976180

Browse files
Copilottig
andauthored
Fixes #5078. Handle JSON null root in SourcesManager.Load (#5079)
* Initial plan * Handle JSON null in SourcesManager.Load and add regression tests Agent-Logs-Url: https://github.com/gui-cs/Terminal.Gui/sessions/866693ea-a3e8-40ba-9863-5053e0fbbd31 Co-authored-by: tig <585482+tig@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: tig <585482+tig@users.noreply.github.com> Co-authored-by: Tig <tig@users.noreply.github.com>
1 parent dfa8967 commit 3976180

2 files changed

Lines changed: 79 additions & 2 deletions

File tree

Terminal.Gui/Configuration/SourcesManager.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,14 @@ internal bool Load (SettingsScope? settingsScope, Stream stream, string source,
158158
stream.Position = 0;
159159
Debug.Assert (json != null);
160160
#endif
161-
var scope = JsonSerializer.Deserialize (stream, typeof (SettingsScope), ConfigurationManager.SerializerContext.Options) as SettingsScope;
162-
settingsScope.UpdateFrom (scope!);
161+
SettingsScope? scope = JsonSerializer.Deserialize (stream, typeof (SettingsScope), ConfigurationManager.SerializerContext.Options) as SettingsScope;
162+
163+
if (scope is null)
164+
{
165+
throw new JsonException ("Configuration JSON root must not be null.");
166+
}
167+
168+
settingsScope.UpdateFrom (scope);
163169
ConfigurationManager.OnUpdated ();
164170

165171
AddSource (location, source);
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using System.Text;
2+
using System.Text.Json;
3+
using static Terminal.Gui.Configuration.ConfigurationManager;
4+
5+
namespace UnitTests.NonParallelizable.ConfigurationTests;
6+
7+
public class SourcesManagerLoadNullJsonTests
8+
{
9+
[Fact]
10+
public void Load_Stream_WithJsonNull_AndThrowOnJsonErrorsFalse_ReturnsFalse_AndAddsJsonError ()
11+
{
12+
// Copilot
13+
SourcesManager sourcesManager = new ();
14+
SettingsScope settingsScope = new ();
15+
string source = "Load_Stream_WithJsonNull_AndThrowOnJsonErrorsFalse_ReturnsFalse_AndAddsJsonError";
16+
ConfigLocations location = ConfigLocations.Runtime;
17+
Stream stream = new MemoryStream (Encoding.UTF8.GetBytes ("null"));
18+
19+
bool? originalThrowOnJsonErrors = ThrowOnJsonErrors;
20+
string originalJsonErrors = _jsonErrors.ToString ();
21+
22+
try
23+
{
24+
ThrowOnJsonErrors = false;
25+
_jsonErrors.Clear ();
26+
27+
bool result = sourcesManager.Load (settingsScope, stream, source, location);
28+
29+
Assert.False (result);
30+
Assert.Empty (sourcesManager.Sources);
31+
Assert.Contains ($"Error reading {source}:", _jsonErrors.ToString ());
32+
}
33+
finally
34+
{
35+
ThrowOnJsonErrors = originalThrowOnJsonErrors;
36+
_jsonErrors.Clear ();
37+
_jsonErrors.Append (originalJsonErrors);
38+
}
39+
}
40+
41+
[Fact]
42+
public void Load_Stream_WithJsonNull_AndThrowOnJsonErrorsTrue_ThrowsJsonException ()
43+
{
44+
// Copilot
45+
SourcesManager sourcesManager = new ();
46+
SettingsScope settingsScope = new ();
47+
string source = "Load_Stream_WithJsonNull_AndThrowOnJsonErrorsTrue_ThrowsJsonException";
48+
ConfigLocations location = ConfigLocations.Runtime;
49+
Stream stream = new MemoryStream (Encoding.UTF8.GetBytes ("null"));
50+
51+
bool? originalThrowOnJsonErrors = ThrowOnJsonErrors;
52+
string originalJsonErrors = _jsonErrors.ToString ();
53+
54+
try
55+
{
56+
ThrowOnJsonErrors = true;
57+
_jsonErrors.Clear ();
58+
59+
JsonException exception = Assert.Throws<JsonException> (() => sourcesManager.Load (settingsScope, stream, source, location));
60+
Assert.Contains ("null", exception.Message, StringComparison.OrdinalIgnoreCase);
61+
Assert.Empty (sourcesManager.Sources);
62+
Assert.Equal (0, _jsonErrors.Length);
63+
}
64+
finally
65+
{
66+
ThrowOnJsonErrors = originalThrowOnJsonErrors;
67+
_jsonErrors.Clear ();
68+
_jsonErrors.Append (originalJsonErrors);
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)