diff --git a/shared/util/codeql/util/AlertFiltering.qll b/shared/util/codeql/util/AlertFiltering.qll index 6ca62e50af22..97acd803f01e 100644 --- a/shared/util/codeql/util/AlertFiltering.qll +++ b/shared/util/codeql/util/AlertFiltering.qll @@ -6,38 +6,92 @@ private import codeql.util.Location /** - * Restricts alerts to a specific location in specific files. + * Holds if the query should produce alerts that match the given line ranges. * - * If this predicate is empty, accept all alerts. Otherwise, accept alerts only at the specified - * locations. Note that alert restrictions apply only to the start line of an alert (even if the - * alert location spans multiple lines) because alerts are displayed on their start lines. + * This predicate is active if and only if it is nonempty. If this predicate is inactive, it has no + * effect. If it is active, it accepts any alert that has at least one matching location. * - * - filePath: Absolute path of the file to restrict alerts to. - * - startLine: Start line number (starting with 1, inclusive) to restrict alerts to. - * - endLine: End line number (starting with 1, inclusive) to restrict alerts to. + * Note that an alert that is not accepted by this filtering predicate may still be included in the + * query results if it is accepted by another active filtering predicate in this module. An alert is + * excluded from the query results if only if (1) there is at least one active filtering predicate, + * and (2) it is not accepted by any active filtering predicate. * - * If startLine and endLine are both 0, accept alerts anywhere in the file. + * An alert location is a match if it matches a row in this predicate. If `startLineStart` and + * `startLineEnd` are both 0, the row specifies a whole-file match, and a location is a match if + * its file path matches `filePath`. Otherwise, the row specifies a line-range match, and a + * location is a match if its file path matches `filePath`, and its start line is between + * `startLineStart` and `startLineEnd`, inclusive. (Note that only start line of the location is + * used for matching because an alert is displayed on the first line of its location.) * - * A query should either completely ignore this predicate (i.e., perform no filtering whatsoever), - * or only return alerts that meet the filtering criteria as specified above. + * - filePath: alert location file path (absolute). + * - startLineStart: inclusive start of the range for alert location start line number (1-based). + * - startLineEnd: inclusive end of the range for alert location start line number (1-based). + * + * A query should either perform no alert filtering, or adhere to all the filtering rules in this + * module and return all and only the accepted alerts. + * + * This predicate is suitable for situations where we want to filter alerts at line granularity, + * such as based on the pull request diff. + * + * See also: `restrictAlertsToExactLocation`. + */ +extensible predicate restrictAlertsTo(string filePath, int startLineStart, int startLineEnd); + +/** + * Holds if the query should produce alerts that match the given locations. + * + * This predicate is active if and only if it is nonempty. If this predicate is inactive, it has no + * effect. If it is active, it accepts any alert that has at least one matching location. + * + * Note that an alert that is not accepted by this filtering predicate may still be included in the + * query results if it is accepted by another active filtering predicate in this module. An alert is + * excluded from the query results if only if (1) there is at least one active filtering predicate, + * and (2) it is not accepted by any active filtering predicate. + * + * An alert location is a match if it matches a row in this predicate. Each row specifies an exact + * location: an alert location is a match if its file path matches `filePath`, its start line and + * column match `startLine` and `startColumn`, and its end line and column match `endLine` and + * `endColumn`. + * + * - filePath: alert location file path (absolute). + * - startLine: alert location start line number (1-based). + * - startColumn: alert location start column number (1-based). + * - endLine: alert location end line number (1-based). + * - endColumn: alert location end column number (1-based). + * + * A query should either perform no alert filtering, or adhere to all the filtering rules in this + * module and return all and only the accepted alerts. + * + * This predicate is suitable for situations where we want to filter by the exact alert location, + * distinguishing between alerts on the same line. + * + * See also: `restrictAlertsTo`. */ -extensible predicate restrictAlertsTo(string filePath, int startLine, int endLine); +extensible predicate restrictAlertsToExactLocation( + string filePath, int startLine, int startColumn, int endLine, int endColumn +); /** Module for applying alert location filtering. */ module AlertFilteringImpl { /** Applies alert filtering to the given location. */ bindingset[location] predicate filterByLocation(Location location) { - not restrictAlertsTo(_, _, _) + not restrictAlertsTo(_, _, _) and not restrictAlertsToExactLocation(_, _, _, _, _) or - exists(string filePath, int startLine, int endLine | - restrictAlertsTo(filePath, startLine, endLine) + exists(string filePath, int startLineStart, int startLineEnd | + restrictAlertsTo(filePath, startLineStart, startLineEnd) | - startLine = 0 and - endLine = 0 and + startLineStart = 0 and + startLineEnd = 0 and location.hasLocationInfo(filePath, _, _, _, _) or - location.hasLocationInfo(filePath, [startLine .. endLine], _, _, _) + location.hasLocationInfo(filePath, [startLineStart .. startLineEnd], _, _, _) + ) + or + exists(string filePath, int startLine, int startColumn, int endLine, int endColumn | + restrictAlertsToExactLocation(filePath, startLine, startColumn, endLine, endColumn) + | + location.hasLocationInfo(filePath, startLine, startColumn, endLine, endColumn) ) } } diff --git a/shared/util/ext/default-alert-filter.yml b/shared/util/ext/default-alert-filter.yml index 0ae5a2f4eb5b..1c4dd263d055 100644 --- a/shared/util/ext/default-alert-filter.yml +++ b/shared/util/ext/default-alert-filter.yml @@ -5,3 +5,9 @@ extensions: extensible: restrictAlertsTo # Empty predicate means no restrictions on alert locations data: [] + + - addsTo: + pack: codeql/util + extensible: restrictAlertsToExactLocation + # Empty predicate means no restrictions on alert locations + data: []