protected override void Analyze(
     PhysicalLocation physicalLocation,
     string physicalLocationPointer)
 {
     EnsureRelativeUriWithUriBaseId(
         physicalLocation.Uri,
         physicalLocation.UriBaseId,
         physicalLocationPointer);
 }
Example #2
0
        private Result GetResultFrom(string fullMessage)
        {
            Match match = s_errorLineRegex.Match(fullMessage);

            if (!match.Success)
            {
                return(null);
            }

            // MSBuild logs can contain duplicate error report lines. Take only one of them.
            if (!_verbose)
            {
                if (_fullMessageHashes.Contains(fullMessage))
                {
                    return(null);
                }
                _fullMessageHashes.Add(fullMessage);
            }

            string fileName           = match.Groups["fileName"].Value;
            string region             = match.Groups["region"].Value;
            string buildTool          = match.Groups["buildTool"].Value;
            string levelQualification = match.Groups["levelQualification"].Value;
            string level   = match.Groups["level"].Value;
            string ruleId  = match.Groups["ruleId"].Value;
            string message = match.Groups["message"].Value;

            var result = new Result
            {
                RuleId  = ruleId,
                Level   = GetFailureLevelFrom(level, out ResultKind resultKind),
                Kind    = resultKind,
                Message = new Message
                {
                    Text = message
                }
            };

            if (!string.IsNullOrWhiteSpace(fileName))
            {
                var physicalLocation = new PhysicalLocation
                {
                    ArtifactLocation = new ArtifactLocation
                    {
                        Uri = new Uri(fileName, UriKind.RelativeOrAbsolute)
                    }
                };

                if (!string.IsNullOrWhiteSpace(region))
                {
                    physicalLocation.Region = GetRegionFrom(region);
                }

                result.Locations = new Location[]
                {
                    new Location
                    {
                        PhysicalLocation = physicalLocation
                    }
                };
            }
            return(result);
        }
Example #3
0
        private Result CreateTestResult()
        {
            Result testResult = new Result()
            {
                RuleId  = "ruleName.test.value",
                Message = new Message {
                    Text = "failure.test.value"
                },
                Level = FailureLevel.Warning,
                Kind  = ResultKind.Fail
            };

            Region region = new Region()
            {
                StartLine   = 3,
                StartColumn = 2,
                EndLine     = 13,
                EndColumn   = 12,

                CharOffset = 3,
                CharLength = 10
            };
            PhysicalLocation physLoc = new PhysicalLocation()
            {
                ArtifactLocation = new ArtifactLocation
                {
                    Uri = new Uri("name.test.value", UriKind.Relative)
                },
                Region = region
            };
            Location location = new Location()
            {
                PhysicalLocation = physLoc
            };

            testResult.Locations = new List <Location>()
            {
                location
            };

            Replacement replacement = new Replacement()
            {
                DeletedRegion = new Region
                {
                    CharLength = 5,
                    CharOffset = 10
                },
                InsertedContent = new ArtifactContent
                {
                    Text = "fix.innerText.test.value"
                }
            };

            testResult.Fixes = new List <Fix>()
            {
                new Fix()
                {
                    ArtifactChanges = new List <ArtifactChange>()
                    {
                        new ArtifactChange()
                        {
                            ArtifactLocation = new ArtifactLocation
                            {
                                Uri = new Uri("name.test.value", UriKind.Relative)
                            },
                            Replacements = new List <Replacement>()
                            {
                                replacement
                            }
                        }
                    }
                }
            };

            return(testResult);
        }
Example #4
0
        private void ParseLocationFromTrace(Result result)
        {
            CodeFlow codeFlow   = result.CodeFlows.First();
            int      step       = 0;
            string   nodeLabel  = null;
            string   lastNodeId = null;

            _reader.Read();

            while (!AtEndOf(_strings.Trace))
            {
                if (AtStartOf(_strings.NodeRef))
                {
                    string nodeId = _reader.GetAttribute(_strings.IdAttribute);

                    if (!string.IsNullOrWhiteSpace(nodeId))
                    {
                        var tfl = new ThreadFlowLocation
                        {
                            Step = ++step
                        };

                        _tflToNodeIdDictionary.Add(tfl, nodeId);
                        codeFlow.ThreadFlows[0].Locations.Add(tfl);
                    }

                    _reader.Read();
                }
                else if (AtStartOf(_strings.Node))
                {
                    nodeLabel = _reader.GetAttribute(_strings.LabelAttribute);
                    _reader.Read();
                }
                else if (AtStartOf(_strings.SourceLocation))
                {
                    // Note: SourceLocation is an empty element (it has only attributes),
                    // so we can't call AtStartOfNonEmpty here.

                    string           snippetId        = _reader.GetAttribute(_strings.SnippetAttribute);
                    PhysicalLocation physicalLocation = ParsePhysicalLocationFromSourceInfo();

                    // Step past the empty SourceLocation element.
                    _reader.Read();

                    // If we don't have a label, get the <Action> value
                    if (string.IsNullOrWhiteSpace(nodeLabel))
                    {
                        nodeLabel = _reader.ReadElementContentAsString();
                    }

                    var tfl = new ThreadFlowLocation
                    {
                        Step     = ++step,
                        Location = new Location
                        {
                            Message = new Message
                            {
                                Text = nodeLabel
                            },
                            PhysicalLocation = physicalLocation
                        }
                    };

                    // Remember the id of the snippet associated with this location.
                    // We'll use it to fill the snippet text when we read the Snippets element later on.
                    if (!string.IsNullOrEmpty(snippetId))
                    {
                        _tflToSnippetIdDictionary.Add(tfl, snippetId);
                    }

                    codeFlow.ThreadFlows[0].Locations.Add(tfl);

                    // Keep track of the snippet associated with the last location in the
                    // CodeFlow; that's the snippet that we'll associate with the Result
                    // as a whole.
                    lastNodeId = snippetId;
                }
                else
                {
                    _reader.Read();
                }
            }

            if (codeFlow.ThreadFlows[0].Locations.Any())
            {
                result.Locations.Add(new Location
                {
                    // TODO: Confirm that the traces are ordered chronologically
                    // (so that we really do want to use the last one as the
                    // overall result location).
                    PhysicalLocation = codeFlow.ThreadFlows[0].Locations.Last().Location?.PhysicalLocation.DeepClone()
                });
                result.RelatedLocations.Add(new Location
                {
                    // Links embedded in the result message refer to related physicalLocation.id
                    PhysicalLocation = codeFlow.ThreadFlows[0].Locations.Last().Location?.PhysicalLocation.DeepClone()
                });

                result.RelatedLocations.Last().PhysicalLocation.Id = 1;

                if (!string.IsNullOrEmpty(lastNodeId))
                {
                    _resultToSnippetIdDictionary.Add(result, lastNodeId);
                }
            }
        }
Example #5
0
 protected virtual void Analyze(PhysicalLocation physicalLocation, string physicalLocationPointer)
 {
 }
Example #6
0
        internal Result CreateResult(TSLintLogEntry entry)
        {
            entry = entry ?? throw new ArgumentNullException(nameof(entry));

            Result result = new Result()
            {
                RuleId  = entry.RuleName,
                Message = new Message {
                    Text = entry.Failure
                }
            };

            switch (entry.RuleSeverity)
            {
            case "ERROR":
                result.Level = ResultLevel.Error;
                break;

            case "WARN":
            case "WARNING":
                result.Level = ResultLevel.Warning;
                break;

            case "DEFAULT":
            default:
                result.Level = ResultLevel.Note;
                break;
            }

            Region region = new Region()
            {
                // The TSLint logs have line and column start at 0, Sarif has them starting at 1, so add 1 to each
                StartLine   = entry.StartPosition.Line + 1,
                StartColumn = entry.StartPosition.Character + 1,
                EndLine     = entry.EndPosition.Line + 1,
                EndColumn   = entry.EndPosition.Character + 1,

                CharOffset = entry.StartPosition.Position
            };

            int length = entry.EndPosition.Position - entry.StartPosition.Position;

            region.CharLength = length > 0 ? length : 0;

            Uri analysisTargetUri = new Uri(entry.Name, UriKind.Relative);

            var      physicalLocation = new PhysicalLocation(id: 0, fileLocation: new FileLocation(uri: analysisTargetUri, uriBaseId: null), region: region, contextRegion: null);
            Location location         = new Location()
            {
                PhysicalLocation = physicalLocation
            };

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

            if (entry.Fixes?.Any() == true)
            {
                IList <Replacement> replacements = new List <Replacement>();

                foreach (TSLintLogFix fix in entry.Fixes)
                {
                    Replacement replacement = new Replacement();

                    replacement.DeletedRegion = new Region
                    {
                        CharLength = fix.InnerLength,
                        CharOffset = fix.InnerStart
                    };

                    if (!string.IsNullOrEmpty(fix.InnerText))
                    {
                        replacement.InsertedContent = new FileContent
                        {
                            Text = fix.InnerText
                        };
                    }

                    replacements.Add(replacement);
                }

                FileChange sarifFileChange = new FileChange(fileLocation: new FileLocation(uri: analysisTargetUri, uriBaseId: null), replacements: replacements);

                Fix sarifFix = new Fix(description: null, fileChanges: new List <FileChange>()
                {
                    sarifFileChange
                });
                result.Fixes = new List <Fix> {
                    sarifFix
                };
            }

            return(result);
        }
Example #7
0
        private void ParseLocationsFromTraces(Result result)
        {
            CodeFlow codeFlow   = null;
            string   nodeLabel  = null;
            string   lastNodeId = null;
            bool?    isDefault  = null;

            while (!AtEndOf(_strings.Unified))
            {
                if (AtStartOf(_strings.Trace))
                {
                    codeFlow = SarifUtilities.CreateSingleThreadedCodeFlow();
                    result.CodeFlows.Add(codeFlow);

                    while (!AtEndOf(_strings.Trace))
                    {
                        if (AtStartOf(_strings.NodeRef))
                        {
                            string nodeId = _reader.GetAttribute(_strings.IdAttribute);

                            if (!string.IsNullOrWhiteSpace(nodeId))
                            {
                                var tfl = new ThreadFlowLocation();
                                _tflToNodeIdDictionary.Add(tfl, nodeId);
                                codeFlow.ThreadFlows[0].Locations.Add(tfl);
                            }

                            _reader.Read();
                        }
                        else if (AtStartOf(_strings.Node))
                        {
                            if (isDefault == null)
                            {
                                // We haven't found the default node yet, so check this one.
                                string isDefaultValue = _reader.GetAttribute(_strings.IsDefaultAttribute);

                                if (!string.IsNullOrWhiteSpace(isDefaultValue) &&
                                    bool.TryParse(isDefaultValue, out bool val) &&
                                    val == true)
                                {
                                    // This is the default, set the flag so we know to add a result location.
                                    isDefault = val;
                                }
                            }

                            nodeLabel = _reader.GetAttribute(_strings.LabelAttribute);
                            _reader.Read();
                        }
                        else if (AtStartOf(_strings.SourceLocation))
                        {
                            // Note: SourceLocation is an empty element (it has only attributes),
                            // so we can't call AtStartOfNonEmpty here.

                            string           snippetId        = _reader.GetAttribute(_strings.SnippetAttribute);
                            PhysicalLocation physicalLocation = ParsePhysicalLocationFromSourceInfo();

                            // Step past the empty SourceLocation element.
                            _reader.Read();

                            string actionType = null;
                            if (AtStartOf(_strings.Action))
                            {
                                actionType = _reader.GetAttribute(_strings.TypeAttribute);
                                actionType = actionType ?? string.Empty; // We use empty string to indicates there is an
                                                                         // Action element without a type attribute.

                                // If we don't have a label, get the <Action> value.
                                if (string.IsNullOrWhiteSpace(nodeLabel))
                                {
                                    nodeLabel = _reader.ReadElementContentAsString();
                                }
                            }

                            if (actionType == string.Empty)
                            {
                                if (codeFlow.ThreadFlows[0].Locations.Count > 0)
                                {
                                    // If there is no type attribute on the Action element, we treat
                                    // it as a note about the prior node.
                                    ThreadFlowLocation tfl = codeFlow.ThreadFlows[0].Locations.Last();

                                    // Annotate the location with the Action text.
                                    if (tfl?.Location != null)
                                    {
                                        tfl.Location.Annotations = new List <Region>();
                                        Region region = physicalLocation.Region;
                                        region.Message = new Message
                                        {
                                            Text = nodeLabel
                                        };
                                        tfl.Location.Annotations.Add(region);
                                    }
                                }
                            }
                            else
                            {
                                var location = new Location
                                {
                                    PhysicalLocation = physicalLocation
                                };

                                if (isDefault == true)
                                {
                                    result.Locations = new List <Location>();
                                    result.Locations.Add(location.DeepClone());
                                    result.RelatedLocations.Add(location.DeepClone());

                                    // Keep track of the snippet associated with the default location.
                                    // That's the snippet that we'll associate with the result.
                                    lastNodeId = snippetId;

                                    isDefault = false; // This indicates we have already found the default node.
                                }

                                var tfl = new ThreadFlowLocation
                                {
                                    Kinds    = ConvertActionTypeToLocationKinds(actionType),
                                    Location = location
                                };

                                if (!string.IsNullOrWhiteSpace(nodeLabel))
                                {
                                    tfl.Location.Message = new Message
                                    {
                                        Text = nodeLabel
                                    };
                                }

                                // Remember the id of the snippet associated with this location.
                                // We'll use it to fill the snippet text when we read the Snippets element later on.
                                if (!string.IsNullOrEmpty(snippetId))
                                {
                                    _tflToSnippetIdDictionary.Add(tfl, snippetId);
                                }

                                codeFlow.ThreadFlows[0].Locations.Add(tfl);
                            }
                        }
                        else
                        {
                            _reader.Read();
                        }
                    }
                }
                else
                {
                    _reader.Read();
                }
            }

            if (result.RelatedLocations.Any())
            {
                Location relatedLocation = result.RelatedLocations.Last();

                if (relatedLocation != null)
                {
                    relatedLocation.Id = 1;
                }
            }

            if (!string.IsNullOrEmpty(lastNodeId))
            {
                _resultToSnippetIdDictionary.Add(result, lastNodeId);
            }
        }
Example #8
0
        private void GenerateCodeFlows(Defect defect, Result result)
        {
            List <SFA> sfas = defect?.Path?.SFAs;

            if (sfas == null || sfas.Count == 0)
            {
                return;
            }

            int  step              = 0;
            var  locations         = new List <ThreadFlowLocation>();
            bool pathUsesKeyEvents = defect.Path.SFAs.Any(x => !string.IsNullOrWhiteSpace(x?.KeyEvent?.Id));

            foreach (var sfa in defect.Path.SFAs)
            {
                var region = new Region()
                {
                    StartColumn = sfa.Column + 1,
                    StartLine   = sfa.Line
                };

                var uri                = new Uri($"{sfa.FilePath}{sfa.FileName}", UriKind.Relative);
                var fileLocation       = new PhysicalLocation(id: 0, fileLocation: new FileLocation(uri: uri, uriBaseId: null), region: region, contextRegion: null);
                var threadFlowLocation = new ThreadFlowLocation
                {
                    Location = new Location
                    {
                        PhysicalLocation = fileLocation
                    },
                    Step = ++step
                };

                if (pathUsesKeyEvents)
                {
                    if (string.IsNullOrWhiteSpace(sfa.KeyEvent?.Id))
                    {
                        threadFlowLocation.Importance = ThreadFlowLocationImportance.Unimportant;
                    }
                    else
                    {
                        threadFlowLocation.SetProperty("keyEventId", sfa.KeyEvent.Id);

                        if (Enum.TryParse(sfa.KeyEvent.Importance, true, out ThreadFlowLocationImportance importance))
                        {
                            threadFlowLocation.Importance = importance;
                        }

                        if (!string.IsNullOrWhiteSpace(sfa.KeyEvent.Message) &&
                            threadFlowLocation.Location?.Message != null)
                        {
                            threadFlowLocation.Location.Message.Text = sfa.KeyEvent.Message;
                        }
                    }
                }

                locations.Add(threadFlowLocation);
            }

            result.CodeFlows = new List <CodeFlow>()
            {
                SarifUtilities.CreateSingleThreadedCodeFlow(locations)
            };
        }
Example #9
0
        /// <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 <ThreadFlowLocation>()
                {
                    new ThreadFlowLocation {
                        Location = new Location {
                            PhysicalLocation = source
                        }
                    },
                    new ThreadFlowLocation {
                        Location = new Location {
                            PhysicalLocation = primaryOrSink
                        }
                    }
                };
                result.CodeFlows = new List <CodeFlow>()
                {
                    SarifUtilities.CreateSingleThreadedCodeFlow(locations)
                };
            }

            return(result);
        }
Example #10
0
        private void WriteRunToErrorList(Run runLog)
        {
            List <SarifError> sarifErrors = new List <SarifError>();

            // Prefer optional fullName,  fall back to required Name property
            string toolName = runLog.Tool.FullName ?? runLog.Tool.Name;

            foreach (Result result in runLog.Results)
            {
                string       category, document, shortMessage, fullMessage;
                Region       region;
                NewLineIndex newLineIndex;
                IRule        rule = null;

                category = null;

                if (result.Properties != null)
                {
                    result.Properties.TryGetValue("category", out category);
                }

                foreach (Location location in result.Locations)
                {
                    region = null;

                    PhysicalLocation physicalLocation = null;
                    if (location.ResultFile != null)
                    {
                        physicalLocation = location.ResultFile;
                        document         = physicalLocation.Uri.LocalPath;
                        region           = physicalLocation.Region;
                    }
                    else if (location.AnalysisTarget != null)
                    {
                        physicalLocation = location.AnalysisTarget;
                        document         = physicalLocation.Uri.LocalPath;
                        region           = physicalLocation.Region;
                    }
                    else
                    {
                        document = location.FullyQualifiedLogicalName;
                    }

                    rule         = GetRule(runLog, result.RuleId);
                    shortMessage = result.GetMessageText(rule, concise: true);
                    fullMessage  = result.GetMessageText(rule, concise: false);

                    if (shortMessage == fullMessage)
                    {
                        fullMessage = null;
                    }

                    SarifError sarifError = new SarifError(document)
                    {
                        Region       = region,
                        RuleId       = result.RuleId,
                        RuleName     = rule?.Name,
                        Kind         = result.Kind,
                        Category     = category,
                        ShortMessage = shortMessage,
                        FullMessage  = fullMessage,
                        Tool         = toolName,
                        HelpLink     = rule?.HelpUri?.ToString()
                    };

                    CaptureAnnotatedCodeLocationCollections(result.Stacks, AnnotatedCodeLocationKind.Stack, sarifError);
                    CaptureAnnotatedCodeLocationCollections(result.CodeFlows, AnnotatedCodeLocationKind.CodeFlow, sarifError);
                    CaptureAnnotatedCodeLocations(result.RelatedLocations, AnnotatedCodeLocationKind.Stack, sarifError);

                    if (region != null)
                    {
                        sarifError.ColumnNumber = region.StartColumn - 1;
                        sarifError.LineNumber   = region.StartLine - 1;
                    }

                    sarifErrors.Add(sarifError);
                }

                // TODO zap this on implementing todo above
                if (result.RelatedLocations != null)
                {
                    foreach (AnnotatedCodeLocation annotation in result.RelatedLocations)
                    {
                        PhysicalLocation physicalLocation = annotation.PhysicalLocation;
                        region       = physicalLocation.Region;
                        shortMessage = annotation.Message;
                        document     = annotation.PhysicalLocation.Uri.LocalPath;

                        if (!this.documentToLineIndexMap.TryGetValue(document, out newLineIndex))
                        {
                            this.documentToLineIndexMap[document] = newLineIndex = new NewLineIndex(File.ReadAllText(document));
                        }

                        if (region != null)
                        {
                            region.Populate(newLineIndex);
                        }

                        SarifError sarifError = new SarifError(document)
                        {
                            Region       = region,
                            RuleId       = result.RuleId,
                            RuleName     = rule?.Name,
                            Kind         = ResultKind.Note,
                            Category     = "Related Location", // or should we prefer original result category?
                            ShortMessage = shortMessage,
                            FullMessage  = null,
                            Tool         = toolName
                        };

                        if (region != null)
                        {
                            sarifError.ColumnNumber = region.StartColumn - 1;
                            sarifError.LineNumber   = region.StartLine - 1;
                        }

                        sarifErrors.Add(sarifError);
                    }
                }

                CodeAnalysisResultManager.Instance.SarifErrors = sarifErrors;
                SarifTableDataSource.Instance.AddErrors(sarifErrors);
            }
        }
Example #11
0
        private Result MakeResultFromError(JsonError error)
        {
            var result = new Result();

            string       analysisTargetFilePath;
            NewLineIndex index = null;

            switch (error.Location)
            {
            case JsonErrorLocation.InstanceDocument:
                analysisTargetFilePath = _instanceFilePath;
                index = InstanceFileIndex;
                break;

            case JsonErrorLocation.Schema:
                analysisTargetFilePath = _schemaFilePath;
                index = SchemaFileIndex;
                break;

            default:
                analysisTargetFilePath = "unknown_file";
                break;
            }

            Uri analysisTargetUri = new Uri(analysisTargetFilePath);

            switch (error.Kind)
            {
            case JsonErrorKind.Syntax:
                result.RuleId           = JsonSyntaxErrorRule.Id;
                result.Kind             = ResultKind.Error;
                result.FormattedMessage = new FormattedMessage(
                    JsonSyntaxErrorFormatSpecifier, new string[] { error.Message });
                break;

            case JsonErrorKind.Validation:
                result.RuleId           = JsonSchemaValidationErrorRule.Id;
                result.Kind             = ResultKind.Error;
                result.FormattedMessage = new FormattedMessage(
                    JsonSchemaValidationErrorFormatSpecifier, new string[] { error.Message });
                break;

            default:
                result.RuleId           = UnknownErrorRule.Id;
                result.Kind             = ResultKind.InternalError;
                result.FormattedMessage = new FormattedMessage(
                    UnknownErrorFormatSpecifier, new string[] { error.Kind.ToString() });
                break;
            }

            Region region;

            if (index != null)
            {
                region = new Region
                {
                    Offset = error.Start,
                    Length = error.Length
                };

                region.Populate(index);
            }
            else
            {
                region = new Region();
            }

            var plc = new PhysicalLocation
            {
                Uri    = analysisTargetUri,
                Region = region
            };

            var location = new Location
            {
                AnalysisTarget = new PhysicalLocation(plc)
            };

            result.Locations = new List <Location> {
                location
            };

            return(result);
        }
        public async Task <IActionResult> AddHardwareItem(HardwareItem hardwareItem)
        {
            if (ModelState.IsValid)
            {
                var user = await _userManager.GetUserAsync(User);

                var category = new Category()
                {
                    Name     = hardwareItem.Category.Name,
                    User     = user,
                    LastUsed = DateTime.Now.Date
                };
                var model = new ItemModel()
                {
                    Name     = hardwareItem.Model.Name,
                    User     = user,
                    LastUsed = DateTime.Now.Date
                };
                var manufacturer = new Manufacturer()
                {
                    Name     = hardwareItem.Manufacturer.Name,
                    User     = user,
                    LastUsed = DateTime.Now.Date
                };
                var physicalLocation = new PhysicalLocation()
                {
                    Name     = hardwareItem.PhysicalLocation.Name,
                    User     = user,
                    LastUsed = DateTime.Now.Date
                };

                var dbCategory = await _applicationDbContext.Categories
                                 .ToAsyncEnumerable()
                                 .SingleOrDefaultAsync(c => c.Name == category.Name && c.User == category.User);

                var dbModel = await _applicationDbContext.ItemModels
                              .ToAsyncEnumerable()
                              .SingleOrDefaultAsync(c => c.Name == model.Name && c.User == model.User);

                var dbManufacturer = await _applicationDbContext.Manufacturers
                                     .ToAsyncEnumerable()
                                     .SingleOrDefaultAsync(c => c.Name == manufacturer.Name && c.User == manufacturer.User);

                var dbPhysicalLocation = await _applicationDbContext.PhysicalLocations
                                         .ToAsyncEnumerable()
                                         .SingleOrDefaultAsync(c => c.Name == physicalLocation.Name && c.User == physicalLocation.User);

                if (dbCategory == null)
                {
                    dbCategory = (await _applicationDbContext.Categories.AddAsync(category)).Entity;
                }
                else
                {
                    dbCategory.Update(category);
                    dbCategory.Uses++;
                    _applicationDbContext.Entry(dbCategory).State = EntityState.Modified;
                }

                if (dbModel == null)
                {
                    dbModel = (await _applicationDbContext.ItemModels.AddAsync(model)).Entity;
                }
                else
                {
                    dbModel.Update(model);
                    dbModel.Uses++;
                    _applicationDbContext.Entry(dbModel).State = EntityState.Modified;
                }

                if (dbManufacturer == null)
                {
                    dbManufacturer = (await _applicationDbContext.Manufacturers.AddAsync(manufacturer)).Entity;
                }
                else
                {
                    dbManufacturer.Update(manufacturer);
                    dbManufacturer.Uses++;
                    _applicationDbContext.Entry(dbManufacturer).State = EntityState.Modified;
                }

                if (dbPhysicalLocation == null)
                {
                    dbPhysicalLocation = (await _applicationDbContext.PhysicalLocations.AddAsync(physicalLocation)).Entity;
                }
                else
                {
                    dbPhysicalLocation.Update(physicalLocation);
                    dbPhysicalLocation.Uses++;
                    _applicationDbContext.Entry(dbPhysicalLocation).State = EntityState.Modified;
                }
                await _applicationDbContext.SaveChangesAsync();

                if (hardwareItem.ReceiptFiles != null && hardwareItem.ReceiptFiles.Count() > 0)
                {
                    var receipts = await hardwareItem.ReceiptFiles
                                   .ToAsyncEnumerable()
                                   .SelectAwait(async h => await GetReceiptAsBytes(h))
                                   .ToListAsync();

                    hardwareItem.Receipts = receipts;
                }

                hardwareItem.Category         = null;
                hardwareItem.Model            = null;
                hardwareItem.Manufacturer     = null;
                hardwareItem.PhysicalLocation = null;

                var inventoryItems = _applicationDbContext.HardwareItems;
                hardwareItem = (await inventoryItems.AddAsync(hardwareItem)).Entity;
                //await _applicationDbContext.SaveChangesAsync();

                hardwareItem.Category         = dbCategory;
                hardwareItem.Model            = dbModel;
                hardwareItem.Manufacturer     = dbManufacturer;
                hardwareItem.PhysicalLocation = dbPhysicalLocation;

                await _applicationDbContext.SaveChangesAsync();
            }

            hardwareItem = (await PrepareComboBoxesAsync(hardwareItem)) as HardwareItem;

            return(View(hardwareItem));
            //return RedirectToAction("EditHardwareItem", new { hardwareItem = hardwareItem });
        }
Example #13
0
            public void Should_Generate_Report()
            {
                // Given
                var fixture = new SarifIssueReportFixture();
                var issues  =
                    new List <IIssue>
                {
                    IssueBuilder
                    .NewIssue("Message Foo.", "ProviderType Foo", "ProviderName Foo")
                    .InFile(@"src\Cake.Issues.Reporting.Sarif.Tests\SarifIssueReportGeneratorTests.cs", 10)
                    .InProjectFile(@"src\Cake.Issues.Reporting.Sarif.Tests\Cake.Issues.Reporting.Sarif.Tests.csproj")
                    .OfRule("Rule Foo")
                    .WithPriority(IssuePriority.Error)
                    .Create(),

                    // Issue to exercise creation of rule metadata with helpUri, and messages
                    // in Markdown format.
                    IssueBuilder
                    .NewIssue("Message Bar.", "ProviderType Bar", "ProviderName Bar")
                    .InFile(@"src\Cake.Issues.Reporting.Sarif.Tests\SarifIssueReportGeneratorTests.cs", 12, 5)
                    .OfRule("Rule Bar", new Uri("https://www.example.come/rules/bar.html"))
                    .WithPriority(IssuePriority.Warning)
                    .WithMessageInMarkdownFormat("Message Bar -- now in **Markdown**!")
                    .Create(),

                    // Issue to exercise the corner case where ruleId is absent (so no rule
                    // metadata is created) but helpUri is present (so it is stored in the
                    // result's property bag.
                    IssueBuilder
                    .NewIssue("Message Bar 2.", "ProviderType Bar", "ProviderName Bar")
                    .InFile(@"src\Cake.Issues.Reporting.Sarif.Tests\SarifIssueReportGeneratorTests.cs", 23, 42, 5, 10)
                    .OfRule(null, new Uri("https://www.example.come/rules/bar2.html"))
                    .WithPriority(IssuePriority.Warning)
                    .Create(),
                };

                // When
                var logContents = fixture.CreateReport(issues);

                // Then
                var sarifLog = JsonConvert.DeserializeObject <SarifLog>(logContents);

                // There are two runs because there are two issue providers.
                sarifLog.Runs.Count.ShouldBe(2);

                Run run = sarifLog.Runs[0];

                run.Tool.Driver.Name.ShouldBe("ProviderType Foo");

                // This run doesn't have any rules that specify a help URI, so we didn't bother
                // adding rule metadata.
                run.Tool.Driver.Rules.ShouldBeNull();

                run.Results.Count.ShouldBe(1);

                Result result = run.Results[0];

                result.RuleId.ShouldBe("Rule Foo");
                result.RuleIndex.ShouldBe(-1); // because there's no rule metadata to point to.
                result.Message.Text.ShouldBe("Message Foo.");
                result.Message.Markdown.ShouldBeNull();
                result.Level.ShouldBe(FailureLevel.Error);
                result.Kind.ShouldBe(ResultKind.Fail);

                result.Locations.Count.ShouldBe(1);
                PhysicalLocation physicalLocation = result.Locations[0].PhysicalLocation;

                physicalLocation.ArtifactLocation.Uri.OriginalString.ShouldBe("src/Cake.Issues.Reporting.Sarif.Tests/SarifIssueReportGeneratorTests.cs");
                physicalLocation.Region.StartLine.ShouldBe(10);

                run.OriginalUriBaseIds.Count.ShouldBe(1);
                run.OriginalUriBaseIds[SarifIssueReportGenerator.RepoRootUriBaseId].Uri.LocalPath.ShouldBe(SarifIssueReportFixture.RepositoryRootPath);

                run = sarifLog.Runs[1];
                run.Tool.Driver.Name.ShouldBe("ProviderType Bar");

                // This run has a rule that specifies a help URI, so we added rule metadata.
                IList <ReportingDescriptor> rules = run.Tool.Driver.Rules;

                rules.Count.ShouldBe(1);

                ReportingDescriptor rule = rules[0];

                rule.Id.ShouldBe("Rule Bar");
                rule.HelpUri.OriginalString.ShouldBe("https://www.example.come/rules/bar.html");

                run.Results.Count.ShouldBe(2);

                result = run.Results[0];
                result.RuleId.ShouldBe("Rule Bar");
                result.RuleIndex.ShouldBe(0); // The index of the metadata for this rule in the rules array.
                result.Message.Text.ShouldBe("Message Bar.");
                result.Message.Markdown.ShouldBe("Message Bar -- now in **Markdown**!");
                result.Level.ShouldBe(FailureLevel.Warning);
                result.Kind.ShouldBe(ResultKind.Fail);

                result.Locations.Count.ShouldBe(1);
                physicalLocation = result.Locations[0].PhysicalLocation;
                physicalLocation.ArtifactLocation.Uri.OriginalString.ShouldBe("src/Cake.Issues.Reporting.Sarif.Tests/SarifIssueReportGeneratorTests.cs");
                physicalLocation.Region.StartLine.ShouldBe(12);
                physicalLocation.Region.StartColumn.ShouldBe(5);

                // This run also includes an issue with a rule URL but no rule name, so we'll find
                // the rule URL in the result's property bag.
                result = run.Results[1];
                result.RuleId.ShouldBeNull();
                result.RuleIndex.ShouldBe(-1);
                result.GetProperty(SarifIssueReportGenerator.RuleUrlPropertyName).ShouldBe("https://www.example.come/rules/bar2.html");
                result.Message.Text.ShouldBe("Message Bar 2.");
                result.Level.ShouldBe(FailureLevel.Warning);
                result.Kind.ShouldBe(ResultKind.Fail);

                result.Locations.Count.ShouldBe(1);
                physicalLocation = result.Locations[0].PhysicalLocation;
                physicalLocation.ArtifactLocation.Uri.OriginalString.ShouldBe("src/Cake.Issues.Reporting.Sarif.Tests/SarifIssueReportGeneratorTests.cs");
                physicalLocation.Region.StartLine.ShouldBe(23);
                physicalLocation.Region.EndLine.ShouldBe(42);
                physicalLocation.Region.StartColumn.ShouldBe(5);
                physicalLocation.Region.EndColumn.ShouldBe(10);

                run.OriginalUriBaseIds.Count.ShouldBe(1);
                run.OriginalUriBaseIds[SarifIssueReportGenerator.RepoRootUriBaseId].Uri.LocalPath.ShouldBe(SarifIssueReportFixture.RepositoryRootPath);
            }
Example #14
0
        private void GenerateCodeFlows(Defect defect, Result result)
        {
            List <SFA> sfas = defect?.Path?.SFAs;

            if (sfas == null || sfas.Count == 0)
            {
                return;
            }

            int  step              = 0;
            var  locations         = new List <AnnotatedCodeLocation>();
            bool pathUsesKeyEvents = defect.Path.SFAs.Any(x => !string.IsNullOrWhiteSpace(x?.KeyEvent?.Id));

            foreach (var sfa in defect.Path.SFAs)
            {
                var region = new Region()
                {
                    StartColumn = sfa.Column + 1,
                    StartLine   = sfa.Line
                };

                var uri                   = new Uri($"{sfa.FilePath}{sfa.FileName}", UriKind.Relative);
                var fileLocation          = new PhysicalLocation(uri: uri, uriBaseId: null, region: region);
                var annotatedCodeLocation = new AnnotatedCodeLocation
                {
                    PhysicalLocation = fileLocation,
                    Step             = ++step
                };

                if (pathUsesKeyEvents)
                {
                    if (string.IsNullOrWhiteSpace(sfa.KeyEvent?.Id))
                    {
                        annotatedCodeLocation.Importance = AnnotatedCodeLocationImportance.Unimportant;
                    }
                    else
                    {
                        annotatedCodeLocation.SetProperty("keyEventId", sfa.KeyEvent.Id);
                        if (Enum.TryParse(sfa.KeyEvent.Kind, true, out AnnotatedCodeLocationKind kind))
                        {
                            annotatedCodeLocation.Kind = kind;
                        }

                        if (Enum.TryParse(sfa.KeyEvent.Importance, true, out AnnotatedCodeLocationImportance importance))
                        {
                            annotatedCodeLocation.Importance = importance;
                        }

                        if (!string.IsNullOrWhiteSpace(sfa.KeyEvent.Message))
                        {
                            annotatedCodeLocation.Message = sfa.KeyEvent.Message;
                        }
                    }
                }

                locations.Add(annotatedCodeLocation);
            }

            result.CodeFlows = new List <CodeFlow>()
            {
                new CodeFlow
                {
                    Locations = locations
                }
            };
        }
Example #15
0
        private IList <AnnotatedCodeLocation> NormalizeRawMessage(string rawMessage, out string normalizedMessage)
        {
            // The rawMessage contains embedded related locations. We need to extract the related locations and reformat the rawMessage embedded links wrapped in [brackets].
            // Example rawMessage
            //     po (coming from [["hbm"|"relative://windows/Core/ntgdi/gre/brushapi.cxx:176:4882:3"],["hbm"|"relative://windows/Core/ntgdi/gre/windows/ntgdi.c:1873:50899:3"],["hbm"|"relative://windows/Core/ntgdi/gre/windows/ntgdi.c:5783:154466:3"]]) may not have been checked for validity before call to vSync.
            // Example normalizedMessage
            //     po (coming from [hbm]) may not have been checked for validity before call to vSync.
            // Example relatedLocations
            //     relative://windows/Core/ntgdi/gre/brushapi.cxx:176:4882:3
            //     relative://windows/Core/ntgdi/gre/windows/ntgdi.c:1873:50899:3
            //     relative://windows/Core/ntgdi/gre/windows/ntgdi.c:5783:154466:3
            List <AnnotatedCodeLocation> relatedLocations = null;

            normalizedMessage = String.Empty;

            var sb = new StringBuilder();

            int index = rawMessage.IndexOf("[[");

            while (index > -1)
            {
                sb.Append(rawMessage.Substring(0, index));

                rawMessage = rawMessage.Substring(index + 2);

                index = rawMessage.IndexOf("]]");

                // embeddedLinksText contains the text for one set of embedded links except for the leading '[[' and trailing ']]'
                // "hbm"|"relative://windows/Core/ntgdi/gre/brushapi.cxx:176:4882:3"],["hbm"|"relative://windows/Core/ntgdi/gre/windows/ntgdi.c:1873:50899:3"],["hbm"|"relative://windows/Core/ntgdi/gre/windows/ntgdi.c:5783:154466:3"
                string embeddedLinksText = rawMessage.Substring(0, index - 1);

                // embeddedLinks splits the set of embedded links into invividual links
                // 1.  "hbm"|"relative://windows/Core/ntgdi/gre/brushapi.cxx:176:4882:3"
                // 2.  "hbm"|"relative://windows/Core/ntgdi/gre/windows/ntgdi.c:1873:50899:3"
                // 3.  "hbm"|"relative://windows/Core/ntgdi/gre/windows/ntgdi.c:5783:154466:3"

                string[] embeddedLinks = embeddedLinksText.Split(new string[] { "],[" }, StringSplitOptions.None);

                foreach (string embeddedLink in embeddedLinks)
                {
                    string[] tokens = embeddedLink.Split(new char[] { '\"' }, StringSplitOptions.RemoveEmptyEntries);

                    // save the text portion of the link
                    embeddedLinksText = tokens[0];

                    string   location       = tokens[2];
                    string[] locationTokens = location.Split(':');

                    relatedLocations = relatedLocations ?? new List <AnnotatedCodeLocation>();
                    PhysicalLocation physicalLocation;

                    if (locationTokens[0].Equals("file", StringComparison.OrdinalIgnoreCase))
                    {
                        // Special case for file paths, e.g.:
                        // "IComparable"|"file://C:/Windows/Microsoft.NET/Framework/v2.0.50727/mscorlib.dll:0:0:0:0"
                        physicalLocation = new PhysicalLocation
                        {
                            Uri    = new Uri($"{locationTokens[0]}:{locationTokens[1]}:{locationTokens[2]}", UriKind.Absolute),
                            Region = new Region
                            {
                                StartLine = Int32.Parse(locationTokens[3]),
                                Offset    = Int32.Parse(locationTokens[4]),
                                Length    = Int32.Parse(locationTokens[5])
                            }
                        };
                    }
                    else
                    {
                        physicalLocation = new PhysicalLocation
                        {
                            Uri       = new Uri(locationTokens[1].Substring(1), UriKind.Relative),
                            UriBaseId = "$srcroot",
                            Region    = new Region
                            {
                                StartLine = Int32.Parse(locationTokens[2]),
                                Offset    = Int32.Parse(locationTokens[3]),
                                Length    = Int32.Parse(locationTokens[4])
                            }
                        };
                    }

                    var relatedLocation = new AnnotatedCodeLocation
                    {
                        PhysicalLocation = physicalLocation
                    };

                    relatedLocations.Add(relatedLocation);
                }

                // Re-add the text portion of the link in brackets.
                sb.Append($"[{embeddedLinksText}]");

                rawMessage = rawMessage.Substring(index + "]]".Length);
                index      = rawMessage.IndexOf("[[");
            }

            sb.Append(rawMessage);
            normalizedMessage = sb.ToString();
            return(relatedLocations);
        }
Example #16
0
        private void ParseLocationFromAnalysisInfo(Result result)
        {
            CodeFlow codeFlow = result.CodeFlows.First();
            int      step     = 0;

            _reader.Read();
            string lastSnippetId = null;

            while (!AtEndOf(_strings.AnalysisInfo))
            {
                // Note: SourceLocation is an empty element (it has only attributes),
                // so we can't call AtStartOfNonEmpty here.
                if (AtStartOf(_strings.SourceLocation))
                {
                    string           snippetId = _reader.GetAttribute(_strings.SnippetAttribute);
                    PhysicalLocation physLoc   = ParsePhysicalLocationFromSourceInfo();

                    var acl = new AnnotatedCodeLocation
                    {
                        Step             = step++,
                        PhysicalLocation = physLoc
                    };

                    // Remember the id of the snippet associated with this location.
                    // We'll use it to fill the snippet text when we read the Snippets element later on.
                    if (!String.IsNullOrEmpty(snippetId))
                    {
                        _aclToSnippetIdDictionary.Add(acl, snippetId);
                    }

                    codeFlow.Locations.Add(acl);

                    // Keep track of the snippet associated with the last location in the
                    // CodeFlow; that's the snippet that we'll associate with the Result
                    // as a whole.
                    lastSnippetId = snippetId;

                    // Step past the empty element.
                    _reader.Read();
                }
                else
                {
                    _reader.Read();
                }
            }

            if (codeFlow.Locations.Any())
            {
                result.Locations.Add(new Location
                {
                    // TODO: Confirm that the traces are ordered chronologically
                    // (so that we really do want to use the last one as the
                    // overall result location).
                    ResultFile = codeFlow.Locations.Last().PhysicalLocation
                });

                if (!String.IsNullOrEmpty(lastSnippetId))
                {
                    _resultToSnippetIdDictionary.Add(result, lastSnippetId);
                }
            }
        }
Example #17
0
 protected override void Analyze(PhysicalLocation physicalLocation, string physicalLocationPointer)
 {
     AnalyzeUri(physicalLocation.Uri, physicalLocationPointer);
 }
Example #18
0
        private void AnalyzeManagedAssembly(string assemblyFilePath, IEnumerable <string> roslynAnalyzerFilePaths, BinaryAnalyzerContext context)
        {
            if (roslynAnalyzerFilePaths == null)
            {
                return;
            }

            if (_globalRoslynAnalysisContext == null)
            {
                _globalRoslynAnalysisContext = new RoslynAnalysisContext();

                // We could use the ILDiagnosticsAnalyzer factory method that initializes
                // an object instance from an enumerable collection of analyzer paths. We
                // initialize a context object from each path one-by-one instead, in order
                // to make an attempt to load each specified analyzer. We will therefore
                // collect information on each analyzer that fails to load. We will also
                // proceed with performing as much analysis as possible. Ultimately, a
                // single analyzer load failure will return in BinSkim returning a non-zero
                // failure code from the run.
                foreach (string analyzerFilePath in roslynAnalyzerFilePaths)
                {
                    InvokeCatchingRelevantIOExceptions
                    (
                        action: () => { ILDiagnosticsAnalyzer.LoadAnalyzer(analyzerFilePath, _globalRoslynAnalysisContext); },
                        exceptionHandler: (ex) =>
                    {
                        Errors.LogExceptionLoadingPlugin(analyzerFilePath, context, ex);
                    }
                    );
                }
            }

            Debug.Assert(context.MimeType == Sarif.Writers.MimeType.Binary);

            ILDiagnosticsAnalyzer roslynAnalyzer = ILDiagnosticsAnalyzer.Create(_globalRoslynAnalysisContext);

            roslynAnalyzer.Analyze(assemblyFilePath, diagnostic =>
            {
                // 0. Populate various members
                var result     = new Result();
                result.Level   = diagnostic.Severity.ConvertToResultLevel();
                result.Message = new Message {
                    Text = diagnostic.GetMessage()
                };

                if (diagnostic.IsSuppressed)
                {
                    result.SuppressionStates = SuppressionStates.SuppressedInSource;
                }

                result.SetProperty("Severity", diagnostic.Severity.ToString());
                result.SetProperty("IsWarningAsError", diagnostic.IsWarningAsError.ToString());
                result.SetProperty("WarningLevel", diagnostic.WarningLevel.ToString());

                foreach (string key in diagnostic.Properties.Keys)
                {
                    string value;
                    if (result.TryGetProperty(key, out value))
                    {
                        // If the properties bag recapitulates one of the values set
                        // previously, we'll retain the already set value
                        continue;
                    }
                    result.SetProperty(key, diagnostic.Properties[key]);
                }

                result.Locations = new List <Sarif.Location>();

                // 1. Record the assembly under analysis
                result.AnalysisTarget = new ArtifactLocation {
                    Uri = new Uri(assemblyFilePath)
                };

                // 2. Record the actual location associated with the result
                var region = diagnostic.Location.ConvertToRegion();
                string filePath;
                PhysicalLocation resultFile = null;

                if (diagnostic.Location != Location.None)
                {
                    filePath = diagnostic.Location.GetLineSpan().Path;

                    resultFile = new PhysicalLocation
                    {
                        ArtifactLocation = { Uri = new Uri(filePath) },
                        Region           = region
                    };
                }

                result.Locations.Add(new Sarif.Location()
                {
                    PhysicalLocation = resultFile
                });


                // 3. If present, emit additional locations associated with diagnostic.
                //    According to docs, these locations typically reference related
                //    locations (i.e., they are not locations that specify other
                //    occurrences of a problem).

                if (diagnostic.AdditionalLocations != null && diagnostic.AdditionalLocations.Count > 0)
                {
                    result.RelatedLocations = new List <Sarif.Location>();

                    foreach (Location location in diagnostic.AdditionalLocations)
                    {
                        filePath = location.GetLineSpan().Path;
                        region   = location.ConvertToRegion();

                        result.RelatedLocations.Add(new Sarif.Location
                        {
                            Message = new Message {
                                Text = "Additional location"
                            },
                            PhysicalLocation = new PhysicalLocation
                            {
                                ArtifactLocation = new ArtifactLocation {
                                    Uri = new Uri(filePath)
                                },
                                Region = region
                            }
                        });
                    }
                }

                ReportingDescriptor rule = diagnostic.ConvertToRuleDescriptor();
                context.Logger.Log(null, result);
            });
        }
 protected override void Analyze(PhysicalLocation physicalLocation, string physicalLocationPointer)
 {
     AnalyzeUri(physicalLocation.Uri, physicalLocationPointer);
 }
Example #20
0
 public static Uri FileUri(this PhysicalLocation physicalLocation, Run run)
 {
     return(FileUri(physicalLocation?.ArtifactLocation, run));
 }
Example #21
0
        private void AddFile(PhysicalLocation physicalLocation)
        {
            if (physicalLocation == null)
            {
                return;
            }

            Uri uri = physicalLocation.Uri;
            string key = UriHelper.MakeValidUri(uri.OriginalString);
            string filePath = key;

            if (uri.IsAbsoluteUri && uri.IsFile)
            {
                filePath = uri.LocalPath;
            }

            if (!_fileInfoDictionary.ContainsKey(key))
            {
                _fileInfoDictionary.Add(
                    key,
                    new FileData
                    {
                        MimeType = _mimeTypeClassifier(filePath)
                    });
            }
        }
Example #22
0
        private IList <Location> NormalizeRawMessage(string rawMessage, out string normalizedMessage)
        {
            // The rawMessage contains embedded related locations. We need to extract the related locations and reformat the rawMessage embedded links wrapped in [brackets].
            // Example rawMessage
            //     po (coming from [["hbm"|"relative://code/.../file1.cxx:176:4882:3"],["hbm"|"relative://code/.../file2.c:1873:50899:3"],["hbm"|"relative://code/.../file2.c:5783:154466:3"]]) may not have been checked for validity before call to vSync.
            // Example normalizedMessage, where 'id' is the related location id to link to
            //   Note: the first link in the message links to the first related location in the list, the second link to the second, etc.
            //     po (coming from [hbm](id)) may not have been checked for validity before call to vSync.
            // Example relatedLocations
            //     relative://code/.../file1.cxx:176:4882:3
            //     relative://code/.../file2.c:1873:50899:3
            //     relative://code/.../file2.c:5783:154466:3
            List <Location> relatedLocations = null;

            var sb = new StringBuilder();

            int count     = 0;
            int linkIndex = 0;
            int index     = rawMessage.IndexOf("[[");

            while (index > -1)
            {
                sb.Append(rawMessage.Substring(0, index));

                rawMessage = rawMessage.Substring(index + 2);

                index = rawMessage.IndexOf("]]");

                // embeddedLinksText contains the text for one set of embedded links except for the leading '[[' and trailing ']]'
                // "hbm"|"relative:/code/.../file1.cxx:176:4882:3"],["hbm"|"relative://code/.../file2.c:1873:50899:3"],["hbm"|"relative://code/.../file2.c:5783:154466:3"
                string embeddedLinksText = rawMessage.Substring(0, index - 1);

                // embeddedLinks splits the set of embedded links into invividual links
                // 1.  "hbm"|"relative://code/.../file1.cxx:176:4882:3"
                // 2.  "hbm"|"relative://code/.../file2.c:1873:50899:3"
                // 3.  "hbm"|"relative://code/.../file2.c:5783:154466:3"

                string[] embeddedLinks = embeddedLinksText.Split(new string[] { "],[" }, StringSplitOptions.None);

                foreach (string embeddedLink in embeddedLinks)
                {
                    string[] tokens = embeddedLink.Split(new char[] { '\"' }, StringSplitOptions.RemoveEmptyEntries);

                    // save the text portion of the link
                    embeddedLinksText = tokens[0];

                    string   location       = tokens[2];
                    string[] locationTokens = location.Split(':');

                    relatedLocations = relatedLocations ?? new List <Location>();
                    PhysicalLocation physicalLocation;

                    if (locationTokens[0].Equals("file", StringComparison.OrdinalIgnoreCase))
                    {
                        // Special case for file paths, e.g.:
                        // "IComparable"|"file://C:/Windows/Microsoft.NET/Framework/v2.0.50727/mscorlib.dll:0:0:0:0"
                        physicalLocation = new PhysicalLocation
                        {
                            ArtifactLocation = new ArtifactLocation
                            {
                                Uri = new Uri($"{locationTokens[0]}:{locationTokens[1]}:{locationTokens[2]}", UriKind.Absolute)
                            },
                            Region = new Region
                            {
                                StartLine  = Int32.Parse(locationTokens[3]),
                                ByteOffset = Int32.Parse(locationTokens[4]),
                                ByteLength = Int32.Parse(locationTokens[5])
                            }
                        };
                    }
                    else
                    {
                        physicalLocation = new PhysicalLocation
                        {
                            ArtifactLocation = new ArtifactLocation
                            {
                                Uri       = new Uri(locationTokens[1].Substring(1), UriKind.Relative),
                                UriBaseId = "$srcroot"
                            },
                            Region = new Region
                            {
                                StartLine  = Int32.Parse(locationTokens[2]),
                                ByteOffset = Int32.Parse(locationTokens[3]),
                                ByteLength = Int32.Parse(locationTokens[4])
                            }
                        };
                    }

                    // TODO: Region.ByteOffset is not being handled correctly in SemmleQlConverter. Fix this!
                    // https://github.com/Microsoft/sarif-sdk/issues/1458

                    if (physicalLocation.Region.ByteLength == 0)
                    {
                        physicalLocation.Region.ByteOffset = -1;
                    }

                    var relatedLocation = new Location
                    {
                        Id = ++count,
                        PhysicalLocation = physicalLocation
                    };

                    relatedLocations.Add(relatedLocation);
                }

                // Re-add the text portion of the link in brackets with the location id in parens, e.g. [link text](id)
                sb.Append($"[{embeddedLinksText}]({relatedLocations[linkIndex++].Id})");

                rawMessage = rawMessage.Substring(index + "]]".Length);
                index      = rawMessage.IndexOf("[[");
            }

            sb.Append(rawMessage);
            normalizedMessage = sb.ToString();
            return(relatedLocations);
        }
        /// <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;
            result.ToolFingerprint = 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 = String.Format(CultureInfo.InvariantCulture, SarifResources.FortifyFallbackMessage, result.RuleId);
            }
            else
            {
                result.Message = String.Join(Environment.NewLine, messageComponents);
            }

            var extraProperties = new Dictionary <string, string>();

            extraProperties.Add("kingdom", fortify.Kingdom);
            if (fortify.Priority != null)
            {
                extraProperties.Add("priority", fortify.Priority);
            }

            if (!fortify.CweIds.IsDefaultOrEmpty)
            {
                extraProperties.Add("cwe", String.Join(", ",
                                                       fortify.CweIds.Select(id => id.ToString(CultureInfo.InvariantCulture))));
            }

            if (fortify.RuleId != null)
            {
                extraProperties.Add("fortifyRuleId", fortify.RuleId);
            }

            result.Properties = extraProperties;

            PhysicalLocation primaryOrSink = ConvertFortifyLocationToPhysicalLocation(fortify.PrimaryOrSink);

            result.Locations = new HashSet <Location>
            {
                new Location
                {
                    ResultFile = primaryOrSink
                }
            };

            if (fortify.Source != null)
            {
                PhysicalLocation source = ConvertFortifyLocationToPhysicalLocation(fortify.Source);
                result.CodeFlows = new HashSet <CodeFlow>
                {
                    new CodeFlow
                    {
                        Locations = new List <AnnotatedCodeLocation>
                        {
                            new AnnotatedCodeLocation {
                                PhysicalLocation = source
                            },
                            new AnnotatedCodeLocation {
                                PhysicalLocation = primaryOrSink
                            }
                        }
                    }
                };
            }

            return(result);
        }
Example #24
0
        public override PhysicalLocation VisitPhysicalLocation(PhysicalLocation node)
        {
            if (node.Region == null || node.Region.IsBinaryRegion)
            {
                goto Exit;
            }

            bool insertRegionSnippets      = _dataToInsert.HasFlag(OptionallyEmittedData.RegionSnippets);
            bool overwriteExistingData     = _dataToInsert.HasFlag(OptionallyEmittedData.OverwriteExistingData);
            bool insertContextCodeSnippets = _dataToInsert.HasFlag(OptionallyEmittedData.ContextRegionSnippets);
            bool populateRegionProperties  = _dataToInsert.HasFlag(OptionallyEmittedData.ComprehensiveRegionProperties);

            if (insertRegionSnippets || populateRegionProperties || insertContextCodeSnippets)
            {
                Region           expandedRegion;
                ArtifactLocation artifactLocation = node.ArtifactLocation;

                _fileRegionsCache = _fileRegionsCache ?? new FileRegionsCache(_run);

                if (artifactLocation.Uri == null && artifactLocation.Index >= 0)
                {
                    // Uri is not stored at result level, but we have an index to go look in run.Artifacts
                    // we must pick the ArtifactLocation details from run.artifacts array
                    Artifact artifactFromRun = _run.Artifacts[artifactLocation.Index];
                    artifactLocation = artifactFromRun.Location;
                }

                // If we can resolve a file location to a newly constructed
                // absolute URI, we will prefer that
                if (!artifactLocation.TryReconstructAbsoluteUri(_run.OriginalUriBaseIds, out Uri resolvedUri))
                {
                    resolvedUri = artifactLocation.Uri;
                }

                if (!resolvedUri.IsAbsoluteUri)
                {
                    goto Exit;
                }

                expandedRegion = _fileRegionsCache.PopulateTextRegionProperties(node.Region, resolvedUri, populateSnippet: insertRegionSnippets);

                ArtifactContent originalSnippet = node.Region.Snippet;

                if (populateRegionProperties)
                {
                    node.Region = expandedRegion;
                }

                if (originalSnippet == null || overwriteExistingData)
                {
                    node.Region.Snippet = expandedRegion.Snippet;
                }
                else
                {
                    node.Region.Snippet = originalSnippet;
                }

                if (insertContextCodeSnippets && (node.ContextRegion == null || overwriteExistingData))
                {
                    node.ContextRegion = _fileRegionsCache.ConstructMultilineContextSnippet(expandedRegion, resolvedUri);
                }
            }

Exit:
            return(base.VisitPhysicalLocation(node));
        }
Example #25
0
 public void ApplyTo(PhysicalLocation physicalLocation)
 {
     physicalLocation.Region        = this.Region;
     physicalLocation.ContextRegion = this.ContextRegion;
 }