Skip to content

Commit

Permalink
Merge pull request #16245 from github/tausbn/python-rename-StrConst-t…
Browse files Browse the repository at this point in the history
…o-StringLiteral

Python: Rename `StrConst` to `StringLiteral`
  • Loading branch information
RasmusWL authored Apr 23, 2024
2 parents 35d1a92 + 81246cd commit 19974f0
Show file tree
Hide file tree
Showing 164 changed files with 936 additions and 884 deletions.
2 changes: 1 addition & 1 deletion python/ql/examples/snippets/raw_string.ql
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@

import python

from StrConst s
from StringLiteral s
where s.getPrefix().matches("%r%")
select s
2 changes: 1 addition & 1 deletion python/ql/examples/snippets/singlequotestring.ql
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

import python

from StrConst s
from StringLiteral s
where s.getPrefix().charAt(_) = "'"
select s
2 changes: 1 addition & 1 deletion python/ql/lib/analysis/DefinitionTracking.qll
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ private predicate sets_attribute(ArgumentRefinement def, string name) {
call = def.getDefiningNode() and
call.getFunction().refersTo(Object::builtin("setattr")) and
def.getInput().getAUse() = call.getArg(0) and
call.getArg(1).getNode().(StrConst).getText() = name
call.getArg(1).getNode().(StringLiteral).getText() = name
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
category: deprecated
---

- Renamed the `StrConst` class to `StringLiteral`, for greater consistency with other languages. The `StrConst` and `Str` classes are now deprecated and will be removed in a future release.
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ module Hashes {
}

override string getName() {
result = super.normalizeName(this.asExpr().(StrConst).getText())
result = super.normalizeName(this.asExpr().(StringLiteral).getText())
or
// if not a known/static string, assume from an outside source and the algorithm is UNKNOWN
not this.asExpr() instanceof StrConst and result = unknownAlgorithm()
not this.asExpr() instanceof StringLiteral and result = unknownAlgorithm()
}
}

Expand All @@ -49,10 +49,10 @@ module Hashes {
}

override string getName() {
result = super.normalizeName(this.asExpr().(StrConst).getText())
result = super.normalizeName(this.asExpr().(StringLiteral).getText())
or
// if not a known/static string, assume from an outside source and the algorithm is UNKNOWN
not this.asExpr() instanceof StrConst and result = unknownAlgorithm()
not this.asExpr() instanceof StringLiteral and result = unknownAlgorithm()
}
}

Expand Down Expand Up @@ -88,9 +88,9 @@ module Hashes {
// Name is a string constant or consider the name unknown
// NOTE: we are excluding hmac.new and hmac.HMAC constructor calls so we are expecting
// a string or an outside configuration only
result = super.normalizeName(this.asExpr().(StrConst).getText())
result = super.normalizeName(this.asExpr().(StringLiteral).getText())
or
not this.asExpr() instanceof StrConst and
not this.asExpr() instanceof StringLiteral and
result = unknownAlgorithm()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ module Hashes {
then result = super.normalizeName("MD5")
else (
// Else get the string name, if its a string constant, or UNKNOWN if otherwise
result = super.normalizeName(this.asExpr().(StrConst).getText())
result = super.normalizeName(this.asExpr().(StringLiteral).getText())
or
not this.asExpr() instanceof StrConst and result = unknownAlgorithm()
not this.asExpr() instanceof StringLiteral and result = unknownAlgorithm()
)
}
}
Expand Down
2 changes: 1 addition & 1 deletion python/ql/lib/semmle/python/ApiGraphs.qll
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ module API {
*/
Node getSubscript(string key) {
exists(API::Node index | result = this.getSubscriptAt(index) |
key = index.getAValueReachingSink().asExpr().(PY::StrConst).getText()
key = index.getAValueReachingSink().asExpr().(PY::StringLiteral).getText()
)
}

Expand Down
4 changes: 2 additions & 2 deletions python/ql/lib/semmle/python/Concepts.qll
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,7 @@ module Http {

/** Gets the URL pattern for this route, if it can be statically determined. */
string getUrlPattern() {
exists(StrConst str |
exists(StringLiteral str |
this.getUrlPatternArg().getALocalSource() = DataFlow::exprNode(str) and
result = str.getText()
)
Expand Down Expand Up @@ -983,7 +983,7 @@ module Http {

/** Gets the mimetype of this HTTP response, if it can be statically determined. */
string getMimetype() {
exists(StrConst str |
exists(StringLiteral str |
this.getMimetypeOrContentTypeArg().getALocalSource() = DataFlow::exprNode(str) and
result = str.getText().splitAt(";", 0)
)
Expand Down
25 changes: 17 additions & 8 deletions python/ql/lib/semmle/python/Exprs.qll
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ class Call extends Call_ {
string getANamedArgumentName() {
result = this.getAKeyword().getArg()
or
result = this.getKwargs().(Dict).getAKey().(StrConst).getText()
result = this.getKwargs().(Dict).getAKey().(StringLiteral).getText()
}

/** Gets the positional argument count of this call, provided there is no more than one tuple (*) argument. */
Expand Down Expand Up @@ -299,7 +299,7 @@ class Repr extends Repr_ {
* A bytes constant, such as `b'ascii'`. Note that unadorned string constants such as
* `"hello"` are treated as Bytes for Python2, but Unicode for Python3.
*/
class Bytes extends StrConst {
class Bytes extends StringLiteral {
/* syntax: b"hello" */
Bytes() { not this.isUnicode() }

Expand Down Expand Up @@ -446,7 +446,7 @@ class NegativeIntegerLiteral extends ImmutableLiteral, UnaryExpr {
* A unicode string expression, such as `u"\u20ac"`. Note that unadorned string constants such as
* "hello" are treated as Bytes for Python2, but Unicode for Python3.
*/
class Unicode extends StrConst {
class Unicode extends StringLiteral {
/* syntax: "hello" */
Unicode() { this.isUnicode() }

Expand Down Expand Up @@ -599,7 +599,7 @@ class Slice extends Slice_ {
/**
* Returns all string prefixes in the database that are explicitly marked as Unicode strings.
*
* Helper predicate for `StrConst::isUnicode`.
* Helper predicate for `StringLiteral::isUnicode`.
*/
pragma[nomagic]
private string unicode_prefix() {
Expand All @@ -610,20 +610,27 @@ private string unicode_prefix() {
/**
* Returns all string prefixes in the database that are _not_ explicitly marked as bytestrings.
*
* Helper predicate for `StrConst::isUnicode`.
* Helper predicate for `StringLiteral::isUnicode`.
*/
pragma[nomagic]
private string non_byte_prefix() {
result = any(Str_ s).getPrefix() and
not result.charAt(_) in ["b", "B"]
}

/** A string constant. This is a placeholder class -- use `StrConst` instead. */
class Str = StrConst;
/** DEPRECATED. Use `StringLiteral` instead. */
deprecated class Str = StringLiteral;

/** DEPRECATED. Use `StringLiteral` instead. */
deprecated class StrConst = StringLiteral;

/** A string constant. */
class StrConst extends Str_, ImmutableLiteral {
class StringLiteral extends Str_, ImmutableLiteral {
/* syntax: "hello" */
/**
* Holds if this string is a unicode string, either by default (e.g. if Python 3), or with an
* explicit prefix.
*/
predicate isUnicode() {
this.getPrefix() = unicode_prefix()
or
Expand Down Expand Up @@ -652,6 +659,8 @@ class StrConst extends Str_, ImmutableLiteral {
}

override Object getLiteralObject() { none() }

override string toString() { result = "StringLiteral" }
}

private predicate name_consts(Name_ n, string id) {
Expand Down
4 changes: 2 additions & 2 deletions python/ql/lib/semmle/python/Files.qll
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class File extends Container, Impl::File {
exists(Stmt s | s.getLocation().getFile() = this)
or
// The file contains the usual `if __name__ == '__main__':` construction
exists(If i, Name name, StrConst main, Cmpop op |
exists(If i, Name name, StringLiteral main, Cmpop op |
i.getScope().(Module).getFile() = this and
op instanceof Eq and
i.getTest().(Compare).compares(name, op, main) and
Expand Down Expand Up @@ -123,7 +123,7 @@ private predicate occupied_line(File f, int n) {
exists(Location l | l.getFile() = f |
l.getStartLine() = n
or
exists(StrConst s | s.getLocation() = l | n in [l.getStartLine() .. l.getEndLine()])
exists(StringLiteral s | s.getLocation() = l | n in [l.getStartLine() .. l.getEndLine()])
)
}

Expand Down
4 changes: 2 additions & 2 deletions python/ql/lib/semmle/python/Module.qll
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,9 @@ class Module extends Module_, Scope, AstNode {
a.getScope() = this and
all.getId() = "__all__" and
(
a.getValue().(List).getAnElt().(StrConst).getText() = name
a.getValue().(List).getAnElt().(StringLiteral).getText() = name
or
a.getValue().(Tuple).getAnElt().(StrConst).getText() = name
a.getValue().(Tuple).getAnElt().(StringLiteral).getText() = name
)
)
}
Expand Down
8 changes: 4 additions & 4 deletions python/ql/lib/semmle/python/PrintAst.qll
Original file line number Diff line number Diff line change
Expand Up @@ -423,13 +423,13 @@ class ParameterNode extends AstElementNode {
}

/**
* A print node for a `StrConst`.
* A print node for a `StringLiteral`.
*
* The string has a child, if the child is used as a regular expression,
* which is the root of the regular expression.
*/
class StrConstNode extends AstElementNode {
override StrConst element;
class StringLiteralNode extends AstElementNode {
override StringLiteral element;
}

/**
Expand Down Expand Up @@ -599,7 +599,7 @@ private module PrettyPrinting {
or
result = "class " + a.(Class).getName()
or
result = a.(StrConst).getText()
result = a.(StringLiteral).getText()
or
result = "yield " + a.(Yield).getValue()
or
Expand Down
2 changes: 1 addition & 1 deletion python/ql/lib/semmle/python/Scope.qll
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class Scope extends Scope_ {
string getName() { py_strs(result, this, 0) }

/** Gets the docstring for this scope */
StrConst getDocString() { result = this.getStmt(0).(ExprStmt).getValue() }
StringLiteral getDocString() { result = this.getStmt(0).(ExprStmt).getValue() }

/** Gets the entry point into this Scope's control flow graph */
ControlFlowNode getEntryNode() { py_scope_flow(result, this, -1) }
Expand Down
2 changes: 1 addition & 1 deletion python/ql/lib/semmle/python/Stmts.qll
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ class If extends If_ {

/** Whether this if statement takes the form `if __name__ == "__main__":` */
predicate isNameEqMain() {
exists(StrConst m, Name n, Compare c |
exists(StringLiteral m, Name n, Compare c |
this.getTest() = c and
c.getOp(0) instanceof Eq and
(
Expand Down
4 changes: 2 additions & 2 deletions python/ql/lib/semmle/python/dataflow/new/BarrierGuards.qll
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ private import semmle.python.dataflow.new.DataFlow

private predicate stringConstCompare(DataFlow::GuardNode g, ControlFlowNode node, boolean branch) {
exists(CompareNode cn | cn = g |
exists(StrConst str_const, Cmpop op |
exists(StringLiteral str_const, Cmpop op |
op = any(Eq eq) and branch = true
or
op = any(NotEq ne) and branch = false
Expand All @@ -21,7 +21,7 @@ private predicate stringConstCompare(DataFlow::GuardNode g, ControlFlowNode node
op = any(NotIn ni) and branch = false
|
forall(ControlFlowNode elem | elem = str_const_iterable.getAnElement() |
elem.getNode() instanceof StrConst
elem.getNode() instanceof StringLiteral
) and
cn.operands(node, op, str_const_iterable)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private module SensitiveDataModeling {
// Note: If this is implemented with type-tracking, we will get cross-talk as
// illustrated in python/ql/test/experimental/dataflow/sensitive-data/test.py
exists(DataFlow::LocalSourceNode source |
source.asExpr().(StrConst).getText() = sensitiveString(classification) and
source.asExpr().(StringLiteral).getText() = sensitiveString(classification) and
source.flowsTo(result)
)
}
Expand Down Expand Up @@ -173,8 +173,8 @@ private module SensitiveDataModeling {
}

pragma[nomagic]
private string sensitiveStrConstCandidate() {
result = any(StrConst s | not s.isDocString()).getText() and
private string sensitiveStringLiteralCandidate() {
result = any(StringLiteral s | not s.isDocString()).getText() and
not result.regexpMatch(notSensitiveRegexp())
}

Expand Down Expand Up @@ -217,7 +217,7 @@ private module SensitiveDataModeling {
result in [
sensitiveNameCandidate(), sensitiveAttributeNameCandidate(),
sensitiveParameterNameCandidate(), sensitiveFunctionNameCandidate(),
sensitiveStrConstCandidate()
sensitiveStringLiteralCandidate()
]
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ abstract class AttrRef extends Node {
or
exists(LocalSourceNode nodeFrom |
nodeFrom.flowsTo(this.getAttributeNameExpr()) and
attrName = nodeFrom.(CfgNode).getNode().getNode().(StrConst).getText()
attrName = nodeFrom.(CfgNode).getNode().getNode().(StringLiteral).getText()
)
}

Expand Down Expand Up @@ -178,7 +178,7 @@ private class SetAttrCallAsAttrWrite extends AttrWrite, CfgNode {
override ExprNode getAttributeNameExpr() { result.asCfgNode() = node.getName() }

override string getAttributeName() {
result = this.getAttributeNameExpr().(CfgNode).getNode().getNode().(StrConst).getText()
result = this.getAttributeNameExpr().(CfgNode).getNode().getNode().(StringLiteral).getText()
}
}

Expand Down Expand Up @@ -254,7 +254,7 @@ private class GetAttrCallAsAttrRead extends AttrRead, CfgNode {
override ExprNode getAttributeNameExpr() { result.asCfgNode() = node.getName() }

override string getAttributeName() {
result = this.getAttributeNameExpr().(CfgNode).getNode().getNode().(StrConst).getText()
result = this.getAttributeNameExpr().(CfgNode).getNode().getNode().(StringLiteral).getText()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@ predicate dictStoreStep(CfgNode nodeFrom, DictionaryElementContent c, Node nodeT
exists(KeyValuePair item |
item = nodeTo.asCfgNode().(DictNode).getNode().(Dict).getAnItem() and
nodeFrom.getNode().getNode() = item.getValue() and
c.getKey() = item.getKey().(StrConst).getS()
c.getKey() = item.getKey().(StringLiteral).getS()
)
}

Expand All @@ -829,13 +829,13 @@ private predicate moreDictStoreSteps(CfgNode nodeFrom, DictionaryElementContent
exists(SubscriptNode subscript |
nodeTo.(PostUpdateNode).getPreUpdateNode().asCfgNode() = subscript.getObject() and
nodeFrom.asCfgNode() = subscript.(DefinitionNode).getValue() and
c.getKey() = subscript.getIndex().getNode().(StrConst).getText()
c.getKey() = subscript.getIndex().getNode().(StringLiteral).getText()
)
or
// see https://docs.python.org/3.10/library/stdtypes.html#dict.setdefault
exists(MethodCallNode call |
call.calls(nodeTo.(PostUpdateNode).getPreUpdateNode(), "setdefault") and
call.getArg(0).asExpr().(StrConst).getText() = c.getKey() and
call.getArg(0).asExpr().(StringLiteral).getText() = c.getKey() and
nodeFrom = call.getArg(1)
)
}
Expand All @@ -844,7 +844,7 @@ predicate dictClearStep(Node node, DictionaryElementContent c) {
exists(SubscriptNode subscript |
subscript instanceof DefinitionNode and
node.asCfgNode() = subscript.getObject() and
c.getKey() = subscript.getIndex().getNode().(StrConst).getText()
c.getKey() = subscript.getIndex().getNode().(StringLiteral).getText()
)
}

Expand Down Expand Up @@ -954,7 +954,7 @@ predicate subscriptReadStep(CfgNode nodeFrom, Content c, CfgNode nodeTo) {
nodeTo.getNode().(SubscriptNode).getIndex().getNode().(IntegerLiteral).getValue()
or
c.(DictionaryElementContent).getKey() =
nodeTo.getNode().(SubscriptNode).getIndex().getNode().(StrConst).getS()
nodeTo.getNode().(SubscriptNode).getIndex().getNode().(StringLiteral).getS()
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -606,17 +606,18 @@ newtype TContent =
/** An element of a dictionary under a specific key. */
TDictionaryElementContent(string key) {
// {"key": ...}
key = any(KeyValuePair kvp).getKey().(StrConst).getText()
key = any(KeyValuePair kvp).getKey().(StringLiteral).getText()
or
// func(key=...)
key = any(Keyword kw).getArg()
or
// d["key"] = ...
key = any(SubscriptNode sub | sub.isStore() | sub.getIndex().getNode().(StrConst).getText())
key =
any(SubscriptNode sub | sub.isStore() | sub.getIndex().getNode().(StringLiteral).getText())
or
// d.setdefault("key", ...)
exists(CallNode call | call.getFunction().(AttrNode).getName() = "setdefault" |
key = call.getArg(0).getNode().(StrConst).getText()
key = call.getArg(0).getNode().(StringLiteral).getText()
)
} or
/** An element of a dictionary under any key. */
Expand Down
Loading

0 comments on commit 19974f0

Please sign in to comment.