diff --git a/python/ql/lib/semmle/python/essa/Definitions.qll b/python/ql/lib/semmle/python/essa/Definitions.qll index ed5e6995e53..be76a7069d4 100644 --- a/python/ql/lib/semmle/python/essa/Definitions.qll +++ b/python/ql/lib/semmle/python/essa/Definitions.qll @@ -70,6 +70,10 @@ abstract class SsaSourceVariable extends @py_variable { SsaSource::exception_capture(this, def) or SsaSource::with_definition(this, def) + or + SsaSource::pattern_capture_definition(this, def) + or + SsaSource::pattern_alias_definition(this, def) } /** diff --git a/python/ql/lib/semmle/python/essa/Essa.qll b/python/ql/lib/semmle/python/essa/Essa.qll index 211c6714907..90a9e0e2ad9 100644 --- a/python/ql/lib/semmle/python/essa/Essa.qll +++ b/python/ql/lib/semmle/python/essa/Essa.qll @@ -545,6 +545,24 @@ class WithDefinition extends EssaNodeDefinition { override string getRepresentation() { result = "with" } } +/** A definition of a variable via a capture pattern */ +class PatternCaptureDefinition extends EssaNodeDefinition { + PatternCaptureDefinition() { + SsaSource::pattern_capture_definition(this.getSourceVariable(), this.getDefiningNode()) + } + + override string getRepresentation() { result = "pattern capture" } +} + +/** A definition of a variable via a pattern alias */ +class PatternAliasDefinition extends EssaNodeDefinition { + PatternAliasDefinition() { + SsaSource::pattern_alias_definition(this.getSourceVariable(), this.getDefiningNode()) + } + + override string getRepresentation() { result = "pattern alias" } +} + /** A definition of a variable by declaring it as a parameter */ class ParameterDefinition extends EssaNodeDefinition { ParameterDefinition() { diff --git a/python/ql/lib/semmle/python/essa/SsaDefinitions.qll b/python/ql/lib/semmle/python/essa/SsaDefinitions.qll index bc68793a023..f384ffd1bbd 100644 --- a/python/ql/lib/semmle/python/essa/SsaDefinitions.qll +++ b/python/ql/lib/semmle/python/essa/SsaDefinitions.qll @@ -40,6 +40,28 @@ module SsaSource { ) } + /** Holds if `v` is defined by a capture pattern. */ + cached + predicate pattern_capture_definition(Variable v, ControlFlowNode defn) { + exists(MatchCapturePattern capture, Name var | + capture.getVariable() = var and + var.getAFlowNode() = defn + | + var = v.getAStore() + ) + } + + /** Holds if `v` is defined by as the alias of an as-pattern. */ + cached + predicate pattern_alias_definition(Variable v, ControlFlowNode defn) { + exists(MatchAsPattern pattern, Name var | + pattern.getAlias() = var and + var.getAFlowNode() = defn + | + var = v.getAStore() + ) + } + /** Holds if `v` is defined by multiple assignment at `defn`. */ cached predicate multi_assignment_definition(Variable v, ControlFlowNode defn, int n, SequenceNode lhs) {