Skip to content

Commit b093aaa

Browse files
committed
Python: switch to type tracking
for tracking compiled regexes
1 parent 175a06f commit b093aaa

File tree

1 file changed

+16
-55
lines changed

1 file changed

+16
-55
lines changed

python/ql/lib/semmle/python/frameworks/Stdlib.qll

Lines changed: 16 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,49 +1540,19 @@ private module StdlibPrivate {
15401540

15411541
/** Helper module for tracking compiled regexes. */
15421542
private module CompiledRegexes {
1543-
private import semmle.python.dataflow.new.DataFlow4
1544-
private import semmle.python.RegexTreeView
1545-
1546-
// TODO: This module should be refactored once API graphs are more expressive.
1547-
// For now it uses data flow, so we pick the version with least chance of collision (4) .
1548-
/** A configuration for finding uses of compiled regexes. */
1549-
class RegexDefinitionConfiguration extends DataFlow4::Configuration {
1550-
RegexDefinitionConfiguration() { this = "RegexDefinitionConfiguration" }
1551-
1552-
override predicate isSource(DataFlow::Node source) { source instanceof RegexDefinitonSource }
1553-
1554-
override predicate isSink(DataFlow::Node sink) { sink instanceof RegexDefinitionSink }
1555-
}
1556-
1557-
/** A regex compilation. */
1558-
class RegexDefinitonSource extends DataFlow::CallCfgNode {
1559-
DataFlow::Node regexNode;
1560-
1561-
RegexDefinitonSource() {
1562-
this = API::moduleImport("re").getMember("compile").getACall() and
1563-
regexNode in [this.getArg(0), this.getArgByName("pattern")]
1564-
}
1565-
1566-
/** Gets the data flow node for the regex being compiled by this node. */
1567-
DataFlow::Node getRegexNode() { result = regexNode }
1543+
private DataFlow::TypeTrackingNode compiledRegex(DataFlow::TypeTracker t, DataFlow::Node regex) {
1544+
t.start() and
1545+
result = API::moduleImport("re").getMember("compile").getACall() and
1546+
regex in [
1547+
result.(DataFlow::CallCfgNode).getArg(0),
1548+
result.(DataFlow::CallCfgNode).getArgByName("pattern")
1549+
]
1550+
or
1551+
exists(DataFlow::TypeTracker t2 | result = compiledRegex(t2, regex).track(t2, t))
15681552
}
15691553

1570-
/** A use of a compiled regex. */
1571-
class RegexDefinitionSink extends DataFlow::Node {
1572-
RegexExecutionMethod method;
1573-
DataFlow::CallCfgNode executingCall;
1574-
1575-
RegexDefinitionSink() {
1576-
executingCall =
1577-
API::moduleImport("re").getMember("compile").getReturn().getMember(method).getACall() and
1578-
this = executingCall.getFunction().(DataFlow::AttrRead).getObject()
1579-
}
1580-
1581-
/** Gets the method used to execute the regex. */
1582-
RegexExecutionMethod getMethod() { result = method }
1583-
1584-
/** Gets the data flow node for the executing call. */
1585-
DataFlow::CallCfgNode getExecutingCall() { result = executingCall }
1554+
DataFlow::Node compiledRegex(DataFlow::Node regex) {
1555+
compiledRegex(DataFlow::TypeTracker::end(), regex).flowsTo(result)
15861556
}
15871557
}
15881558

@@ -1608,28 +1578,19 @@ private module StdlibPrivate {
16081578
*
16091579
* See https://docs.python.org/3/library/re.html#regular-expression-objects
16101580
*/
1611-
private class CompiledRegexExecution extends DataFlow::CallCfgNode, RegexExecution::Range {
1581+
private class CompiledRegexExecution extends DataFlow::MethodCallNode, RegexExecution::Range {
16121582
DataFlow::Node regexNode;
1613-
RegexExecutionMethod method;
1583+
RegexExecutionMethod methodName;
16141584

1615-
CompiledRegexExecution() {
1616-
exists(
1617-
RegexDefinitionConfiguration conf, RegexDefinitonSource source, RegexDefinitionSink sink
1618-
|
1619-
conf.hasFlow(source, sink) and
1620-
regexNode = source.getRegexNode() and
1621-
method = sink.getMethod() and
1622-
this = sink.getExecutingCall()
1623-
)
1624-
}
1585+
CompiledRegexExecution() { this.calls(compiledRegex(regexNode), methodName) }
16251586

16261587
override DataFlow::Node getRegex() { result = regexNode }
16271588

16281589
override DataFlow::Node getString() {
1629-
result in [this.getArg(getStringArgIndex(method) - 1), this.getArgByName("string")]
1590+
result in [this.getArg(getStringArgIndex(methodName) - 1), this.getArgByName("string")]
16301591
}
16311592

1632-
override string getName() { result = "re." + method }
1593+
override string getName() { result = "re." + methodName }
16331594
}
16341595

16351596
/**

0 commit comments

Comments
 (0)