-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sarif1008: ContextRegionMustBeProperSupersetOfRegion check #1925
Changes from 1 commit
8b11976
8538964
de68307
c58f30e
4e7aee3
2d2c9a9
80b4f18
186aa05
d359e99
5d1284f
800861c
af20b43
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,10 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq.Expressions; | ||
using System.Runtime.InteropServices.WindowsRuntime; | ||
|
||
namespace Microsoft.CodeAnalysis.Sarif.Multitool.Rules | ||
{ | ||
|
@@ -18,15 +21,130 @@ public class PhysicalLocationPropertiesMustBeConsistent : SarifValidationSkimmer | |
|
||
protected override IEnumerable<string> MessageResourceNames => new string[] | ||
{ | ||
nameof(RuleResources.SARIF1008_PhysicalLocationPropertiesMustBeConsistent_Error_ContextRegionRequiresRegion_Text) | ||
nameof(RuleResources.SARIF1008_PhysicalLocationPropertiesMustBeConsistent_Error_ContextRegionRequiresRegion_Text), | ||
nameof(RuleResources.SARIF1008_PhysicalLocationPropertiesMustBeConsistent_Error_ContextRegionMustBeProperSupersetOfRegion_Text) | ||
}; | ||
|
||
protected override void Analyze(PhysicalLocation physicalLocation, string physicalLocationPointer) | ||
{ | ||
if (physicalLocation.ContextRegion != null && physicalLocation.Region == null) | ||
if (physicalLocation.ContextRegion == null) | ||
{ | ||
return; | ||
} | ||
|
||
if (physicalLocation.Region == null) | ||
{ | ||
LogResult(physicalLocationPointer, nameof(RuleResources.SARIF1008_PhysicalLocationPropertiesMustBeConsistent_Error_ContextRegionRequiresRegion_Text)); | ||
return; | ||
} | ||
|
||
if (!IsRegionProperSuperset(physicalLocation.ContextRegion, physicalLocation.Region)) | ||
{ | ||
LogResult(physicalLocationPointer, nameof(RuleResources.SARIF1008_PhysicalLocationPropertiesMustBeConsistent_Error_ContextRegionMustBeProperSupersetOfRegion_Text)); | ||
} | ||
} | ||
|
||
private static bool IsRegionProperSuperset(Region superRegion, Region subRegion) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is all very nicely factored. I think the function names are reasonable. #Closed |
||
{ | ||
if (IsLineColumnBasedTextRegion(superRegion) && | ||
IsLineColumnBasedTextRegion(subRegion) && | ||
!IsLineColumnBasedTextRegionProperSuperset(superRegion, subRegion)) | ||
{ | ||
return false; | ||
} | ||
|
||
if (IsOffsetBasedTextRegion(superRegion) && | ||
IsOffsetBasedTextRegion(subRegion) && | ||
!IsOffsetBasedTextRegionProperSupetSet(superRegion, subRegion)) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Nit: remove extra blank line below. Also just below the final |
||
|
||
return false; | ||
} | ||
|
||
if (IsBinaryRegion(superRegion) && | ||
IsBinaryRegion(subRegion) && | ||
!IsBinaryRegionProperSuperset(superRegion, subRegion)) | ||
{ | ||
return false; | ||
} | ||
|
||
// if we reach here, the region and context region have been expressed as different property sets, | ||
// and it is not possible to judge validity without looking at the actual content. | ||
// It is a potential false negative. | ||
return true; | ||
|
||
} | ||
|
||
private static bool IsBinaryRegionProperSuperset(Region superRegion, Region subRegion) | ||
{ | ||
if (superRegion.ByteOffset > subRegion.ByteOffset) | ||
{ | ||
return false; | ||
} | ||
|
||
if (superRegion.ByteOffset == subRegion.ByteOffset && superRegion.ByteLength <= subRegion.ByteLength) | ||
{ | ||
return false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This misses the case where superRegion starts before subRegion and ends after. You need to compute endOffset = startOffset + length for each region, then compare the starts and ends. #Closed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
|
||
return true; | ||
} | ||
|
||
private static bool IsLineColumnBasedTextRegionProperSuperset(Region superRegion, Region subRegion) | ||
{ | ||
if (superRegion.StartLine > subRegion.StartLine || superRegion.EndLine < subRegion.EndLine) | ||
{ | ||
return false; | ||
} | ||
|
||
if (superRegion.StartLine == subRegion.StartLine && superRegion.StartColumn < subRegion.StartColumn) | ||
{ | ||
return false; | ||
} | ||
|
||
if (superRegion.EndLine == subRegion.EndLine && superRegion.EndColumn > subRegion.EndColumn) | ||
{ | ||
return false; | ||
} | ||
|
||
if (superRegion.StartLine == subRegion.StartLine && | ||
superRegion.EndLine == subRegion.EndLine && | ||
superRegion.StartColumn == subRegion.StartColumn && | ||
superRegion.EndColumn == subRegion.EndColumn) | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. all these could be a single if condition with a bunch of "ORs". i went back & forth on it and ultimately decided - this form is better for quicker undersantding of all the things we check. i follow same pattern in parent method as well. #Closed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine with splitting it. A seven-clause OR statement could be a bit much. In reply to: 443859402 [](ancestors = 443859402) |
||
return false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Having said that, the logic is wrong (as the faulty test shows). #Closed |
||
} | ||
|
||
return true; | ||
} | ||
|
||
private static bool IsOffsetBasedTextRegionProperSupetSet(Region superRegion, Region subRegion) | ||
{ | ||
if (superRegion.CharOffset > subRegion.CharOffset) | ||
{ | ||
return false; | ||
} | ||
|
||
if (superRegion.CharOffset == subRegion.CharOffset && superRegion.CharLength <= subRegion.CharLength) | ||
{ | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
private static bool IsLineColumnBasedTextRegion(Region region) | ||
{ | ||
return region.StartLine >= 1; | ||
} | ||
|
||
private static bool IsOffsetBasedTextRegion(Region region) | ||
{ | ||
return region.CharOffset > 0; | ||
} | ||
|
||
private static bool IsBinaryRegion(Region region) | ||
{ | ||
return region.ByteOffset >= 0; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My typo. Should be "... simply reversed 'region' and 'contextRegion',". #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh my! :) i should have noticed it! thank u, will fix
In reply to: 443860795 [](ancestors = 443860795)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PS: wats "fix it" ? is it some tool? re: then fix it puts the correct values in the correct properties.
In reply to: 443861877 [](ancestors = 443861877,443860795)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, "fix it" refers to the tool that produced that bad SARIF. And "then fix it so puts" is another typo. I meant "then fix it so it puts", but probably "then modify the tool so it puts" is better.
In reply to: 443862647 [](ancestors = 443862647,443861877,443860795)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, let's make that change.
In reply to: 443868912 [](ancestors = 443868912,443862647,443861877,443860795)