-
Notifications
You must be signed in to change notification settings - Fork 91
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
Changes from 29 commits
a04aa00
e60baa9
e6b19a0
d2af119
d5b0257
dd97a7a
64120ea
c90577d
c3c7586
6f59135
d7fa53d
240efb8
83a3103
7da454e
b26133c
046d33f
a6cc5a4
d0cc2c4
4a9c09d
a848fd7
2bb3414
6a27bf4
408468e
99aa70c
dbb552f
4b5773a
1949f57
8ea8d6f
06e6504
1d51085
b7b16a6
3894245
88b9c22
a8098f7
4976b3f
d2b94c4
373d0cc
d21f3df
2261d1a
39489e0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) | ||
|
@@ -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). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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)) | ||
{ | ||
|
@@ -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); | ||
|
@@ -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; | ||
|
||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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):
In reply to: 305429284 [](ancestors = 305429284) There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
where's the check for logicalLocation.parentIndex? #Resolved There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 In reply to: 305428389 [](ancestors = 305428389) There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 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); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this text can be changed to cover all index based validations #Resolved
There was a problem hiding this comment.
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)