/// <summary>Converts a Fortify result to a static analysis results interchange format result.</summary> /// <param name="fortify">The Fortify result convert.</param> /// <returns> /// A SARIF result <see cref="Result"/> containing the same content as the supplied /// <see cref="FortifyIssue"/>. /// </returns> public static Result ConvertFortifyIssueToSarifIssue(FortifyIssue fortify) { var result = new Result(); result.RuleId = fortify.Category; if (!string.IsNullOrWhiteSpace(fortify.InstanceId)) { if (result.PartialFingerprints == null) { result.PartialFingerprints = new Dictionary <string, string>(); } SarifUtilities.AddOrUpdateDictionaryEntry(result.PartialFingerprints, "InstanceId", fortify.InstanceId); } List <string> messageComponents = new List <string>(); if (fortify.Abstract != null) { messageComponents.Add(fortify.Abstract); } if (fortify.AbstractCustom != null) { messageComponents.Add(fortify.AbstractCustom); } if (messageComponents.Count == 0) { result.Message = new Message { Text = String.Format(CultureInfo.InvariantCulture, ConverterResources.FortifyFallbackMessage, result.RuleId) }; } else { result.Message = new Message { Text = String.Join(Environment.NewLine, messageComponents) }; } result.SetProperty("kingdom", fortify.Kingdom); if (fortify.Priority != null) { result.SetProperty("priority", fortify.Priority); } if (!fortify.CweIds.IsDefaultOrEmpty) { result.SetProperty("cwe", String.Join(", ", fortify.CweIds.Select(id => id.ToString(CultureInfo.InvariantCulture)))); } if (fortify.RuleId != null) { result.SetProperty("fortifyRuleId", fortify.RuleId); } PhysicalLocation primaryOrSink = ConvertFortifyLocationToPhysicalLocation(fortify.PrimaryOrSink); result.Locations = new List <Location> { new Location { PhysicalLocation = primaryOrSink } }; if (fortify.Source != null) { PhysicalLocation source = ConvertFortifyLocationToPhysicalLocation(fortify.Source); var locations = new List <CodeFlowLocation>() { new CodeFlowLocation { Location = new Location { PhysicalLocation = source } }, new CodeFlowLocation { Location = new Location { PhysicalLocation = primaryOrSink } } }; result.CodeFlows = new List <CodeFlow>() { SarifUtilities.CreateSingleThreadedCodeFlow(locations) }; } return(result); }
internal Result CreateResult(FxCopLogReader.Context context) { Result result = new Result(); string uniqueId = context.GetUniqueId(); if (!String.IsNullOrWhiteSpace(uniqueId)) { if (result.PartialFingerprints == null) { result.PartialFingerprints = new Dictionary <string, string>(); } SarifUtilities.AddOrUpdateDictionaryEntry(result.PartialFingerprints, "UniqueId", uniqueId); } string status = context.Status; if ("ExcludedInSource".Equals(status)) { result.SuppressionStates = SuppressionStates.SuppressedInSource; } else if ("ExcludedInProject".Equals(status)) { result.BaselineState = BaselineState.Unchanged; } result.RuleId = context.CheckId; result.Message = new Message { Arguments = context.Items, MessageId = context.ResolutionName, Text = context.Message }; var location = new Location(); string sourceFile = GetFilePath(context); string targetFile = context.Target; // If both source and target have values and they're different, set analysis target if (!string.IsNullOrWhiteSpace(sourceFile) && !string.IsNullOrWhiteSpace(targetFile) && !sourceFile.Equals(targetFile)) { result.AnalysisTarget = BuildFileLocationFromFxCopReference(targetFile); } else { // One or the other or both is null, or they're different sourceFile = string.IsNullOrWhiteSpace(sourceFile) ? targetFile : sourceFile; } // If we have a value, set physical location if (!string.IsNullOrWhiteSpace(sourceFile)) { location.PhysicalLocation = new PhysicalLocation { ArtifactLocation = BuildFileLocationFromFxCopReference(sourceFile), Region = context.Line == null ? null : Extensions.CreateRegion(context.Line.Value) }; } location.FullyQualifiedLogicalName = CreateFullyQualifiedLogicalName(context, out int logicalLocationIndex); location.LogicalLocationIndex = logicalLocationIndex; result.Locations = new List <Location> { location }; bool mapsDirectlyToSarifName; result.Level = ConvertFxCopLevelToResultLevel(context.Level ?? "Warning", out mapsDirectlyToSarifName); if (!mapsDirectlyToSarifName) { // We will not recapitulate FxCop MessageLevel names (such as // "Error" and "Warning") as a property. For names that differ // (such as "CriticalWarning" and "Information"), we will also // include the FxCop-specific values in the property bag. AddProperty(result, context.Level, "Level"); } AddProperty(result, context.Category, "Category"); AddProperty(result, context.FixCategory, "FixCategory"); return(result); }
internal Result CreateResult(FxCopLogReader.Context context) { Result result = new Result(); string uniqueId = context.GetUniqueId(); if (!string.IsNullOrWhiteSpace(uniqueId)) { if (result.PartialFingerprints == null) { result.PartialFingerprints = new Dictionary <string, string>(); } SarifUtilities.AddOrUpdateDictionaryEntry(result.PartialFingerprints, "UniqueId", uniqueId); } string status = context.Status; if ("ExcludedInSource".Equals(status)) { result.Suppressions = new List <Suppression> { new Suppression { Kind = SuppressionKind.InSource } }; } else if ("ExcludedInProject".Equals(status)) { result.BaselineState = BaselineState.Unchanged; } result.RuleId = context.CheckId; string messageText = context.Message ?? ConverterResources.FxCopNoMessage; result.Message = new Message { Arguments = context.Items, Id = context.ResolutionName, Text = messageText }; var location = new Location(); string sourceFile = GetFilePath(context); string targetFile = context.Target; // If both source and target have values and they're different, set analysis target if (!string.IsNullOrWhiteSpace(sourceFile) && !string.IsNullOrWhiteSpace(targetFile) && !sourceFile.Equals(targetFile)) { result.AnalysisTarget = BuildFileLocationFromFxCopReference(targetFile); } else { // One or the other or both is null, or they're different 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). // 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)) { location.PhysicalLocation = new PhysicalLocation { ArtifactLocation = BuildFileLocationFromFxCopReference(sourceFile), Region = context.Line == null ? null : Extensions.CreateRegion(context.Line.Value) }; emitLocation = true; } string fullyQualifiedLogicalName = CreateFullyQualifiedLogicalName(context, out int logicalLocationIndex); if (!string.IsNullOrWhiteSpace(fullyQualifiedLogicalName) || logicalLocationIndex > -1) { location.LogicalLocation = new LogicalLocation { FullyQualifiedName = fullyQualifiedLogicalName, Index = logicalLocationIndex }; emitLocation = true; } if (emitLocation) { result.Locations = new List <Location> { location }; } bool mapsDirectlyToSarifName; result.Level = ConvertFxCopLevelToResultLevel(context.Level ?? "Warning", out mapsDirectlyToSarifName); if (!mapsDirectlyToSarifName) { // We will not recapitulate FxCop MessageLevel names (such as // "Error" and "Warning") as a property. For names that differ // (such as "CriticalWarning" and "Information"), we will also // include the FxCop-specific values in the property bag. AddProperty(result, context.Level, "Level"); } AddProperty(result, context.Category, "Category"); AddProperty(result, context.FixCategory, "FixCategory"); return(result); }