Skip to content

Commit

Permalink
Fixes exception on resource without synopsis microsoft#1230
Browse files Browse the repository at this point in the history
  • Loading branch information
BernieWhite committed Aug 18, 2022
1 parent 4bab75f commit 36ca0bc
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 23 deletions.
2 changes: 2 additions & 0 deletions docs/CHANGELOG-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ What's changed since pre-release v2.4.0-B0022:
[#1229](https://github.com/microsoft/PSRule/issues/1229)
- Added `Execution.DuplicateResourceId` option to configure PSRule behaviour.
- By default, duplicate resource identifiers return an error.
- Fixed exception on JSON baseline without a synopsis by @BernieWhite.
[#1230](https://github.com/microsoft/PSRule/issues/1230)

## v2.4.0-B0022 (pre-release)

Expand Down
8 changes: 4 additions & 4 deletions src/PSRule/Common/JsonConverters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ protected override IList<JsonProperty> CreateProperties(Type type, MemberSeriali
}

/// <summary>
/// A custom deserializer to convert JSON into ResourceObject
/// A custom deserializer to convert JSON into a <see cref="ResourceObject"/>.
/// </summary>
internal sealed class ResourceObjectJsonConverter : JsonConverter
{
Expand Down Expand Up @@ -385,7 +385,7 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
private IResource MapResource(JsonReader reader, JsonSerializer serializer)
{
reader.GetSourceExtent(RunspaceContext.CurrentThread.Source.File.Path, out var extent);
reader.SkipComments();
reader.SkipComments(out _);
if (reader.TokenType != JsonToken.StartObject || !reader.Read())
throw new PipelineSerializationException(PSRuleResources.ReadJsonFailed);

Expand Down Expand Up @@ -672,7 +672,7 @@ private LanguageExpression MapOperator(string type, JsonReader reader)
{
while (reader.TokenType != JsonToken.EndArray)
{
if (reader.SkipComments())
if (reader.SkipComments(out var hasComments) && hasComments)
continue;

result.Add(MapExpression(reader));
Expand Down Expand Up @@ -800,7 +800,7 @@ private void MapProperty(LanguageExpression.PropertyBag properties, JsonReader r
var objects = new List<string>();
while (reader.TokenType != JsonToken.EndArray)
{
if (reader.SkipComments())
if (reader.SkipComments(out var hasComments) && hasComments)
continue;

var item = reader.ReadAsString();
Expand Down
15 changes: 10 additions & 5 deletions src/PSRule/Common/JsonReaderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,18 @@ public static void Consume(this JsonReader reader, JsonToken token)
/// Skip JSON comments.
/// </summary>
[DebuggerStepThrough]
public static bool SkipComments(this JsonReader reader)
public static bool SkipComments(this JsonReader reader, out bool hasComments)
{
var hasComments = false;
while (reader.TokenType == JsonToken.Comment && reader.Read())
hasComments = true;
hasComments = false;
while (reader.TokenType == JsonToken.Comment || reader.TokenType == JsonToken.None)
{
if (reader.TokenType == JsonToken.Comment)
hasComments = true;

return hasComments;
if (!reader.Read())
return false;
}
return true;
}
}
}
2 changes: 1 addition & 1 deletion src/PSRule/Definitions/SpecFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public SpecDescriptor(string apiVersion, string name)

public IResource CreateInstance(SourceFile source, ResourceMetadata metadata, CommentMetadata comment, ISourceExtent extent, object spec)
{
var info = new ResourceHelpInfo(metadata.Name, metadata.Name, new InfoString(comment.Synopsis), new InfoString());
var info = new ResourceHelpInfo(metadata.Name, metadata.Name, new InfoString(comment?.Synopsis), new InfoString());
return (IResource)Activator.CreateInstance(typeof(T), ApiVersion, source, metadata, info, extent, spec);
}
}
Expand Down
15 changes: 5 additions & 10 deletions src/PSRule/Host/HostHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -313,14 +313,10 @@ private static ILanguageBlock[] GetJsonLanguageBlocks(Source[] sources, Runspace
using var reader = new JsonTextReader(new StreamReader(file.Path));

// Consume lines until start of array
while (reader.TokenType == JsonToken.None || reader.TokenType == JsonToken.Comment)
{
if (!reader.Read())
break;
}

if (reader.TokenType == JsonToken.StartArray && reader.Read())
reader.SkipComments(out _);
if (reader.TryConsume(JsonToken.StartArray))
{
reader.SkipComments(out _);
while (reader.TokenType != JsonToken.EndArray)
{
var value = deserializer.Deserialize<ResourceObject>(reader);
Expand All @@ -331,8 +327,7 @@ private static ILanguageBlock[] GetJsonLanguageBlocks(Source[] sources, Runspace
}

// Consume all end objects at the end of each resource
while (reader.TokenType == JsonToken.EndObject)
reader.Read();
while (reader.TryConsume(JsonToken.EndObject)) { }
}
}
}
Expand Down Expand Up @@ -798,7 +793,7 @@ internal static RuleHelpInfo GetRuleHelpInfo(RunspaceContext context, string nam

internal static void UpdateHelpInfo(RunspaceContext context, IResource resource)
{
if (resource == null || !TryHelpPath(context, resource.Name, out var path) || !TryHelpInfo(path, out var info))
if (context == null || resource == null || !TryHelpPath(context, resource.Name, out var path) || !TryHelpInfo(path, out var info))
return;

resource.Info.Update(info);
Expand Down
4 changes: 2 additions & 2 deletions tests/PSRule.Tests/Baseline.Rule.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@
}
}
},
// Baseline without synopsis.
{
// Synopsis: This is an example baseline
"apiVersion": "github.com/microsoft/PSRule/v1",
"kind": "Baseline",
"metadata": {
Expand Down Expand Up @@ -116,4 +116,4 @@
},
"spec": {}
}
]
]
2 changes: 1 addition & 1 deletion tests/PSRule.Tests/Baseline.Rule.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ spec:
tag:
category: group2

# Baseline without synopsis.
---
# Synopsis: This is an example baseline
apiVersion: github.com/microsoft/PSRule/v1
kind: Baseline
metadata:
Expand Down
12 changes: 12 additions & 0 deletions tests/PSRule.Tests/BaselineTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public void ReadBaselineYaml()
Assert.Equal("github.com/microsoft/PSRule/v1", baseline[0].ApiVersion);
Assert.Equal("value", baseline[0].Metadata.Annotations["key"]);
Assert.False(baseline[0].Obsolete);
Assert.Equal("This is an example baseline", baseline[0].Info.Synopsis.Text);

var config = baseline[0].Spec.Configuration["key2"] as Array;
Assert.NotNull(config);
Expand All @@ -46,10 +47,15 @@ public void ReadBaselineYaml()
pso = config.GetValue(1) as PSObject;
Assert.Equal("def", pso.PropertyValue<string>("value2"));

// TestBaseline4
Assert.Equal("TestBaseline4", baseline[3].Name);
Assert.Null(baseline[3].Info.Synopsis.Text);

// TestBaseline5
Assert.Equal("TestBaseline5", baseline[4].Name);
Assert.Equal("github.com/microsoft/PSRule/v1", baseline[4].ApiVersion);
Assert.True(baseline[4].Obsolete);
Assert.Equal("This is an example obsolete baseline", baseline[4].Info.Synopsis.Text);
}

[Fact]
Expand All @@ -64,6 +70,7 @@ public void ReadBaselineJson()
Assert.Equal("github.com/microsoft/PSRule/v1", baseline[0].ApiVersion);
Assert.Equal("value", baseline[0].Metadata.Annotations["key"]);
Assert.False(baseline[0].Obsolete);
Assert.Equal("This is an example baseline", baseline[0].Info.Synopsis.Text);

var config = (JArray)baseline[0].Spec.Configuration["key2"];
Assert.NotNull(config);
Expand All @@ -73,10 +80,15 @@ public void ReadBaselineJson()
Assert.True(config[1].Type == JTokenType.Object);
Assert.Equal("def", config[1]["value2"]);

// TestBaseline4
Assert.Equal("TestBaseline4", baseline[3].Name);
Assert.Null(baseline[3].Info.Synopsis.Text);

// TestBaseline5
Assert.Equal("TestBaseline5", baseline[4].Name);
Assert.Equal("github.com/microsoft/PSRule/v1", baseline[4].ApiVersion);
Assert.True(baseline[4].Obsolete);
Assert.Equal("This is an example obsolete baseline", baseline[4].Info.Synopsis.Text);
}

[Theory]
Expand Down

0 comments on commit 36ca0bc

Please sign in to comment.