├── .gitignore
├── .nuget
└── NuGet.exe
├── BuildAndTest.cmd
├── LICENSE
├── README.md
├── SECURITY.md
└── src
├── Nuget
└── Sarif.Driver.nuspec
├── Sarif.Driver.UnitTests
├── AnalyzeCommandTests.cs
├── ExceptionCondition.cs
├── ExceptionRaisingRule.cs
├── Properties
│ └── AssemblyInfo.cs
├── Sarif.Driver.UnitTests.csproj
├── SarifHelpers.cs
├── TestAnalysisContext.cs
├── TestAnalyzeCommand.cs
├── TestAnalyzeOptions.cs
├── TestMessageLogger.cs
└── packages.config
├── Sarif.Driver.sln
├── Sarif.Driver
├── ArgumentSplitter.cs
├── BrandedVersionAttribute.cs
├── Configuration
│ ├── ConfigurationBase.cs
│ ├── ConfigurationParseContext.cs
│ ├── FieldAttribute.cs
│ ├── FieldTypes.cs
│ └── NoMinusAttribute.cs
├── DisposableEnumerable.cs
├── DisposableEnumerableView.cs
├── DriverResources.resx
├── EnumerableExtensions.cs
├── EnvironmentVariables.cs
├── ExceptionStrings.Designer.cs
├── ExceptionStrings.resx
├── FileSpecifier.cs
├── FileStreamExtensionMethods.cs
├── FileSystem.cs
├── IAppConfig.cs
├── IEnvironmentVariables.cs
├── IFileSystem.cs
├── KeyEventImportance.cs
├── LineInfo.cs
├── MultiplyByPrimesHash.cs
├── MurmurHash.cs
├── NewLineIndex.cs
├── OffsetInfo.cs
├── Pair.cs
├── PathExtensions.cs
├── Properties
│ └── AssemblyInfo.cs
├── Ref.cs
├── ReferenceEqualityComparer`1.cs
├── RentalStream.cs
├── Sarif.Driver.csproj
├── Sdk
│ ├── AggregatingLogger.cs
│ ├── AnalysisApplicability.cs
│ ├── AnalyzeCommandBase.cs
│ ├── AnalyzeOptionsBase.cs
│ ├── CompositionUtilities.cs
│ ├── ConsoleLogger.cs
│ ├── DriverCommand.cs
│ ├── ErrorDescriptors.cs
│ ├── ExitApplicationException.cs
│ ├── ExitReason.cs
│ ├── ExportConfigurationCommandBase.cs
│ ├── ExportConfigurationOptions.cs
│ ├── ExportRulesMetadataCommandBase.cs
│ ├── ExportRulesMetadataOptions.cs
│ ├── Hash.cs
│ ├── IAnalysisContext.cs
│ ├── IAnalyzeOptions.cs
│ ├── IOption.cs
│ ├── IOptionsProvider.cs
│ ├── IResultLogger.cs
│ ├── ISkimmer.cs
│ ├── IntegerSet.cs
│ ├── MessageUtilities.cs
│ ├── NoteDescriptors.cs
│ ├── PerLanguageOption.cs
│ ├── PlugInDriverCommand.cs
│ ├── PropertyBag.cs
│ ├── PropertyBagExtensionMethods.cs
│ ├── ResultLogger.cs
│ ├── RuntimeConditions.cs
│ ├── SarifLogger.cs
│ ├── SdkResources.Designer.cs
│ ├── SdkResources.resx
│ ├── SkimmerBase.cs
│ ├── StatisticsLogger.cs
│ ├── StringSet.cs
│ └── TypedPropertyBag.cs
├── SemanticVersion.cs
├── StringExtensions.cs
├── TempDirectory.cs
├── TempFile.cs
├── VersionConstants.cs
├── XmlWriterExtensions.cs
└── packages.config
└── build.props
/.gitignore:
--------------------------------------------------------------------------------
1 | *.suo
2 | *.user
3 | *.userosscache
4 | *.sln.docstates
5 |
6 | # Build results
7 | bin/
8 | obj/
9 | src/packages/
10 | src/TestResults
--------------------------------------------------------------------------------
/.nuget/NuGet.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/driver-utilities/ca3e55bad0604d8e10a3aaf9a4efa1fc0c2c7d55/.nuget/NuGet.exe
--------------------------------------------------------------------------------
/BuildAndTest.cmd:
--------------------------------------------------------------------------------
1 | SETLOCAL
2 | @REM Uncomment this line to update nuget.exe
3 | @REM Doing so can break SLN build (which uses nuget.exe to
4 | @REM create a nuget package for binskim) so must opt-in
5 | @REM %~dp0.nuget\NuGet.exe update -self
6 |
7 | set MAJOR=1
8 | set MINOR=0
9 | set PATCH=9
10 | set PRERELEASE=-beta
11 |
12 | set VERSION_CONSTANTS=src\Sarif.Driver\VersionConstants.cs
13 |
14 | rd /s /q bld
15 |
16 | @REM Rewrite VersionConstants.cs
17 | echo // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT > %VERSION_CONSTANTS%
18 | echo // license. See LICENSE file in the project root for full license information. >> %VERSION_CONSTANTS%
19 | echo namespace Microsoft.CodeAnalysis.Sarif >> %VERSION_CONSTANTS%
20 | echo { >> %VERSION_CONSTANTS%
21 | echo public static class VersionConstants >> %VERSION_CONSTANTS%
22 | echo { >> %VERSION_CONSTANTS%
23 | echo public const string Prerelease = "%PRERELEASE%"; >> %VERSION_CONSTANTS%
24 | echo public const string AssemblyVersion = "%MAJOR%.%MINOR%.%PATCH%"; >> %VERSION_CONSTANTS%
25 | echo public const string FileVersion = AssemblyVersion + ".0"; >> %VERSION_CONSTANTS%
26 | echo public const string Version = AssemblyVersion + Prerelease; >> %VERSION_CONSTANTS%
27 | echo } >> %VERSION_CONSTANTS%
28 | echo } >> %VERSION_CONSTANTS%
29 |
30 | %~dp0.nuget\NuGet.exe restore src\Sarif.Driver.sln
31 | msbuild /verbosity:minimal /target:rebuild src\Sarif.Driver.sln /p:Configuration=Release
32 |
33 | md bld\bin\nuget
34 |
35 | .nuget\NuGet.exe pack .\src\Nuget\Sarif.Driver.nuspec -Symbols -Properties id=Sarif.Driver;major=%MAJOR%;minor=%MINOR%;patch=%PATCH%;prerelease=%PRERELEASE% -Verbosity Quiet -BasePath .\bld\bin\Sarif.Driver\AnyCPU_Release\ -OutputDirectory .\bld\bin\Nuget
36 |
37 | src\packages\xunit.runner.console.2.1.0\tools\xunit.console.x86.exe bld\bin\Sarif.Driver.UnitTests\AnyCPU_Release\Sarif.Driver.UnitTests.dll
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Microsoft Driver Utilities
2 |
3 | Copyright (c) Microsoft Corporation
4 |
5 | All rights reserved.
6 |
7 | MIT License
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
14 | THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # driver-utilities
2 | Driver utilities for building static analysis and other command-line tools.
3 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Security
4 |
5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
6 |
7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
8 |
9 | ## Reporting Security Issues
10 |
11 | **Please do not report security vulnerabilities through public GitHub issues.**
12 |
13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
14 |
15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
16 |
17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
18 |
19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
20 |
21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
22 | * Full paths of source file(s) related to the manifestation of the issue
23 | * The location of the affected source code (tag/branch/commit or direct URL)
24 | * Any special configuration required to reproduce the issue
25 | * Step-by-step instructions to reproduce the issue
26 | * Proof-of-concept or exploit code (if possible)
27 | * Impact of the issue, including how an attacker might exploit the issue
28 |
29 | This information will help us triage your report more quickly.
30 |
31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
32 |
33 | ## Preferred Languages
34 |
35 | We prefer all communications to be in English.
36 |
37 | ## Policy
38 |
39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/Nuget/Sarif.Driver.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $id$
5 | $major$.$minor$.$patch$$prerelease$
6 | Microsoft SARIF Driver Framework (includes SARIF SDK)
7 | Microsoft
8 | Michael C. Fanning, Billy O'Neal
9 | false
10 | SARIF-based classes and utilities for building static analysis drivers. Includes the SARIF SDK.
11 | Version $major$.$minor$.$patch$$prerelease$ of the Microsoft SARIF Driver Utilities
12 | Copyright Microsoft 2015
13 | https://github.com/Microsoft/driver-utilities/blob/master/LICENSE
14 | https://github.com/microsoft/driver-utilities
15 | command line driver utilities static analysis sarif framework utils driver.utilities
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/Sarif.Driver.UnitTests/ExceptionCondition.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
5 | {
6 | public enum ExceptionCondition
7 | {
8 | None,
9 | AccessingId,
10 | AccessingName,
11 | InvokingConstructor,
12 | InvokingAnalyze,
13 | InvokingCanAnalyze,
14 | InvokingInitialize
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Sarif.Driver.UnitTests/ExceptionRaisingRule.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using Microsoft.CodeAnalysis.Sarif.Sdk;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
9 | {
10 | internal class ExceptionRaisingRule : IRuleDescriptor, ISkimmer
11 | {
12 | internal static ExceptionCondition s_exceptionCondition;
13 |
14 | private ExceptionCondition _exceptionCondition;
15 |
16 | public ExceptionRaisingRule()
17 | {
18 | _exceptionCondition = s_exceptionCondition;
19 |
20 | if (_exceptionCondition == ExceptionCondition.InvokingConstructor)
21 | {
22 | throw new InvalidOperationException(nameof(ExceptionCondition.InvokingConstructor));
23 | }
24 | }
25 |
26 | public string ExceptionRaisingRuleId = "TEST1001";
27 |
28 | public string Id
29 | {
30 | get
31 | {
32 | if (_exceptionCondition == ExceptionCondition.AccessingId)
33 | {
34 | throw new InvalidOperationException(nameof(ExceptionCondition.AccessingId));
35 | }
36 | return ExceptionRaisingRuleId;
37 | }
38 | }
39 |
40 | public string Name
41 | {
42 | get
43 | {
44 | if (_exceptionCondition == ExceptionCondition.AccessingName)
45 | {
46 | throw new InvalidOperationException(nameof(ExceptionCondition.AccessingName));
47 | }
48 | return nameof(ExceptionRaisingRule);
49 | }
50 | }
51 |
52 | public string FullDescription
53 | {
54 | get { return "Test Rule Description"; }
55 | }
56 |
57 | public string ShortDescription
58 | {
59 | get
60 | {
61 | throw new NotImplementedException();
62 | }
63 | }
64 |
65 | public Dictionary Options
66 | {
67 | get
68 | {
69 | throw new NotImplementedException();
70 | }
71 | }
72 |
73 | public Dictionary FormatSpecifiers
74 | {
75 | get
76 | {
77 | throw new NotImplementedException();
78 | }
79 | }
80 |
81 | public Dictionary Properties
82 | {
83 | get
84 | {
85 | throw new NotImplementedException();
86 | }
87 | }
88 |
89 | public void Analyze(TestAnalysisContext context)
90 | {
91 | if (_exceptionCondition == ExceptionCondition.InvokingAnalyze)
92 | {
93 | throw new InvalidOperationException(nameof(ExceptionCondition.InvokingAnalyze));
94 | }
95 | }
96 |
97 | public AnalysisApplicability CanAnalyze(TestAnalysisContext context, out string reasonIfNotApplicable)
98 | {
99 | reasonIfNotApplicable = null;
100 | if (_exceptionCondition == ExceptionCondition.InvokingCanAnalyze)
101 | {
102 | throw new InvalidOperationException(nameof(ExceptionCondition.InvokingCanAnalyze));
103 | }
104 | return AnalysisApplicability.ApplicableToSpecifiedTarget;
105 | }
106 |
107 | public void Initialize(TestAnalysisContext context)
108 | {
109 | if (_exceptionCondition == ExceptionCondition.InvokingInitialize)
110 | {
111 | throw new InvalidOperationException(nameof(ExceptionCondition.InvokingInitialize));
112 | }
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/Sarif.Driver.UnitTests/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Reflection;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("Sarif Driver Utilities Unit Tests")]
10 | [assembly: AssemblyDescription("Unit tests for the SARIF driver utilities framework")]
11 |
--------------------------------------------------------------------------------
/src/Sarif.Driver.UnitTests/Sarif.Driver.UnitTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {66915F7B-9872-4390-AFED-DB8DE7B761BE}
6 |
7 |
8 |
9 |
10 | Microsoft.CodeAnalysis.Driver
11 |
12 |
13 | Sarif.Driver.UnitTests
14 |
15 |
16 | Library
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll
25 | True
26 |
27 |
28 | ..\packages\Sarif.Sdk.1.4.10-beta\lib\net40\Sarif.dll
29 | True
30 |
31 |
32 |
33 | ..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll
34 | True
35 |
36 |
37 |
38 |
39 |
40 | ..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll
41 | True
42 |
43 |
44 | ..\packages\xunit.assert.2.1.0\lib\dotnet\xunit.assert.dll
45 | True
46 |
47 |
48 | ..\packages\xunit.extensibility.core.2.1.0\lib\dotnet\xunit.core.dll
49 | True
50 |
51 |
52 | ..\packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll
53 | True
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | {8ceaea61-b1a2-4777-bcbe-c9a129a5f6c5}
76 | Sarif.Driver
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/src/Sarif.Driver.UnitTests/SarifHelpers.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | using Microsoft.CodeAnalysis.Sarif.Sdk;
7 |
8 | using Xunit;
9 |
10 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
11 | {
12 | internal static class SarifHelpers
13 | {
14 | public static void ValidateRunLog(RunLog runLog, Action resultAction)
15 | {
16 | ValidateToolInfo(runLog.ToolInfo);
17 |
18 | foreach (Result result in runLog.Results) { resultAction(result); }
19 | }
20 |
21 | public static void ValidateToolInfo(ToolInfo toolInfo)
22 | {
23 | Assert.Equal("Sarif.Driver", toolInfo.Name);
24 | // TODO version, etc
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Sarif.Driver.UnitTests/TestAnalysisContext.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Microsoft.CodeAnalysis.Sarif.Sdk;
6 |
7 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
8 | {
9 | public class TestAnalysisContext : IAnalysisContext
10 | {
11 | public bool IsValidAnalysisTarget { get; set; }
12 |
13 | public IResultLogger Logger { get; set; }
14 |
15 | public PropertyBag Policy { get; set; }
16 |
17 | public IRuleDescriptor Rule { get; set; }
18 |
19 | public Exception TargetLoadException { get; set; }
20 |
21 | public Uri TargetUri { get; set; }
22 |
23 | public void Dispose()
24 | {
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Sarif.Driver.UnitTests/TestAnalyzeCommand.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Collections.Generic;
5 | using System.Reflection;
6 |
7 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
8 | {
9 | public class TestAnalyzeCommand : AnalyzeCommandBase
10 | {
11 | public override IEnumerable DefaultPlugInAssemblies { get; set; }
12 |
13 | public override string Prerelease { get { return ""; } }
14 |
15 | protected override TestAnalysisContext CreateContext(TestAnalyzeOptions options, IResultLogger logger, PropertyBag policy, string filePath = null)
16 | {
17 | var context = base.CreateContext(options, logger, policy, filePath);
18 | context.IsValidAnalysisTarget = options.RegardAnalysisTargetAsValid;
19 | return context;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Sarif.Driver.UnitTests/TestAnalyzeOptions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Collections.Generic;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
7 | {
8 | public class TestAnalyzeOptions : IAnalyzeOptions
9 | {
10 | public TestAnalyzeOptions()
11 | {
12 | RegardAnalysisTargetAsValid = true;
13 | }
14 |
15 | public bool ComputeTargetsHash { get; set; }
16 |
17 | public string OutputFilePath { get; set; }
18 |
19 | public IList PlugInFilePaths { get; set; }
20 |
21 |
22 | public string PolicyFilePath { get; set; }
23 |
24 | public bool Recurse { get; set; }
25 |
26 | public bool Statistics { get; set; }
27 |
28 | public IEnumerable TargetFileSpecifiers { get; set; }
29 |
30 | public bool Verbose { get; set; }
31 |
32 | public bool RegardAnalysisTargetAsValid { get; set; }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/Sarif.Driver.UnitTests/TestMessageLogger.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using Microsoft.CodeAnalysis.Sarif.Sdk;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
9 | {
10 | internal class TestMessageLogger : IResultLogger
11 | {
12 | public TestMessageLogger()
13 | {
14 | FailTargets = new HashSet();
15 | PassTargets = new HashSet();
16 | NotApplicableTargets = new HashSet();
17 | }
18 |
19 | public HashSet PassTargets { get; set; }
20 |
21 | public HashSet FailTargets { get; set; }
22 |
23 | public HashSet NotApplicableTargets { get; set; }
24 |
25 | public void Log(ResultKind messageKind, IAnalysisContext context, string message)
26 | {
27 | switch (messageKind)
28 | {
29 | case ResultKind.Pass:
30 | {
31 | PassTargets.Add(context.TargetUri.LocalPath);
32 | break;
33 | }
34 |
35 | case ResultKind.Error:
36 | {
37 | FailTargets.Add(context.TargetUri.LocalPath);
38 | break;
39 | }
40 |
41 | case ResultKind.NotApplicable:
42 | {
43 | NotApplicableTargets.Add(context.TargetUri.LocalPath);
44 | break;
45 | }
46 |
47 | case ResultKind.Note:
48 | case ResultKind.InternalError:
49 | case ResultKind.ConfigurationError:
50 | {
51 | throw new NotImplementedException();
52 | }
53 | default:
54 | {
55 | throw new InvalidOperationException();
56 | }
57 | }
58 | }
59 |
60 | public void Log(ResultKind messageKind, IAnalysisContext context, FormattedMessage message)
61 | {
62 | throw new NotImplementedException();
63 | }
64 | }
65 | }
--------------------------------------------------------------------------------
/src/Sarif.Driver.UnitTests/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/Sarif.Driver.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.24720.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sarif.Driver", "Sarif.Driver\Sarif.Driver.csproj", "{8CEAEA61-B1A2-4777-BCBE-C9A129A5F6C5}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sarif.Driver.UnitTests", "Sarif.Driver.UnitTests\Sarif.Driver.UnitTests.csproj", "{66915F7B-9872-4390-AFED-DB8DE7B761BE}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Debug|x64 = Debug|x64
14 | Debug|x86 = Debug|x86
15 | Release|Any CPU = Release|Any CPU
16 | Release|x64 = Release|x64
17 | Release|x86 = Release|x86
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {8CEAEA61-B1A2-4777-BCBE-C9A129A5F6C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {8CEAEA61-B1A2-4777-BCBE-C9A129A5F6C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {8CEAEA61-B1A2-4777-BCBE-C9A129A5F6C5}.Debug|x64.ActiveCfg = Debug|x64
23 | {8CEAEA61-B1A2-4777-BCBE-C9A129A5F6C5}.Debug|x64.Build.0 = Debug|x64
24 | {8CEAEA61-B1A2-4777-BCBE-C9A129A5F6C5}.Debug|x86.ActiveCfg = Debug|x86
25 | {8CEAEA61-B1A2-4777-BCBE-C9A129A5F6C5}.Debug|x86.Build.0 = Debug|x86
26 | {8CEAEA61-B1A2-4777-BCBE-C9A129A5F6C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
27 | {8CEAEA61-B1A2-4777-BCBE-C9A129A5F6C5}.Release|Any CPU.Build.0 = Release|Any CPU
28 | {8CEAEA61-B1A2-4777-BCBE-C9A129A5F6C5}.Release|x64.ActiveCfg = Release|x64
29 | {8CEAEA61-B1A2-4777-BCBE-C9A129A5F6C5}.Release|x64.Build.0 = Release|x64
30 | {8CEAEA61-B1A2-4777-BCBE-C9A129A5F6C5}.Release|x86.ActiveCfg = Release|x86
31 | {8CEAEA61-B1A2-4777-BCBE-C9A129A5F6C5}.Release|x86.Build.0 = Release|x86
32 | {66915F7B-9872-4390-AFED-DB8DE7B761BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
33 | {66915F7B-9872-4390-AFED-DB8DE7B761BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
34 | {66915F7B-9872-4390-AFED-DB8DE7B761BE}.Debug|x64.ActiveCfg = Debug|x64
35 | {66915F7B-9872-4390-AFED-DB8DE7B761BE}.Debug|x64.Build.0 = Debug|x64
36 | {66915F7B-9872-4390-AFED-DB8DE7B761BE}.Debug|x86.ActiveCfg = Debug|x86
37 | {66915F7B-9872-4390-AFED-DB8DE7B761BE}.Debug|x86.Build.0 = Debug|x86
38 | {66915F7B-9872-4390-AFED-DB8DE7B761BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
39 | {66915F7B-9872-4390-AFED-DB8DE7B761BE}.Release|Any CPU.Build.0 = Release|Any CPU
40 | {66915F7B-9872-4390-AFED-DB8DE7B761BE}.Release|x64.ActiveCfg = Release|x64
41 | {66915F7B-9872-4390-AFED-DB8DE7B761BE}.Release|x64.Build.0 = Release|x64
42 | {66915F7B-9872-4390-AFED-DB8DE7B761BE}.Release|x86.ActiveCfg = Release|x86
43 | {66915F7B-9872-4390-AFED-DB8DE7B761BE}.Release|x86.Build.0 = Release|x86
44 | EndGlobalSection
45 | GlobalSection(SolutionProperties) = preSolution
46 | HideSolutionNode = FALSE
47 | EndGlobalSection
48 | GlobalSection(ExtensibilityGlobals) = postSolution
49 | EnterpriseLibraryConfigurationToolBinariesPathV6 = packages\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\lib\portable-net45+win+wp8;packages\EnterpriseLibrary.TransientFaultHandling.Data.6.0.1304.1\lib\NET45
50 | EndGlobalSection
51 | EndGlobal
52 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/ArgumentSplitter.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Text;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver
9 | {
10 | /// This class contains argument splitting functionality.
11 | public static class ArgumentSplitter
12 | {
13 | private enum WhitespaceMode
14 | {
15 | Ignore,
16 | PartOfArgument,
17 | EndArgument
18 | }
19 |
20 | ///
21 | /// Mimics CommandLineToArgvW's argument splitting behavior, plus bug fixes.
22 | ///
23 | /// The command line to split into arguments.
24 | /// The values of the arguments supplied in the input.
25 | public static List CommandLineToArgvW(string input)
26 | {
27 | // This function mimics CommandLineToArgvW's escaping behavior, documented here:
28 | // http://msdn.microsoft.com/en-us/library/windows/desktop/bb776391.aspx
29 |
30 | //
31 | // We used to P/Invoke to the real CommandLineToArgvW, but re-implement it here
32 | // as a workaround for the following:
33 | //
34 | // * CommandLineToArgvW does not treat newlines as whitespace (twcsec-tfs01 bug # 17291)
35 | // * CommandLineToArgvW returns the executable name for the empty string, not the empty set
36 | // * CommandLineToArgvW chokes on leading whitespace (twcsec-tfs01 bug# 17378)
37 | //
38 | // and as a result of the above we expect to find more nasty edge cases in the future.
39 | //
40 |
41 | if (input == null)
42 | {
43 | throw new ArgumentNullException("input");
44 | }
45 |
46 | WhitespaceMode whitespaceMode = WhitespaceMode.Ignore;
47 | int slashCount = 0;
48 |
49 | var result = new List();
50 | var sb = new StringBuilder();
51 |
52 | foreach (char c in input)
53 | {
54 | if (whitespaceMode == WhitespaceMode.Ignore && Char.IsWhiteSpace(c))
55 | {
56 | // Purposely do nothing
57 | }
58 | else if (whitespaceMode == WhitespaceMode.EndArgument && Char.IsWhiteSpace(c))
59 | {
60 | AddSlashes(sb, ref slashCount);
61 | EmitArgument(result, sb);
62 | whitespaceMode = WhitespaceMode.Ignore;
63 | }
64 | else if (c == '\\')
65 | {
66 | ++slashCount;
67 | if (whitespaceMode == WhitespaceMode.Ignore)
68 | {
69 | whitespaceMode = WhitespaceMode.EndArgument;
70 | }
71 | }
72 | else if (c == '\"')
73 | {
74 | bool quoteIsEscaped = (slashCount & 1) == 1;
75 | slashCount >>= 1; // Using >> to avoid C# bankers rounding
76 | // 2n backslashes followed by a quotation mark produce n slashes followed by a quotation mark
77 | AddSlashes(sb, ref slashCount);
78 |
79 | if (quoteIsEscaped)
80 | {
81 | sb.Append(c);
82 | }
83 | else if (whitespaceMode == WhitespaceMode.PartOfArgument)
84 | {
85 | whitespaceMode = WhitespaceMode.EndArgument;
86 | }
87 | else
88 | {
89 | whitespaceMode = WhitespaceMode.PartOfArgument;
90 | }
91 | }
92 | else
93 | {
94 | AddSlashes(sb, ref slashCount);
95 | sb.Append(c);
96 | if (whitespaceMode == WhitespaceMode.Ignore)
97 | {
98 | whitespaceMode = WhitespaceMode.EndArgument;
99 | }
100 | }
101 | }
102 |
103 | AddSlashes(sb, ref slashCount);
104 | if (sb.Length != 0)
105 | {
106 | EmitArgument(result, sb);
107 | }
108 |
109 | return result;
110 | }
111 |
112 | private static void EmitArgument(List result, StringBuilder sb)
113 | {
114 | result.Add(sb.ToString());
115 | sb.Clear();
116 | }
117 |
118 | private static void AddSlashes(StringBuilder sb, ref int slashCount)
119 | {
120 | sb.Append('\\', slashCount);
121 | slashCount = 0;
122 | }
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/BrandedVersionAttribute.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver
7 | {
8 | /// Attribute for branded version information.
9 | ///
10 | [AttributeUsage(AttributeTargets.Assembly)]
11 | public sealed class BrandedVersionAttribute : Attribute
12 | {
13 | ///
14 | /// Initializes a new instance of the class.
15 | ///
16 | /// The branded version.
17 | public BrandedVersionAttribute(string brandedVersion)
18 | {
19 | this.BrandedVersion = brandedVersion;
20 | }
21 |
22 | ///
23 | /// Gets the branded version for the assembly. For example, externally shipping assemblies are
24 | /// typically branded with a year instead of the SDL version.
25 | ///
26 | /// The branded version.
27 | public string BrandedVersion { get; private set; }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Configuration/ConfigurationParseContext.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Reflection;
8 |
9 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Configuration
10 | {
11 | internal class ConfigurationParseContext
12 | {
13 | public readonly Dictionary> MultipleUseArgumentValues = new Dictionary>();
14 | public readonly HashSet FlagsSetOnCommandLine = new HashSet();
15 | public readonly HashSet FlagsSetInConfigurationFile = new HashSet();
16 | private readonly Dictionary _errors = new Dictionary(StringComparer.OrdinalIgnoreCase);
17 |
18 | public void AddConfigurationError(string argument, string errorCondition)
19 | {
20 | // Configuration errors take lower priority; the console always wins.
21 | if (!_errors.ContainsKey(argument))
22 | {
23 | _errors.Add(argument, new ErrorEntry { Source = ErrorSource.ConfigurationFile, ErrorText = errorCondition });
24 | }
25 | }
26 |
27 | public void RemoveConfigurationError(string argument)
28 | {
29 | // This happens when a bad configuration error is overridden by a good command line option.
30 | ErrorEntry configError;
31 | if (_errors.TryGetValue(argument, out configError) && configError.Source == ErrorSource.ConfigurationFile)
32 | {
33 | _errors.Remove(argument);
34 | }
35 | }
36 |
37 | public void AddCommandLineError(string argument, string errorCondition)
38 | {
39 | ErrorEntry configError;
40 | if (!_errors.TryGetValue(argument, out configError))
41 | {
42 | // No previous error for that argument
43 | _errors.Add(argument, new ErrorEntry { Source = ErrorSource.CommandLine, ErrorText = errorCondition });
44 | }
45 | else if (configError.Source == ErrorSource.ConfigurationFile)
46 | {
47 | // Previous error for that argument was a configuration file error;
48 | // pave over it
49 | configError.Source = ErrorSource.CommandLine;
50 | configError.ErrorText = errorCondition;
51 | }
52 | // Otherwise there was a previous error with source == CommandLine, so do nothing.
53 | }
54 |
55 | public Dictionary GenerateErrorDictionary()
56 | {
57 | return _errors.ToDictionary(x => x.Key, x => x.Value.ErrorText, StringComparer.OrdinalIgnoreCase);
58 | }
59 |
60 | public void RemoveAllErrors()
61 | {
62 | _errors.Clear();
63 | }
64 |
65 | private enum ErrorSource
66 | {
67 | CommandLine,
68 | ConfigurationFile
69 | }
70 |
71 | private class ErrorEntry
72 | {
73 | public ErrorSource Source { get; set; }
74 | public string ErrorText { get; set; }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Configuration/FieldAttribute.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Configuration
7 | {
8 | ///
9 | /// Attribute for specifying a configuration field. Allows the field to be made required, and allows override of the field name, short name, and validation method.
10 | ///
11 | ///
12 | [AttributeUsage(AttributeTargets.Property)]
13 | public sealed class FieldAttribute : Attribute
14 | {
15 | /// Initializes a new instance of the FieldAttribute class.
16 | public FieldAttribute()
17 | {
18 | }
19 |
20 | /// Gets or sets the name of the field.
21 | /// The name of the field.
22 | public string Name { get; set; }
23 |
24 | /// Gets or sets the short form of the name of the field.
25 | /// The short form of the name of the field.
26 | public string ShortName { get; set; }
27 |
28 | /// Gets or sets the usage, or help text.
29 | /// The usage, or help text.
30 | public string Usage { get; set; }
31 |
32 | /// Gets or sets the type, or option flags, on the field.
33 | /// The type / option flags of the field.
34 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods", Justification = "GetType() is inherited from System.Object and cannot be removed.")]
35 | public FieldTypes Type { get; set; }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Configuration/FieldTypes.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Configuration
7 | {
8 | ///
9 | /// Specify fields
10 | ///
11 | [Flags]
12 | public enum FieldTypes
13 | {
14 | /// The default, specifies that the given field is optional.
15 | None = 0x00,
16 | Optional = None,
17 |
18 | ///
19 | /// Indicates that this field is required. An error will be displayed
20 | /// if it is not present when parsing arguments.
21 | ///
22 | Required = 0x01,
23 |
24 | ///
25 | /// Default field--if values in command line are not preceded by an arg, they're parsed as this field
26 | ///
27 | Default = 0x02,
28 |
29 | ///
30 | /// This field will not be described in the usage summary.
31 | ///
32 | Hidden = 0x04,
33 |
34 | ///
35 | /// Show the field on the CLI, but do not parse it from or save it to the XML, or place it in the schema. If CliOnly & Required, an error will not be raised if the parameter is missing from an XML config.
36 | ///
37 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cli", Justification = "This is spelled correctly.")]
38 | CliOnly = 0x08
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Configuration/NoMinusAttribute.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Configuration
7 | {
8 | ///
9 | /// This attribute disables the generated "minus" version of a given flag
10 | /// in ConfigurationParser.
11 | ///
12 | ///
13 | [AttributeUsage(AttributeTargets.Property)]
14 | public sealed class NoMinusAttribute : Attribute
15 | {
16 | ///
17 | /// Initializes a new instance of the NoMinusAttribute class.
18 | ///
19 | public NoMinusAttribute()
20 | {
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/DisposableEnumerable.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Diagnostics.CodeAnalysis;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver
9 | {
10 | /// A wrapper for enumerables of disposable objects that ensures that they are
11 | /// destroyed as they are produced.
12 | /// This wrapper breaks several of the built in
13 | /// extension methods that attempt to copy elements into backing collections, such as
14 | /// . Callers must be
15 | /// informed of the consequences of not being able to copy elements or references to elements
16 | /// as usual.
17 | /// Note however that most of these mechanisms are not safe to use if the underlying
18 | /// type is disposable, because they remove elements from the source stream that the caller
19 | /// would need to dispose.
20 | /// Note that this class should only be used for enumerables that "stream" their
21 | /// elements and produce new disposable values when reset or similar. If you create one of
22 | /// these wrappers around a collection that actually owns the disposable item, such as
23 | /// , enumerating the collection will destroy the collection's
24 | /// contents (which is not what the caller expects).
25 | /// The type wrapped in this enumerable.
26 | ///
27 | [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")] //Justification: This isn't actually a collection type.
28 | public sealed class DisposableEnumerable : IEnumerable>
29 | where T : IDisposable
30 | {
31 | private readonly IEnumerable _backingEnumerable;
32 |
33 | /// Initializes a new instance of the class.
34 | /// An enumerable implementation that this instance will wrap.
35 | public DisposableEnumerable(IEnumerable backingEnumerable)
36 | {
37 | _backingEnumerable = backingEnumerable;
38 | }
39 |
40 | /// Gets an enumerator to walk a view of the underlying collection.
41 | /// An enumerator that iterates over elements in this collection.
42 | public IEnumerator> GetEnumerator()
43 | {
44 | return new Enumerator(_backingEnumerable.GetEnumerator());
45 | }
46 |
47 | /// Gets an enumerator to walk a view of the underlying collection.
48 | /// An enumerator that iterates over elements in this collection.
49 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
50 | {
51 | return this.GetEnumerator();
52 | }
53 |
54 | private sealed class Enumerator : IEnumerator>
55 | {
56 | private readonly IEnumerator _backingEnumerator;
57 | private DisposableEnumerableView _current;
58 |
59 | private void DestroyCurrent()
60 | {
61 | if (_current != null)
62 | {
63 | _current.Destroy();
64 | }
65 |
66 | _current = null;
67 | }
68 |
69 | public Enumerator(IEnumerator backingEnumerator)
70 | {
71 | _backingEnumerator = backingEnumerator;
72 | }
73 |
74 | public DisposableEnumerableView Current
75 | {
76 | get { return _current; }
77 | }
78 |
79 | public void Dispose()
80 | {
81 | this.DestroyCurrent();
82 | _backingEnumerator.Dispose();
83 | }
84 |
85 | object System.Collections.IEnumerator.Current
86 | {
87 | get { return _current; }
88 | }
89 |
90 | public bool MoveNext()
91 | {
92 | // The caller may have stashed a reference to the "view" away somewhere, so we need
93 | // to allocate a new view object.
94 | // The common use for this at the moment will be where T is a COM RCW class; and as
95 | // such one would expect construction / destruction of T to dwarf the 24 or 32 bytes
96 | // of GC overhead per element when iterating. (Particularly given that view objects
97 | // should be short lived and stay on ephemeral GC generations)
98 | // If GC profiling shows that DisposableEnumerableView objects are a lot of GC overhead,
99 | // one may need to replace this wrapper with something that sacrifices some amount of
100 | // safety for perf.
101 |
102 | this.DestroyCurrent();
103 | if (_backingEnumerator.MoveNext())
104 | {
105 | _current = new DisposableEnumerableView(_backingEnumerator.Current);
106 | return true;
107 | }
108 |
109 | return false;
110 | }
111 |
112 | public void Reset()
113 | {
114 | this.DestroyCurrent();
115 | _backingEnumerator.Reset();
116 | }
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/DisposableEnumerableView.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver
7 | {
8 | /// A view of a disposable object inside of a collection.
9 | /// The type of disposable object in the collection.
10 | public sealed class DisposableEnumerableView
11 | where T : IDisposable
12 | {
13 | private readonly T _value;
14 | // Using "nonOwning" rather than "owning" so that the default value, false,
15 | // is what we want most of the time.
16 | private bool _nonOwning;
17 |
18 | /// Initializes a new instance of the
19 | /// class that owns a value.
20 | /// The value this view wraps.
21 | public DisposableEnumerableView(T value)
22 | {
23 | _value = value;
24 | }
25 |
26 | /// Gets a non-owning reference to the element stored in this view.
27 | /// The underlying value in this view.
28 | /// Thrown if this view no longer owns
29 | /// the underlying value.
30 | public T Value
31 | {
32 | get
33 | {
34 | if (_nonOwning)
35 | {
36 | throw new InvalidOperationException(ExceptionStrings.NonOwningDisposableViewAccess);
37 | }
38 |
39 | return _value;
40 | }
41 | }
42 |
43 | /// Takes ownership of the underlying element stored in this view.
44 | /// Thrown if this view no longer owns the
45 | /// underlying value.
46 | /// A the underlying value in this view.
47 | public T StealValue()
48 | {
49 | if (_nonOwning)
50 | {
51 | throw new InvalidOperationException(ExceptionStrings.NonOwningDisposableViewAccess);
52 | }
53 |
54 | _nonOwning = true;
55 | return _value;
56 | }
57 |
58 | /// If this instance owns the underlying value, destroys (calls
59 | /// ) on the underlying value.
60 | internal void Destroy()
61 | {
62 | if (!_nonOwning && _value != null)
63 | {
64 | _value.Dispose();
65 | }
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/DriverResources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | A binary was not analyzed as the it does not appear to be a valid portable executable.
122 |
123 |
124 | No analyzer paths specified
125 |
126 |
127 | Application exited unexpectedly.
128 |
129 |
130 | An exception was raised during analysis:
131 | {0}
132 |
133 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/EnvironmentVariables.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver
7 | {
8 | ///
9 | /// A wrapper class for accessing environment variables.
10 | ///
11 | ///
12 | /// Clients should use this class rather than directly using the System.EnvironmentVariable
13 | /// class, so they can mock the IEnvironmentVariables interface in unit tests.
14 | ///
15 | public class EnvironmentVariables : IEnvironmentVariables
16 | {
17 | ///
18 | /// Replaces the name of each environment variable embedded in the specified string with
19 | /// the string equivalent of the value of the variable, then returns the resulting string.
20 | ///
21 | ///
22 | /// A string containing the names of zero or more environment variables. Each environment
23 | /// variable is quoted with the percent sign character (%).
24 | ///
25 | ///
26 | /// A string with each environment variable replaced by its value.
27 | ///
28 | public string ExpandEnvironmentVariables(string name)
29 | {
30 | return Environment.ExpandEnvironmentVariables(name);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/ExceptionStrings.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Line number supplied was out of range [1, numberOfLinesInFile + 1)
122 |
123 |
124 | Attempted to access a DisposableEnumerable which is non-owning.
125 |
126 |
127 | Invalid PREfast defect state.
128 |
129 |
130 | PREfast defects require a main SFA where the defect occurs
131 |
132 |
133 | Probability must be between 0.0 and 1.0, inclusive; or be unset.
134 |
135 |
136 | Rank must be between 0 and 10, inclusive; or be unset.
137 |
138 |
139 | PREfast defects require descriptions with content.
140 |
141 |
142 | PREfast defects require content in their defect code.
143 |
144 |
145 | The function line number must be strictly positive; files begin at line 1.
146 |
147 |
148 | KeyEvent ids must be strictly positive.
149 |
150 |
151 | SequenceNumber must be positive, or 0 to disable sequence numbering.
152 |
153 |
154 | The value cannot be negative.
155 |
156 |
157 | The value must be greater than or equal to 1.
158 |
159 |
160 | The local element name was not set.
161 |
162 |
163 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/FileSpecifier.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.IO;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver
9 | {
10 | public class FileSpecifier
11 | {
12 | public FileSpecifier(string specifier, bool recurse = false, string filter = "")
13 | {
14 | _recurse = recurse;
15 |
16 | if (filter != "" && specifier.EndsWith(filter, StringComparison.OrdinalIgnoreCase))
17 | filter = "";
18 |
19 | _specifier = Path.Combine(specifier, filter);
20 | }
21 |
22 | private readonly bool _recurse;
23 | private readonly string _specifier;
24 | private List _files;
25 | private List _directories;
26 |
27 | public IList Files
28 | {
29 | get { return _files ?? BuildFiles(); }
30 | }
31 |
32 | public IList Directories
33 | {
34 | get { return _directories ?? BuildDirectories(); }
35 | }
36 |
37 | private List BuildDirectories()
38 | {
39 | BuildFilesAndDirectoriesList();
40 | return _directories;
41 | }
42 |
43 | private List BuildFiles()
44 | {
45 | BuildFilesAndDirectoriesList();
46 | return _files;
47 | }
48 |
49 | private void BuildFilesAndDirectoriesList()
50 | {
51 | string expandedSpecifier;
52 |
53 | _files = new List();
54 | _directories = new List();
55 | expandedSpecifier = Environment.ExpandEnvironmentVariables(_specifier);
56 |
57 | string computedFilter = Path.GetFileName(expandedSpecifier);
58 |
59 | if (-1 == computedFilter.IndexOf("*"))
60 | {
61 | computedFilter = null;
62 | }
63 | else
64 | {
65 | expandedSpecifier = Path.GetDirectoryName(expandedSpecifier.Substring(0, expandedSpecifier.Length - computedFilter.Length));
66 | }
67 |
68 | if (File.Exists(expandedSpecifier))
69 | {
70 | AddFileToList(expandedSpecifier);
71 | }
72 | else
73 | {
74 | string dir;
75 | dir = expandedSpecifier;
76 |
77 | if (!Directory.Exists(expandedSpecifier))
78 | {
79 | dir = Path.GetDirectoryName(expandedSpecifier);
80 | computedFilter = Path.GetFileName(expandedSpecifier);
81 | }
82 | else
83 | {
84 | _directories.Add(expandedSpecifier);
85 | }
86 | AddFilesFromDirectory(dir, computedFilter);
87 | }
88 | }
89 |
90 | private void AddFilesFromDirectory(string dir, string filter)
91 | {
92 | if (filter == null)
93 | return;
94 |
95 | if (Directory.Exists(dir))
96 | {
97 | foreach (string file in Directory.GetFiles(dir, filter))
98 | {
99 | AddFileToList(file);
100 | }
101 |
102 | if (_recurse)
103 | {
104 | try
105 | {
106 | foreach (string subdir in Directory.GetDirectories(dir))
107 | {
108 | AddFilesFromDirectory(subdir, filter);
109 | }
110 | }
111 | catch (UnauthorizedAccessException)
112 | {
113 | Console.Error.WriteLineAsync("Unauthorized access exception for directory: " + dir);
114 | }
115 | }
116 | }
117 | }
118 |
119 | private void AddFileToList(string expandedSpecifier)
120 | {
121 | _files.Add(Path.GetFullPath(expandedSpecifier));
122 | }
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/FileStreamExtensionMethods.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.IO;
6 |
7 | namespace Microsoft.CodeAnalysisDriver
8 | {
9 | public static class FileStreamExtensionMethods
10 | {
11 | public static string ReadString(this FileStream stream, int padTo)
12 | {
13 | long startPosition = stream.Position;
14 |
15 | int byteRead;
16 | int byteCount = 0;
17 |
18 | while ((byteRead = stream.ReadByte()) > 0)
19 | {
20 | byteCount++;
21 | };
22 |
23 | stream.Seek(startPosition, SeekOrigin.Begin);
24 | byte[] abString = stream.ReadToArray(byteCount);
25 |
26 | int padding = padTo - (byteCount + 1) % padTo;
27 | if (padding > 0)
28 | {
29 | stream.Seek(padding + 1, SeekOrigin.Current);
30 | }
31 |
32 | return System.Text.Encoding.UTF8.GetString(abString);
33 | }
34 |
35 | public static UInt16 ReadUInt16(this FileStream stream)
36 | {
37 | return BitConverter.ToUInt16(stream.ReadToArray(2), 0);
38 | }
39 |
40 | public static Int32 ReadInt32(this FileStream stream)
41 | {
42 | return BitConverter.ToInt32(stream.ReadToArray(4), 0);
43 | }
44 |
45 | public static Int64 ReadInt64(this FileStream stream)
46 | {
47 | return BitConverter.ToInt64(stream.ReadToArray(8), 0);
48 | }
49 |
50 | public static byte[] ReadToArray(this FileStream stream, int length)
51 | {
52 | byte[] bytes = new byte[length];
53 | int dataRead = stream.Read(bytes, 0, length);
54 | if (dataRead != length)
55 | {
56 | throw new InvalidDataException("Invalid data length read. Expected " + length + " read " + dataRead);
57 | }
58 |
59 | return bytes;
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/FileSystem.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.IO;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver
7 | {
8 | ///
9 | /// A wrapper class for accessing the file system.
10 | ///
11 | ///
12 | /// Clients should use this class rather directly using the .NET file system classes, so they
13 | /// can mock the IFileSystem interface in unit tests.
14 | ///
15 | public class FileSystem : IFileSystem
16 | {
17 | ///
18 | /// Determines whether the specified file exists.
19 | ///
20 | ///
21 | /// The file to check.
22 | ///
23 | ///
24 | /// true if the caller has the required permissions and path contains the name of an
25 | /// existing file; otherwise, false.
26 | ///
27 | public bool FileExists(string path)
28 | {
29 | return File.Exists(path);
30 | }
31 |
32 | ///
33 | /// Returns the absolute path for the specified path string.
34 | ///
35 | ///
36 | /// The file or directory for which to obtain absolute path information.
37 | ///
38 | ///
39 | /// The fully qualified location of , such as "C:\MyFile.txt".
40 | ///
41 | public string GetFullPath(string path)
42 | {
43 | return Path.GetFullPath(path);
44 | }
45 |
46 | ///
47 | /// Opens a text file, reads all lines of the file, and then closes the file.
48 | ///
49 | ///
50 | /// The file to open for reading.
51 | ///
52 | ///
53 | /// A string array containing all lines of the file.
54 | ///
55 | public string[] ReadAllLines(string path)
56 | {
57 | return File.ReadAllLines(path);
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/IAppConfig.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.CodeAnalysis.Sarif.Driver
5 | {
6 | ///
7 | /// An interface for accessing the contents of an application's config file.
8 | ///
9 | ///
10 | /// Clients wishing to access an application's config file should instantiate an
11 | /// AppConfig object, rather than directly using the ConfigurationManager class,
12 | /// so they can mock the IAppConfig interface in unit tests.
13 | ///
14 | public interface IAppConfig
15 | {
16 | ///
17 | /// Gets the specified member of the AppSettings collection.
18 | ///
19 | ///
20 | /// The name of the app setting to return.
21 | ///
22 | ///
23 | /// The string value of the specified app setting, or null if the application's
24 | /// config file does not contain the specified setting.
25 | ///
26 | string GetAppSetting(string name);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/IEnvironmentVariables.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.CodeAnalysis.Sarif.Driver
5 | {
6 | ///
7 | /// An interface for accessing environment variables.
8 | ///
9 | ///
10 | /// Clients wishing to access environment variables should instantiate an EnvironmentVariables
11 | /// object rather than directly using the System.Environment class, so they can mock the
12 | /// IEnvironmentVariables interface in unit tests.
13 | ///
14 | public interface IEnvironmentVariables
15 | {
16 | ///
17 | /// Replaces the name of each environment variable embedded in the specified string with
18 | /// the string equivalent of the value of the variable, then returns the resulting string.
19 | ///
20 | ///
21 | /// A string containing the names of zero or more environment variables. Each environment
22 | /// variable is quoted with the percent sign character (%).
23 | ///
24 | ///
25 | /// A string with each environment variable replaced by its value.
26 | ///
27 | string ExpandEnvironmentVariables(string name);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/IFileSystem.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.CodeAnalysis.Sarif.Driver
5 | {
6 | ///
7 | /// An interface for accessing the file system.
8 | ///
9 | ///
10 | /// Clients wishing to access the file system should instantiate a FileSystem object rather
11 | /// than directly using the .NET file system classes, so they can mock the IFileSystem
12 | /// interface in unit tests.
13 | ///
14 | public interface IFileSystem
15 | {
16 | ///
17 | /// Determines whether the specified file exists.
18 | ///
19 | ///
20 | /// The file to check.
21 | ///
22 | ///
23 | /// true if the caller has the required permissions and contains
24 | /// the name of an existing file; otherwise, false.
25 | ///
26 | bool FileExists(string path);
27 |
28 | ///
29 | /// Returns the absolute path for the specified path string.
30 | ///
31 | ///
32 | /// The file or directory for which to obtain absolute path information.
33 | ///
34 | ///
35 | /// The fully qualified location of , such as "C:\MyFile.txt".
36 | ///
37 | string GetFullPath(string path);
38 |
39 | ///
40 | /// Opens a text file, reads all lines of the file, and then closes the file.
41 | ///
42 | ///
43 | /// The file to open for reading.
44 | ///
45 | ///
46 | /// A string array containing all lines of the file.
47 | ///
48 | string[] ReadAllLines(string path);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/KeyEventImportance.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.CodeAnalysis.Sarif.Driver
5 | {
6 | /// Kinds of importance that can be applied to a .
7 | public enum KeyEventImportance
8 | {
9 | /// This (and the SFA to which it is attached) is
10 | /// essential to understand the defect.
11 | Essential,
12 |
13 | /// This describes the defect, but may not be
14 | /// absolutely necessary to understand its impact.
15 | Full
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/LineInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Globalization;
6 |
7 | namespace Microsoft.CodeAnalysis.Sarif.Driver
8 | {
9 | /// Information about a line of text.
10 | public struct LineInfo : IEquatable
11 | {
12 | private readonly int _startOffset;
13 | private readonly int _lineNumber;
14 |
15 | // The Math.Max calls are present because arbitrary bytes can be interpreted as a struct;
16 | // they maintain the invariants that ColumnNumber >= 0, LineNumber >= 1
17 | //
18 | // If profiling indicates that these Max calls are expensive it may make sense to sacrifice
19 | // some safety by turning them into asserts instead.
20 |
21 | /// The zero-based index into a file or string at which a given line starts.
22 | public int StartOffset { get { return Math.Max(_startOffset, 0); } }
23 |
24 | /// The one-based index of the line in the file or string.
25 | public int LineNumber { get { return Math.Max(_lineNumber, 1); } }
26 |
27 | /// Initializes a new instance of the struct.
28 | /// Thrown when is
29 | /// negative or is not at least 1.
30 | /// The zero-based index into a file or string at which a given line
31 | /// starts.
32 | /// The one-based index of the line in the file or string.
33 | public LineInfo(int startOffset, int lineNumber)
34 | {
35 | if (startOffset < 0)
36 | {
37 | throw new ArgumentOutOfRangeException("startOffset", startOffset, ExceptionStrings.ValueCannotBeNegative);
38 | }
39 |
40 | if (lineNumber <= 0)
41 | {
42 | throw new ArgumentOutOfRangeException("lineNumber", lineNumber, ExceptionStrings.ValueMustBeAtLeastOne);
43 | }
44 |
45 | _startOffset = startOffset;
46 | _lineNumber = lineNumber;
47 | }
48 |
49 | /// Tests if this object is considered equal to another.
50 | /// Another object to compare to.
51 | /// true if the objects are considered equal, false if they are not.
52 | public override bool Equals(object obj)
53 | {
54 | LineInfo? other = obj as LineInfo?;
55 | return other != null
56 | && this.Equals(other.Value);
57 | }
58 |
59 | /// Tests if this is considered equal to another.
60 | /// Another object to compare to.
61 | /// true if the objects are considered equal, false if they are not.
62 | public bool Equals(LineInfo other)
63 | {
64 | return this.LineNumber == other.LineNumber
65 | && this.StartOffset == other.StartOffset;
66 | }
67 |
68 | /// Returns a hash code for this object.
69 | /// A hash code for this object.
70 | public override int GetHashCode()
71 | {
72 | var hash = new MultiplyByPrimesHash();
73 | hash.Add(this.LineNumber);
74 | hash.Add(this.StartOffset);
75 | return hash.GetHashCode();
76 | }
77 |
78 | /// Convert this object into a string representation.
79 | /// A string that represents this object.
80 | public override string ToString()
81 | {
82 | return String.Format(CultureInfo.InvariantCulture, "Line {0} starting at {1}", this.LineNumber, this.StartOffset);
83 | }
84 |
85 | /// Equality operator.
86 | /// The left hand side.
87 | /// The right hand side.
88 | /// The result of the operation.
89 | public static bool operator ==(LineInfo lhs, LineInfo rhs)
90 | {
91 | return lhs.Equals(rhs);
92 | }
93 |
94 | /// Inequality operator.
95 | /// The left hand side.
96 | /// The right hand side.
97 | /// The result of the operation.
98 | public static bool operator !=(LineInfo lhs, LineInfo rhs)
99 | {
100 | return !lhs.Equals(rhs);
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/MultiplyByPrimesHash.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Collections;
5 | using System.Collections.Generic;
6 | using System.Diagnostics.CodeAnalysis;
7 | using System.Globalization;
8 | // Copyright (c) Microsoft. All rights reserved.
9 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
10 |
11 | // /********************************************************
12 | // * *
13 | // * Copyright (C) Microsoft. All rights reserved. *
14 | // * *
15 | // ********************************************************/
16 |
17 | namespace Microsoft.CodeAnalysis.Sarif.Driver
18 | {
19 | /// Multiply by primes hash calculator.
20 | public class MultiplyByPrimesHash
21 | {
22 | /// Internal state of the hash.
23 | private int _state;
24 |
25 | /// Initializes a new instance of the MultiplyByPrimesHash class.
26 | public MultiplyByPrimesHash()
27 | {
28 | _state = 17;
29 | }
30 |
31 | /// Equality operator.
32 | /// The left hand side.
33 | /// The right hand side.
34 | /// true of is equal to ; otherwise, false.
35 | public static bool operator ==(MultiplyByPrimesHash lhs, MultiplyByPrimesHash rhs)
36 | {
37 | if (object.ReferenceEquals(lhs, null))
38 | {
39 | return object.ReferenceEquals(rhs, null);
40 | }
41 | else if (object.ReferenceEquals(rhs, null))
42 | {
43 | return false;
44 | }
45 |
46 | return lhs._state == rhs._state;
47 | }
48 |
49 | /// Inequality operator.
50 | /// The left hand side.
51 | /// The right hand side.
52 | /// true of is not equal to ; otherwise, false.
53 | public static bool operator !=(MultiplyByPrimesHash lhs, MultiplyByPrimesHash rhs)
54 | {
55 | return !(lhs == rhs);
56 | }
57 |
58 | /// Adds item to the calculated hash.
59 | /// The item to add to the calculated hash.
60 | public void Add(int item)
61 | {
62 | _state = unchecked((_state * 31) + item);
63 | }
64 |
65 | /// Adds multiple items to the calculated hash.
66 | /// The items to add.
67 | [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
68 | public void AddRange(int[] items)
69 | {
70 | foreach (int item in items)
71 | {
72 | this.Add(item);
73 | }
74 | }
75 |
76 | /// Adds multiple items to the calculated hash.
77 | /// The items to add.
78 | [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
79 | public void AddRange(IEnumerable items)
80 | {
81 | foreach (int item in items)
82 | {
83 | this.Add(item);
84 | }
85 | }
86 |
87 | /// Indicates whether this instance and a specified object are equal.
88 | /// Another object to compare to.
89 | /// true if and this instance are the same type and
90 | /// represent the same value; otherwise, false.
91 | public override bool Equals(object obj)
92 | {
93 | var other = obj as MultiplyByPrimesHash;
94 | if (other == null)
95 | {
96 | return false;
97 | }
98 | else
99 | {
100 | return other._state == _state;
101 | }
102 | }
103 |
104 | /// Returns the hash code for this instance.
105 | /// A 32-bit signed integer that is the hash code for this instance.
106 | public override int GetHashCode()
107 | {
108 | return _state;
109 | }
110 |
111 | /// Returns a human readable string describing this instance.
112 | /// A human readable string describing this instance.
113 | public override string ToString()
114 | {
115 | return string.Format(CultureInfo.InvariantCulture, "MultiplyByPrimesHash state: 0x{0:X}", _state);
116 | }
117 |
118 | /// Adds item to the calculated hash.
119 | /// The item to add to the calculated hash. If this parameter is
120 | /// null, the effect will be the same as if its
121 | /// function returns 0.
122 | public void Add(object item)
123 | {
124 | this.Add(item == null ? 0 : item.GetHashCode());
125 | }
126 |
127 | /// Adds a set of items to the calculated hash.
128 | /// The items to add. If any item is null, the effect is the
129 | /// same as if that item's returned null.
130 | [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
131 | public void AddRange(IEnumerable items)
132 | {
133 | foreach (object item in items)
134 | {
135 | if (item == null)
136 | {
137 | this.Add(0);
138 | }
139 | else
140 | {
141 | this.Add(item.GetHashCode());
142 | }
143 | }
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/MurmurHash.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Collections;
5 | using System.Collections.Generic;
6 | using System.Diagnostics.CodeAnalysis;
7 | using System.Globalization;
8 |
9 | namespace Microsoft.CodeAnalysis.Sarif.Driver
10 | {
11 | /// Murmur hash 3 implementation of IHashCalculator. See
12 | /// http://www.codeproject.com/Articles/32829/Hash-Functions-An-Empirical-Comparison
13 | /// http://code.google.com/p/smhasher/
14 | /// http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
15 | ///
16 | /// This implementation is the x86_32 version. Note that we don't deal with the "tail" bits of the algorithm
17 | /// because we allow only integer inputs.
18 | public class MurmurHash
19 | {
20 | /// The first murmur hash constant.
21 | private const uint ConstantOne = 0xCC9E2D51u;
22 |
23 | /// The second murmur hash constant.
24 | private const uint ConstantTwo = 0x1B873593u;
25 |
26 | /// The internal state of the hash.
27 | private uint _internalState;
28 |
29 | /// Number of items inserted into the hash.
30 | private uint _itemCount;
31 |
32 | /// Equality operator.
33 | /// The left hand side.
34 | /// The right hand side.
35 | /// true of is equal to ; otherwise, false.
36 | public static bool operator ==(MurmurHash lhs, MurmurHash rhs)
37 | {
38 | if (object.ReferenceEquals(lhs, null))
39 | {
40 | return object.ReferenceEquals(rhs, null);
41 | }
42 | else if (object.ReferenceEquals(rhs, null))
43 | {
44 | return false;
45 | }
46 |
47 | return lhs._internalState == rhs._internalState
48 | && lhs._itemCount == rhs._itemCount;
49 | }
50 |
51 | /// Inequality operator.
52 | /// The left hand side.
53 | /// The right hand side.
54 | /// true of is not equal to ; otherwise, false.
55 | public static bool operator !=(MurmurHash lhs, MurmurHash rhs)
56 | {
57 | return !(lhs == rhs);
58 | }
59 |
60 | /// Adds item to the calculated hash.
61 | /// The item to add to the calculated hash.
62 | public void Add(int item)
63 | {
64 | unchecked
65 | {
66 | _itemCount++;
67 | uint istate = _internalState;
68 | uint uitem = (uint)item;
69 | uitem *= ConstantOne;
70 | uitem = RotateLeft(uitem, 15);
71 | uitem *= ConstantTwo;
72 | istate ^= uitem;
73 | istate = RotateLeft(istate, 13);
74 | istate = (istate * 5) + 0xE6546B64u;
75 | _internalState = istate;
76 | }
77 | }
78 |
79 | /// Adds multiple items to the calculated hash.
80 | /// The items to add.
81 | [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
82 | public void AddRange(int[] items)
83 | {
84 | foreach (int item in items)
85 | {
86 | this.Add(item);
87 | }
88 | }
89 |
90 | /// Adds multiple items to the calculated hash.
91 | /// The items to add.
92 | [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
93 | public void AddRange(IEnumerable items)
94 | {
95 | foreach (int item in items)
96 | {
97 | this.Add(item);
98 | }
99 | }
100 |
101 | /// Indicates whether this instance and a specified object are equal.
102 | /// Another object to compare to.
103 | /// true if and this instance are the same type and
104 | /// represent the same value; otherwise, false.
105 | public override bool Equals(object obj)
106 | {
107 | var other = obj as MurmurHash;
108 | if (other == null)
109 | {
110 | return false;
111 | }
112 | else
113 | {
114 | return other._internalState == _internalState
115 | && other._itemCount == _itemCount;
116 | }
117 | }
118 |
119 | /// Returns the hash code for this instance.
120 | /// A 32-bit signed integer that is the hash code for this instance.
121 | public override int GetHashCode()
122 | {
123 | uint result = _internalState;
124 | result ^= _itemCount * 4;
125 | result = Mix(result);
126 | return unchecked((int)result);
127 | }
128 |
129 | /// Returns a human readable string describing this instance.
130 | /// A human readable string describing this instance.
131 | public override string ToString()
132 | {
133 | return string.Format(CultureInfo.InvariantCulture, "MurmurHash state: h: 0x{0:X} count: 0x{1:X}", _internalState, _itemCount);
134 | }
135 |
136 | /// Adds item to the calculated hash.
137 | /// The item to add to the calculated hash. If this parameter is
138 | /// null, the effect will be the same as if its
139 | /// function returns 0.
140 | public void Add(object item)
141 | {
142 | if (item == null)
143 | {
144 | this.Add(0);
145 | }
146 | else
147 | {
148 | this.Add(item.GetHashCode());
149 | }
150 | }
151 |
152 | /// Adds a set of items to the calculated hash.
153 | /// The items to add. If any item is null, the effect is the
154 | /// same as if that item's returned null.
155 | [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
156 | public void AddRange(IEnumerable items)
157 | {
158 | foreach (object item in items)
159 | {
160 | if (item == null)
161 | {
162 | this.Add(0);
163 | }
164 | else
165 | {
166 | this.Add(item.GetHashCode());
167 | }
168 | }
169 | }
170 |
171 | /// Mixes the given hash value.
172 | /// Hash value to process.
173 | /// The mixed hash value.
174 | /// This function must be in an unchecked context.
175 | private static uint Mix(uint h)
176 | {
177 | h ^= h >> 16;
178 | h *= 0x85EBCA6Bu;
179 | h ^= h >> 13;
180 | h *= 0xC2B2AE35u;
181 | h ^= h >> 16;
182 |
183 | return h;
184 | }
185 |
186 | /// Rotates left.
187 | /// Hash value to process.
188 | /// The amount by which shall be rotated.
189 | /// The rotated value of .
190 | private static uint RotateLeft(uint h, byte amount)
191 | {
192 | return (h << amount) | (h >> (32 - amount));
193 | }
194 | }
195 | }
196 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/NewLineIndex.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Immutable;
6 | using System.Diagnostics;
7 | using System.Diagnostics.CodeAnalysis;
8 |
9 | namespace Microsoft.CodeAnalysis.Sarif.Driver
10 | {
11 | ///
12 | /// An index of newline start locations in a string in order to relatively cheaply
13 | /// turn a given offset into a line / column number.
14 | ///
15 | public class NewLineIndex
16 | {
17 | // Each index n in this list denotes the halfopen range
18 | // [lineOffsetStarts(n), lineOffsetStarts(n+1))
19 | // which is the line in the file at index n.
20 | private readonly ImmutableArray _lineOffsetStarts;
21 |
22 | /// Initializes a new instance of the class indexing the
23 | /// specified string.
24 | /// The text to add to this .
25 | [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0")]
26 | public NewLineIndex(string textToIndex)
27 | {
28 | ImmutableArray.Builder result = ImmutableArray.CreateBuilder();
29 | result.Add(0);
30 |
31 | int indexLength = textToIndex.Length;
32 | for (int charCount = 0; charCount < indexLength; ++charCount)
33 | {
34 | char c = textToIndex[charCount];
35 | // Detect \r, \n, \u2028, \u2029, but NOT \r\n
36 | // (\r\n gets taken care of on the following loop
37 | // iteration and is detected as \n there)
38 | if (c == '\n' ||
39 | (c == '\r' && (charCount + 1 >= indexLength || textToIndex[charCount + 1] != '\n')) ||
40 | c == '\u2028' || // Unicode line separator
41 | c == '\u2029' // Unicode paragraph separator
42 | )
43 | {
44 | result.Add(charCount + 1);
45 | }
46 | }
47 |
48 | _lineOffsetStarts = result.ToImmutable();
49 | }
50 |
51 | /// Gets a for the line at the specified index.
52 | /// Thrown when is not
53 | /// a valid line number; e.g. if it is zero, negative, or greater than the maximum line count in
54 | /// the file.
55 | /// The line number.
56 | /// A for .
57 | public LineInfo GetLineInfoForLine(int lineNumber)
58 | {
59 | if (lineNumber <= 0 || lineNumber > this.MaximumLineNumber)
60 | {
61 | throw new ArgumentOutOfRangeException("lineNumber", lineNumber, ExceptionStrings.LineNumberWasOutOfRange);
62 | }
63 |
64 | return new LineInfo(_lineOffsetStarts[lineNumber - 1], lineNumber);
65 | }
66 |
67 | /// Gets the maximum line number.
68 | /// The maximum line number.
69 | public int MaximumLineNumber
70 | {
71 | get
72 | {
73 | return _lineOffsetStarts.Length;
74 | }
75 | }
76 |
77 | /// Gets line information for the line containing the character at the specified offset.
78 | /// Thrown when is negative.
79 | /// The offset.
80 | /// The line information for the specified offset.
81 | public LineInfo GetLineInfoForOffset(int offset)
82 | {
83 | if (offset < 0)
84 | {
85 | throw new ArgumentOutOfRangeException("offset", offset, ExceptionStrings.ValueCannotBeNegative);
86 | }
87 |
88 | int startLine = _lineOffsetStarts.BinarySearch(offset);
89 |
90 | if (startLine < 0)
91 | {
92 | // If BinarySearch returns negative, returns the bitwise
93 | // complement of the next larger index. (upper_bound)
94 | // We want the next smaller index, which is where the -1 comes from.
95 | startLine = ~startLine - 1;
96 | Debug.Assert(startLine >= 0); // Because startLine < 0 if block
97 | }
98 |
99 | return new LineInfo(_lineOffsetStarts[startLine], startLine + 1);
100 | }
101 |
102 | /// Gets information for a given offset, such as the line and column numbers.
103 | /// Thrown when is negative.
104 | /// The offset for which information shall be obtained.
105 | /// The information for offset.
106 | public OffsetInfo GetOffsetInfoForOffset(int offset)
107 | {
108 | if (offset < 0)
109 | {
110 | throw new ArgumentOutOfRangeException("offset", offset, ExceptionStrings.ValueCannotBeNegative);
111 | }
112 |
113 | LineInfo lineInfo = this.GetLineInfoForOffset(offset);
114 | return new OffsetInfo(offset - lineInfo.StartOffset, lineInfo.LineNumber);
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/OffsetInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Globalization;
6 | using System.Runtime.Serialization;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver
9 | {
10 | /// Information about an offset in a block of text.
11 | [Serializable]
12 | public struct OffsetInfo : IEquatable, ISerializable
13 | {
14 | private readonly int _columnNumber;
15 | private readonly int _lineNumber;
16 |
17 | // The Math.Max calls are present because arbitrary bytes can be interpreted as a struct;
18 | // they maintain the invariants that ColumnNumber >= 0, LineNumber >= 1
19 | //
20 | // If profiling indicates that these Max calls are expensive it may make sense to sacrifice
21 | // some safety by turning them into asserts instead.
22 |
23 | /// The zero-based index of the column where the offset is located.
24 | public int ColumnNumber { get { return Math.Max(_columnNumber, 0); } }
25 |
26 | /// The one-based index of the line in the file or string on which the offset is
27 | /// located.
28 | public int LineNumber { get { return Math.Max(_lineNumber, 1); } }
29 |
30 | /// Initializes a new instance of the struct.
31 | /// Thrown when is
32 | /// negative or is not at least 1.
33 | /// The zero-based index of the column on which an offset is located.
34 | /// The one-based index of the line in the file or string.
35 | public OffsetInfo(int columnNumber, int lineNumber)
36 | {
37 | if (columnNumber < 0)
38 | {
39 | throw new ArgumentOutOfRangeException("columnNumber", columnNumber, ExceptionStrings.ValueCannotBeNegative);
40 | }
41 |
42 | if (lineNumber <= 0)
43 | {
44 | throw new ArgumentOutOfRangeException("lineNumber", lineNumber, ExceptionStrings.ValueMustBeAtLeastOne);
45 | }
46 |
47 | _columnNumber = columnNumber;
48 | _lineNumber = lineNumber;
49 | }
50 |
51 | /// Initializes a new instance of the struct.
52 | /// The serialization info from which the value shall be deserialized.
53 | /// The streaming context from which the value shall be deserialized.
54 | private OffsetInfo(SerializationInfo info, StreamingContext context)
55 | : this(info.GetInt32("ColumnNumber"), info.GetInt32("lineNumber"))
56 | { }
57 |
58 | /// Tests if this object is considered equal to another.
59 | /// Another object to compare to.
60 | /// true if the objects are considered equal, false if they are not.
61 | public override bool Equals(object obj)
62 | {
63 | OffsetInfo? other = obj as OffsetInfo?;
64 | return other != null
65 | && this.Equals(other.Value);
66 | }
67 |
68 | /// Tests if this is considered equal to another.
69 | /// Another object to compare to.
70 | /// true if the objects are considered equal, false if they are not.
71 | public bool Equals(OffsetInfo other)
72 | {
73 | return this.LineNumber == other.LineNumber
74 | && this.ColumnNumber == other.ColumnNumber;
75 | }
76 |
77 | /// Returns a hash code for this object.
78 | /// A hash code for this object.
79 | public override int GetHashCode()
80 | {
81 | var hash = new MultiplyByPrimesHash();
82 | hash.Add(this.LineNumber);
83 | hash.Add(this.ColumnNumber);
84 | return hash.GetHashCode();
85 | }
86 |
87 | /// Convert this object into a string representation.
88 | /// A string that represents this object.
89 | public override string ToString()
90 | {
91 | return String.Format(CultureInfo.InvariantCulture, "{0}:{1}", this.LineNumber, this.ColumnNumber);
92 | }
93 |
94 | /// Gets object data for serialization.
95 | /// The serialization info into which the value shall be serialized.
96 | /// The streaming context into which the value shall be serialized.
97 | public void GetObjectData(SerializationInfo info, StreamingContext context)
98 | {
99 | if (info == null)
100 | {
101 | throw new ArgumentNullException("info");
102 | }
103 |
104 | info.AddValue("ColumnNumber", this.ColumnNumber);
105 | info.AddValue("LineNumber", this.LineNumber);
106 | }
107 |
108 | /// Equality operator.
109 | /// The left hand side.
110 | /// The right hand side.
111 | /// The result of the operation.
112 | public static bool operator ==(OffsetInfo lhs, OffsetInfo rhs)
113 | {
114 | return lhs.Equals(rhs);
115 | }
116 |
117 | /// Inequality operator.
118 | /// The left hand side.
119 | /// The right hand side.
120 | /// The result of the operation.
121 | public static bool operator !=(OffsetInfo lhs, OffsetInfo rhs)
122 | {
123 | return !lhs.Equals(rhs);
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Pair.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Collections.Generic;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver
7 | {
8 | /// Contains a function to make it less verbose to make key value pairs. Similar to C++'s
9 | /// std::make_pair.
10 | public static class Pair
11 | {
12 | /// Makes a pair, with the generic type parameters determined using generic argument deduction.
13 | /// Key type.
14 | /// Value type.
15 | /// The key to use in the new pair.
16 | /// The value to use in the new pair.
17 | /// A KeyValuePair{TKey,TValue} containing the supplied key and value.
18 | public static KeyValuePair Make(TKey key, TValue value)
19 | {
20 | return new KeyValuePair(key, value);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/PathExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.IO;
6 | using System.Linq;
7 | using System.Reflection;
8 | // Copyright (c) Microsoft. All rights reserved.
9 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
10 |
11 | // /********************************************************
12 | // * *
13 | // * Copyright (C) Microsoft. All rights reserved. *
14 | // * *
15 | // ********************************************************/
16 |
17 | namespace Microsoft.CodeAnalysis.Sarif.Driver
18 | {
19 | /// Path extension functions.
20 | public static class PathExtensions
21 | {
22 | /// Gets a path relative to the SdlCommon library.
23 | /// The relative path to obtain to SdlCommon.dll.
24 | /// The path relative to the SdlCommon library.
25 | public static string GetPathRelativeToSdlCommon(string relativePath)
26 | {
27 | string dllPath = Assembly.GetExecutingAssembly().Location;
28 | string dllDirectory = Path.GetDirectoryName(dllPath);
29 | return Path.Combine(dllDirectory, relativePath);
30 | }
31 |
32 | ///
33 | /// Try to get the directory containing a file or the directory itself if path is a directory.
34 | ///
35 | /// file or directory
36 | /// directory if possible, otherwise null
37 | public static string TryGetDirectory(string fileOrDirectory)
38 | {
39 | if (File.Exists(fileOrDirectory))
40 | {
41 | return Path.GetDirectoryName(fileOrDirectory);
42 | }
43 |
44 | if (Directory.Exists(fileOrDirectory))
45 | {
46 | return fileOrDirectory;
47 | }
48 |
49 | try
50 | {
51 | string result = Path.GetDirectoryName(fileOrDirectory);
52 | if (!string.IsNullOrEmpty(result))
53 | {
54 | return result;
55 | }
56 | }
57 | catch (ArgumentException) { }
58 | // GetDirectoryName path parameter contains invalid characters, is empty, or contains only white spaces.
59 | // We can't determine a directory so fall through.
60 |
61 | catch (PathTooLongException) { }
62 | // GetDirectoryName path parameter is longer than the system-defined maximum length.
63 | // We can't determine a directory so fall through.
64 |
65 | catch (IOException) { }
66 | // GetDirectoryName (or File.Exists, Directory.Exists) failed for some other reason. There aren't any others documented in .Net 4.0 but 4.5 has
67 | // IOException.
68 | // We can't determine a directory so fall through.
69 |
70 | // If there are any other unexpected exceptions, like NullReferenceException or AccessViolationException or StackOverflowException, we want to fail.
71 |
72 | return null;
73 | }
74 |
75 | /// Unescapes a potentially quoted path.
76 | /// Thrown when an invalid path is supplied.
77 | /// The path to unescape.
78 | /// An unescaped version of .
79 | public static string PathUnescapePath(string sourcePath)
80 | {
81 | if (sourcePath == null)
82 | {
83 | return string.Empty;
84 | }
85 |
86 | char[] invalidPathChars = Path.GetInvalidPathChars();
87 | if (sourcePath.StartsWith("\"", StringComparison.Ordinal))
88 | {
89 | // Path is a quoted path
90 | // http://msdn.microsoft.com/en-us/library/windows/desktop/bb776391.aspx
91 | // CommandLineToArgvW has a special interpretation of backslash characters when they are followed by a quotation mark character ("), as follows:
92 | // * 2n backslashes followed by a quotation mark produce n backslashes followed by a quotation mark.
93 | // * (2n) + 1 backslashes followed by a quotation mark again produce n backslashes followed by a quotation mark.
94 | // * n backslashes not followed by a quotation mark simply produce n backslashes.
95 | int sourceLength = sourcePath.Length;
96 | char[] resultTemp = new char[sourceLength - 1]; // would be - 2 because of 2 quote characters, but the end quote might not be there.
97 | int resultIdx = 0;
98 | int backslashN = 0;
99 | for (int idx = 1; idx != sourceLength; ++idx)
100 | {
101 | char c = sourcePath[idx];
102 |
103 | if (c != '"' && invalidPathChars.Contains(c))
104 | {
105 | throw new IOException("Invalid path detected: " + sourcePath + " had invalid characters.");
106 | }
107 |
108 | if (c == '\\')
109 | {
110 | backslashN++;
111 | continue;
112 | }
113 | else if (backslashN != 0 && c == '"')
114 | {
115 | AddSlashes(resultTemp, ref resultIdx, backslashN / 2);
116 | if (backslashN % 2 == 0)
117 | {
118 | backslashN = 0;
119 | break;
120 | }
121 | else
122 | {
123 | backslashN = 0;
124 | }
125 | }
126 | else if (backslashN != 0 && c != '"')
127 | {
128 | AddSlashes(resultTemp, ref resultIdx, backslashN);
129 | backslashN = 0;
130 | }
131 | else if (c == '"')
132 | {
133 | break;
134 | }
135 |
136 | resultTemp[resultIdx++] = c;
137 | }
138 |
139 | AddSlashes(resultTemp, ref resultIdx, backslashN);
140 | return new string(resultTemp, 0, resultIdx);
141 | }
142 | else
143 | {
144 | // Path is an unquoted path. Make sure it contains all valid characters.
145 | foreach (char c in sourcePath)
146 | {
147 | if (invalidPathChars.Contains(c))
148 | {
149 | throw new IOException("Invalid path detected: " + sourcePath + " had invalid characters.");
150 | }
151 | }
152 |
153 | return sourcePath;
154 | }
155 | }
156 |
157 | /// Adds slashes to the temporary array.
158 | /// The result temporary array.
159 | /// [in,out] Zero-based index of where slashes are being added. On return, set to the next insertion index in .
160 | /// The number of slashes to add.
161 | private static void AddSlashes(char[] resultTemp, ref int resultIdx, int slashesToAdd)
162 | {
163 | for (int slashCount = slashesToAdd; slashCount != 0; --slashCount)
164 | {
165 | resultTemp[resultIdx++] = '\\';
166 | }
167 | }
168 | }
169 | }
--------------------------------------------------------------------------------
/src/Sarif.Driver/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Reflection;
5 | using System.Runtime.InteropServices;
6 |
7 | [assembly: AssemblyTitle("Microsoft Driver Utilities")]
8 | [assembly: AssemblyProduct("Driver.Utilities")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyCopyright("Copyright \u00A9 2015")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | [assembly: ComVisible(false)]
17 | [assembly: AssemblyVersion("1.0.0.0")]
18 | [assembly: AssemblyFileVersion("1.0.0.0")]
19 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Ref.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Diagnostics;
6 | using System.Diagnostics.CodeAnalysis;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver
9 | {
10 | /// A class that makes atomized string reference comparison easier. Stolen (slightly
11 | /// modified) from http://referencesource.microsoft.com/#System.Xml/System/Xml/Ref.cs.
12 | public static class Ref
13 | {
14 | /// Compares strings for reference equality and asserts if they are equal but not reference equal in debug mode.
15 | /// The first string to compare.
16 | /// The second string to compare.
17 | /// true if Object.ReferenceEquals(lhs, rhs); otherwise, false.
18 | public static bool Equal(string lhs, string rhs)
19 | {
20 | Debug.Assert(((object)lhs) == ((object)rhs) || !String.Equals(lhs, rhs, StringComparison.Ordinal),
21 | "Object comparison used for non-atomized string \"" + lhs + "\".");
22 | return ((object)lhs) == ((object)rhs);
23 | }
24 |
25 | /// Do not call this function. Prevents typo Ref.Equals from compiling.
26 | /// Object to be compared.
27 | /// Object to be compared.
28 | [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "unusedA")]
29 | [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "unusedB")]
30 | public static new void Equals(object unusedA, object unusedB)
31 | { }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/ReferenceEqualityComparer`1.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Collections.Generic;
5 | using System.Diagnostics.CodeAnalysis;
6 | using System.Runtime.CompilerServices;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver
9 | {
10 | /// Reference equals equality comparer.
11 | /// Generic type compared.
12 | ///
13 | public class ReferenceEqualityComparer : IEqualityComparer
14 | {
15 | /// The instance of equality comparer for T.
16 | [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
17 | [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
18 | public static readonly ReferenceEqualityComparer Instance = new ReferenceEqualityComparer();
19 |
20 | ///
21 | /// Prevents clients from constructing instances.
22 | ///
23 | private ReferenceEqualityComparer()
24 | { }
25 |
26 | /// Tests if two T objects are considered equal.
27 | /// Left T to be compared.
28 | /// Right T to be compared.
29 | /// true if the objects are considered equal, false if they are not.
30 | ///
31 | public bool Equals(T x, T y)
32 | {
33 | return object.ReferenceEquals(x, y);
34 | }
35 |
36 | /// Calculates the hash code for a given T.
37 | /// The object to get a hash code for.
38 | /// The hash code for .
39 | ///
40 | public int GetHashCode(T obj)
41 | {
42 | return RuntimeHelpers.GetHashCode(obj);
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/AggregatingLogger.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 |
7 | using Microsoft.CodeAnalysis.Sarif.Sdk;
8 |
9 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
10 | {
11 | public class AggregatingLogger : IDisposable, IResultLogger
12 | {
13 | public AggregatingLogger() : this(null)
14 | {
15 | }
16 |
17 | public AggregatingLogger(IEnumerable loggers)
18 | {
19 | this.Loggers = loggers != null ?
20 | new List(loggers) :
21 | new List();
22 | }
23 |
24 | public IList Loggers { get; set; }
25 |
26 | public void Dispose()
27 | {
28 | foreach (IResultLogger logger in Loggers)
29 | {
30 | using (logger as IDisposable) { };
31 | }
32 | }
33 |
34 | public void Log(ResultKind messageKind, IAnalysisContext context, FormattedMessage message)
35 | {
36 | foreach (IResultLogger logger in Loggers)
37 | {
38 | logger.Log(messageKind, context, message);
39 | }
40 | }
41 |
42 | public void Log(ResultKind messageKind, IAnalysisContext context, string message)
43 | {
44 | foreach (IResultLogger logger in Loggers)
45 | {
46 | logger.Log(messageKind, context, message);
47 | }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/AnalysisApplicability.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 |
5 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
6 | {
7 | public enum AnalysisApplicability
8 | {
9 | Unknown,
10 | NotApplicableToSpecifiedTarget,
11 | ApplicableToSpecifiedTarget,
12 | NotApplicableToAnyTargetWithoutPolicy
13 | }
14 | }
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/AnalyzeOptionsBase.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Collections.Generic;
5 |
6 | using CommandLine;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
9 | {
10 | [Verb("analyze", HelpText = "Analyze one or more binary files for security and correctness issues.")]
11 | public class AnalyzeOptionsBase : IAnalyzeOptions
12 | {
13 | [Value(0,
14 | HelpText = "One or more specifiers to a file, directory, or filter pattern that resolves to one or more binaries to analyze.")]
15 | public IEnumerable TargetFileSpecifiers { get; set; }
16 |
17 | [Option(
18 | 'o',
19 | "output",
20 | HelpText = "File path to which analysis output will be written.")]
21 | public string OutputFilePath { get; set; }
22 |
23 | [Option(
24 | 'v',
25 | "verbose",
26 | HelpText = "Emit verbose output. The resulting comprehensive report is designed to provide appropriate evidence for compliance scenarios.")]
27 | public bool Verbose { get; set; }
28 |
29 | [Option(
30 | 'r',
31 | "recurse",
32 | HelpText = "Recurse into subdirectories when evaluating file specifier arguments.")]
33 | public bool Recurse { get; set; }
34 |
35 | [Option(
36 | 'c',
37 | "config",
38 | HelpText = "Path to policy file that will be used to configure analysis. Pass value of 'default' to use built-in settings.")]
39 | public string PolicyFilePath { get; set; }
40 |
41 | [Option(
42 | 's',
43 | "statistics",
44 | HelpText = "Generate timing and other statistics for analysis session.")]
45 | public bool Statistics { get; set; }
46 |
47 | [Option(
48 | 'h',
49 | "hashes",
50 | HelpText = "Output SHA-256 hash of analysis targets when emitting SARIF reports.")]
51 | public bool ComputeTargetsHash { get; set; }
52 |
53 | [Option(
54 | 'p',
55 | "plug-in",
56 | Separator = ';',
57 | HelpText = "Path to plug-in that will be invoked against all targets in the analysis set.")]
58 | public IList PlugInFilePaths { get; set; }
59 | }
60 | }
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/CompositionUtilities.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Collections.Generic;
5 | using System.Collections.Immutable;
6 | using System.Composition.Convention;
7 | using System.Composition.Hosting;
8 | using System.Reflection;
9 |
10 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
11 | {
12 | internal static class DriverUtilities
13 | {
14 | public static ImmutableArray GetExports(IEnumerable assemblies)
15 | {
16 | var container = CreateCompositionContainer(assemblies);
17 | return container.GetExports().ToImmutableArray();
18 | }
19 |
20 | private static CompositionHost CreateCompositionContainer(IEnumerable assemblies)
21 | {
22 | ConventionBuilder conventions = GetConventions();
23 |
24 | return new ContainerConfiguration()
25 | .WithAssemblies(assemblies, conventions)
26 | .CreateContainer();
27 | }
28 |
29 | private static ConventionBuilder GetConventions()
30 | {
31 | var conventions = new ConventionBuilder();
32 |
33 | // New per-analyzer options mechanism
34 | conventions.ForTypesDerivedFrom()
35 | .Export();
36 |
37 | return conventions;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/ConsoleLogger.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using Microsoft.CodeAnalysis.Sarif.Sdk;
6 |
7 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
8 | {
9 | public class ConsoleLogger : IResultLogger
10 | {
11 | public ConsoleLogger(bool verbose)
12 | {
13 | Verbose = verbose;
14 | }
15 |
16 | public bool Verbose { get; set; }
17 |
18 | public void Log(ResultKind messageKind, IAnalysisContext context, string message)
19 | {
20 | switch (messageKind)
21 | {
22 |
23 | // These result types are optionally emitted
24 | case ResultKind.Pass:
25 | case ResultKind.Note:
26 | case ResultKind.NotApplicable:
27 | {
28 | if (Verbose)
29 | {
30 | Console.WriteLine(GetMessageText(context, message, messageKind));
31 | }
32 | break;
33 | }
34 |
35 | // These result types are alwayss emitted
36 | case ResultKind.Error:
37 | case ResultKind.Warning:
38 | case ResultKind.InternalError:
39 | case ResultKind.ConfigurationError:
40 | {
41 | Console.WriteLine(GetMessageText(context, message, messageKind));
42 | break;
43 | }
44 |
45 | default:
46 | {
47 | throw new InvalidOperationException();
48 | }
49 | }
50 | }
51 | public static string GetMessageText(
52 | IAnalysisContext context,
53 | string message,
54 | ResultKind messageKind,
55 | Region region = null)
56 | {
57 | string path = null;
58 | Uri uri = context.TargetUri;
59 |
60 | if (uri != null)
61 | {
62 | // If a path refers to a URI of form file://blah, we will convert to the local path
63 | if (uri.IsAbsoluteUri && uri.Scheme == Uri.UriSchemeFile)
64 | {
65 | path = uri.LocalPath;
66 | }
67 | else
68 | {
69 | path = uri.ToString();
70 | }
71 | }
72 |
73 | string issueType = null;
74 |
75 | switch (messageKind)
76 | {
77 | case ResultKind.ConfigurationError:
78 | {
79 | issueType = "CONFIGURATION ERROR";
80 | break;
81 | }
82 |
83 | case ResultKind.InternalError:
84 | {
85 | issueType = "INTERNAL ERROR";
86 | break;
87 | }
88 |
89 | case ResultKind.Error:
90 | {
91 | issueType = "error";
92 | break;
93 | }
94 |
95 | case ResultKind.Warning:
96 | {
97 | issueType = "warning";
98 | break;
99 | }
100 |
101 | case ResultKind.NotApplicable:
102 | case ResultKind.Note:
103 | {
104 | issueType = "note";
105 | break;
106 | }
107 |
108 | default:
109 | {
110 | throw new InvalidOperationException("Unknown message kind:" + messageKind.ToString());
111 | }
112 | }
113 |
114 | string detailedDiagnosis = NormalizeMessage(message, enquote: false);
115 |
116 | string location = "";
117 |
118 | if (region != null)
119 | {
120 | // TODO
121 | if (region.Offset > 0 || region.StartColumn == 0) { throw new NotImplementedException(); }
122 |
123 | if (region.StartLine == 0) { throw new InvalidOperationException(); }
124 |
125 | // VS supports the following formatting options:
126 | // (startLine)
127 | // (startLine-endLine)
128 | // (startLine,startColumn)
129 | // (startLine,startColumn-endColumn)
130 | // (startLine,startColumn,endLine,endColumn
131 | //
132 | // For expedience, we'll convert everything to the most fully qualified format
133 |
134 | string start = region.StartLine.ToString() + "," +
135 | (region.StartColumn > 0 ? region.StartColumn.ToString() : "1");
136 |
137 | string end = (region.EndLine > region.StartLine ? region.EndLine.ToString() : region.StartLine.ToString()) + "," +
138 | (region.EndColumn > 0 ? region.EndColumn.ToString() : region.StartColumn.ToString());
139 |
140 | location =
141 | "(" +
142 | start + (end != start ? "," + end : "") +
143 | ")";
144 | }
145 |
146 | return (path != null ? (path + location + ": ") : "") +
147 | issueType + " " +
148 | context.Rule.Id + ": " +
149 | detailedDiagnosis;
150 | }
151 |
152 | public static string NormalizeMessage(string message, bool enquote)
153 | {
154 | return (enquote ? "\"" : "") +
155 | message.Replace('"', '\'') +
156 | (enquote ? "\"" : "");
157 | }
158 |
159 | public void Log(ResultKind messageKind, IAnalysisContext context, FormattedMessage message)
160 | {
161 | throw new NotImplementedException();
162 | }
163 | }
164 | }
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/DriverCommand.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Reflection;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
9 | {
10 | public abstract class DriverCommand
11 | {
12 | abstract public int Run(T options);
13 |
14 | public const int FAILURE = 1;
15 | public const int SUCCESS = 0;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/ErrorDescriptors.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using Microsoft.CodeAnalysis.Sarif.Sdk;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
9 | {
10 | public static class ErrorDescriptors
11 | {
12 | public static IRuleDescriptor InvalidConfiguration = new RuleDescriptor()
13 | {
14 | Id = "ERR0997",
15 | Name = nameof(InvalidConfiguration),
16 | FullDescription = SdkResources.InvalidConfiguration_Description,
17 | FormatSpecifiers = BuildDictionary(new string[] {
18 | nameof(SdkResources.ExceptionCreatingLogFile),
19 | nameof(SdkResources.ExceptionLoadingAnalysisPlugIn),
20 | nameof(SdkResources.ExceptionLoadingAnalysisTarget)
21 | })
22 | };
23 |
24 | public static IRuleDescriptor UnhandledRuleException = new RuleDescriptor()
25 | {
26 | Id = "ERR0998",
27 | Name = nameof(UnhandledRuleException),
28 | FullDescription = SdkResources.ExceptionInRule_Description,
29 | FormatSpecifiers = BuildDictionary(new string[] {
30 | nameof(SdkResources.ExceptionInitializingRule),
31 | nameof(SdkResources.ExceptionAnalyzingTarget)
32 | })
33 | };
34 |
35 | public static IRuleDescriptor UnhandledEngineException = new RuleDescriptor()
36 | {
37 | Id = "ERR0999",
38 | Name = nameof(UnhandledEngineException),
39 | FullDescription = SdkResources.ExceptionInAnalysisEngine_Description,
40 | FormatSpecifiers = BuildDictionary(new string[] {
41 | nameof(SdkResources.ExceptionInAnalysisEngine)
42 | })
43 | };
44 |
45 |
46 | public static IRuleDescriptor ParseError = new RuleDescriptor()
47 | {
48 | Id = "ERR1001",
49 | Name = nameof(ParseError),
50 | FullDescription = SdkResources.ParseError_Description,
51 | FormatSpecifiers = BuildDictionary(new string[] {
52 | nameof(SdkResources.ParseError)
53 | })
54 | };
55 |
56 | private static Dictionary BuildDictionary(IEnumerable resourceNames)
57 | {
58 | // Note this dictionary provides for case-insensitive keys
59 | var dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase);
60 |
61 | foreach (string resourceName in resourceNames)
62 | {
63 | string resourceValue = SdkResources.ResourceManager.GetString(resourceName);
64 | dictionary[resourceName] = resourceValue;
65 | }
66 |
67 | return dictionary;
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/ExitApplicationException.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
7 | {
8 | public class ExitApplicationException : Exception where T : struct
9 | {
10 | public ExitApplicationException() : base() { }
11 | public ExitApplicationException(string message) : base(message) { }
12 | public ExitApplicationException(string message, Exception innerException) : base(message, innerException) { }
13 |
14 | public T ExitReason { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/ExitReason.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
5 | {
6 | public enum ExitReason
7 | {
8 | None,
9 | ExceptionCreatingLogFile,
10 | UnhandledExceptionInstantiatingSkimmers,
11 | UnhandledExceptionInEngine,
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/ExportConfigurationCommandBase.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Immutable;
6 | using System.IO;
7 | using System.Reflection;
8 |
9 |
10 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
11 | {
12 | public abstract class ExportConfigurationCommandBase : PlugInDriverCommand
13 | {
14 | public override int Run(ExportConfigurationOptions exportOptions)
15 | {
16 | int result = FAILURE;
17 |
18 | try
19 | {
20 | PropertyBag allOptions = new PropertyBag();
21 |
22 | // The export command could be updated in the future to accept an arbitrary set
23 | // of analyzers for which to build an options XML file suitable for configuring them.
24 | // Currently, we perform discovery against the built-in CodeFormatter rules
25 | // and analyzers only.
26 | ImmutableArray providers = DriverUtilities.GetExports(DefaultPlugInAssemblies);
27 | foreach (IOptionsProvider provider in providers)
28 | {
29 | foreach (IOption option in provider.GetOptions())
30 | {
31 | allOptions.SetProperty(option, option.DefaultValue, cacheDescription: true);
32 | }
33 | }
34 |
35 | string exe = Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location);
36 |
37 | allOptions.SaveTo(exportOptions.OutputFilePath, id: exe + "-config");
38 | Console.WriteLine("Configuration file saved to: " + Path.GetFullPath(exportOptions.OutputFilePath));
39 |
40 | result = SUCCESS;
41 | }
42 | catch (Exception ex)
43 | {
44 | Console.Error.WriteLine(ex.ToString());
45 | }
46 |
47 | return result;
48 | }
49 |
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/ExportConfigurationOptions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using CommandLine;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
7 | {
8 | [Verb("exportConfig", HelpText = "Export rule options to an XML file that can be edited and used to configure subsequent analysis.")]
9 | public class ExportConfigurationOptions
10 | {
11 | [Value(0, HelpText = "Output path for exported analysis options", Required = true)]
12 | public string OutputFilePath { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/ExportRulesMetadataCommandBase.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Collections.Immutable;
7 | using System.IO;
8 | using System.Text;
9 |
10 | using Microsoft.CodeAnalysis.Sarif.Sdk;
11 | using Microsoft.CodeAnalysis.Sarif.Readers;
12 | using Microsoft.CodeAnalysis.Sarif;
13 |
14 | using Newtonsoft.Json;
15 |
16 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
17 | {
18 | public abstract class ExportRulesMetadataCommandBase : PlugInDriverCommand
19 | {
20 |
21 | public override int Run(ExportRulesMetadataOptions exportOptions)
22 | {
23 | int result = FAILURE;
24 |
25 | try
26 | {
27 | ImmutableArray skimmers = DriverUtilities.GetExports(DefaultPlugInAssemblies);
28 |
29 | string format = "";
30 | string outputFilePath = exportOptions.OutputFilePath;
31 | string extension = Path.GetExtension(outputFilePath);
32 |
33 | switch (extension)
34 | {
35 | case (".json"):
36 | case (".sarif"):
37 | {
38 | format = "SARIF";
39 | ImmutableArray options = DriverUtilities.GetExports(DefaultPlugInAssemblies);
40 | OutputSarifRulesMetada(outputFilePath, skimmers, options);
41 | break;
42 | }
43 |
44 | case (".xml"):
45 | {
46 | format = "SonarQube";
47 | OutputSonarQubeRulesMetada(outputFilePath, skimmers);
48 | break;
49 | }
50 |
51 | default:
52 | {
53 | throw new InvalidOperationException("Unrecognized output file extension: " + extension);
54 | }
55 | }
56 |
57 | result = SUCCESS;
58 | Console.WriteLine(format + " rules metadata exported to: " + Path.GetFullPath(outputFilePath));
59 | }
60 | catch (Exception ex)
61 | {
62 | Console.Error.WriteLine(ex.ToString());
63 | }
64 |
65 | return result;
66 | }
67 |
68 | private void OutputSonarQubeRulesMetada(string outputFilePath, ImmutableArray skimmers)
69 | {
70 | const string TAB = " ";
71 | var sb = new StringBuilder();
72 |
73 | SortedDictionary sortedRuleContexts = new SortedDictionary();
74 |
75 | foreach (IRuleDescriptor ruleDescriptor in skimmers)
76 | {
77 | int numericId = GetIdIntegerSuffix(ruleDescriptor.Id);
78 | sortedRuleContexts[numericId] = ruleDescriptor;
79 | }
80 |
81 | sb.AppendLine("" + Environment.NewLine +
82 | "");
83 |
84 | foreach (IRuleDescriptor ruleContext in sortedRuleContexts.Values)
85 | {
86 | sb.AppendLine(TAB + "");
87 | sb.AppendLine(TAB + TAB + "" + ruleContext.Id + "");
88 | sb.AppendLine(TAB + TAB + "" + ruleContext.Name + "");
89 | sb.AppendLine(TAB + TAB + "MAJOR");
90 |
91 | sb.AppendLine(TAB + TAB + "" + Environment.NewLine +
92 | TAB + TAB + TAB + "" + Environment.NewLine +
95 | TAB + TAB + "");
96 |
97 | sb.AppendLine(TAB + TAB + "binary");
98 | sb.AppendLine(TAB + "");
99 | }
100 |
101 | sb.AppendLine("" + Environment.NewLine + "");
102 |
103 | File.WriteAllText(outputFilePath, sb.ToString());
104 | }
105 |
106 | private void OutputSarifRulesMetada(string outputFilePath, ImmutableArray skimmers, ImmutableArray options)
107 | {
108 | var log = new ResultLog();
109 |
110 | log.Version = SarifVersion.ZeroDotFour;
111 |
112 | // The SARIF spec currently requires an array
113 | // of run logs with at least one member
114 | log.RunLogs = new List();
115 |
116 | var runLog = new RunLog();
117 | runLog.ToolInfo = new ToolInfo();
118 |
119 | runLog.ToolInfo.InitializeFromAssembly(this.GetType().Assembly, Prerelease);
120 | runLog.Results = new List();
121 |
122 | log.RunLogs.Add(runLog);
123 | runLog.ToolInfo.RuleInfo = new List();
124 |
125 | SortedDictionary sortedRuleDescriptors = new SortedDictionary();
126 |
127 | foreach (IRuleDescriptor descriptor in skimmers)
128 | {
129 | var ruleDescriptor = new RuleDescriptor();
130 |
131 | ruleDescriptor.Id = descriptor.Id;
132 | ruleDescriptor.Name = descriptor.Name;
133 | ruleDescriptor.FullDescription = descriptor.FullDescription;
134 |
135 | int numericId = GetIdIntegerSuffix(ruleDescriptor.Id);
136 |
137 | sortedRuleDescriptors[numericId] = ruleDescriptor;
138 | }
139 |
140 | foreach (RuleDescriptor ruleDescriptor in sortedRuleDescriptors.Values)
141 | {
142 | runLog.ToolInfo.RuleInfo.Add(ruleDescriptor);
143 | }
144 |
145 | var settings = new JsonSerializerSettings()
146 | {
147 | ContractResolver = SarifContractResolver.Instance,
148 | Formatting = Formatting.Indented,
149 | };
150 | File.WriteAllText(outputFilePath, JsonConvert.SerializeObject(log, settings));
151 | }
152 |
153 | private int GetIdIntegerSuffix(string id)
154 | {
155 | int alphaCount = 0;
156 |
157 | foreach (char ch in id)
158 | {
159 | if (Char.IsLetter(ch))
160 | {
161 | alphaCount++;
162 | continue;
163 | }
164 | break;
165 | }
166 | return Int32.Parse(id.Substring(alphaCount));
167 | }
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/ExportRulesMetadataOptions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using CommandLine;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
7 | {
8 | [Verb("exportRules", HelpText = "Export rules metadata to a SARIF or SonarQube XML file.")]
9 | public class ExportRulesMetadataOptions
10 | {
11 | [Value(0, HelpText = "Output path for exported analysis options. Use a .json or .sarif extension to produce SARIF. Use .xml to produce a SonarQube rule descriptor file.", Required = true)]
12 | public string OutputFilePath { get; set; }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/Hash.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.IO;
6 | using System.Security.Cryptography;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
9 | {
10 | public static class HashUtilities
11 | {
12 | public static string ComputeSha256Hash(string fileName)
13 | {
14 | string sha256Hash = null;
15 |
16 | try
17 | {
18 | using (FileStream stream = File.OpenRead(fileName))
19 | {
20 | using (var bufferedStream = new BufferedStream(stream, 1024 * 32))
21 | {
22 | var sha = new SHA256Cng();
23 | byte[] checksum = sha.ComputeHash(bufferedStream);
24 | sha256Hash = BitConverter.ToString(checksum).Replace("-", String.Empty);
25 | }
26 | }
27 | }
28 | catch (IOException) { }
29 | catch (UnauthorizedAccessException) { }
30 | return sha256Hash;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/IAnalysisContext.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.using System;
3 |
4 | using System;
5 |
6 | using Microsoft.CodeAnalysis.Sarif.Sdk;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
9 | {
10 | public interface IAnalysisContext : IDisposable
11 | {
12 | Uri TargetUri { get; set; }
13 |
14 | Exception TargetLoadException { get; set; }
15 |
16 | bool IsValidAnalysisTarget { get; }
17 |
18 | IRuleDescriptor Rule { get; set; }
19 |
20 | PropertyBag Policy { get; set; }
21 |
22 | IResultLogger Logger { get; set; }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/IAnalyzeOptions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Collections.Generic;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
7 | {
8 | public interface IAnalyzeOptions
9 | {
10 | IEnumerable TargetFileSpecifiers { get; }
11 |
12 | string OutputFilePath { get; }
13 |
14 | bool Verbose { get; }
15 |
16 | bool Recurse { get; }
17 |
18 | string PolicyFilePath { get; }
19 |
20 | bool Statistics { get; }
21 |
22 | bool ComputeTargetsHash { get; }
23 |
24 | IList PlugInFilePaths { get; }
25 | }
26 | }
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/IOption.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
7 | {
8 | public interface IOption
9 | {
10 | string Description { get; }
11 | string Feature { get; }
12 | string Name { get; }
13 | Type Type { get; }
14 | object DefaultValue { get; }
15 | bool IsPerLanguage { get; }
16 | }
17 | }
18 |
19 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/IOptionsProvider.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System.Collections.Generic;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
7 | {
8 | public interface IOptionsProvider
9 | {
10 | IEnumerable GetOptions();
11 | }
12 | }
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/IResultLogger.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Microsoft.CodeAnalysis.Sarif.Sdk;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
7 | {
8 | public interface IResultLogger
9 | {
10 | void Log(ResultKind messageKind, IAnalysisContext context, string message);
11 |
12 | void Log(ResultKind messageKind, IAnalysisContext context, FormattedMessage message);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/ISkimmer.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using Microsoft.CodeAnalysis.Sarif.Sdk;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
7 | {
8 | public interface ISkimmer : IRuleDescriptor
9 | {
10 | ///
11 | /// Initialize method for skimmer instance. This method will only
12 | /// only be called a single time per skimmer instantiation.
13 | ///
14 | ///
15 | void Initialize(TContext context);
16 |
17 | ///
18 | /// Determine whether a target is a valid target for analysis.
19 | /// May be called from multiple threads.
20 | ///
21 | ///
22 | ///
23 | /// An analysis applicability value that indicates whether a check is
24 | /// applicable to a specified target, is not applicable to a specified target,
25 | /// or is not applicable to any target due to the absence of a configured
26 | /// policy. In cases where the analysis is determined not to be applicable,
27 | /// the 'reasonIfNotApplicable' property should be set to a string that
28 | /// describes the observed state or condition that prevents analysis.
29 | ///
30 | AnalysisApplicability CanAnalyze(TContext context, out string reasonIfNotApplicable);
31 |
32 | ///
33 | /// Analyze specified binary target and use context-resident loggers
34 | /// to record the results of the analysis. May be called from multiple threads.
35 | ///
36 | ///
37 | void Analyze(TContext context);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/IntegerSet.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Runtime.Serialization;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
9 | {
10 | [Serializable]
11 | public class IntegerSet : HashSet
12 | {
13 | public IntegerSet() { }
14 |
15 | public IntegerSet(IEnumerable integers) : base(integers) { }
16 |
17 | protected IntegerSet(SerializationInfo info, StreamingContext context)
18 | : base(info, context)
19 | {
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/MessageUtilities.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Diagnostics;
6 | using System.Globalization;
7 | using System.IO;
8 | using Microsoft.CodeAnalysis.Sarif.Sdk;
9 |
10 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
11 | {
12 | public static class MessageUtilities
13 | {
14 | public static string BuildMessage(IAnalysisContext context, string messageFormatString, params string[] arguments)
15 | {
16 | // By convention, the first argument is always the target name,
17 | // which we retrieve from the context
18 | Debug.Assert(File.Exists(context.TargetUri.LocalPath));
19 | string targetName = Path.GetFileName(context.TargetUri.LocalPath);
20 |
21 | string[] fullArguments = new string[arguments != null ? arguments.Length + 1 : 1];
22 | fullArguments[0] = targetName;
23 |
24 | if (fullArguments.Length > 1)
25 | {
26 | arguments.CopyTo(fullArguments, 1);
27 | }
28 |
29 | return String.Format(CultureInfo.InvariantCulture,
30 | messageFormatString, fullArguments);
31 | }
32 |
33 |
34 | public static string BuildTargetNotAnalyzedMessage(string targetPath, string ruleName, string reason)
35 | {
36 | targetPath = Path.GetFileName(targetPath);
37 |
38 | // Image '{0}' was not evaluated for check '{1}' as the analysis
39 | // is not relevant based on observed metadata: {2}
40 | return String.Format(
41 | CultureInfo.InvariantCulture,
42 | SdkResources.TargetNotAnalyzed_NotApplicable,
43 | targetPath,
44 | ruleName,
45 | reason);
46 | }
47 |
48 | public static string BuildRuleDisabledDueToMissingPolicyMessage(string ruleName, string reason)
49 | {
50 | // BinSkim command-line using the --policy argument (recommended), or
51 | // pass --defaultPolicy to invoke built-in settings. Invoke the
52 | // BinSkim.exe 'export' command to produce an initial policy file
53 | // that can be edited if required and passed back into the tool.
54 | return String.Format(
55 | CultureInfo.InvariantCulture,
56 | SdkResources.RuleWasDisabledDueToMissingPolicy,
57 | ruleName,
58 | reason);
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/NoteDescriptors.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using Microsoft.CodeAnalysis.Sarif.Sdk;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
9 | {
10 | public static class NoteDescriptors
11 | {
12 | public static IRuleDescriptor AnalyzingTarget = new RuleDescriptor()
13 | {
14 | // A file is being analyzed.
15 | Id = "MSG1001",
16 | Name = nameof(AnalyzingTarget),
17 | FullDescription = SdkResources.InvalidTarget_Description,
18 | FormatSpecifiers = BuildDictionary(new string[] {
19 | nameof(SdkResources.Analyzing),
20 | })
21 | };
22 |
23 | public static IRuleDescriptor InvalidTarget = new RuleDescriptor()
24 | {
25 | // A file was skipped as it does not appear to be a valid target for analysis.
26 | Id = "MSG1002",
27 | Name = nameof(InvalidTarget),
28 | FullDescription = SdkResources.InvalidTarget_Description,
29 | FormatSpecifiers = BuildDictionary(new string[] {
30 | nameof(SdkResources.TargetNotAnalyzed_InvalidTarget),
31 | })
32 | };
33 |
34 | private static Dictionary BuildDictionary(IEnumerable resourceNames)
35 | {
36 | // Note this dictionary provides for case-insensitive keys
37 | var dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase);
38 |
39 | foreach (string resourceName in resourceNames)
40 | {
41 | string resourceValue = SdkResources.ResourceManager.GetString(resourceName);
42 | dictionary[resourceName] = resourceValue;
43 | }
44 |
45 | return dictionary;
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/PerLanguageOption.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 |
6 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
7 | {
8 | ///
9 | /// An option that can be specified once per language.
10 | ///
11 | ///
12 | public class PerLanguageOption : IOption
13 | {
14 | ///
15 | /// A description of this specificoption.
16 | ///
17 | public string Description { get; }
18 |
19 | ///
20 | /// Feature this option is associated with.
21 | ///
22 | public string Feature { get; }
23 |
24 | ///
25 | /// The name of the option.
26 | ///
27 | public string Name { get; }
28 |
29 | ///
30 | /// The type of the option value.
31 | ///
32 | public Type Type
33 | {
34 | get { return typeof(T); }
35 | }
36 |
37 | ///
38 | /// The default option value.
39 | ///
40 | public Func DefaultValue { get; }
41 |
42 | public PerLanguageOption(string feature, string name, Func defaultValue, string description = null)
43 | {
44 | if (string.IsNullOrWhiteSpace(feature))
45 | {
46 | throw new ArgumentNullException(nameof(feature));
47 | }
48 |
49 | if (string.IsNullOrWhiteSpace(name))
50 | {
51 | throw new ArgumentException(nameof(name));
52 | }
53 |
54 | this.Feature = feature;
55 | this.Name = name;
56 | this.DefaultValue = defaultValue;
57 | this.Description = description;
58 | }
59 |
60 | Type IOption.Type
61 | {
62 | get { return typeof(T); }
63 | }
64 |
65 | object IOption.DefaultValue
66 | {
67 | get { return this.DefaultValue(); }
68 | }
69 |
70 | bool IOption.IsPerLanguage
71 | {
72 | get { return true; }
73 | }
74 |
75 | public override string ToString()
76 | {
77 | return string.Format("{0} - {1}", this.Feature, this.Name);
78 | }
79 | }
80 | }
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/PlugInDriverCommand.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Reflection;
7 |
8 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
9 | {
10 | public abstract class PlugInDriverCommand : DriverCommand
11 | {
12 | public virtual IEnumerable DefaultPlugInAssemblies
13 | {
14 | get { return null; }
15 | set { throw new InvalidOperationException(); }
16 | }
17 |
18 | public abstract string Prerelease { get; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/Sarif.Driver/Sdk/PropertyBag.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft. All rights reserved.
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Collections.Immutable;
7 | using System.ComponentModel;
8 | using System.IO;
9 | using System.Runtime.Serialization;
10 | using System.Xml;
11 |
12 | namespace Microsoft.CodeAnalysis.Sarif.Driver.Sdk
13 | {
14 | [Serializable]
15 | public class PropertyBag : TypedPropertyBag