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

Fix #1571: FxCop converter doesn't emit run.logicalLocations + add validation rule #1570

Merged
40 commits merged into from
Aug 9, 2019
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
a04aa00
Define rule id and add tests; no rule implementation yet.
Jul 10, 2019
e60baa9
Implement rule.
Jul 10, 2019
e6b19a0
To aid debugging, implement Region.ToString.
Jul 10, 2019
d2af119
Update SarifValidationSkimmerBase.HelpUri to always point to the late…
Jul 11, 2019
d5b0257
Prevent validator from emitting empty rule help messages.
Jul 11, 2019
dd97a7a
Merge branch 'master' into users/lgolding/validate-logical-location-i…
Jul 11, 2019
64120ea
Bump version number to 2.1.9.
Jul 11, 2019
c90577d
Shorten rule name to avoid "path name to long" test breaks.
Jul 11, 2019
c3c7586
Fix #1571: FxCop converter doesn't emit logical locations.
Jul 11, 2019
6f59135
Don't emit empty locations.
Jul 12, 2019
d7fa53d
Merge branch 'master' into users/lgolding/validate-logical-location-i…
Jul 15, 2019
240efb8
PR feedback: Don't use object[] for message args.
Jul 15, 2019
83a3103
PR feedback: One rule for all indices: renames and message fixes.
Jul 15, 2019
7da454e
Factor out index validation logic.
Jul 15, 2019
b26133c
Validate artifactLocation.index.
Jul 15, 2019
046d33f
DRY out validation logic.
Jul 15, 2019
a6cc5a4
Validate artifact.parentIndex.
Jul 15, 2019
d0cc2c4
Validate result.ruleIndex.
Jul 16, 2019
4a9c09d
Validate address.index.
Jul 17, 2019
a848fd7
Validate address.parentIndex.
Jul 17, 2019
2bb3414
Validate threadFlowLocation.index.
Jul 17, 2019
6a27bf4
Validate graphTraversal.{run,result}GraphIndex.
Jul 17, 2019
408468e
Improve jpointer to offending array.
Jul 17, 2019
99aa70c
Validate web{request,response}.index.
Jul 17, 2019
dbb552f
Validate web{Request,Response}.index in threadFlowLocation.
Jul 18, 2019
4b5773a
Validate resultProvenance.invocationIndex.
Jul 18, 2019
1949f57
Validate invocation.ruleConfigurationOverrides[].descriptor.index
Jul 18, 2019
8ea8d6f
Validate invocation.notificationConfigurationOverrides[].descriptor.i…
Jul 19, 2019
06e6504
Add files omitted from previous commit
Jul 19, 2019
1d51085
Merge branch 'master' into users/lgolding/validate-logical-location-i…
Jul 20, 2019
b7b16a6
Validate logicalLocation.parentIndex.
Jul 20, 2019
3894245
Validate notification.{descriptor,associatedRule}.index.
Jul 20, 2019
88b9c22
Capitalize "SARIF" in test output.
Jul 20, 2019
a8098f7
Validate reportingDescriptorRelationship.target.index.
Jul 20, 2019
4976b3f
Validate result.taxa[i].index.
Jul 20, 2019
d2b94c4
Validate threadFlowLocation.taxa[].index.
Jul 20, 2019
373d0cc
Validate reportingDescriptorReference.index for extensions.
Jul 20, 2019
d21f3df
Validate toolComponentReference.index.
Jul 20, 2019
2261d1a
Validate toolComponent.associatedComponent.index.
Jul 20, 2019
39489e0
Merge branch 'master' into users/lgolding/validate-logical-location-i…
Aug 9, 2019
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
6 changes: 5 additions & 1 deletion src/ReleaseHistory.md
Original file line number Diff line number Diff line change
Expand Up @@ -420,4 +420,8 @@
* BUGFIX: The `SarifCurrentToVersionOneVisitor` was dropping `run.id` and emitting an empty `run.stableId`. https://github.com/microsoft/sarif-sdk/issues/1557

## **v2.1.8** [Sdk](https://www.nuget.org/packages/Sarif.Sdk/2.1.8) | [Driver](https://www.nuget.org/packages/Sarif.Driver/2.1.8) | [Converters](https://www.nuget.org/packages/Sarif.Converters/2.1.8) | [Multitool](https://www.nuget.org/packages/Sarif.Multitool/2.1.8)
* BUGFIX: Add missing `"additionalProperties": false` constraints to schema; add missing object descriptions and improve other object descriptions in schema; update schema version to -rtm.4.
* BUGFIX: Add missing `"additionalProperties": false` constraints to schema; add missing object descriptions and improve other object descriptions in schema; update schema version to -rtm.4.

## **v2.1.9** [Sdk](https://www.nuget.org/packages/Sarif.Sdk/2.1.9) | [Driver](https://www.nuget.org/packages/Sarif.Driver/2.1.9) | [Converters](https://www.nuget.org/packages/Sarif.Converters/2.1.9) | [Multitool](https://www.nuget.org/packages/Sarif.Multitool/2.1.9)
* BUGFIX: FxCop converter produced logicalLocation.index but did not produce the run.logicalLocations array. https://github.com/microsoft/sarif-sdk/issues/1571
* FEATURE: Add validation rule to ensure that `logicalLocation.index` is not present unless `run.logicalLocations` is present.
Copy link
Contributor

@harleenkohli harleenkohli Aug 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logicalLocation.index is not present unless run.logicalLocations [](start = 46, length = 68)

this text can be changed to cover all index based validations #Resolved

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, fixed.


In reply to: 312603755 [](ancestors = 312603755)

16 changes: 15 additions & 1 deletion src/Sarif.Converters/FxCopConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ public override void Convert(Stream input, IResultLogWriter output, OptionallyEm
};

PersistResults(output, results, run);

output.WriteLogicalLocations(LogicalLocations);
}

internal ReportingDescriptor CreateRule(FxCopLogReader.Context context)
Expand Down Expand Up @@ -138,6 +140,11 @@ internal Result CreateResult(FxCopLogReader.Context context)
sourceFile = string.IsNullOrWhiteSpace(sourceFile) ? targetFile : sourceFile;
}

// Don't emit a location if neither physical location nor logical location information
// is present. This is the case for CA0001, (unexpected error in analysis tool).
Copy link
Member

@michaelcfanning michaelcfanning Jul 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

, [](start = 54, length = 1)

remove this comma? #Resolved

// https://docs.microsoft.com/en-us/visualstudio/code-quality/ca0001?view=vs-2019
bool emitLocation = false;

// If we have a value, set physical location
if (!string.IsNullOrWhiteSpace(sourceFile))
{
Expand All @@ -146,6 +153,8 @@ internal Result CreateResult(FxCopLogReader.Context context)
ArtifactLocation = BuildFileLocationFromFxCopReference(sourceFile),
Region = context.Line == null ? null : Extensions.CreateRegion(context.Line.Value)
};

emitLocation = true;
}

string fullyQualifiedLogicalName = CreateFullyQualifiedLogicalName(context, out int logicalLocationIndex);
Expand All @@ -157,9 +166,14 @@ internal Result CreateResult(FxCopLogReader.Context context)
FullyQualifiedName = fullyQualifiedLogicalName,
Index = logicalLocationIndex
};

emitLocation = true;
}

result.Locations = new List<Location> { location };
if (emitLocation)
{
result.Locations = new List<Location> { location };
}

bool mapsDirectlyToSarifName;

Expand Down
1 change: 1 addition & 0 deletions src/Sarif.Multitool/Rules/RuleId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ public static class RuleId
public const string UriBaseIdRequiresRelativeUri = "SARIF1014";
public const string UriMustBeAbsolute = "SARIF1015";
public const string ContextRegionRequiresRegion = "SARIF1016";
public const string InvalidIndex = "SARIF1017";
}
}
22 changes: 20 additions & 2 deletions src/Sarif.Multitool/Rules/RuleResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/Sarif.Multitool/Rules/RuleResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,10 @@
<data name="SARIF1016_Default" xml:space="preserve">
<value>{0}: This "physicalLocation" object contains a "contextRegion" property, but it does not contain a "region" property.</value>
</data>
<data name="SARIF1017_Default" xml:space="preserve">
<value>{0}: This "{1}" object contains a property "{2}" with value {3}, but either "{4}" is absent, or it has fewer than {5} elements.</value>
</data>
<data name="SARIF1017_InvalidIndex" xml:space="preserve">
<value>If an object contains a property that is used as an array index, then that array must be present and must contain at least "index + 1" elements.</value>
</data>
</root>
209 changes: 209 additions & 0 deletions src/Sarif.Multitool/Rules/SARIF1017.InvalidIndex.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Collections.Generic;

namespace Microsoft.CodeAnalysis.Sarif.Multitool.Rules
{
public class InvalidIndex : SarifValidationSkimmerBase
{
private readonly MultiformatMessageString _fullDescription = new MultiformatMessageString
{
Text = RuleResources.SARIF1017_InvalidIndex
};

public override MultiformatMessageString FullDescription => _fullDescription;

public override FailureLevel DefaultLevel => FailureLevel.Error;

/// <summary>
/// SARIF1017
/// </summary>
public override string Id => RuleId.InvalidIndex;

protected override IEnumerable<string> MessageResourceNames => new string[]
{
nameof(RuleResources.SARIF1017_Default)
};

protected override void Analyze(Address address, string addressPointer)
{
ValidateArrayIndex(
address.Index,
Context.CurrentRun.Addresses,
addressPointer,
"address",
"index",
$"runs[{Context.CurrentRunIndex}].addresses");

ValidateArrayIndex(
address.ParentIndex,
Context.CurrentRun.Addresses,
addressPointer,
"address",
"parentIndex",
$"runs[{Context.CurrentRunIndex}].addresses");
}

protected override void Analyze(Artifact artifact, string artifactPointer)
{
ValidateArrayIndex(
artifact.ParentIndex,
Context.CurrentRun.Artifacts,
artifactPointer,
"artifact",
"parentIndex",
$"runs[{Context.CurrentRunIndex}].artifacts");
}

protected override void Analyze(ArtifactLocation artifactLocation, string artifactLocationPointer)
{
ValidateArrayIndex(
artifactLocation.Index,
Context.CurrentRun.Artifacts,
artifactLocationPointer,
"artifactLocation",
"index",
$"runs[{Context.CurrentRunIndex}].artifacts");
}

protected override void Analyze(GraphTraversal graphTraversal, string graphTraversalPointer)
{
ValidateArrayIndex(
Copy link
Member

@michaelcfanning michaelcfanning Jul 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ValidateArrayIndex [](start = 12, length = 18)

please double check you've covered all 15 identified cases. Am I correct that I find only 13 here? logicalLocations.parentIndex certainly seems missing, can't find the other, assuming there is another. #Resolved

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely. I have a list of cases to cover. Here's the current status (which I think includes work done after you did your review):

[ ] One rule for invalid index
    [x] logicalLocation.parentIndex
    [x] artifactLocation.index
    [x] artifact.parentIndex
    [x] result.ruleIndex
    [x] address.index
    [x] address.parentIndex
    [x] threadFlowLocation.index
    [x] graphTraversal.resultGraphIndex
    [x] graphTraversal.runGraphIndex
    [x] webRequest.index
        [x] result.webRequest
        [x] threadFlowLocation.webRequest
    [x] webResponse.index
        [x] result.webResponse
        [x] threadFlowLocation.webResponse
    [x] resultProvenance.invocationIndex
    [ ] reportingDescriptorReference.index
        [x] result.rule
          [ ] Cover the case where there is a toolComponent reference that affects the array this points into.
        [x] configurationOverride.descriptor
            [x] invocation.ruleConfigurationOverrides
            [x] invocation.notificationConfigurationOverrides
        [ ] reportingDescriptorRelationship.target
        [ ] notification.descriptor
        [ ] notification.associatedRule
        [ ] Use in Taxa
        [ ] Use in ReportingDescriptorRelationship
    [ ] toolComponentReference.index
        [ ] toolComponent.associatedComponent
        [ ] reportingDescriptorReference.toolComponent

In reply to: 305429284 [](ancestors = 305429284)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great. Resetting my review to 'reviewing' pending your completion of the work. Carry on! Good stuff.


In reply to: 305525771 [](ancestors = 305525771,305429284)

graphTraversal.RunGraphIndex,
Context.CurrentRun.Graphs,
graphTraversalPointer,
"graphTraversal",
"runGraphIndex",
$"runs[{Context.CurrentRunIndex}].graphTraversals");

ValidateArrayIndex(
graphTraversal.ResultGraphIndex,
Context.CurrentResult.Graphs,
graphTraversalPointer,
"graphTraversal",
"resultGraphIndex",
$"runs[{Context.CurrentRunIndex}].results[{Context.CurrentResultIndex}].graphTraversals");
}

protected override void Analyze(LogicalLocation logicalLocation, string logicalLocationPointer)
Copy link
Member

@michaelcfanning michaelcfanning Jul 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LogicalLocation [](start = 40, length = 15)

where's the check for logicalLocation.parentIndex? #Resolved

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not finished all the cases yet. And some of the cases have sub-cases: for instance, you have to validate ReportingDescriptorReference.Index, but ReportingDescriptorReferences occur in several different contexts -- and you need tests for all of them to ensure you've got error message arguments right in each case.


In reply to: 305428389 [](ancestors = 305428389)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having said that, I just looked at my checklist (I pasted it into another comment), and I see that I put an x in the logicalLocation.parentIndex box -- and that was a mistake. Good catch! I'll uncheck it and implement it (and then re-check it ;-)).


In reply to: 305525258 [](ancestors = 305525258,305428389)

{
ValidateArrayIndex(
logicalLocation.Index,
Context.CurrentRun.LogicalLocations,
logicalLocationPointer,
"logicalLocation",
"index",
$"runs[{Context.CurrentRunIndex}].logicalLocations");
}

protected override void Analyze(ReportingDescriptorReference reportingDescriptorReference, string reportingDescriptorReferencePointer)
{
string arrayPropertyName;
IList<ReportingDescriptor> reportingDescriptors;

if (Context.CurrentReportingDescriptorKind == SarifValidationContext.ReportingDescriptorKind.Rule)
{
arrayPropertyName = "rules";
reportingDescriptors = Context.CurrentRun.Tool.Driver.Rules;
}
else if (Context.CurrentReportingDescriptorKind == SarifValidationContext.ReportingDescriptorKind.Notification)
{
arrayPropertyName = "notifications";
reportingDescriptors = Context.CurrentRun.Tool.Driver.Notifications;
}
else
{
throw new InvalidOperationException("Unexpected call to Analyze(ReportingDescriptorReference)");
}

ValidateArrayIndex(
reportingDescriptorReference.Index,
reportingDescriptors,
reportingDescriptorReferencePointer,
"reportingDescriptorReference",
"index",
$"runs[{Context.CurrentRunIndex}].tool.driver.{arrayPropertyName}");
}

protected override void Analyze(Result result, string resultPointer)
{
ValidateArrayIndex(
result.RuleIndex,
Context.CurrentRun.Tool.Driver.Rules,
resultPointer,
"result",
"ruleIndex",
$"runs[{Context.CurrentRunIndex}].tool.driver.rules");
}

protected override void Analyze(ResultProvenance resultProvenance, string resultProvenancePointer)
{
ValidateArrayIndex(
resultProvenance.InvocationIndex,
Context.CurrentRun.Invocations,
resultProvenancePointer,
"resultProvenance",
"invocationIndex",
$"runs[{Context.CurrentRunIndex}].invocations");
}

protected override void Analyze(ThreadFlowLocation threadFlowLocation, string threadFlowLocationPointer)
{
ValidateArrayIndex(
threadFlowLocation.Index,
Context.CurrentRun.ThreadFlowLocations,
threadFlowLocationPointer,
"threadFlowLocation",
"index",
$"runs[{Context.CurrentRunIndex}].threadFlowLocations");
}

protected override void Analyze(WebRequest webRequest, string webRequestPointer)
{
ValidateArrayIndex(
webRequest.Index,
Context.CurrentRun.WebRequests,
webRequestPointer,
"webRequest",
"index",
$"runs[{Context.CurrentRunIndex}].webRequests");
}

protected override void Analyze(WebResponse webResponse, string webResponsePointer)
{
ValidateArrayIndex(
webResponse.Index,
Context.CurrentRun.WebResponses,
webResponsePointer,
"webResponse",
"index",
$"runs[{Context.CurrentRunIndex}].webResponses");
}

private void ValidateArrayIndex<T>(
int index,
IList<T> container,
string jsonPointer,
string objectName,
string propertyName,
string arrayName)
{
if (!IndexIsValid(index, container))
{
LogResult(
jsonPointer,
nameof(RuleResources.SARIF1017_Default),
objectName,
propertyName,
index.ToInvariantString(),
arrayName,
(index + 1).ToInvariantString());
}
}

private static bool IndexIsValid<T>(int index, IList<T> container)
=> index == -1 || (index >= 0 && container?.Count > index);
}
}
Loading