diff --git a/src/Sarif.Multitool/Rules/RuleResources.Designer.cs b/src/Sarif.Multitool/Rules/RuleResources.Designer.cs
index dbb6dd390..fd0d86a94 100644
--- a/src/Sarif.Multitool/Rules/RuleResources.Designer.cs
+++ b/src/Sarif.Multitool/Rules/RuleResources.Designer.cs
@@ -636,7 +636,7 @@ internal static string SARIF2011_ProvideContextRegion_FullDescription_Text {
}
///
- /// Looks up a localized string similar to Placeholder_SARIF2011_ProvideContextRegion_Note_Default_Text.
+ /// Looks up a localized string similar to {0}: Placeholder.
///
internal static string SARIF2011_ProvideContextRegion_Note_Default_Text {
get {
diff --git a/src/Sarif.Multitool/Rules/RuleResources.resx b/src/Sarif.Multitool/Rules/RuleResources.resx
index b204530bb..9f3df8cd5 100644
--- a/src/Sarif.Multitool/Rules/RuleResources.resx
+++ b/src/Sarif.Multitool/Rules/RuleResources.resx
@@ -320,7 +320,7 @@ Many tool use similar names for 'uriBaseId' symbols. We suggest 'REPOROOT' for t
Placeholder_SARIF2011_ProvideContextRegion_FullDescription_Text
- Placeholder_SARIF2011_ProvideContextRegion_Note_Default_Text
+ {0}: Placeholder
{0}: Placeholder '{1}' '{2}'
diff --git a/src/Sarif.Multitool/Rules/SARIF2011.ProvideContextRegion.cs b/src/Sarif.Multitool/Rules/SARIF2011.ProvideContextRegion.cs
new file mode 100644
index 000000000..114864383
--- /dev/null
+++ b/src/Sarif.Multitool/Rules/SARIF2011.ProvideContextRegion.cs
@@ -0,0 +1,56 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System.Collections.Generic;
+
+using Microsoft.Json.Pointer;
+
+namespace Microsoft.CodeAnalysis.Sarif.Multitool.Rules
+{
+ public class ProvideContextRegion : SarifValidationSkimmerBase
+ {
+ ///
+ /// SARIF2011
+ ///
+ public override string Id => RuleId.ProvideContextRegion;
+
+ ///
+ /// Placeholder
+ ///
+ public override MultiformatMessageString FullDescription => new MultiformatMessageString { Text = RuleResources.SARIF2011_ProvideContextRegion_FullDescription_Text };
+
+ protected override IEnumerable MessageResourceNames => new string[] {
+ nameof(RuleResources.SARIF2011_ProvideContextRegion_Note_Default_Text)
+ };
+
+ public override FailureLevel DefaultLevel => FailureLevel.Note;
+
+ protected override void Analyze(Result result, string resultPointer)
+ {
+ if (result.Locations != null)
+ {
+ string locationsPointer = resultPointer.AtProperty(SarifPropertyName.Locations);
+ for (int i = 0; i < result.Locations.Count; i++)
+ {
+ AnalyzeLocation(result.Locations[i], locationsPointer.AtIndex(i));
+ }
+ }
+ }
+
+ private void AnalyzeLocation(Location location, string locationPointer)
+ {
+ if (location.PhysicalLocation?.Region != null)
+ {
+ if (location.PhysicalLocation?.ContextRegion == null)
+ {
+ string physicalLocationPointer = locationPointer.AtProperty(SarifPropertyName.PhysicalLocation);
+
+ // {0}: Placeholder
+ LogResult(
+ physicalLocationPointer,
+ nameof(RuleResources.SARIF2011_ProvideContextRegion_Note_Default_Text));
+ }
+ }
+ }
+ }
+}
diff --git a/src/Test.FunctionalTests.Sarif/Multitool/ValidateCommandTests.cs b/src/Test.FunctionalTests.Sarif/Multitool/ValidateCommandTests.cs
index 2e30db4ed..9d39b2685 100644
--- a/src/Test.FunctionalTests.Sarif/Multitool/ValidateCommandTests.cs
+++ b/src/Test.FunctionalTests.Sarif/Multitool/ValidateCommandTests.cs
@@ -224,6 +224,18 @@ public void SARIF2009_ConsiderConventionalIdentifierValues_Invalid()
MakeInvalidTestFileName(RuleId.ConsiderConventionalIdentifierValues, nameof(RuleId.ConsiderConventionalIdentifierValues)),
parameter: new TestParameters(verbose: true));
+ [Fact]
+ public void SARIF2011_ProvideContextRegion_Valid()
+ => RunTest(
+ MakeValidTestFileName(RuleId.ProvideContextRegion, nameof(RuleId.ProvideContextRegion)),
+ parameter: new TestParameters(verbose: true));
+
+ [Fact]
+ public void SARIF2011_ProvideContextRegion_Invalid()
+ => RunTest(
+ MakeInvalidTestFileName(RuleId.ProvideContextRegion, nameof(RuleId.ProvideContextRegion)),
+ parameter: new TestParameters(verbose: true));
+
private const string ValidTestFileNameSuffix = "_Valid.sarif";
private const string InvalidTestFileNameSuffix = "_Invalid.sarif";
diff --git a/src/Test.FunctionalTests.Sarif/TestData/Multitool/ValidateCommand/ExpectedOutputs/SARIF2011.ProvideContextRegion_Invalid.sarif b/src/Test.FunctionalTests.Sarif/TestData/Multitool/ValidateCommand/ExpectedOutputs/SARIF2011.ProvideContextRegion_Invalid.sarif
new file mode 100644
index 000000000..03864398d
--- /dev/null
+++ b/src/Test.FunctionalTests.Sarif/TestData/Multitool/ValidateCommand/ExpectedOutputs/SARIF2011.ProvideContextRegion_Invalid.sarif
@@ -0,0 +1,89 @@
+{
+ "$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json",
+ "version": "2.1.0",
+ "runs": [
+ {
+ "tool": {
+ "driver": {
+ "name": "SARIF Functional Testing",
+ "rules": [
+ {
+ "id": "SARIF2011",
+ "name": "ProvideContextRegion",
+ "shortDescription": {
+ "text": "Placeholder_SARIF2011_ProvideContextRegion_FullDescription_Text."
+ },
+ "fullDescription": {
+ "text": "Placeholder_SARIF2011_ProvideContextRegion_FullDescription_Text"
+ },
+ "messageStrings": {
+ "Note_Default": {
+ "text": "{0}: Placeholder"
+ }
+ },
+ "helpUri": "http://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html"
+ }
+ ]
+ }
+ },
+ "invocations": [
+ {
+ "toolConfigurationNotifications": [
+ {
+ "message": {
+ "text": "Rule 'SARIF2002' was explicitly disabled by the user. As result, this tool run cannot be used for compliance or other auditing processes that require a comprehensive analysis."
+ },
+ "descriptor": {
+ "id": "WRN999.RuleExplicitlyDisabled"
+ }
+ },
+ {
+ "message": {
+ "text": "Rule 'SARIF2006' was explicitly disabled by the user. As result, this tool run cannot be used for compliance or other auditing processes that require a comprehensive analysis."
+ },
+ "descriptor": {
+ "id": "WRN999.RuleExplicitlyDisabled"
+ }
+ }
+ ],
+ "executionSuccessful": true
+ }
+ ],
+ "artifacts": [
+ {
+ "location": {
+ "uri": "FunctionalTestOutput.ValidateCommand/Inputs.SARIF2011.ProvideContextRegion_Invalid.sarif",
+ "uriBaseId": "TEST_DIR"
+ }
+ }
+ ],
+ "results": [
+ {
+ "ruleId": "SARIF2011",
+ "ruleIndex": 0,
+ "level": "note",
+ "message": {
+ "id": "Note_Default",
+ "arguments": [
+ "runs[0].results[0].locations[0].physicalLocation"
+ ]
+ },
+ "locations": [
+ {
+ "physicalLocation": {
+ "artifactLocation": {
+ "index": 0
+ },
+ "region": {
+ "startLine": 26,
+ "startColumn": 35
+ }
+ }
+ }
+ ]
+ }
+ ],
+ "columnKind": "utf16CodeUnits"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/Test.FunctionalTests.Sarif/TestData/Multitool/ValidateCommand/ExpectedOutputs/SARIF2011.ProvideContextRegion_Valid.sarif b/src/Test.FunctionalTests.Sarif/TestData/Multitool/ValidateCommand/ExpectedOutputs/SARIF2011.ProvideContextRegion_Valid.sarif
new file mode 100644
index 000000000..08d67563e
--- /dev/null
+++ b/src/Test.FunctionalTests.Sarif/TestData/Multitool/ValidateCommand/ExpectedOutputs/SARIF2011.ProvideContextRegion_Valid.sarif
@@ -0,0 +1,46 @@
+{
+ "$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json",
+ "version": "2.1.0",
+ "runs": [
+ {
+ "tool": {
+ "driver": {
+ "name": "SARIF Functional Testing"
+ }
+ },
+ "invocations": [
+ {
+ "toolConfigurationNotifications": [
+ {
+ "message": {
+ "text": "Rule 'SARIF2002' was explicitly disabled by the user. As result, this tool run cannot be used for compliance or other auditing processes that require a comprehensive analysis."
+ },
+ "descriptor": {
+ "id": "WRN999.RuleExplicitlyDisabled"
+ }
+ },
+ {
+ "message": {
+ "text": "Rule 'SARIF2006' was explicitly disabled by the user. As result, this tool run cannot be used for compliance or other auditing processes that require a comprehensive analysis."
+ },
+ "descriptor": {
+ "id": "WRN999.RuleExplicitlyDisabled"
+ }
+ }
+ ],
+ "executionSuccessful": true
+ }
+ ],
+ "artifacts": [
+ {
+ "location": {
+ "uri": "FunctionalTestOutput.ValidateCommand/Inputs.SARIF2011.ProvideContextRegion_Valid.sarif",
+ "uriBaseId": "TEST_DIR"
+ }
+ }
+ ],
+ "results": [],
+ "columnKind": "utf16CodeUnits"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/Test.FunctionalTests.Sarif/TestData/Multitool/ValidateCommand/Inputs/SARIF2011.ProvideContextRegion_Invalid.sarif b/src/Test.FunctionalTests.Sarif/TestData/Multitool/ValidateCommand/Inputs/SARIF2011.ProvideContextRegion_Invalid.sarif
new file mode 100644
index 000000000..9dda72123
--- /dev/null
+++ b/src/Test.FunctionalTests.Sarif/TestData/Multitool/ValidateCommand/Inputs/SARIF2011.ProvideContextRegion_Invalid.sarif
@@ -0,0 +1,41 @@
+{
+ "$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json",
+ "version": "2.1.0",
+ "runs": [
+ {
+ "tool": {
+ "driver": {
+ "name": "CodeScanner",
+ "version": "1.0"
+ }
+ },
+ "versionControlProvenance": [
+ {
+ "repositoryUri": "https://github.com/microsoft/sarif-sdk"
+ }
+ ],
+ "results": [
+ {
+ "ruleId": "TST0001",
+ "level": "error",
+ "message": {
+ "text": "Some testing occurred."
+ },
+ "locations": [
+ {
+ "physicalLocation": {
+ "artifactLocation": {
+ "uri": "src/test.c"
+ },
+ "region": {
+ "startLine": 3
+ }
+ }
+ }
+ ]
+ }
+ ],
+ "columnKind": "utf16CodeUnits"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/Test.FunctionalTests.Sarif/TestData/Multitool/ValidateCommand/Inputs/SARIF2011.ProvideContextRegion_Valid.sarif b/src/Test.FunctionalTests.Sarif/TestData/Multitool/ValidateCommand/Inputs/SARIF2011.ProvideContextRegion_Valid.sarif
new file mode 100644
index 000000000..53ebcac18
--- /dev/null
+++ b/src/Test.FunctionalTests.Sarif/TestData/Multitool/ValidateCommand/Inputs/SARIF2011.ProvideContextRegion_Valid.sarif
@@ -0,0 +1,45 @@
+{
+ "$schema": "https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json",
+ "version": "2.1.0",
+ "runs": [
+ {
+ "tool": {
+ "driver": {
+ "name": "CodeScanner",
+ "version": "1.0"
+ }
+ },
+ "versionControlProvenance": [
+ {
+ "repositoryUri": "https://github.com/microsoft/sarif-sdk"
+ }
+ ],
+ "results": [
+ {
+ "ruleId": "TST0001",
+ "level": "error",
+ "message": {
+ "text": "Some testing occurred."
+ },
+ "locations": [
+ {
+ "physicalLocation": {
+ "artifactLocation": {
+ "uri": "src/test.c"
+ },
+ "region": {
+ "startLine": 3
+ },
+ "contextRegion": {
+ "startLine": 2,
+ "endLine": 4
+ }
+ }
+ }
+ ]
+ }
+ ],
+ "columnKind": "utf16CodeUnits"
+ }
+ ]
+}
\ No newline at end of file