Merge pull request #16245 from github/tausbn/python-rename-StrConst-to-StringLiteral

Python: Rename `StrConst` to `StringLiteral`
This commit is contained in:
Rasmus Wriedt Larsen
2024-04-23 09:35:24 +02:00
committed by GitHub
164 changed files with 936 additions and 884 deletions

View File

@@ -8,6 +8,6 @@
import python
from StrConst s
from StringLiteral s
where s.getPrefix().matches("%r%")
select s

View File

@@ -9,6 +9,6 @@
import python
from StrConst s
from StringLiteral s
where s.getPrefix().charAt(_) = "'"
select s

View File

@@ -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
)
}

View File

@@ -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.

View File

@@ -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()
}
}
@@ -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()
}
}
@@ -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()
}
}

View File

@@ -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()
)
}
}

View File

@@ -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()
)
}

View File

@@ -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()
)
@@ -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)
)

View File

@@ -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. */
@@ -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() }
@@ -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() }
@@ -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() {
@@ -610,7 +610,7 @@ 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() {
@@ -618,12 +618,19 @@ private string non_byte_prefix() {
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
@@ -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) {

View File

@@ -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
@@ -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()])
)
}

View File

@@ -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
)
)
}

View File

@@ -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;
}
/**
@@ -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

View File

@@ -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) }

View File

@@ -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
(

View File

@@ -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
@@ -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)
)

View File

@@ -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)
)
}
@@ -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())
}
@@ -217,7 +217,7 @@ private module SensitiveDataModeling {
result in [
sensitiveNameCandidate(), sensitiveAttributeNameCandidate(),
sensitiveParameterNameCandidate(), sensitiveFunctionNameCandidate(),
sensitiveStrConstCandidate()
sensitiveStringLiteralCandidate()
]
}

View File

@@ -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()
)
}
@@ -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()
}
}
@@ -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()
}
}

View File

@@ -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()
)
}
@@ -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)
)
}
@@ -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()
)
}
@@ -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()
)
}

View File

@@ -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. */

View File

@@ -146,7 +146,7 @@ module ImportResolution {
def.getValue() = n and
def.(NameNode).getId() = "__all__" and
def.getScope() = m and
any(StrConst s | s.getText() = name) = n.getAnElement().getNode()
any(StringLiteral s | s.getText() = name) = n.getAnElement().getNode()
)
}
@@ -210,7 +210,7 @@ module ImportResolution {
exists(SubscriptNode sub |
sub.getObject() = sys_modules_reference().asCfgNode() and
sub.getIndex() = n and
n.getNode().(StrConst).getText() = name and
n.getNode().(StringLiteral).getText() = name and
sub.(DefinitionNode).getValue() = mod.asCfgNode() and
mod = getModuleReference(result)
)

View File

@@ -224,7 +224,7 @@ predicate matchMappingReadStep(Node nodeFrom, Content c, Node nodeTo) {
|
nodeFrom.(CfgNode).getNode().getNode() = subject and
nodeTo.(CfgNode).getNode().getNode() = value and
c.(DictionaryElementContent).getKey() = key.getLiteral().(StrConst).getText()
c.(DictionaryElementContent).getKey() = key.getLiteral().(StringLiteral).getText()
)
}
@@ -256,7 +256,7 @@ predicate matchMappingClearStep(Node n, Content c) {
dstar = subject.getAMapping()
|
n.(CfgNode).getNode().getNode() = dstar.getTarget() and
c.(DictionaryElementContent).getKey() = key.getLiteral().(StrConst).getText()
c.(DictionaryElementContent).getKey() = key.getLiteral().(StringLiteral).getText()
)
}

View File

@@ -18,7 +18,7 @@ private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPr
*/
string prettyExpr(Expr e) {
not e instanceof Num and
not e instanceof StrConst and
not e instanceof StringLiteral and
not e instanceof Subscript and
not e instanceof Call and
not e instanceof Attribute and
@@ -27,8 +27,8 @@ string prettyExpr(Expr e) {
result = e.(Num).getN()
or
result =
e.(StrConst).getPrefix() + e.(StrConst).getText() +
e.(StrConst).getPrefix().regexpReplaceAll("[a-zA-Z]+", "")
e.(StringLiteral).getPrefix() + e.(StringLiteral).getText() +
e.(StringLiteral).getPrefix().regexpReplaceAll("[a-zA-Z]+", "")
or
result = prettyExpr(e.(Subscript).getObject()) + "[" + prettyExpr(e.(Subscript).getIndex()) + "]"
or

View File

@@ -410,7 +410,7 @@ class TaintTrackingImplementation extends string instanceof TaintTracking::Confi
call = node.asCfgNode() and
call.getFunction().pointsTo(ObjectInternal::builtin("getattr")) and
arg = call.getArg(0) and
attrname = call.getArg(1).getNode().(StrConst).getText() and
attrname = call.getArg(1).getNode().(StringLiteral).getText() and
arg = srcnode.asCfgNode()
|
path = srcpath.fromAttribute(attrname) and

View File

@@ -83,7 +83,7 @@ private module CryptodomeModel {
/** Gets the name of the curve to use, as well as the origin that explains how we obtained this name. */
string getCurveWithOrigin(DataFlow::Node origin) {
exists(StrConst str | origin = DataFlow::exprNode(str) |
exists(StringLiteral str | origin = DataFlow::exprNode(str) |
origin = this.getCurveArg().getALocalSource() and
result = str.getText()
)

View File

@@ -2862,14 +2862,14 @@ module PrivateDjango {
//
// This also strongly implies that `mw` is in fact a Django middleware setting and
// not just a variable named `MIDDLEWARE`.
list.getAnElt().(StrConst).getText() =
list.getAnElt().(StringLiteral).getText() =
"django.contrib.auth.middleware.AuthenticationMiddleware"
)
}
override boolean getVerificationSetting() {
if
list.getAnElt().(StrConst).getText() in [
list.getAnElt().(StringLiteral).getText() in [
"django.middleware.csrf.CsrfViewMiddleware",
// see https://github.com/mozilla/django-session-csrf
"session_csrf.CsrfMiddleware"

View File

@@ -183,7 +183,7 @@ module FastApi {
|
exists(Assign assign | assign = cls.getAStmt() |
assign.getATarget().(Name).getId() = "media_type" and
result = assign.getValue().(StrConst).getText()
result = assign.getValue().(StringLiteral).getText()
)
or
// TODO: this should use a proper MRO calculation instead
@@ -372,7 +372,7 @@ module FastApi {
headers.accesses(instance(), "headers") and
this.calls(headers, "append") and
keyArg in [this.getArg(0), this.getArgByName("key")] and
keyArg.getALocalSource().asExpr().(StrConst).getText().toLowerCase() = "set-cookie"
keyArg.getALocalSource().asExpr().(StringLiteral).getText().toLowerCase() = "set-cookie"
)
}

View File

@@ -80,7 +80,7 @@ private module Rsa {
result.getName() = "RSA"
or
// hashing part
exists(StrConst str, DataFlow::Node hashNameArg |
exists(StringLiteral str, DataFlow::Node hashNameArg |
hashNameArg in [this.getArg(2), this.getArgByName("hash_method")] and
DataFlow::exprNode(str) = hashNameArg.getALocalSource() and
result.matchesName(str.getText())
@@ -132,7 +132,7 @@ private module Rsa {
override DataFlow::Node getInitialization() { result = this }
override Cryptography::CryptographicAlgorithm getAlgorithm() {
exists(StrConst str, DataFlow::Node hashNameArg |
exists(StringLiteral str, DataFlow::Node hashNameArg |
hashNameArg in [this.getArg(1), this.getArgByName("method_name")] and
DataFlow::exprNode(str) = hashNameArg.getALocalSource() and
result.matchesName(str.getText())

View File

@@ -2785,7 +2785,7 @@ module StdlibPrivate {
/** Gets a call to `hashlib.new` with `algorithmName` as the first argument. */
private API::CallNode hashlibNewCall(string algorithmName) {
algorithmName =
result.getParameter(0, "name").getAValueReachingSink().asExpr().(StrConst).getText() and
result.getParameter(0, "name").getAValueReachingSink().asExpr().(StringLiteral).getText() and
result = API::moduleImport("hashlib").getMember("new").getACall()
}
@@ -2908,7 +2908,8 @@ module StdlibPrivate {
exists(string algorithmName | result.matchesName(algorithmName) |
this.getDigestArg().asSink() = hashlibMember(algorithmName).asSource()
or
this.getDigestArg().getAValueReachingSink().asExpr().(StrConst).getText() = algorithmName
this.getDigestArg().getAValueReachingSink().asExpr().(StringLiteral).getText() =
algorithmName
)
}
@@ -4418,7 +4419,7 @@ module StdlibPrivate {
override DataFlow::CallCfgNode getACall() {
result.(DataFlow::MethodCallNode).getMethodName() = "pop" and
result.getArg(0).getALocalSource().asExpr().(StrConst).getText() = key
result.getArg(0).getALocalSource().asExpr().(StringLiteral).getText() = key
}
override DataFlow::ArgumentNode getACallback() { none() }
@@ -4441,7 +4442,7 @@ module StdlibPrivate {
override DataFlow::CallCfgNode getACall() {
result.(DataFlow::MethodCallNode).getMethodName() = "get" and
result.getArg(0).getALocalSource().asExpr().(StrConst).getText() = key
result.getArg(0).getALocalSource().asExpr().(StringLiteral).getText() = key
}
override DataFlow::ArgumentNode getACallback() { none() }
@@ -4541,7 +4542,7 @@ module StdlibPrivate {
override DataFlow::CallCfgNode getACall() {
result.(DataFlow::MethodCallNode).getMethodName() = "setdefault" and
result.getArg(0).getALocalSource().asExpr().(StrConst).getText() = key
result.getArg(0).getALocalSource().asExpr().(StringLiteral).getText() = key
}
override DataFlow::ArgumentNode getACallback() { none() }

View File

@@ -78,7 +78,7 @@ module Urllib3 {
// see https://urllib3.readthedocs.io/en/stable/user-guide.html?highlight=cert_reqs#certificate-verification
disablingNode = constructor.getKeywordParameter("cert_reqs").asSink() and
argumentOrigin = constructor.getKeywordParameter("cert_reqs").getAValueReachingSink() and
argumentOrigin.asExpr().(StrConst).getText() = "CERT_NONE"
argumentOrigin.asExpr().(StringLiteral).getText() = "CERT_NONE"
or
// assert_hostname
// see https://urllib3.readthedocs.io/en/stable/reference/urllib3.connectionpool.html?highlight=assert_hostname#urllib3.HTTPSConnectionPool

View File

@@ -239,8 +239,8 @@ class UnicodeObjectInternal extends ConstantObjectInternal, TUnicode {
override predicate introducedAt(ControlFlowNode node, PointsToContext context) {
context.appliesTo(node) and
node.getNode().(StrConst).getText() = this.strValue() and
node.getNode().(StrConst).isUnicode()
node.getNode().(StringLiteral).getText() = this.strValue() and
node.getNode().(StringLiteral).isUnicode()
}
override ObjectInternal getClass() { result = TBuiltinClassObject(Builtin::special("unicode")) }
@@ -272,8 +272,8 @@ class BytesObjectInternal extends ConstantObjectInternal, TBytes {
override predicate introducedAt(ControlFlowNode node, PointsToContext context) {
context.appliesTo(node) and
node.getNode().(StrConst).getText() = this.strValue() and
not node.getNode().(StrConst).isUnicode()
node.getNode().(StringLiteral).getText() = this.strValue() and
not node.getNode().(StringLiteral).isUnicode()
}
override ObjectInternal getClass() { result = TBuiltinClassObject(Builtin::special("bytes")) }

View File

@@ -201,7 +201,7 @@ class ModuleValue extends Value instanceof ModuleObjectInternal {
(
not this.getPath().getExtension() = "py"
or
exists(If i, Name name, StrConst main, Cmpop op |
exists(If i, Name name, StringLiteral main, Cmpop op |
i.getScope() = this.getScope() and
op instanceof Eq and
i.getTest().(Compare).compares(name, op, main) and

View File

@@ -84,7 +84,7 @@ newtype TObject =
/** The unicode string `s` */
TUnicode(string s) {
// Any string explicitly mentioned in the source code.
exists(StrConst str |
exists(StringLiteral str |
s = str.getText() and
str.isUnicode()
)
@@ -100,7 +100,7 @@ newtype TObject =
/** The byte string `s` */
TBytes(string s) {
// Any string explicitly mentioned in the source code.
exists(StrConst str |
exists(StringLiteral str |
s = str.getText() and
not str.isUnicode()
)

View File

@@ -9,7 +9,7 @@ import python
predicate hasattr(CallNode c, ControlFlowNode obj, string attr) {
c.getFunction().getNode().(Name).getId() = "hasattr" and
c.getArg(0) = obj and
c.getArg(1).getNode().(StrConst).getText() = attr
c.getArg(1).getNode().(StringLiteral).getText() = attr
}
/** Holds if `c` is a call to `isinstance(use, cls)`. */

View File

@@ -691,7 +691,7 @@ module PointsToInternal {
sub.getObject() = sys_modules_flow and
pointsTo(sys_modules_flow, _, ObjectInternal::sysModules(), _) and
sub.getIndex() = n and
n.getNode().(StrConst).getText() = name and
n.getNode().(StringLiteral).getText() = name and
sub.(DefinitionNode).getValue() = mod and
pointsTo(mod, _, m, _)
)

View File

@@ -253,7 +253,7 @@ predicate executes_in_runtime_context(Function f) {
}
private predicate maybe_main(Module m) {
exists(If i, Compare cmp, Name name, StrConst main | m.getAStmt() = i and i.getTest() = cmp |
exists(If i, Compare cmp, Name name, StringLiteral main | m.getAStmt() = i and i.getTest() = cmp |
cmp.compares(name, any(Eq eq), main) and
name.getId() = "__name__" and
main.getText() = "__main__"

View File

@@ -15,7 +15,7 @@ RegExpTerm getTermForExecution(Concepts::RegexExecution exec) {
)
}
/** A StrConst used as a regular expression */
/** A StringLiteral used as a regular expression */
deprecated class RegexString extends Regex {
RegexString() { this = RegExpTracking::regExpSource(_).asExpr() }
}

View File

@@ -9,7 +9,7 @@ import Impl as RegexTreeView
import Impl
/** Gets the parse tree resulting from parsing `re`, if such has been constructed. */
RegExpTerm getParsedRegExp(StrConst re) { result.getRegex() = re and result.isRootTerm() }
RegExpTerm getParsedRegExp(StringLiteral re) { result.getRegex() = re and result.isRootTerm() }
/**
* An element containing a regular expression term, that is, either
@@ -230,7 +230,8 @@ module Impl implements RegexTreeViewSig {
index > 0 and
exists(int previousOffset | previousOffset = this.getPartOffset(index - 1) |
result =
previousOffset + re.(StrConst).getImplicitlyConcatenatedPart(index - 1).getContentLength()
previousOffset +
re.(StringLiteral).getImplicitlyConcatenatedPart(index - 1).getContentLength()
)
}
@@ -240,7 +241,7 @@ module Impl implements RegexTreeViewSig {
*/
StringPart getPart(int localOffset) {
exists(int index, int prefixLength | index = max(int i | this.getPartOffset(i) <= start) |
result = re.(StrConst).getImplicitlyConcatenatedPart(index) and
result = re.(StringLiteral).getImplicitlyConcatenatedPart(index) and
result.contextSize(prefixLength, _) and
// Example:
// re.compile('...' r"""...this..""")

View File

@@ -105,8 +105,8 @@ private module FindRegexMode {
*/
deprecated class Regex = RegExp;
/** A StrConst used as a regular expression */
class RegExp extends Expr instanceof StrConst {
/** A StringLiteral used as a regular expression */
class RegExp extends Expr instanceof StringLiteral {
DataFlow::Node use;
RegExp() { this = RegExpTracking::regExpSource(use).asExpr() }

View File

@@ -15,7 +15,7 @@ private import semmle.python.dataflow.new.DataFlow
private import semmle.python.Concepts as Concepts
/** Gets a constant string value that may be used as a regular expression. */
DataFlow::LocalSourceNode strStart() { result.asExpr() instanceof StrConst }
DataFlow::LocalSourceNode strStart() { result.asExpr() instanceof StringLiteral }
private import semmle.python.regex as Regex

View File

@@ -90,7 +90,7 @@ module LogInjection {
// TODO: Consider rewriting using flow states.
ReplaceLineBreaksSanitizer() {
this.getFunction().(DataFlow::AttrRead).getAttributeName() = "replace" and
this.getArg(0).asExpr().(StrConst).getText() in ["\r\n", "\n"]
this.getArg(0).asExpr().(StringLiteral).getText() in ["\r\n", "\n"]
}
}
}

View File

@@ -20,7 +20,7 @@ module PamAuthorizationCustomizations {
exists(API::CallNode findLibCall, API::CallNode cdllCall |
findLibCall =
API::moduleImport("ctypes").getMember("util").getMember("find_library").getACall() and
findLibCall.getParameter(0).getAValueReachingSink().asExpr().(StrConst).getText() = "pam" and
findLibCall.getParameter(0).getAValueReachingSink().asExpr().(StringLiteral).getText() = "pam" and
cdllCall = API::moduleImport("ctypes").getMember("CDLL").getACall() and
cdllCall.getParameter(0).getAValueReachingSink() = findLibCall
|

View File

@@ -88,7 +88,9 @@ module ServerSideRequestForgery {
exists(BinaryExprNode add |
add.getOp() instanceof Add and
add.getRight() = this.asCfgNode() and
not add.getLeft().getNode().(StrConst).getText().toLowerCase() in ["http://", "https://"]
not add.getLeft().getNode().(StringLiteral).getText().toLowerCase() in [
"http://", "https://"
]
)
or
// % formatting
@@ -97,7 +99,7 @@ module ServerSideRequestForgery {
fmt.getRight() = this.asCfgNode() and
// detecting %-formatting is not super easy, so we simplify it to only handle
// when there is a **single** substitution going on.
not fmt.getLeft().getNode().(StrConst).getText().regexpMatch("^(?i)https?://%s[^%]*$")
not fmt.getLeft().getNode().(StringLiteral).getText().regexpMatch("^(?i)https?://%s[^%]*$")
)
or
// arguments to a format call
@@ -106,9 +108,9 @@ module ServerSideRequestForgery {
|
call.getMethodName() = "format" and
(
if call.getObject().asExpr().(StrConst).getText().regexpMatch(httpPrefixRe)
if call.getObject().asExpr().(StringLiteral).getText().regexpMatch(httpPrefixRe)
then
exists(string text | text = call.getObject().asExpr().(StrConst).getText() |
exists(string text | text = call.getObject().asExpr().(StringLiteral).getText() |
// `http://{}...`
exists(text.regexpCapture(httpPrefixRe, 1)) and
this in [call.getArg(any(int i | i >= 1)), call.getArgByName(_)]
@@ -129,7 +131,7 @@ module ServerSideRequestForgery {
or
// f-string
exists(Fstring fstring |
if fstring.getValue(0).(StrConst).getText().toLowerCase() in ["http://", "https://"]
if fstring.getValue(0).(StringLiteral).getText().toLowerCase() in ["http://", "https://"]
then fstring.getValue(any(int i | i >= 2)) = this.asExpr()
else fstring.getValue(any(int i | i >= 1)) = this.asExpr()
)

View File

@@ -39,7 +39,7 @@ module TarSlip {
this = API::moduleImport("tarfile").getMember("open").getACall() and
// If argument refers to a string object, then it's a hardcoded path and
// this tarfile is safe.
not this.(DataFlow::CallCfgNode).getArg(0).getALocalSource().asExpr() instanceof StrConst and
not this.(DataFlow::CallCfgNode).getArg(0).getALocalSource().asExpr() instanceof StringLiteral and
// Ignore opens within the tarfile module itself
not this.getLocation().getFile().getBaseName() = "tarfile.py"
}
@@ -70,7 +70,7 @@ module TarSlip {
exists(Expr filterValue |
filterValue = call.getParameter(4, "filter").getAValueReachingSink().asExpr() and
(
filterValue.(StrConst).getText() = "fully_trusted"
filterValue.(StringLiteral).getText() = "fully_trusted"
or
filterValue instanceof None
)

View File

@@ -33,7 +33,7 @@ module UnsafeShellCommandConstruction {
/** A sink for shell command constructed from library input vulnerabilities. */
abstract class Sink extends DataFlow::Node {
Sink() { not this.asExpr() instanceof StrConst } // filter out string constants, makes testing easier
Sink() { not this.asExpr() instanceof StringLiteral } // filter out string constants, makes testing easier
/** Gets a description of how the string in this sink was constructed. */
abstract string describe();
@@ -113,7 +113,7 @@ module UnsafeShellCommandConstruction {
ArrayJoin() {
call.getMethodName() = "join" and
unique( | | call.getArg(_)).asExpr().(Str).getText() = " " and
unique( | | call.getArg(_)).asExpr().(StringLiteral).getText() = " " and
isUsedAsShellCommand(call, s) and
(
this = call.getArg(0) and

View File

@@ -118,8 +118,8 @@ module UrlRedirect {
ReplaceBackslashesSanitizer() {
this.calls(receiver, "replace") and
this.getArg(0).asExpr().(StrConst).getText() = "\\" and
this.getArg(1).asExpr().(StrConst).getText() in ["/", ""]
this.getArg(0).asExpr().(StringLiteral).getText() = "\\" and
this.getArg(1).asExpr().(StringLiteral).getText() in ["/", ""]
}
override predicate sanitizes(FlowState state) { state instanceof MayContainBackslashes }

View File

@@ -1,10 +1,10 @@
import python
predicate format_string(StrConst e) {
predicate format_string(StringLiteral e) {
exists(BinaryExpr b | b.getOp() instanceof Mod and b.getLeft() = e)
}
predicate mapping_format(StrConst e) {
predicate mapping_format(StringLiteral e) {
conversion_specifier(e, _).regexpMatch("%\\([A-Z_a-z0-9]+\\).*")
}
@@ -17,18 +17,18 @@ predicate mapping_format(StrConst e) {
* TYPE = "[bdiouxXeEfFgGcrs%]"
*/
private string conversion_specifier_string(StrConst e, int number, int position) {
private string conversion_specifier_string(StringLiteral e, int number, int position) {
exists(string s, string regex | s = e.getText() |
regex = "%(\\([^)]*\\))?[#0\\- +]*(\\*|[0-9]*)(\\.(\\*|[0-9]*))?(h|H|l|L)?[badiouxXeEfFgGcrs%]" and
result = s.regexpFind(regex, number, position)
)
}
private string conversion_specifier(StrConst e, int number) {
private string conversion_specifier(StringLiteral e, int number) {
result = conversion_specifier_string(e, number, _) and result != "%%"
}
int illegal_conversion_specifier(StrConst e) {
int illegal_conversion_specifier(StringLiteral e) {
format_string(e) and
"%" = e.getText().charAt(result) and
// not the start of a conversion specifier or the second % of a %%
@@ -37,7 +37,7 @@ int illegal_conversion_specifier(StrConst e) {
}
/** Gets the number of format items in a format string */
int format_items(StrConst e) {
int format_items(StringLiteral e) {
result =
count(int i | | conversion_specifier(e, i)) +
// a conversion specifier uses an extra item for each *
@@ -47,7 +47,7 @@ int format_items(StrConst e) {
private string str(Expr e) {
result = e.(Num).getN()
or
result = "'" + e.(StrConst).getText() + "'"
result = "'" + e.(StringLiteral).getText() + "'"
}
/** Gets a string representation of an expression more suited for embedding in message strings than .toString() */

View File

@@ -15,7 +15,7 @@ private predicate is_script(ModuleObject m) {
(
m.getModule().getFile().getExtension() != ".py"
or
exists(If i, Name name, StrConst main, Cmpop op |
exists(If i, Name name, StringLiteral main, Cmpop op |
i.getScope() = m.getModule() and
op instanceof Eq and
i.getTest().(Compare).compares(name, op, main) and

View File

@@ -9,7 +9,7 @@ private predicate is_an_object(@py_object obj) {
/* CFG nodes for numeric literals, all of which have a @py_cobject for the value of that literal */
obj instanceof ControlFlowNode and
not obj.(ControlFlowNode).getNode() instanceof IntegerLiteral and
not obj.(ControlFlowNode).getNode() instanceof StrConst
not obj.(ControlFlowNode).getNode() instanceof StringLiteral
or
obj instanceof Builtin
}

View File

@@ -22,7 +22,7 @@ predicate dict_key(Dict d, Expr k, string s) {
// We use <20> to mark unrepresentable characters
// so two instances of <20> may represent different strings in the source code
not "<22>" = s.charAt(_) and
exists(StrConst c | c = k |
exists(StringLiteral c | c = k |
s = "u\"" + c.getText() + "\"" and c.isUnicode()
or
s = "b\"" + c.getText() + "\"" and not c.isUnicode()

View File

@@ -1,7 +1,7 @@
import python
/** A string constant that looks like it may be used in string formatting operations. */
class PossibleAdvancedFormatString extends StrConst {
class PossibleAdvancedFormatString extends StringLiteral {
PossibleAdvancedFormatString() { this.getText().matches("%{%}%") }
private predicate field(int start, int end) {

View File

@@ -21,7 +21,7 @@ predicate comparison_using_is(Compare comp, ControlFlowNode left, Cmpop op, Cont
}
private predicate cpython_interned_value(Expr e) {
exists(string text | text = e.(StrConst).getText() |
exists(string text | text = e.(StringLiteral).getText() |
text.length() = 0
or
text.length() = 1 and text.regexpMatch("[U+0000-U+00ff]")
@@ -34,7 +34,7 @@ private predicate cpython_interned_value(Expr e) {
predicate uninterned_literal(Expr e) {
(
e instanceof StrConst
e instanceof StringLiteral
or
e instanceof IntegerLiteral
or

View File

@@ -49,7 +49,7 @@ predicate simple_constant(ControlFlowNode f) {
}
private predicate cpython_interned_value(Expr e) {
exists(string text | text = e.(StrConst).getText() |
exists(string text | text = e.(StringLiteral).getText() |
text.length() = 0
or
text.length() = 1 and text.regexpMatch("[U+0000-U+00ff]")
@@ -70,7 +70,7 @@ private predicate universally_interned_value(Expr e) {
or
exists(Tuple t | t = e and not exists(t.getAnElt()))
or
e.(StrConst).getText() = ""
e.(StringLiteral).getText() = ""
}
/** Holds if the expression `e` points to an interned constant in CPython. */

View File

@@ -15,12 +15,12 @@
import python
predicate string_const(Expr s) {
s instanceof StrConst
s instanceof StringLiteral
or
string_const(s.(BinaryExpr).getLeft()) and string_const(s.(BinaryExpr).getRight())
}
from StrConst s
from StringLiteral s
where
// Implicitly concatenated string is in a list and that list contains at least one other string.
exists(List l, Expr other |

View File

@@ -15,7 +15,7 @@
import python
import semmle.python.strings
predicate string_format(BinaryExpr operation, StrConst str, Value args, AstNode origin) {
predicate string_format(BinaryExpr operation, StringLiteral str, Value args, AstNode origin) {
operation.getOp() instanceof Mod and
exists(Context ctx |
operation.getLeft().pointsTo(ctx, _, str) and
@@ -34,7 +34,7 @@ int sequence_length(Value args) {
}
from
BinaryExpr operation, StrConst fmt, Value args, int slen, int alen, AstNode origin,
BinaryExpr operation, StringLiteral fmt, Value args, int slen, int alen, AstNode origin,
string provided
where
string_format(operation, fmt, args, origin) and

View File

@@ -53,7 +53,7 @@ predicate imported_module_used_in_doctest(Import imp) {
pragma[noinline]
private string doctest_in_scope(Scope scope) {
exists(StrConst doc |
exists(StringLiteral doc |
doc.getEnclosingModule() = scope and
doc.isDocString() and
result = doc.getText() and
@@ -63,7 +63,7 @@ private string doctest_in_scope(Scope scope) {
pragma[noinline]
private string typehint_annotation_in_module(Module module_scope) {
exists(StrConst annotation |
exists(StringLiteral annotation |
annotation = any(Arguments a).getAnAnnotation().getASubExpression*()
or
annotation = any(AnnAssign a).getAnnotation().getASubExpression*()

View File

@@ -29,9 +29,9 @@ private string vulnerableHostname() {
/** Gets a reference to a hostname that can be used to bind to all interfaces. */
private DataFlow::TypeTrackingNode vulnerableHostnameRef(DataFlow::TypeTracker t, string hostname) {
t.start() and
exists(StrConst allInterfacesStrConst | hostname = vulnerableHostname() |
allInterfacesStrConst.getText() = hostname and
result.asExpr() = allInterfacesStrConst
exists(StringLiteral allInterfacesStringLiteral | hostname = vulnerableHostname() |
allInterfacesStringLiteral.getText() = hostname and
result.asExpr() = allInterfacesStringLiteral
)
or
exists(DataFlow::TypeTracker t2 | result = vulnerableHostnameRef(t2, hostname).track(t2, t))

View File

@@ -16,7 +16,7 @@ import semmle.python.regex
private string commonTopLevelDomainRegex() { result = "com|org|edu|gov|uk|net|io" }
predicate looksLikeUrl(StrConst s) {
predicate looksLikeUrl(StringLiteral s) {
exists(string text | text = s.getText() |
text.regexpMatch("(?i)([a-z]*:?//)?\\.?([a-z0-9-]+\\.)+(" + commonTopLevelDomainRegex() +
")(:[0-9]+)?/?")
@@ -26,7 +26,7 @@ predicate looksLikeUrl(StrConst s) {
)
}
predicate incomplete_sanitization(Expr sanitizer, StrConst url) {
predicate incomplete_sanitization(Expr sanitizer, StringLiteral url) {
looksLikeUrl(url) and
(
sanitizer.(Compare).compares(url, any(In i), _)
@@ -37,19 +37,19 @@ predicate incomplete_sanitization(Expr sanitizer, StrConst url) {
)
}
predicate unsafe_call_to_startswith(Call sanitizer, StrConst url) {
predicate unsafe_call_to_startswith(Call sanitizer, StringLiteral url) {
sanitizer.getFunc().(Attribute).getName() = "startswith" and
sanitizer.getArg(0) = url and
not url.getText().regexpMatch("(?i)https?://[\\.a-z0-9-]+/.*")
}
predicate unsafe_call_to_endswith(Call sanitizer, StrConst url) {
predicate unsafe_call_to_endswith(Call sanitizer, StringLiteral url) {
sanitizer.getFunc().(Attribute).getName() = "endswith" and
sanitizer.getArg(0) = url and
not url.getText().regexpMatch("(?i)\\.([a-z0-9-]+)(\\.[a-z0-9-]+)+")
}
from Expr sanitizer, StrConst url
from Expr sanitizer, StringLiteral url
where incomplete_sanitization(sanitizer, url)
select sanitizer, "The string $@ may be at an arbitrary position in the sanitized URL.", url,
url.getText()

View File

@@ -20,7 +20,7 @@ private import semmle.python.dataflow.new.internal.DataFlowDispatch as DataFlowD
private import semmle.python.dataflow.new.internal.Builtins::Builtins as Builtins
bindingset[char, fraction]
predicate fewer_characters_than(StrConst str, string char, float fraction) {
predicate fewer_characters_than(StringLiteral str, string char, float fraction) {
exists(string text, int chars |
text = str.getText() and
chars = count(int i | text.charAt(i) = char)
@@ -41,15 +41,15 @@ predicate possible_reflective_name(string name) {
exists(Builtins::likelyBuiltin(name))
}
int char_count(StrConst str) { result = count(string c | c = str.getText().charAt(_)) }
int char_count(StringLiteral str) { result = count(string c | c = str.getText().charAt(_)) }
predicate capitalized_word(StrConst str) { str.getText().regexpMatch("[A-Z][a-z]+") }
predicate capitalized_word(StringLiteral str) { str.getText().regexpMatch("[A-Z][a-z]+") }
predicate format_string(StrConst str) { str.getText().matches("%{%}%") }
predicate format_string(StringLiteral str) { str.getText().matches("%{%}%") }
predicate maybeCredential(ControlFlowNode f) {
/* A string that is not too short and unlikely to be text or an identifier. */
exists(StrConst str | str = f.getNode() |
exists(StringLiteral str | str = f.getNode() |
/* At least 10 characters */
str.getText().length() > 9 and
/* Not too much whitespace */

View File

@@ -21,7 +21,7 @@ where
exists(Expr test | test = a.getTest() |
value = test.(IntegerLiteral).getN()
or
value = "\"" + test.(StrConst).getS() + "\""
value = "\"" + test.(StringLiteral).getS() + "\""
or
value = test.(NameConstant).toString()
) and

View File

@@ -121,7 +121,7 @@ predicate python2_print(Expr e) {
predicate no_effect(Expr e) {
// strings can be used as comments
not e instanceof StrConst and
not e instanceof StringLiteral and
not e.hasSideEffects() and
forall(Expr sub | sub = e.getASubExpression*() |
not side_effecting_binary(sub) and

View File

@@ -14,7 +14,7 @@
import python
predicate main_eq_name(If i) {
exists(Name n, StrConst m, Compare c |
exists(Name n, StringLiteral m, Compare c |
i.getTest() = c and
c.getLeft() = n and
c.getAComparator() = m and

View File

@@ -9,7 +9,7 @@ private predicate empty_sequence(Expr e) {
or
e instanceof Tuple and not exists(e.(Tuple).getAnElt())
or
e.(StrConst).getText().length() = 0
e.(StringLiteral).getText().length() = 0
}
/* This has the potential for refinement, but we err on the side of fewer false positives for now. */

View File

@@ -1,7 +1,7 @@
import python
predicate monkey_patched_builtin(string name) {
exists(AttrNode attr, SubscriptNode subscr, StrConst s |
exists(AttrNode attr, SubscriptNode subscr, StringLiteral s |
subscr.isStore() and
subscr.getIndex().getNode() = s and
s.getText() = name and
@@ -9,7 +9,7 @@ predicate monkey_patched_builtin(string name) {
attr.getObject("__dict__").pointsTo(Module::builtinModule())
)
or
exists(CallNode call, ControlFlowNode bltn, StrConst s |
exists(CallNode call, ControlFlowNode bltn, StringLiteral s |
call.getArg(0) = bltn and
bltn.pointsTo(Module::builtinModule()) and
call.getArg(1).getNode() = s and

View File

@@ -43,7 +43,7 @@ predicate simple_literal(Expr e) {
or
e instanceof Dict and not exists(e.(Dict).getAKey())
or
e.(StrConst).getText() = ""
e.(StringLiteral).getText() = ""
}
/**

View File

@@ -14,7 +14,7 @@
import python
/** Whether name is declared in the __all__ list of this module */
predicate declaredInAll(Module m, StrConst name) {
predicate declaredInAll(Module m, StringLiteral name) {
exists(Assign a, GlobalVariable all |
a.defines(all) and
a.getScope() = m and
@@ -70,7 +70,7 @@ predicate contains_unknown_import_star(ModuleValue m) {
)
}
from ModuleValue m, StrConst name, string exported_name
from ModuleValue m, StringLiteral name, string exported_name
where
declaredInAll(m.getScope(), name) and
exported_name = name.getText() and

View File

@@ -24,7 +24,7 @@ predicate complex_all(Module m) {
|
not a.getValue() instanceof List
or
exists(Expr e | e = a.getValue().(List).getAnElt() | not e instanceof StrConst)
exists(Expr e | e = a.getValue().(List).getAnElt() | not e instanceof StringLiteral)
)
or
exists(Call c, GlobalVariable all |

View File

@@ -121,7 +121,7 @@ module FlaskConstantSecretKeyConfig {
.getACall() and
result =
[
cn.getParameter(0).getAValueReachingSink().asExpr().(StrConst).getText(),
cn.getParameter(0).getAValueReachingSink().asExpr().(StringLiteral).getText(),
cn.getParameter(0).asSink().asExpr().(Name).getId()
]
}
@@ -134,6 +134,6 @@ module FlaskConstantSecretKeyConfig {
.getASuccessor*()
.getMember("from_object")
.getACall() and
result = cn.getParameter(0).asSink().asExpr().(StrConst).getText()
result = cn.getParameter(0).asSink().asExpr().(StringLiteral).getText()
}
}

View File

@@ -11,12 +11,12 @@ class WebAppConstantSecretKeySource extends DataFlow::Node {
env = API::moduleImport("environ").getMember("Env") and
// has default value
exists(API::Node param | param = env.getKeywordParameter("SECRET_KEY") |
param.asSink().asExpr().getASubExpression*() instanceof StrConst
param.asSink().asExpr().getASubExpression*() instanceof StringLiteral
) and
this = env.getReturn().getReturn().asSource()
)
or
this.asExpr() instanceof StrConst
this.asExpr() instanceof StringLiteral
or
exists(API::CallNode cn |
cn =
@@ -25,7 +25,8 @@ class WebAppConstantSecretKeySource extends DataFlow::Node {
API::moduleImport("os").getMember("environ").getMember("get").getACall()
] and
cn.getNumArgument() = 2 and
DataFlow::localFlow(any(DataFlow::Node n | n.asExpr() instanceof StrConst), cn.getArg(1)) and
DataFlow::localFlow(any(DataFlow::Node n | n.asExpr() instanceof StringLiteral),
cn.getArg(1)) and
this.asExpr() = cn.asExpr()
)
) and

View File

@@ -20,7 +20,7 @@ predicate authenticatesImproperly(LdapBind ldapBind) {
not exists(ldapBind.getPassword())
)
or
exists(StrConst emptyString |
exists(StringLiteral emptyString |
emptyString.getText() = "" and
DataFlow::localFlow(DataFlow::exprNode(emptyString), ldapBind.getPassword())
)

View File

@@ -109,7 +109,7 @@ private module AzureBlobClientConfig implements DataFlow::StateConfigSig {
exists(DataFlow::AttrWrite attr |
node = anyClient(_).getAValueReachableFromSource() and
attr.accesses(node, "encryption_version") and
attr.getValue().asExpr().(StrConst).getText() in ["'2.0'", "2.0"]
attr.getValue().asExpr().(StringLiteral).getText() in ["'2.0'", "2.0"]
)
or
// small optimization to block flow with no encryption out of the post-update node

View File

@@ -41,7 +41,7 @@ private module ClientSuppliedIpUsedInSecurityCheckConfig implements DataFlow::Co
exists(Subscript ss |
not ss.getIndex().(IntegerLiteral).getText() = "0" and
ss.getObject().(Call).getFunc().(Attribute).getName() = "split" and
ss.getObject().(Call).getAnArg().(StrConst).getText() = "," and
ss.getObject().(Call).getAnArg().(StringLiteral).getText() = "," and
ss = node.asExpr()
)
}

View File

@@ -20,7 +20,7 @@ private class FlaskClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIpU
{
FlaskClientSuppliedIpUsedInSecurityCheck() {
this = Flask::request().getMember("headers").getMember(["get", "get_all", "getlist"]).getACall() and
this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = clientIpParameterName()
this.getArg(0).asExpr().(StringLiteral).getText().toLowerCase() = clientIpParameterName()
}
}
@@ -35,7 +35,7 @@ private class DjangoClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedIp
headers.getAttributeName() in ["headers", "META"] and
this.calls(headers, "get")
) and
this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = clientIpParameterName()
this.getArg(0).asExpr().(StringLiteral).getText().toLowerCase() = clientIpParameterName()
}
}
@@ -54,7 +54,7 @@ private class TornadoClientSuppliedIpUsedInSecurityCheck extends ClientSuppliedI
headers.getAttributeName() = "headers" and
this.calls(headers, ["get", "get_list"])
) and
this.getArg(0).asExpr().(StrConst).getText().toLowerCase() = clientIpParameterName()
this.getArg(0).asExpr().(StringLiteral).getText().toLowerCase() = clientIpParameterName()
}
}
@@ -85,8 +85,8 @@ private class CompareSink extends PossibleSecurityCheck {
CompareSink() {
exists(Call call |
call.getFunc().(Attribute).getName() = "startswith" and
call.getArg(0).(StrConst).getText().regexpMatch(getIpAddressRegex()) and
not call.getArg(0).(StrConst).getText() = "0:0:0:0:0:0:0:1" and
call.getArg(0).(StringLiteral).getText().regexpMatch(getIpAddressRegex()) and
not call.getArg(0).(StringLiteral).getText() = "0:0:0:0:0:0:0:1" and
call.getFunc().(Attribute).getObject() = this.asExpr()
)
or
@@ -97,12 +97,12 @@ private class CompareSink extends PossibleSecurityCheck {
) and
(
compare.getLeft() = this.asExpr() and
compare.getComparator(0).(StrConst).getText() instanceof PrivateHostName and
not compare.getComparator(0).(StrConst).getText() = "0:0:0:0:0:0:0:1"
compare.getComparator(0).(StringLiteral).getText() instanceof PrivateHostName and
not compare.getComparator(0).(StringLiteral).getText() = "0:0:0:0:0:0:0:1"
or
compare.getComparator(0) = this.asExpr() and
compare.getLeft().(StrConst).getText() instanceof PrivateHostName and
not compare.getLeft().(StrConst).getText() = "0:0:0:0:0:0:0:1"
compare.getLeft().(StringLiteral).getText() instanceof PrivateHostName and
not compare.getLeft().(StringLiteral).getText() = "0:0:0:0:0:0:0:1"
)
)
or
@@ -115,7 +115,7 @@ private class CompareSink extends PossibleSecurityCheck {
compare.getLeft() = this.asExpr()
or
compare.getComparator(0) = this.asExpr() and
not compare.getLeft().(StrConst).getText() in ["%", ",", "."]
not compare.getLeft().(StringLiteral).getText() in ["%", ",", "."]
)
)
}

View File

@@ -25,16 +25,22 @@ class UnicodeCompatibilityNormalize extends API::CallNode {
UnicodeCompatibilityNormalize() {
(
this = API::moduleImport("unicodedata").getMember("normalize").getACall() and
this.getParameter(0).getAValueReachingSink().asExpr().(StrConst).getText() in ["NFKC", "NFKD"]
this.getParameter(0).getAValueReachingSink().asExpr().(StringLiteral).getText() in [
"NFKC", "NFKD"
]
or
this = API::moduleImport("pyunormalize").getMember("normalize").getACall() and
this.getParameter(0).getAValueReachingSink().asExpr().(StrConst).getText() in ["NFKC", "NFKD"]
this.getParameter(0).getAValueReachingSink().asExpr().(StringLiteral).getText() in [
"NFKC", "NFKD"
]
) and
argIdx = 1
or
(
this = API::moduleImport("textnorm").getMember("normalize_unicode").getACall() and
this.getParameter(1).getAValueReachingSink().asExpr().(StrConst).getText() in ["NFKC", "NFKD"]
this.getParameter(1).getAValueReachingSink().asExpr().(StringLiteral).getText() in [
"NFKC", "NFKD"
]
or
this = API::moduleImport("unidecode").getMember("unidecode").getACall()
or

View File

@@ -28,7 +28,7 @@ import experimental.semmle.python.Concepts
*/
class CookieHeader extends Cookie::Range instanceof HeaderDeclaration {
CookieHeader() {
exists(StrConst str |
exists(StringLiteral str |
str.getText() = "Set-Cookie" and
DataFlow::exprNode(str)
.(DataFlow::LocalSourceNode)
@@ -37,7 +37,7 @@ class CookieHeader extends Cookie::Range instanceof HeaderDeclaration {
}
override predicate isSecure() {
exists(StrConst str |
exists(StringLiteral str |
str.getText().regexpMatch(".*; *Secure;.*") and
DataFlow::exprNode(str)
.(DataFlow::LocalSourceNode)
@@ -46,7 +46,7 @@ class CookieHeader extends Cookie::Range instanceof HeaderDeclaration {
}
override predicate isHttpOnly() {
exists(StrConst str |
exists(StringLiteral str |
str.getText().regexpMatch(".*; *HttpOnly;.*") and
DataFlow::exprNode(str)
.(DataFlow::LocalSourceNode)
@@ -55,7 +55,7 @@ class CookieHeader extends Cookie::Range instanceof HeaderDeclaration {
}
override predicate isSameSite() {
exists(StrConst str |
exists(StringLiteral str |
str.getText().regexpMatch(".*; *SameSite=(Strict|Lax);.*") and
DataFlow::exprNode(str)
.(DataFlow::LocalSourceNode)

View File

@@ -159,7 +159,7 @@ private module ExperimentalPrivateDjango {
}
override predicate isSameSite() {
exists(StrConst str |
exists(StringLiteral str |
str.getText() in ["Strict", "Lax"] and
DataFlow::exprNode(str)
.(DataFlow::LocalSourceNode)

View File

@@ -119,7 +119,7 @@ module ExperimentalFlask {
}
override predicate isSameSite() {
exists(StrConst str |
exists(StringLiteral str |
str.getText() in ["Strict", "Lax"] and
DataFlow::exprNode(str)
.(DataFlow::LocalSourceNode)

View File

@@ -6,7 +6,7 @@ predicate isEmptyOrNone(DataFlow::Node arg) { isEmpty(arg) or isNone(arg) }
/** Checks if an empty string `""` flows to `arg` */
predicate isEmpty(DataFlow::Node arg) {
exists(StrConst emptyString |
exists(StringLiteral emptyString |
emptyString.getText() = "" and
DataFlow::exprNode(emptyString).(DataFlow::LocalSourceNode).flowsTo(arg)
)

View File

@@ -74,7 +74,7 @@ private module Sendgrid {
private DataFlow::Node sendgridContent(DataFlow::CallCfgNode contentCall, string mime) {
mime in ["text/plain", "text/html", "text/x-amp-html"] and
exists(StrConst mimeNode |
exists(StringLiteral mimeNode |
mimeNode.getText() = mime and
DataFlow::exprNode(mimeNode).(DataFlow::LocalSourceNode).flowsTo(contentCall.getArg(0)) and
result = contentCall.getArg(1)
@@ -122,8 +122,12 @@ private module Sendgrid {
contentElement =
this.getKeywordParameter("request_body").getSubscript("content").getASubscript()
|
contentElement.getSubscript("type").getAValueReachingSink().asExpr().(StrConst).getText() =
["text/html", "text/x-amp-html"] and
contentElement
.getSubscript("type")
.getAValueReachingSink()
.asExpr()
.(StringLiteral)
.getText() = ["text/html", "text/x-amp-html"] and
result = contentElement.getSubscript("value").getAValueReachingSink()
)
or

View File

@@ -49,7 +49,7 @@ private module Authlib {
}
override string getAlgorithmString() {
exists(StrConst str |
exists(StringLiteral str |
DataFlow::exprNode(str).(DataFlow::LocalSourceNode).flowsTo(this.getAlgorithm()) and
result = str.getText()
)

View File

@@ -39,7 +39,7 @@ private module PyJwt {
}
override string getAlgorithmString() {
exists(StrConst str |
exists(StringLiteral str |
DataFlow::exprNode(str).(DataFlow::LocalSourceNode).flowsTo(this.getAlgorithm()) and
result = str.getText()
)
@@ -75,7 +75,7 @@ private module PyJwt {
}
override string getAlgorithmString() {
exists(StrConst str |
exists(StringLiteral str |
DataFlow::exprNode(str).(DataFlow::LocalSourceNode).flowsTo(this.getAlgorithm()) and
result = str.getText()
)

View File

@@ -40,7 +40,7 @@ private module PythonJose {
}
override string getAlgorithmString() {
exists(StrConst str |
exists(StringLiteral str |
DataFlow::exprNode(str).(DataFlow::LocalSourceNode).flowsTo(this.getAlgorithm()) and
result = str.getText()
)
@@ -76,7 +76,7 @@ private module PythonJose {
}
override string getAlgorithmString() {
exists(StrConst str |
exists(StringLiteral str |
DataFlow::exprNode(str).(DataFlow::LocalSourceNode).flowsTo(this.getAlgorithm()) and
result = str.getText()
)

View File

@@ -38,7 +38,7 @@ private module Python_Jwt {
override DataFlow::Node getAlgorithm() { result = this.verifyCall().getArg(2) }
override string getAlgorithmString() {
exists(StrConst str |
exists(StringLiteral str |
DataFlow::exprNode(str).(DataFlow::LocalSourceNode).flowsTo(this.getAlgorithm()) and
result = str.getText()
)

View File

@@ -23,7 +23,8 @@ module SmtpLib {
private DataFlow::CallCfgNode mimeText(string mimetype) {
result = smtpMimeTextInstance().getACall() and
[result.getArg(1), result.getArgByName("_subtype")].asExpr().(StrConst).getText() = mimetype
[result.getArg(1), result.getArgByName("_subtype")].asExpr().(StringLiteral).getText() =
mimetype
}
/**

View File

@@ -145,7 +145,7 @@ module TarFile {
.getParameter(1, "mode")
.getAValueReachingSink()
.asExpr()
.(StrConst)
.(StringLiteral)
.getText()
) or
not result
@@ -153,7 +153,7 @@ module TarFile {
.getParameter(1, "mode")
.getAValueReachingSink()
.asExpr()
.(StrConst)
.(StringLiteral)
.getText()
.matches("r:%")
)
@@ -211,7 +211,7 @@ module Pandas {
.getKeywordParameter("compression")
.getAValueReachingSink()
.asExpr()
.(StrConst)
.(StringLiteral)
.getText() = "tar"
)
)
@@ -260,13 +260,18 @@ module Gzip {
this = gzipCall.getParameter(0, "filename").asSink() and
(
not exists(
gzipCall.getParameter(1, "mode").getAValueReachingSink().asExpr().(StrConst).getText()
gzipCall
.getParameter(1, "mode")
.getAValueReachingSink()
.asExpr()
.(StringLiteral)
.getText()
) or
gzipCall
.getParameter(1, "mode")
.getAValueReachingSink()
.asExpr()
.(StrConst)
.(StringLiteral)
.getText()
.matches("%r%")
)
@@ -297,13 +302,18 @@ module Bz2 {
this = bz2Call.getParameter(0, "filename").asSink() and
(
not exists(
bz2Call.getParameter(1, "mode").getAValueReachingSink().asExpr().(StrConst).getText()
bz2Call
.getParameter(1, "mode")
.getAValueReachingSink()
.asExpr()
.(StringLiteral)
.getText()
) or
bz2Call
.getParameter(1, "mode")
.getAValueReachingSink()
.asExpr()
.(StrConst)
.(StringLiteral)
.getText()
.matches("%r%")
)
@@ -334,13 +344,18 @@ module Lzma {
this = lzmaCall.getParameter(0, "filename").asSink() and
(
not exists(
lzmaCall.getParameter(1, "mode").getAValueReachingSink().asExpr().(StrConst).getText()
lzmaCall
.getParameter(1, "mode")
.getAValueReachingSink()
.asExpr()
.(StringLiteral)
.getText()
) or
lzmaCall
.getParameter(1, "mode")
.getAValueReachingSink()
.asExpr()
.(StrConst)
.(StringLiteral)
.getText()
.matches("%r%")
)

View File

@@ -18,7 +18,7 @@ string getPrivateHostRegex() {
}
// "ldap://somethingon.theinternet.com"
class LdapFullHost extends StrConst {
class LdapFullHost extends StringLiteral {
LdapFullHost() {
exists(string s |
s = this.getText() and
@@ -29,15 +29,15 @@ class LdapFullHost extends StrConst {
}
}
class LdapSchema extends StrConst {
class LdapSchema extends StringLiteral {
LdapSchema() { this.getText().regexpMatch(getSchemaRegex()) }
}
class LdapPrivateHost extends StrConst {
class LdapPrivateHost extends StringLiteral {
LdapPrivateHost() { this.getText().regexpMatch(getPrivateHostRegex()) }
}
predicate concatAndCompareAgainstFullHostRegex(LdapSchema schema, StrConst host) {
predicate concatAndCompareAgainstFullHostRegex(LdapSchema schema, StringLiteral host) {
not host instanceof LdapPrivateHost and
(schema.getText() + host.getText()).regexpMatch(getFullHostRegex())
}

View File

@@ -204,8 +204,11 @@ abstract class ClientSuppliedSecret extends DataFlow::CallCfgNode { }
private class FlaskClientSuppliedSecret extends ClientSuppliedSecret {
FlaskClientSuppliedSecret() {
this = Flask::request().getMember("headers").getMember(["get", "get_all", "getlist"]).getACall() and
[this.getArg(0), this.getArgByName(["key", "name"])].asExpr().(StrConst).getText().toLowerCase() =
sensitiveheaders()
[this.getArg(0), this.getArgByName(["key", "name"])]
.asExpr()
.(StringLiteral)
.getText()
.toLowerCase() = sensitiveheaders()
}
}
@@ -216,7 +219,7 @@ private class DjangoClientSuppliedSecret extends ClientSuppliedSecret {
.getMember(["headers", "META"])
.getMember("get")
.getACall() and
[this.getArg(0), this.getArgByName("key")].asExpr().(StrConst).getText().toLowerCase() =
[this.getArg(0), this.getArgByName("key")].asExpr().(StringLiteral).getText().toLowerCase() =
sensitiveheaders()
}
}
@@ -229,7 +232,7 @@ API::Node requesthandler() {
private class TornadoClientSuppliedSecret extends ClientSuppliedSecret {
TornadoClientSuppliedSecret() {
this = requesthandler().getMember(["headers", "META"]).getMember("get").getACall() and
[this.getArg(0), this.getArgByName("key")].asExpr().(StrConst).getText().toLowerCase() =
[this.getArg(0), this.getArgByName("key")].asExpr().(StringLiteral).getText().toLowerCase() =
sensitiveheaders()
}
}
@@ -243,8 +246,11 @@ private class WerkzeugClientSuppliedSecret extends ClientSuppliedSecret {
WerkzeugClientSuppliedSecret() {
this =
headers().getMember(["headers", "META"]).getMember(["get", "get_all", "getlist"]).getACall() and
[this.getArg(0), this.getArgByName(["key", "name"])].asExpr().(StrConst).getText().toLowerCase() =
sensitiveheaders()
[this.getArg(0), this.getArgByName(["key", "name"])]
.asExpr()
.(StringLiteral)
.getText()
.toLowerCase() = sensitiveheaders()
}
}
@@ -314,10 +320,10 @@ class CompareSink extends DataFlow::Node {
) and
(
compare.getLeft() = this.asExpr() and
not compare.getComparator(0).(StrConst).getText() = "bearer"
not compare.getComparator(0).(StringLiteral).getText() = "bearer"
or
compare.getComparator(0) = this.asExpr() and
not compare.getLeft().(StrConst).getText() = "bearer"
not compare.getLeft().(StringLiteral).getText() = "bearer"
)
)
or

View File

@@ -3,8 +3,8 @@
| test.py | 1 | ControlFlowNode for f | 0 | Exit node for Module test | normal |
| test.py | 1 | ControlFlowNode for x | 2 | ControlFlowNode for exec | normal |
| test.py | 1 | Entry node for Function f | 1 | ControlFlowNode for x | normal |
| test.py | 2 | ControlFlowNode for Str | 2 | ControlFlowNode for exec() | normal |
| test.py | 2 | ControlFlowNode for exec | 2 | ControlFlowNode for Str | normal |
| test.py | 2 | ControlFlowNode for StringLiteral | 2 | ControlFlowNode for exec() | normal |
| test.py | 2 | ControlFlowNode for exec | 2 | ControlFlowNode for StringLiteral | normal |
| test.py | 2 | ControlFlowNode for exec() | 3 | ControlFlowNode for x | normal |
| test.py | 3 | ControlFlowNode for Return | 1 | Exit node for Function f | normal |
| test.py | 3 | ControlFlowNode for x | 3 | ControlFlowNode for Return | normal |
@@ -16,8 +16,8 @@
| unicode.py | 3 | ControlFlowNode for f | 0 | Exit node for Module unicode | normal |
| unicode.py | 3 | ControlFlowNode for x | 4 | ControlFlowNode for exec | normal |
| unicode.py | 3 | Entry node for Function f | 3 | ControlFlowNode for x | normal |
| unicode.py | 4 | ControlFlowNode for Str | 4 | ControlFlowNode for exec() | normal |
| unicode.py | 4 | ControlFlowNode for exec | 4 | ControlFlowNode for Str | normal |
| unicode.py | 4 | ControlFlowNode for StringLiteral | 4 | ControlFlowNode for exec() | normal |
| unicode.py | 4 | ControlFlowNode for exec | 4 | ControlFlowNode for StringLiteral | normal |
| unicode.py | 4 | ControlFlowNode for exec() | 5 | ControlFlowNode for x | normal |
| unicode.py | 5 | ControlFlowNode for Return | 3 | Exit node for Function f | normal |
| unicode.py | 5 | ControlFlowNode for x | 5 | ControlFlowNode for Return | normal |

View File

@@ -1,6 +1,6 @@
| test.py:3:1:3:11 | Str | \u0111\u0142e\u00b6\u014b\u00b6\u0142\u014b |
| test.py:3:15:3:19 | Str | hi |
| test.py:3:23:3:27 | Str | \n |
| test.py:4:1:4:11 | Str | \u0111\u0142e\u00b6\u014b\u00b6\u0142\u014b |
| test.py:4:15:4:19 | Str | hi |
| test.py:4:23:4:27 | Str | \n |
| test.py:3:1:3:11 | StringLiteral | \u0111\u0142e\u00b6\u014b\u00b6\u0142\u014b |
| test.py:3:15:3:19 | StringLiteral | hi |
| test.py:3:23:3:27 | StringLiteral | \n |
| test.py:4:1:4:11 | StringLiteral | \u0111\u0142e\u00b6\u014b\u00b6\u0142\u014b |
| test.py:4:15:4:19 | StringLiteral | hi |
| test.py:4:23:4:27 | StringLiteral | \n |

View File

@@ -1,4 +1,4 @@
import python
from StrConst s
from StringLiteral s
select s, s.getText()

View File

@@ -9,7 +9,7 @@
| foo.py | 2 | ControlFlowNode for foo | class foo | ControlFlowNode for ClassExpr |
| foo.py | 2 | ControlFlowNode for object | builtin-class object | ControlFlowNode for object |
| foo.py | 5 | ControlFlowNode for List | List | ControlFlowNode for List |
| foo.py | 5 | ControlFlowNode for Str | str b'foo' | ControlFlowNode for Str |
| foo.py | 5 | ControlFlowNode for StringLiteral | str b'foo' | ControlFlowNode for StringLiteral |
| foo.py | 5 | ControlFlowNode for __all__ | List | ControlFlowNode for List |
| test.py | 2 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
| test.py | 2 | ControlFlowNode for ImportMember | class foo | ControlFlowNode for ClassExpr |

View File

@@ -1,4 +1,4 @@
import python
from StrConst s
from StringLiteral s
select s.getLocation().getStartLine(), s.getText(), s.getPrefix()

View File

@@ -1,5 +1,5 @@
import python
from StrConst s, int bl, int bc, int el, int ec
from StringLiteral s, int bl, int bc, int el, int ec
where s.getLocation().hasLocationInfo(_, bl, bc, el, ec)
select bl, bc, el, ec, s.getText()

View File

@@ -1 +1 @@
| statements_test.py:21:5:21:19 | For | Iteration over $@, of class list, may also iterate over $@. | statements_test.py:20:13:20:33 | ControlFlowNode for List | sequence | statements_test.py:18:13:18:26 | ControlFlowNode for Str | string |
| statements_test.py:21:5:21:19 | For | Iteration over $@, of class list, may also iterate over $@. | statements_test.py:20:13:20:33 | ControlFlowNode for List | sequence | statements_test.py:18:13:18:26 | ControlFlowNode for StringLiteral | string |

View File

@@ -1,4 +1,4 @@
| UndefinedExport.py:3:18:3:20 | Str | The name 'y' is exported by __all__ but is not defined. |
| UndefinedExport.py:3:23:3:25 | Str | The name 'z' is exported by __all__ but is not defined. |
| UndefinedExport.py:3:28:3:35 | Str | The name 'module' is exported by __all__ but is not defined. |
| package/__init__.py:1:23:1:34 | Str | The name 'not_exists' is exported by __all__ but is not defined. |
| UndefinedExport.py:3:18:3:20 | StringLiteral | The name 'y' is exported by __all__ but is not defined. |
| UndefinedExport.py:3:23:3:25 | StringLiteral | The name 'z' is exported by __all__ but is not defined. |
| UndefinedExport.py:3:28:3:35 | StringLiteral | The name 'module' is exported by __all__ but is not defined. |
| package/__init__.py:1:23:1:34 | StringLiteral | The name 'not_exists' is exported by __all__ but is not defined. |

View File

@@ -6,7 +6,7 @@
| 5 | 18 | 5 | 22 | delay |
| 5 | 25 | 5 | 26 | to |
| 6 | 5 | 6 | 61 | ExprStmt |
| 6 | 5 | 6 | 61 | Str |
| 6 | 5 | 6 | 61 | StringLiteral |
| 7 | 5 | 7 | 23 | For |
| 7 | 9 | 7 | 9 | i |
| 7 | 14 | 7 | 18 | range |

View File

@@ -1,7 +1,7 @@
| 5 | Function ticker | 5 | delay |
| 5 | delay | 5 | to |
| 5 | to | 6 | Str |
| 6 | Str | 7 | range |
| 5 | to | 6 | StringLiteral |
| 6 | StringLiteral | 7 | range |
| 7 | For | 5 | Function ticker |
| 7 | For | 7 | i |
| 7 | i | 8 | i |

View File

@@ -1,75 +1,75 @@
| 2 | Fstring | 0 | Str |
| 2 | Fstring | 0 | StringLiteral |
| 2 | Fstring | 1 | world |
| 2 | Fstring | 2 | Str |
| 3 | Fstring | 0 | Str |
| 2 | Fstring | 2 | StringLiteral |
| 3 | Fstring | 0 | StringLiteral |
| 3 | Fstring | 1 | one |
| 3 | Fstring | 2 | Str |
| 3 | Fstring | 2 | StringLiteral |
| 3 | Fstring | 3 | two |
| 3 | Fstring | 4 | Str |
| 3 | Fstring | 4 | StringLiteral |
| 3 | Fstring | 5 | three |
| 3 | Fstring | 6 | Str |
| 4 | Fstring | 0 | Str |
| 3 | Fstring | 6 | StringLiteral |
| 4 | Fstring | 0 | StringLiteral |
| 4 | Fstring | 1 | cruel |
| 4 | Fstring | 2 | Str |
| 5 | Fstring | 0 | Str |
| 4 | Fstring | 2 | StringLiteral |
| 5 | Fstring | 0 | StringLiteral |
| 5 | Fstring | 1 | thing |
| 5 | Fstring | 2 | Str |
| 6 | Fstring | 0 | Str |
| 5 | Fstring | 2 | StringLiteral |
| 6 | Fstring | 0 | StringLiteral |
| 6 | Fstring | 1 | x |
| 6 | Fstring | 2 | Str |
| 8 | Fstring | 0 | Str |
| 6 | Fstring | 2 | StringLiteral |
| 8 | Fstring | 0 | StringLiteral |
| 8 | Fstring | 1 | name |
| 8 | Fstring | 2 | Str |
| 8 | Fstring | 2 | StringLiteral |
| 8 | Fstring | 3 | BinaryExpr |
| 8 | Fstring | 4 | Str |
| 8 | Fstring | 4 | StringLiteral |
| 8 | Fstring | 5 | anniversary |
| 8 | Fstring | 6 | Str |
| 13 | Fstring | 0 | Str |
| 8 | Fstring | 6 | StringLiteral |
| 13 | Fstring | 0 | StringLiteral |
| 13 | Fstring | 1 | world |
| 13 | Fstring | 2 | Str |
| 16 | Fstring | 0 | Str |
| 13 | Fstring | 2 | StringLiteral |
| 16 | Fstring | 0 | StringLiteral |
| 16 | Fstring | 1 | Tuple |
| 16 | Fstring | 2 | Str |
| 16 | Fstring | 2 | StringLiteral |
| 16 | Fstring | 3 | Tuple |
| 16 | Fstring | 4 | Str |
| 19 | Fstring | 0 | Str |
| 16 | Fstring | 4 | StringLiteral |
| 19 | Fstring | 0 | StringLiteral |
| 19 | Fstring | 1 | Tuple |
| 19 | Fstring | 2 | Str |
| 19 | Fstring | 2 | StringLiteral |
| 19 | Fstring | 3 | Tuple |
| 19 | Fstring | 4 | Str |
| 32 | Fstring | 0 | Str |
| 19 | Fstring | 4 | StringLiteral |
| 32 | Fstring | 0 | StringLiteral |
| 32 | Fstring | 1 | IntegerLiteral |
| 32 | Fstring | 2 | Str |
| 34 | Fstring | 0 | Str |
| 32 | Fstring | 2 | StringLiteral |
| 34 | Fstring | 0 | StringLiteral |
| 34 | Fstring | 1 | IntegerLiteral |
| 34 | Fstring | 2 | Str |
| 36 | Fstring | 0 | Str |
| 34 | Fstring | 2 | StringLiteral |
| 36 | Fstring | 0 | StringLiteral |
| 36 | Fstring | 1 | IntegerLiteral |
| 36 | Fstring | 2 | Str |
| 38 | Fstring | 0 | Str |
| 36 | Fstring | 2 | StringLiteral |
| 38 | Fstring | 0 | StringLiteral |
| 38 | Fstring | 1 | IntegerLiteral |
| 38 | Fstring | 2 | Str |
| 53 | Fstring | 0 | Str |
| 38 | Fstring | 2 | StringLiteral |
| 53 | Fstring | 0 | StringLiteral |
| 53 | Fstring | 1 | degrees |
| 53 | Fstring | 2 | Str |
| 56 | Fstring | 0 | Str |
| 53 | Fstring | 2 | StringLiteral |
| 56 | Fstring | 0 | StringLiteral |
| 56 | Fstring | 1 | IntegerLiteral |
| 56 | Fstring | 2 | Str |
| 59 | Fstring | 0 | Str |
| 56 | Fstring | 2 | StringLiteral |
| 59 | Fstring | 0 | StringLiteral |
| 59 | Fstring | 1 | IntegerLiteral |
| 59 | Fstring | 2 | Str |
| 62 | Fstring | 0 | Str |
| 59 | Fstring | 2 | StringLiteral |
| 62 | Fstring | 0 | StringLiteral |
| 62 | Fstring | 1 | IntegerLiteral |
| 62 | Fstring | 2 | Str |
| 67 | Fstring | 0 | Str |
| 62 | Fstring | 2 | StringLiteral |
| 67 | Fstring | 0 | StringLiteral |
| 67 | Fstring | 1 | IntegerLiteral |
| 67 | Fstring | 2 | Str |
| 70 | Fstring | 0 | Str |
| 67 | Fstring | 2 | StringLiteral |
| 70 | Fstring | 0 | StringLiteral |
| 70 | Fstring | 1 | IntegerLiteral |
| 70 | Fstring | 2 | Str |
| 75 | Fstring | 0 | Str |
| 70 | Fstring | 2 | StringLiteral |
| 75 | Fstring | 0 | StringLiteral |
| 75 | Fstring | 1 | IntegerLiteral |
| 75 | Fstring | 2 | Str |
| 78 | Fstring | 0 | Str |
| 75 | Fstring | 2 | StringLiteral |
| 78 | Fstring | 0 | StringLiteral |
| 78 | Fstring | 1 | IntegerLiteral |
| 78 | Fstring | 2 | Str |
| 78 | Fstring | 2 | StringLiteral |

View File

@@ -8,7 +8,7 @@ where
not exists(val.getConversion()) and typeconv = " "
) and
(
format = val.getFormatSpec().getValue(0).(StrConst).getText()
format = val.getFormatSpec().getValue(0).(StringLiteral).getText()
or
not exists(val.getFormatSpec()) and format = ""
)

View File

@@ -1,116 +1,116 @@
| 2 | 1 | 2 | 9 | Str |
| 2 | 1 | 2 | 9 | StringLiteral |
| 2 | 1 | 2 | 18 | Fstring |
| 2 | 10 | 2 | 14 | world |
| 2 | 17 | 2 | 18 | Str |
| 3 | 1 | 3 | 4 | Str |
| 2 | 17 | 2 | 18 | StringLiteral |
| 3 | 1 | 3 | 4 | StringLiteral |
| 3 | 1 | 3 | 42 | Fstring |
| 3 | 5 | 3 | 7 | one |
| 3 | 13 | 3 | 15 | Str |
| 3 | 13 | 3 | 15 | StringLiteral |
| 3 | 16 | 3 | 18 | two |
| 3 | 26 | 3 | 28 | Str |
| 3 | 26 | 3 | 28 | StringLiteral |
| 3 | 29 | 3 | 33 | three |
| 3 | 41 | 3 | 42 | Str |
| 4 | 1 | 4 | 11 | Str |
| 3 | 41 | 3 | 42 | StringLiteral |
| 4 | 1 | 4 | 11 | StringLiteral |
| 4 | 1 | 4 | 24 | Fstring |
| 4 | 12 | 4 | 16 | cruel |
| 4 | 17 | 4 | 24 | Str |
| 5 | 1 | 5 | 8 | Str |
| 4 | 17 | 4 | 24 | StringLiteral |
| 5 | 1 | 5 | 8 | StringLiteral |
| 5 | 1 | 5 | 17 | Fstring |
| 5 | 9 | 5 | 13 | thing |
| 5 | 16 | 5 | 17 | Str |
| 6 | 1 | 6 | 3 | Str |
| 5 | 16 | 5 | 17 | StringLiteral |
| 6 | 1 | 6 | 3 | StringLiteral |
| 6 | 1 | 6 | 8 | Fstring |
| 6 | 4 | 6 | 4 | x |
| 6 | 7 | 6 | 8 | Str |
| 8 | 1 | 8 | 16 | Str |
| 6 | 7 | 6 | 8 | StringLiteral |
| 8 | 1 | 8 | 16 | StringLiteral |
| 8 | 1 | 10 | 31 | Fstring |
| 8 | 17 | 8 | 20 | name |
| 8 | 21 | 9 | 1 | Str |
| 8 | 21 | 9 | 1 | StringLiteral |
| 9 | 2 | 9 | 4 | age |
| 9 | 2 | 9 | 6 | BinaryExpr |
| 9 | 6 | 9 | 6 | IntegerLiteral |
| 9 | 7 | 10 | 1 | Str |
| 9 | 7 | 10 | 1 | StringLiteral |
| 10 | 2 | 10 | 12 | anniversary |
| 10 | 27 | 10 | 31 | Str |
| 13 | 1 | 13 | 12 | Str |
| 10 | 27 | 10 | 31 | StringLiteral |
| 13 | 1 | 13 | 12 | StringLiteral |
| 13 | 1 | 13 | 21 | Fstring |
| 13 | 13 | 13 | 17 | world |
| 13 | 20 | 13 | 21 | Str |
| 16 | 1 | 16 | 3 | Str |
| 13 | 20 | 13 | 21 | StringLiteral |
| 16 | 1 | 16 | 3 | StringLiteral |
| 16 | 1 | 16 | 13 | Fstring |
| 16 | 4 | 16 | 4 | IntegerLiteral |
| 16 | 4 | 16 | 6 | Tuple |
| 16 | 6 | 16 | 6 | IntegerLiteral |
| 16 | 7 | 16 | 8 | Str |
| 16 | 7 | 16 | 8 | StringLiteral |
| 16 | 9 | 16 | 9 | IntegerLiteral |
| 16 | 9 | 16 | 11 | Tuple |
| 16 | 11 | 16 | 11 | IntegerLiteral |
| 16 | 12 | 16 | 13 | Str |
| 19 | 1 | 19 | 3 | Str |
| 16 | 12 | 16 | 13 | StringLiteral |
| 19 | 1 | 19 | 3 | StringLiteral |
| 19 | 1 | 19 | 11 | Fstring |
| 19 | 4 | 19 | 4 | IntegerLiteral |
| 19 | 4 | 19 | 5 | Tuple |
| 19 | 6 | 19 | 7 | Str |
| 19 | 6 | 19 | 7 | StringLiteral |
| 19 | 8 | 19 | 8 | IntegerLiteral |
| 19 | 8 | 19 | 9 | Tuple |
| 19 | 10 | 19 | 11 | Str |
| 24 | 2 | 24 | 9 | Str |
| 26 | 2 | 26 | 5 | Str |
| 28 | 2 | 28 | 9 | Str |
| 30 | 2 | 30 | 5 | Str |
| 32 | 2 | 32 | 6 | Str |
| 19 | 10 | 19 | 11 | StringLiteral |
| 24 | 2 | 24 | 9 | StringLiteral |
| 26 | 2 | 26 | 5 | StringLiteral |
| 28 | 2 | 28 | 9 | StringLiteral |
| 30 | 2 | 30 | 5 | StringLiteral |
| 32 | 2 | 32 | 6 | StringLiteral |
| 32 | 2 | 32 | 11 | Fstring |
| 32 | 7 | 32 | 7 | IntegerLiteral |
| 32 | 8 | 32 | 11 | Str |
| 34 | 2 | 34 | 4 | Str |
| 32 | 8 | 32 | 11 | StringLiteral |
| 34 | 2 | 34 | 4 | StringLiteral |
| 34 | 2 | 34 | 7 | Fstring |
| 34 | 5 | 34 | 5 | IntegerLiteral |
| 34 | 6 | 34 | 7 | Str |
| 36 | 2 | 36 | 6 | Str |
| 34 | 6 | 34 | 7 | StringLiteral |
| 36 | 2 | 36 | 6 | StringLiteral |
| 36 | 2 | 36 | 11 | Fstring |
| 36 | 7 | 36 | 7 | IntegerLiteral |
| 36 | 8 | 36 | 11 | Str |
| 38 | 2 | 38 | 4 | Str |
| 36 | 8 | 36 | 11 | StringLiteral |
| 38 | 2 | 38 | 4 | StringLiteral |
| 38 | 2 | 38 | 7 | Fstring |
| 38 | 5 | 38 | 5 | IntegerLiteral |
| 38 | 6 | 38 | 7 | Str |
| 40 | 2 | 40 | 8 | Str |
| 42 | 2 | 42 | 4 | Str |
| 44 | 2 | 44 | 8 | Str |
| 46 | 2 | 46 | 4 | Str |
| 53 | 1 | 53 | 18 | Str |
| 38 | 6 | 38 | 7 | StringLiteral |
| 40 | 2 | 40 | 8 | StringLiteral |
| 42 | 2 | 42 | 4 | StringLiteral |
| 44 | 2 | 44 | 8 | StringLiteral |
| 46 | 2 | 46 | 4 | StringLiteral |
| 53 | 1 | 53 | 18 | StringLiteral |
| 53 | 1 | 53 | 27 | Fstring |
| 53 | 19 | 53 | 25 | degrees |
| 53 | 26 | 53 | 27 | Str |
| 56 | 1 | 56 | 3 | Str |
| 53 | 26 | 53 | 27 | StringLiteral |
| 56 | 1 | 56 | 3 | StringLiteral |
| 56 | 1 | 56 | 21 | Fstring |
| 56 | 4 | 56 | 4 | IntegerLiteral |
| 56 | 5 | 56 | 21 | Str |
| 59 | 1 | 59 | 7 | Str |
| 56 | 5 | 56 | 21 | StringLiteral |
| 59 | 1 | 59 | 7 | StringLiteral |
| 59 | 1 | 59 | 11 | Fstring |
| 59 | 8 | 59 | 8 | IntegerLiteral |
| 59 | 9 | 59 | 11 | Str |
| 62 | 1 | 62 | 4 | Str |
| 59 | 9 | 59 | 11 | StringLiteral |
| 62 | 1 | 62 | 4 | StringLiteral |
| 62 | 1 | 62 | 10 | Fstring |
| 62 | 5 | 62 | 5 | IntegerLiteral |
| 62 | 6 | 62 | 10 | Str |
| 67 | 1 | 67 | 6 | Str |
| 62 | 6 | 62 | 10 | StringLiteral |
| 67 | 1 | 67 | 6 | StringLiteral |
| 67 | 1 | 67 | 43 | Fstring |
| 67 | 7 | 67 | 7 | IntegerLiteral |
| 67 | 38 | 67 | 43 | Str |
| 70 | 1 | 70 | 6 | Str |
| 67 | 38 | 67 | 43 | StringLiteral |
| 70 | 1 | 70 | 6 | StringLiteral |
| 70 | 1 | 70 | 39 | Fstring |
| 70 | 7 | 70 | 7 | IntegerLiteral |
| 70 | 34 | 70 | 39 | Str |
| 75 | 1 | 75 | 7 | Str |
| 70 | 34 | 70 | 39 | StringLiteral |
| 75 | 1 | 75 | 7 | StringLiteral |
| 75 | 1 | 75 | 11 | Fstring |
| 75 | 8 | 75 | 8 | IntegerLiteral |
| 75 | 9 | 75 | 11 | Str |
| 78 | 1 | 78 | 4 | Str |
| 75 | 9 | 75 | 11 | StringLiteral |
| 78 | 1 | 78 | 4 | StringLiteral |
| 78 | 1 | 78 | 10 | Fstring |
| 78 | 5 | 78 | 5 | IntegerLiteral |
| 78 | 6 | 78 | 10 | Str |
| 81 | 1 | 81 | 3 | Str |
| 82 | 1 | 82 | 3 | Str |
| 83 | 1 | 83 | 7 | Str |
| 84 | 1 | 84 | 7 | Str |
| 78 | 6 | 78 | 10 | StringLiteral |
| 81 | 1 | 81 | 3 | StringLiteral |
| 82 | 1 | 82 | 3 | StringLiteral |
| 83 | 1 | 83 | 7 | StringLiteral |
| 84 | 1 | 84 | 7 | StringLiteral |

View File

@@ -1,9 +1,9 @@
import python
string repr(AstNode a) {
not a instanceof StrConst and result = a.toString()
not a instanceof StringLiteral and result = a.toString()
or
result = "\"" + a.(StrConst).getText() + "\""
result = "\"" + a.(StringLiteral).getText() + "\""
}
from ControlFlowNode p, ControlFlowNode s, BasicBlock b, int n

Some files were not shown because too many files have changed in this diff Show More