mirror of
https://github.com/github/codeql.git
synced 2026-05-02 04:05:14 +02:00
Python: Port use-use implementation from Java
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
private import python
|
||||
private import DataFlowPublic
|
||||
import semmle.python.SpecialMethods
|
||||
private import semmle.python.essa.SsaCompute
|
||||
|
||||
//--------
|
||||
// Data flow graph
|
||||
@@ -97,12 +98,19 @@ module EssaFlow {
|
||||
contextManager.strictlyDominates(var)
|
||||
)
|
||||
or
|
||||
// Use
|
||||
// First use after definition
|
||||
// `y = 42`
|
||||
// `x = f(y)`
|
||||
// nodeFrom is `y` on first line, essa var
|
||||
// nodeTo is `y` on second line, cfg node
|
||||
nodeFrom.(EssaNode).getVar().getASourceUse() = nodeTo.(CfgNode).getNode()
|
||||
defToFirstUse(nodeFrom.asVar(), nodeTo.asCfgNode())
|
||||
or
|
||||
// Next use after use
|
||||
// `x = f(y)`
|
||||
// `z = y + 1`
|
||||
// nodeFrom is 'y' on first line, cfg node
|
||||
// nodeTo is `y` on second line, cfg node
|
||||
useToNextUse(nodeFrom.asCfgNode(), nodeTo.asCfgNode())
|
||||
or
|
||||
// Refinements
|
||||
exists(EssaEdgeRefinement r |
|
||||
@@ -120,6 +128,14 @@ module EssaFlow {
|
||||
nodeFrom.(EssaNode).getVar() = p.getAnInput()
|
||||
)
|
||||
}
|
||||
|
||||
predicate useToNextUse(NameNode nodeFrom, NameNode nodeTo) {
|
||||
AdjacentUses::adjacentUseUseSameVar(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
predicate defToFirstUse(EssaVariable var, NameNode nodeTo) {
|
||||
AdjacentUses::firstUse(var.getDefinition(), nodeTo)
|
||||
}
|
||||
}
|
||||
|
||||
//--------
|
||||
@@ -136,6 +152,10 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
EssaFlow::essaFlowStep(update(nodeFrom), nodeTo)
|
||||
}
|
||||
|
||||
/**
|
||||
* If a node `n` has a post-update node `pun(n)`, we want forward flow to go from
|
||||
* `pun(n)` rather than from `n`.
|
||||
*/
|
||||
private Node update(Node node) {
|
||||
exists(PostUpdateNode pun |
|
||||
node = pun.getPreUpdateNode() and
|
||||
|
||||
@@ -348,11 +348,141 @@ private module SsaComputeImpl {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
cached
|
||||
module AdjacentUsesImpl {
|
||||
/**
|
||||
* Holds if `rankix` is the rank the index `i` at which there is an SSA definition or explicit use of
|
||||
* `v` in the basic block `b`.
|
||||
*/
|
||||
cached
|
||||
predicate defSourceUseRank(SsaSourceVariable v, BasicBlock b, int rankix, int i) {
|
||||
i = rank[rankix](int j | variableDefine(v, _, b, j) or variableSourceUse(v, _, b, j))
|
||||
}
|
||||
|
||||
/** A `VarAccess` `use` of `v` in `b` at index `i`. */
|
||||
cached
|
||||
predicate variableSourceUse(SsaSourceVariable v, ControlFlowNode use, BasicBlock b, int i) {
|
||||
v.getASourceUse() = use and
|
||||
exists(int j |
|
||||
b.getNode(j) = use and
|
||||
i = 2 * j
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the maximum rank index for the given variable and basic block. */
|
||||
private int lastSourceUseRank(SsaSourceVariable v, BasicBlock b) {
|
||||
result = max(int rankix | defSourceUseRank(v, b, rankix, _))
|
||||
}
|
||||
|
||||
/** Holds if `v` is defined or used in `b`. */
|
||||
private predicate varOccursInBlock(SsaSourceVariable v, BasicBlock b) {
|
||||
defSourceUseRank(v, b, _, _)
|
||||
}
|
||||
|
||||
/** Holds if `v` occurs in `b` or one of `b`'s transitive successors. */
|
||||
private predicate blockPrecedesVar(SsaSourceVariable v, BasicBlock b) {
|
||||
varOccursInBlock(v, b.getASuccessor*())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `b2` is a transitive successor of `b1` and `v` occurs in `b1` [and
|
||||
* in `b2` or one of its transitive successors]? but not in any block on the path
|
||||
* between `b1` and `b2`.
|
||||
*/
|
||||
private predicate varBlockReaches(SsaSourceVariable v, BasicBlock b1, BasicBlock b2) {
|
||||
varOccursInBlock(v, b1) and b2 = b1.getASuccessor()
|
||||
or
|
||||
exists(BasicBlock mid |
|
||||
varBlockReaches(v, b1, mid) and
|
||||
b2 = mid.getASuccessor() and
|
||||
not varOccursInBlock(v, mid) and
|
||||
blockPrecedesVar(v, b2)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `b2` is a transitive successor of `b1` and `v` occurs in `b1` and
|
||||
* `b2` but not in any block on the path between `b1` and `b2`.
|
||||
*/
|
||||
private predicate varBlockStep(SsaSourceVariable v, BasicBlock b1, BasicBlock b2) {
|
||||
varBlockReaches(v, b1, b2) and
|
||||
varOccursInBlock(v, b2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `v` occurs at index `i1` in `b1` and at index `i2` in `b2` and
|
||||
* there is a path between them without any occurrence of `v`.
|
||||
*/
|
||||
cached
|
||||
predicate adjacentVarRefs(SsaSourceVariable v, BasicBlock b1, int i1, BasicBlock b2, int i2) {
|
||||
exists(int rankix |
|
||||
b1 = b2 and
|
||||
defSourceUseRank(v, b1, rankix, i1) and
|
||||
defSourceUseRank(v, b2, rankix + 1, i2)
|
||||
)
|
||||
or
|
||||
defSourceUseRank(v, b1, lastSourceUseRank(v, b1), i1) and
|
||||
varBlockStep(v, b1, b2) and
|
||||
defSourceUseRank(v, b2, 1, i2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `use1` and `use2` form an adjacent use-use-pair of the same SSA
|
||||
* variable, that is, the value read in `use1` can reach `use2` without passing
|
||||
* through any other use or any SSA definition of the variable.
|
||||
*/
|
||||
cached
|
||||
predicate adjacentUseUseSameVar(ControlFlowNode use1, ControlFlowNode use2) {
|
||||
exists(SsaSourceVariable v, BasicBlock b1, int i1, BasicBlock b2, int i2 |
|
||||
adjacentVarRefs(v, b1, i1, b2, i2) and
|
||||
variableUse(v, use1, b1, i1) and
|
||||
variableUse(v, use2, b2, i2)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the value defined at `def` can reach `use` without passing through
|
||||
* any other uses, but possibly through phi nodes and uncertain implicit updates.
|
||||
*/
|
||||
cached
|
||||
predicate firstUse(EssaDefinition def, ControlFlowNode use) {
|
||||
exists(SsaSourceVariable v, BasicBlock b1, int i1, BasicBlock b2, int i2 |
|
||||
adjacentVarRefs(v, b1, i1, b2, i2) and
|
||||
definesAt(def, v, b1, i1) and
|
||||
variableUse(v, use, b2, i2)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
SsaSourceVariable v, EssaDefinition redef, BasicBlock b1, int i1, BasicBlock b2, int i2
|
||||
|
|
||||
redef instanceof PhiFunction
|
||||
|
|
||||
adjacentVarRefs(v, b1, i1, b2, i2) and
|
||||
definesAt(def, v, b1, i1) and
|
||||
definesAt(redef, v, b2, i2) and
|
||||
firstUse(redef, use)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate definesAt(EssaDefinition def, SsaSourceVariable v, BasicBlock b, int i) {
|
||||
exists(ControlFlowNode defNode |
|
||||
def.(EssaNodeDefinition).definedBy(v, defNode) and
|
||||
variableDefine(v, defNode, b, i)
|
||||
)
|
||||
or
|
||||
v = def.(PhiFunction).getSourceVariable() and
|
||||
b = def.(PhiFunction).getBasicBlock() and
|
||||
i = -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
import SsaComputeImpl::SsaDefinitionsImpl as SsaDefinitions
|
||||
import SsaComputeImpl::EssaDefinitionsImpl as EssaDefinitions
|
||||
import SsaComputeImpl::LivenessImpl as Liveness
|
||||
import SsaComputeImpl::AdjacentUsesImpl as AdjacentUses
|
||||
|
||||
/* This is exported primarily for testing */
|
||||
/*
|
||||
|
||||
@@ -5,6 +5,7 @@ uniqueEnclosingCallable
|
||||
| module.py:2:8:2:13 | ControlFlowNode for Str | Node should have one enclosing callable but has 0. |
|
||||
| module.py:5:1:5:21 | ControlFlowNode for FunctionExpr | Node should have one enclosing callable but has 0. |
|
||||
| module.py:5:5:5:18 | GSSA Variable dangerous_func | Node should have one enclosing callable but has 0. |
|
||||
| module.py:9:9:9:14 | ControlFlowNode for SOURCE | Node should have one enclosing callable but has 0. |
|
||||
| module.py:10:1:10:5 | GSSA Variable safe2 | Node should have one enclosing callable but has 0. |
|
||||
| module.py:10:9:10:14 | ControlFlowNode for Str | Node should have one enclosing callable but has 0. |
|
||||
| test.py:6:1:6:12 | ControlFlowNode for FunctionExpr | Node should have one enclosing callable but has 0. |
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
edges
|
||||
| datamodel.py:13:1:13:6 | GSSA Variable SOURCE | datamodel.py:38:6:38:17 | GSSA Variable SOURCE |
|
||||
| datamodel.py:13:1:13:6 | GSSA Variable SOURCE | datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:13:1:13:6 | GSSA Variable SOURCE |
|
||||
| datamodel.py:38:6:38:17 | GSSA Variable SOURCE | datamodel.py:71:6:71:24 | GSSA Variable SOURCE |
|
||||
| datamodel.py:38:6:38:17 | GSSA Variable SOURCE | datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() |
|
||||
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | datamodel.py:80:6:80:26 | GSSA Variable SOURCE |
|
||||
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:80:6:80:26 | GSSA Variable SOURCE | datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() |
|
||||
| test.py:32:10:32:26 | ControlFlowNode for Tuple [Tuple element at index 1] | test.py:33:9:33:9 | ControlFlowNode for x [Tuple element at index 1] |
|
||||
@@ -77,20 +70,16 @@ edges
|
||||
| test.py:335:12:335:17 | ControlFlowNode for SOURCE | test.py:335:10:335:18 | ControlFlowNode for f() |
|
||||
| test.py:339:28:339:33 | ControlFlowNode for SOURCE | test.py:339:10:339:34 | ControlFlowNode for second() |
|
||||
| test.py:372:9:372:14 | ControlFlowNode for SOURCE | test.py:374:10:374:10 | ControlFlowNode for a |
|
||||
| test.py:372:9:372:14 | ControlFlowNode for SOURCE | test.py:379:10:379:10 | ControlFlowNode for b |
|
||||
nodes
|
||||
| datamodel.py:13:1:13:6 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
|
||||
| datamodel.py:13:10:13:17 | ControlFlowNode for Str | semmle.label | ControlFlowNode for Str |
|
||||
| datamodel.py:38:6:38:17 | ControlFlowNode for f() | semmle.label | ControlFlowNode for f() |
|
||||
| datamodel.py:38:6:38:17 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
|
||||
| datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:71:6:71:24 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
|
||||
| datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:80:6:80:26 | GSSA Variable SOURCE | semmle.label | GSSA Variable SOURCE |
|
||||
| datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
|
||||
| datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
@@ -182,17 +171,12 @@ nodes
|
||||
| test.py:339:28:339:33 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:372:9:372:14 | ControlFlowNode for SOURCE | semmle.label | ControlFlowNode for SOURCE |
|
||||
| test.py:374:10:374:10 | ControlFlowNode for a | semmle.label | ControlFlowNode for a |
|
||||
| test.py:379:10:379:10 | ControlFlowNode for b | semmle.label | ControlFlowNode for b |
|
||||
#select
|
||||
| datamodel.py:38:6:38:17 | ControlFlowNode for f() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:38:6:38:17 | ControlFlowNode for f() | <message> |
|
||||
| datamodel.py:38:6:38:17 | ControlFlowNode for f() | datamodel.py:38:8:38:13 | ControlFlowNode for SOURCE | datamodel.py:38:6:38:17 | ControlFlowNode for f() | <message> |
|
||||
| datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | datamodel.py:71:15:71:20 | ControlFlowNode for SOURCE | datamodel.py:71:6:71:24 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | datamodel.py:72:18:72:23 | ControlFlowNode for SOURCE | datamodel.py:72:6:72:27 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | datamodel.py:80:20:80:25 | ControlFlowNode for SOURCE | datamodel.py:80:6:80:26 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | datamodel.py:13:10:13:17 | ControlFlowNode for Str | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | <message> |
|
||||
| datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | datamodel.py:81:20:81:25 | ControlFlowNode for SOURCE | datamodel.py:81:6:81:26 | ControlFlowNode for Attribute() | <message> |
|
||||
| test.py:34:10:34:10 | ControlFlowNode for y | test.py:32:21:32:26 | ControlFlowNode for SOURCE | test.py:34:10:34:10 | ControlFlowNode for y | <message> |
|
||||
| test.py:44:10:44:10 | ControlFlowNode for x | test.py:43:9:43:14 | ControlFlowNode for SOURCE | test.py:44:10:44:10 | ControlFlowNode for x | <message> |
|
||||
@@ -218,4 +202,3 @@ nodes
|
||||
| test.py:335:10:335:18 | ControlFlowNode for f() | test.py:335:12:335:17 | ControlFlowNode for SOURCE | test.py:335:10:335:18 | ControlFlowNode for f() | <message> |
|
||||
| test.py:339:10:339:34 | ControlFlowNode for second() | test.py:339:28:339:33 | ControlFlowNode for SOURCE | test.py:339:10:339:34 | ControlFlowNode for second() | <message> |
|
||||
| test.py:374:10:374:10 | ControlFlowNode for a | test.py:372:9:372:14 | ControlFlowNode for SOURCE | test.py:374:10:374:10 | ControlFlowNode for a | <message> |
|
||||
| test.py:379:10:379:10 | ControlFlowNode for b | test.py:372:9:372:14 | ControlFlowNode for SOURCE | test.py:379:10:379:10 | ControlFlowNode for b | <message> |
|
||||
|
||||
@@ -15,5 +15,3 @@
|
||||
| test.py:178:9:178:14 | ControlFlowNode for SOURCE | test.py:182:16:182:16 | ControlFlowNode for t |
|
||||
| test.py:178:9:178:14 | ControlFlowNode for SOURCE | test.py:184:16:184:16 | ControlFlowNode for t |
|
||||
| test.py:178:9:178:14 | ControlFlowNode for SOURCE | test.py:186:14:186:14 | ControlFlowNode for t |
|
||||
| test.py:195:9:195:14 | ControlFlowNode for SOURCE | test.py:197:14:197:14 | ControlFlowNode for t |
|
||||
| test.py:195:9:195:14 | ControlFlowNode for SOURCE | test.py:199:14:199:14 | ControlFlowNode for t |
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
| test_collections.py:16 | ok | test_access | tainted_list.copy() |
|
||||
| test_collections.py:24 | ok | list_clear | tainted_list |
|
||||
| test_collections.py:27 | fail | list_clear | tainted_list |
|
||||
| test_collections.py:27 | ok | list_clear | tainted_list |
|
||||
| test_string.py:17 | ok | str_methods | ts.casefold() |
|
||||
| test_string.py:19 | ok | str_methods | ts.format_map(..) |
|
||||
| test_string.py:20 | ok | str_methods | "{unsafe}".format_map(..) |
|
||||
| test_string.py:19 | fail | str_methods | ts.format_map(..) |
|
||||
| test_string.py:20 | fail | str_methods | "{unsafe}".format_map(..) |
|
||||
| test_string.py:31 | fail | binary_decode_encode | base64.a85encode(..) |
|
||||
| test_string.py:32 | fail | binary_decode_encode | base64.a85decode(..) |
|
||||
| test_string.py:35 | fail | binary_decode_encode | base64.b85encode(..) |
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
| test_collections.py:32 | ok | test_construction | list(..) |
|
||||
| test_collections.py:33 | ok | test_construction | list(..) |
|
||||
| test_collections.py:34 | ok | test_construction | list(..) |
|
||||
| test_collections.py:35 | ok | test_construction | list(..) |
|
||||
| test_collections.py:35 | fail | test_construction | list(..) |
|
||||
| test_collections.py:37 | ok | test_construction | tuple(..) |
|
||||
| test_collections.py:38 | ok | test_construction | set(..) |
|
||||
| test_collections.py:39 | ok | test_construction | frozenset(..) |
|
||||
@@ -25,10 +25,10 @@
|
||||
| test_collections.py:63 | ok | test_access | i |
|
||||
| test_collections.py:70 | ok | test_dict_access | tainted_dict["name"] |
|
||||
| test_collections.py:71 | ok | test_dict_access | tainted_dict.get(..) |
|
||||
| test_collections.py:72 | ok | test_dict_access | tainted_dict[x] |
|
||||
| test_collections.py:73 | ok | test_dict_access | tainted_dict.copy() |
|
||||
| test_collections.py:77 | ok | test_dict_access | v |
|
||||
| test_collections.py:79 | ok | test_dict_access | v |
|
||||
| test_collections.py:72 | fail | test_dict_access | tainted_dict[x] |
|
||||
| test_collections.py:73 | fail | test_dict_access | tainted_dict.copy() |
|
||||
| test_collections.py:77 | fail | test_dict_access | v |
|
||||
| test_collections.py:79 | fail | test_dict_access | v |
|
||||
| test_collections.py:87 | fail | test_named_tuple | point[0] |
|
||||
| test_collections.py:88 | fail | test_named_tuple | point.x |
|
||||
| test_collections.py:92 | ok | test_named_tuple | point[1] |
|
||||
@@ -65,7 +65,7 @@
|
||||
| test_collections.py:227 | ok | set_add | my_set |
|
||||
| test_collections.py:230 | fail | set_add | my_set |
|
||||
| test_json.py:26 | ok | test | json.dumps(..) |
|
||||
| test_json.py:27 | ok | test | json.loads(..) |
|
||||
| test_json.py:27 | fail | test | json.loads(..) |
|
||||
| test_json.py:34 | fail | test | tainted_filelike |
|
||||
| test_json.py:35 | fail | test | json.load(..) |
|
||||
| test_json.py:48 | fail | non_syntacical | dumps(..) |
|
||||
@@ -76,53 +76,53 @@
|
||||
| test_string.py:25 | ok | str_operations | ts |
|
||||
| test_string.py:26 | ok | str_operations | BinaryExpr |
|
||||
| test_string.py:27 | ok | str_operations | BinaryExpr |
|
||||
| test_string.py:28 | ok | str_operations | BinaryExpr |
|
||||
| test_string.py:29 | ok | str_operations | ts[Slice] |
|
||||
| test_string.py:30 | ok | str_operations | ts[Slice] |
|
||||
| test_string.py:31 | ok | str_operations | ts[Slice] |
|
||||
| test_string.py:32 | ok | str_operations | ts[0] |
|
||||
| test_string.py:33 | ok | str_operations | str(..) |
|
||||
| test_string.py:28 | fail | str_operations | BinaryExpr |
|
||||
| test_string.py:29 | fail | str_operations | ts[Slice] |
|
||||
| test_string.py:30 | fail | str_operations | ts[Slice] |
|
||||
| test_string.py:31 | fail | str_operations | ts[Slice] |
|
||||
| test_string.py:32 | fail | str_operations | ts[0] |
|
||||
| test_string.py:33 | fail | str_operations | str(..) |
|
||||
| test_string.py:34 | ok | str_operations | bytes(..) |
|
||||
| test_string.py:35 | ok | str_operations | unicode(..) |
|
||||
| test_string.py:35 | fail | str_operations | unicode(..) |
|
||||
| test_string.py:39 | ok | str_operations | aug_assignment |
|
||||
| test_string.py:41 | ok | str_operations | aug_assignment |
|
||||
| test_string.py:49 | ok | str_methods | ts.capitalize() |
|
||||
| test_string.py:50 | ok | str_methods | ts.center(..) |
|
||||
| test_string.py:51 | ok | str_methods | ts.expandtabs() |
|
||||
| test_string.py:53 | ok | str_methods | ts.format() |
|
||||
| test_string.py:54 | ok | str_methods | "{}".format(..) |
|
||||
| test_string.py:55 | ok | str_methods | "{unsafe}".format(..) |
|
||||
| test_string.py:57 | ok | str_methods | ts.join(..) |
|
||||
| test_string.py:58 | ok | str_methods | "".join(..) |
|
||||
| test_string.py:60 | ok | str_methods | ts.ljust(..) |
|
||||
| test_string.py:61 | ok | str_methods | ts.lstrip() |
|
||||
| test_string.py:62 | ok | str_methods | ts.lower() |
|
||||
| test_string.py:64 | ok | str_methods | ts.replace(..) |
|
||||
| test_string.py:65 | ok | str_methods | "safe".replace(..) |
|
||||
| test_string.py:67 | ok | str_methods | ts.rjust(..) |
|
||||
| test_string.py:68 | ok | str_methods | ts.rstrip() |
|
||||
| test_string.py:69 | ok | str_methods | ts.strip() |
|
||||
| test_string.py:70 | ok | str_methods | ts.swapcase() |
|
||||
| test_string.py:71 | ok | str_methods | ts.title() |
|
||||
| test_string.py:72 | ok | str_methods | ts.upper() |
|
||||
| test_string.py:73 | ok | str_methods | ts.zfill(..) |
|
||||
| test_string.py:75 | ok | str_methods | ts.encode(..) |
|
||||
| test_string.py:76 | ok | str_methods | ts.encode(..).decode(..) |
|
||||
| test_string.py:50 | fail | str_methods | ts.center(..) |
|
||||
| test_string.py:51 | fail | str_methods | ts.expandtabs() |
|
||||
| test_string.py:53 | fail | str_methods | ts.format() |
|
||||
| test_string.py:54 | fail | str_methods | "{}".format(..) |
|
||||
| test_string.py:55 | fail | str_methods | "{unsafe}".format(..) |
|
||||
| test_string.py:57 | fail | str_methods | ts.join(..) |
|
||||
| test_string.py:58 | fail | str_methods | "".join(..) |
|
||||
| test_string.py:60 | fail | str_methods | ts.ljust(..) |
|
||||
| test_string.py:61 | fail | str_methods | ts.lstrip() |
|
||||
| test_string.py:62 | fail | str_methods | ts.lower() |
|
||||
| test_string.py:64 | fail | str_methods | ts.replace(..) |
|
||||
| test_string.py:65 | fail | str_methods | "safe".replace(..) |
|
||||
| test_string.py:67 | fail | str_methods | ts.rjust(..) |
|
||||
| test_string.py:68 | fail | str_methods | ts.rstrip() |
|
||||
| test_string.py:69 | fail | str_methods | ts.strip() |
|
||||
| test_string.py:70 | fail | str_methods | ts.swapcase() |
|
||||
| test_string.py:71 | fail | str_methods | ts.title() |
|
||||
| test_string.py:72 | fail | str_methods | ts.upper() |
|
||||
| test_string.py:73 | fail | str_methods | ts.zfill(..) |
|
||||
| test_string.py:75 | fail | str_methods | ts.encode(..) |
|
||||
| test_string.py:76 | fail | str_methods | ts.encode(..).decode(..) |
|
||||
| test_string.py:78 | ok | str_methods | tb.decode(..) |
|
||||
| test_string.py:79 | ok | str_methods | tb.decode(..).encode(..) |
|
||||
| test_string.py:82 | ok | str_methods | ts.partition(..) |
|
||||
| test_string.py:83 | ok | str_methods | ts.rpartition(..) |
|
||||
| test_string.py:84 | ok | str_methods | ts.rsplit(..) |
|
||||
| test_string.py:85 | ok | str_methods | ts.split(..) |
|
||||
| test_string.py:86 | ok | str_methods | ts.splitlines() |
|
||||
| test_string.py:79 | fail | str_methods | tb.decode(..).encode(..) |
|
||||
| test_string.py:82 | fail | str_methods | ts.partition(..) |
|
||||
| test_string.py:83 | fail | str_methods | ts.rpartition(..) |
|
||||
| test_string.py:84 | fail | str_methods | ts.rsplit(..) |
|
||||
| test_string.py:85 | fail | str_methods | ts.split(..) |
|
||||
| test_string.py:86 | fail | str_methods | ts.splitlines() |
|
||||
| test_string.py:91 | ok | str_methods | "safe".replace(..) |
|
||||
| test_string.py:93 | fail | str_methods | ts.join(..) |
|
||||
| test_string.py:94 | fail | str_methods | ts.join(..) |
|
||||
| test_string.py:93 | ok | str_methods | ts.join(..) |
|
||||
| test_string.py:94 | ok | str_methods | ts.join(..) |
|
||||
| test_string.py:104 | fail | non_syntactic | meth() |
|
||||
| test_string.py:105 | fail | non_syntactic | _str(..) |
|
||||
| test_string.py:114 | ok | percent_fmt | BinaryExpr |
|
||||
| test_string.py:115 | ok | percent_fmt | BinaryExpr |
|
||||
| test_string.py:116 | ok | percent_fmt | BinaryExpr |
|
||||
| test_string.py:116 | fail | percent_fmt | BinaryExpr |
|
||||
| test_string.py:126 | fail | binary_decode_encode | base64.b64encode(..) |
|
||||
| test_string.py:127 | fail | binary_decode_encode | base64.b64decode(..) |
|
||||
| test_string.py:129 | fail | binary_decode_encode | base64.standard_b64encode(..) |
|
||||
|
||||
Reference in New Issue
Block a user