mirror of
https://github.com/github/codeql.git
synced 2026-06-23 21:57:01 +02:00
Compare commits
5 Commits
copilot/sw
...
yoff/pytho
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7f79f2d34 | ||
|
|
9cdeb8e7ee | ||
|
|
ea0b2e9219 | ||
|
|
9c41238eee | ||
|
|
d7c0ef7e4d |
@@ -1,3 +0,0 @@
|
|||||||
import go
|
|
||||||
private import semmle.go.controlflow.ControlFlowGraphShared
|
|
||||||
import GoCfg::ControlFlow::Consistency
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
---
|
|
||||||
category: fix
|
|
||||||
---
|
|
||||||
* The Go control flow graph implementation has been migrated to use the shared CFG library. This is an internal change with no user-visible API changes.
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/**
|
|
||||||
* @name Print CFG
|
|
||||||
* @description Produces a representation of a file's Control Flow Graph.
|
|
||||||
* This query is used by the VS Code extension.
|
|
||||||
* @id go/print-cfg
|
|
||||||
* @kind graph
|
|
||||||
* @tags ide-contextual-queries/print-cfg
|
|
||||||
*/
|
|
||||||
|
|
||||||
import go
|
|
||||||
import semmle.go.controlflow.ControlFlowGraph
|
|
||||||
private import semmle.go.controlflow.ControlFlowGraphShared
|
|
||||||
|
|
||||||
external string selectedSourceFile();
|
|
||||||
|
|
||||||
private predicate selectedSourceFileAlias = selectedSourceFile/0;
|
|
||||||
|
|
||||||
external int selectedSourceLine();
|
|
||||||
|
|
||||||
private predicate selectedSourceLineAlias = selectedSourceLine/0;
|
|
||||||
|
|
||||||
external int selectedSourceColumn();
|
|
||||||
|
|
||||||
private predicate selectedSourceColumnAlias = selectedSourceColumn/0;
|
|
||||||
|
|
||||||
module ViewCfgQueryInput implements GoCfg::ControlFlow::ViewCfgQueryInputSig<File> {
|
|
||||||
predicate selectedSourceFile = selectedSourceFileAlias/0;
|
|
||||||
|
|
||||||
predicate selectedSourceLine = selectedSourceLineAlias/0;
|
|
||||||
|
|
||||||
predicate selectedSourceColumn = selectedSourceColumnAlias/0;
|
|
||||||
|
|
||||||
predicate cfgScopeSpan(
|
|
||||||
CfgScope scope, File file, int startLine, int startColumn, int endLine, int endColumn
|
|
||||||
) {
|
|
||||||
file = scope.getFile() and
|
|
||||||
scope.getLocation().getStartLine() = startLine and
|
|
||||||
scope.getLocation().getStartColumn() = startColumn and
|
|
||||||
exists(Location loc |
|
|
||||||
loc.getEndLine() = endLine and
|
|
||||||
loc.getEndColumn() = endColumn and
|
|
||||||
loc = scope.(FuncDef).getBody().getLocation()
|
|
||||||
)
|
|
||||||
or
|
|
||||||
file = scope.(File) and
|
|
||||||
startLine = 1 and
|
|
||||||
startColumn = 1 and
|
|
||||||
endLine = file.getNumberOfLines() and
|
|
||||||
endColumn = 999999
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
import GoCfg::ControlFlow::ViewCfgQuery<File, ViewCfgQueryInput>
|
|
||||||
@@ -431,7 +431,7 @@ private class HeuristicLoggerFunction extends Method {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate mustNotReturnNormally() { logFunctionPrefix = "Fatal" }
|
override predicate mayReturnNormally() { logFunctionPrefix != "Fatal" }
|
||||||
|
|
||||||
override predicate mustPanic() { logFunctionPrefix = "Panic" }
|
override predicate mustPanic() { logFunctionPrefix = "Panic" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* Provides queries to pretty-print a Go AST as a graph.
|
* Provides queries to pretty-print a Go AST as a graph.
|
||||||
*/
|
*/
|
||||||
overlay[local?]
|
overlay[local]
|
||||||
module;
|
module;
|
||||||
|
|
||||||
import go
|
import go
|
||||||
|
|||||||
@@ -437,12 +437,11 @@ class Function extends ValueEntity, @functionobject {
|
|||||||
* This predicate is an over-approximation: it may hold for functions that can never
|
* This predicate is an over-approximation: it may hold for functions that can never
|
||||||
* return normally, but it never fails to hold for functions that can.
|
* return normally, but it never fails to hold for functions that can.
|
||||||
*
|
*
|
||||||
* Library models should not override this predicate; override `mustNotReturnNormally`
|
* Note this is declared here and not in `DeclaredFunction` so that library models can override this
|
||||||
* instead, so that the control-flow graph construction can take the model into account.
|
* by extending `Function` rather than having to remember to extend `DeclaredFunction`.
|
||||||
*/
|
*/
|
||||||
predicate mayReturnNormally() {
|
predicate mayReturnNormally() {
|
||||||
not this.mustPanic() and
|
not this.mustPanic() and
|
||||||
not this.mustNotReturnNormally() and
|
|
||||||
(ControlFlow::mayReturnNormally(this.getFuncDecl()) or not exists(this.getBody()))
|
(ControlFlow::mayReturnNormally(this.getFuncDecl()) or not exists(this.getBody()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -462,16 +461,6 @@ class Function extends ValueEntity, @functionobject {
|
|||||||
*/
|
*/
|
||||||
predicate mustPanic() { none() }
|
predicate mustPanic() { none() }
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if calling this function never returns normally (for example because it
|
|
||||||
* always panics, exits the process, or loops forever).
|
|
||||||
*
|
|
||||||
* Unlike `mayReturnNormally`, this predicate must be defined without reference to
|
|
||||||
* the control-flow graph, so that it can be used during CFG construction to
|
|
||||||
* suppress normal-flow successors of calls to this function.
|
|
||||||
*/
|
|
||||||
predicate mustNotReturnNormally() { none() }
|
|
||||||
|
|
||||||
/** Gets the number of parameters of this function. */
|
/** Gets the number of parameters of this function. */
|
||||||
int getNumParameter() { result = this.getType().(SignatureType).getNumParameter() }
|
int getNumParameter() { result = this.getType().(SignatureType).getNumParameter() }
|
||||||
|
|
||||||
|
|||||||
@@ -761,7 +761,7 @@ class CaseClause extends @caseclause, Stmt, ScopeNode {
|
|||||||
*
|
*
|
||||||
* Note that the default clause does not have any expressions.
|
* Note that the default clause does not have any expressions.
|
||||||
*/
|
*/
|
||||||
Expr getAnExpr() { result = this.getExpr(_) }
|
Expr getAnExpr() { result = this.getAChildExpr() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the number of expressions of this `case` clause.
|
* Gets the number of expressions of this `case` clause.
|
||||||
|
|||||||
@@ -5,27 +5,66 @@ overlay[local]
|
|||||||
module;
|
module;
|
||||||
|
|
||||||
import go
|
import go
|
||||||
private import ControlFlowGraphShared
|
private import ControlFlowGraphImpl
|
||||||
|
private import codeql.controlflow.BasicBlock as BB
|
||||||
|
private import codeql.controlflow.SuccessorType
|
||||||
|
|
||||||
/** A basic block in the control-flow graph. */
|
private module Input implements BB::InputSig<Location> {
|
||||||
class BasicBlock = GoCfg::Cfg::BasicBlock;
|
/** A delineated part of the AST with its own CFG. */
|
||||||
|
class CfgScope = ControlFlow::Root;
|
||||||
|
|
||||||
/** An entry basic block. */
|
/** The class of control flow nodes. */
|
||||||
class EntryBasicBlock = GoCfg::Cfg::EntryBasicBlock;
|
class Node = ControlFlowNode;
|
||||||
|
|
||||||
|
/** Gets the CFG scope in which this node occurs. */
|
||||||
|
CfgScope nodeGetCfgScope(Node node) { node.getRoot() = result }
|
||||||
|
|
||||||
|
/** Gets an immediate successor of this node. */
|
||||||
|
Node nodeGetASuccessor(Node node, SuccessorType t) {
|
||||||
|
result = node.getASuccessor() and
|
||||||
|
(
|
||||||
|
not result instanceof ControlFlow::ConditionGuardNode and t instanceof DirectSuccessor
|
||||||
|
or
|
||||||
|
t.(BooleanSuccessor).getValue() = result.(ControlFlow::ConditionGuardNode).getOutcome()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `node` represents an entry node to be used when calculating
|
||||||
|
* dominance.
|
||||||
|
*/
|
||||||
|
predicate nodeIsDominanceEntry(Node node) { node instanceof EntryNode }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `node` represents an exit node to be used when calculating
|
||||||
|
* post dominance.
|
||||||
|
*/
|
||||||
|
predicate nodeIsPostDominanceExit(Node node) { node instanceof ExitNode }
|
||||||
|
}
|
||||||
|
|
||||||
|
module Cfg = BB::Make<Location, Input>;
|
||||||
|
|
||||||
|
class BasicBlock = Cfg::BasicBlock;
|
||||||
|
|
||||||
|
class EntryBasicBlock = Cfg::EntryBasicBlock;
|
||||||
|
|
||||||
|
cached
|
||||||
|
private predicate reachableBB(BasicBlock bb) {
|
||||||
|
bb instanceof EntryBasicBlock
|
||||||
|
or
|
||||||
|
exists(BasicBlock predBB | predBB.getASuccessor(_) = bb | reachableBB(predBB))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A basic block that is reachable from an entry basic block.
|
* A basic block that is reachable from an entry basic block.
|
||||||
*
|
|
||||||
* Since the shared CFG library only creates nodes for reachable code,
|
|
||||||
* all basic blocks are reachable by construction.
|
|
||||||
*/
|
*/
|
||||||
class ReachableBasicBlock extends BasicBlock {
|
class ReachableBasicBlock extends BasicBlock {
|
||||||
ReachableBasicBlock() { any() }
|
ReachableBasicBlock() { reachableBB(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reachable basic block with more than one predecessor.
|
* A reachable basic block with more than one predecessor.
|
||||||
*/
|
*/
|
||||||
class ReachableJoinBlock extends ReachableBasicBlock {
|
class ReachableJoinBlock extends ReachableBasicBlock {
|
||||||
ReachableJoinBlock() { this.getFirstNode().(ControlFlow::Node).isJoin() }
|
ReachableJoinBlock() { this.getFirstNode().isJoin() }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,17 +5,13 @@ overlay[local]
|
|||||||
module;
|
module;
|
||||||
|
|
||||||
import go
|
import go
|
||||||
private import ControlFlowGraphShared
|
private import ControlFlowGraphImpl
|
||||||
|
|
||||||
/** Provides helper predicates for mapping between CFG nodes and the AST. */
|
/** Provides helper predicates for mapping btween CFG nodes and the AST. */
|
||||||
module ControlFlow {
|
module ControlFlow {
|
||||||
/** A file or function with which a CFG is associated. */
|
/** A file or function with which a CFG is associated. */
|
||||||
class Root extends AstNode {
|
class Root extends AstNode {
|
||||||
Root() {
|
Root() { exists(this.(File).getADecl()) or exists(this.(FuncDef).getBody()) }
|
||||||
exists(this.(FuncDef).getBody())
|
|
||||||
or
|
|
||||||
exists(this.(File).getADecl())
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Holds if `nd` belongs to this file or function. */
|
/** Holds if `nd` belongs to this file or function. */
|
||||||
predicate isRootOf(AstNode nd) {
|
predicate isRootOf(AstNode nd) {
|
||||||
@@ -33,16 +29,22 @@ module ControlFlow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A node in the intra-procedural control-flow graph of a Go function.
|
* A node in the intra-procedural control-flow graph of a Go function or file.
|
||||||
*
|
*
|
||||||
* Nodes correspond to expressions and statements that compute a value or perform
|
* Nodes correspond to expressions and statements that compute a value or perform
|
||||||
* an operation (as opposed to providing syntactic structure or type information).
|
* an operation (as opposed to providing syntactic structure or type information).
|
||||||
*
|
*
|
||||||
* There are also synthetic entry and exit nodes for each Go function
|
* There are also synthetic entry and exit nodes for each Go function and file
|
||||||
* that mark the beginning and the end, respectively, of the execution of the
|
* that mark the beginning and the end, respectively, of the execution of the
|
||||||
* function.
|
* function and the loading of the file.
|
||||||
*/
|
*/
|
||||||
class Node extends GoCfg::ControlFlowNode {
|
class Node extends TControlFlowNode {
|
||||||
|
/** Gets a node that directly follows this one in the control-flow graph. */
|
||||||
|
Node getASuccessor() { result = CFG::succ(this) }
|
||||||
|
|
||||||
|
/** Gets a node that directly precedes this one in the control-flow graph. */
|
||||||
|
Node getAPredecessor() { this = result.getASuccessor() }
|
||||||
|
|
||||||
/** Holds if this is a node with more than one successor. */
|
/** Holds if this is a node with more than one successor. */
|
||||||
predicate isBranch() { strictcount(this.getASuccessor()) > 1 }
|
predicate isBranch() { strictcount(this.getASuccessor()) > 1 }
|
||||||
|
|
||||||
@@ -50,23 +52,22 @@ module ControlFlow {
|
|||||||
predicate isJoin() { strictcount(this.getAPredecessor()) > 1 }
|
predicate isJoin() { strictcount(this.getAPredecessor()) > 1 }
|
||||||
|
|
||||||
/** Holds if this is the first control-flow node in `subtree`. */
|
/** Holds if this is the first control-flow node in `subtree`. */
|
||||||
predicate isFirstNodeOf(AstNode subtree) {
|
predicate isFirstNodeOf(AstNode subtree) { CFG::firstNode(subtree, this) }
|
||||||
this.isBefore(subtree)
|
|
||||||
or
|
|
||||||
this.injects(subtree)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Holds if this node is the (unique) entry node of a function. */
|
/** Holds if this node is the (unique) entry node of a function or file. */
|
||||||
predicate isEntryNode() { this instanceof GoCfg::ControlFlow::EntryNode }
|
predicate isEntryNode() { this instanceof MkEntryNode }
|
||||||
|
|
||||||
/** Holds if this node is the (unique) exit node of a function. */
|
/** Holds if this node is the (unique) exit node of a function or file. */
|
||||||
predicate isExitNode() { this instanceof GoCfg::ControlFlow::ExitNode }
|
predicate isExitNode() { this instanceof MkExitNode }
|
||||||
|
|
||||||
|
/** Gets the basic block to which this node belongs. */
|
||||||
|
BasicBlock getBasicBlock() { result.getANode() = this }
|
||||||
|
|
||||||
/** Holds if this node dominates `dominee` in the control-flow graph. */
|
/** Holds if this node dominates `dominee` in the control-flow graph. */
|
||||||
overlay[caller?]
|
overlay[caller?]
|
||||||
pragma[inline]
|
pragma[inline]
|
||||||
predicate dominatesNode(ControlFlow::Node dominee) {
|
predicate dominatesNode(ControlFlow::Node dominee) {
|
||||||
exists(GoCfg::Cfg::BasicBlock thisbb, GoCfg::Cfg::BasicBlock dbb, int i, int j |
|
exists(ReachableBasicBlock thisbb, ReachableBasicBlock dbb, int i, int j |
|
||||||
this = thisbb.getNode(i) and dominee = dbb.getNode(j)
|
this = thisbb.getNode(i) and dominee = dbb.getNode(j)
|
||||||
|
|
|
|
||||||
thisbb.strictlyDominates(dbb)
|
thisbb.strictlyDominates(dbb)
|
||||||
@@ -75,12 +76,20 @@ module ControlFlow {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the innermost function to which this node belongs. */
|
/** Gets the innermost function or file to which this node belongs. */
|
||||||
Root getRoot() { result = this.getEnclosingCallable() }
|
Root getRoot() { none() }
|
||||||
|
|
||||||
/** Gets the file to which this node belongs. */
|
/** Gets the file to which this node belongs. */
|
||||||
File getFile() { result = this.getLocation().getFile() }
|
File getFile() { result = this.getLocation().getFile() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a textual representation of this control flow node.
|
||||||
|
*/
|
||||||
|
string toString() { result = "control-flow node" }
|
||||||
|
|
||||||
|
/** Gets the source location for this element. */
|
||||||
|
Location getLocation() { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DEPRECATED: Use `getLocation()` instead.
|
* DEPRECATED: Use `getLocation()` instead.
|
||||||
*
|
*
|
||||||
@@ -104,22 +113,6 @@ module ControlFlow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A synthetic entry node for a function. */
|
|
||||||
class EntryNode extends Node instanceof GoCfg::ControlFlow::EntryNode { }
|
|
||||||
|
|
||||||
/** A synthetic exit node for a function. */
|
|
||||||
class ExitNode extends Node instanceof GoCfg::ControlFlow::ExitNode { }
|
|
||||||
|
|
||||||
private predicate isBranchConditionRoot(Expr expr) {
|
|
||||||
expr = any(LogicalBinaryExpr lbe).getLeftOperand()
|
|
||||||
or
|
|
||||||
expr = any(ForStmt fs).getCond()
|
|
||||||
or
|
|
||||||
expr = any(IfStmt is).getCond()
|
|
||||||
or
|
|
||||||
expr = any(ExpressionSwitchStmt ess | not exists(ess.getExpr())).getACase().getAnExpr()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A control-flow node that initializes or updates the value of a constant, a variable,
|
* A control-flow node that initializes or updates the value of a constant, a variable,
|
||||||
* a field, or an (array, slice, or map) element.
|
* a field, or an (array, slice, or map) element.
|
||||||
@@ -179,7 +172,7 @@ module ControlFlow {
|
|||||||
exists(IR::FieldTarget trg | trg = super.getLhs() |
|
exists(IR::FieldTarget trg | trg = super.getLhs() |
|
||||||
(
|
(
|
||||||
trg.getBase() = base or
|
trg.getBase() = base or
|
||||||
trg.getBase() = IR::implicitDerefInstruction(base.(IR::EvalInstruction).getExpr())
|
trg.getBase() = MkImplicitDeref(base.(IR::EvalInstruction).getExpr())
|
||||||
) and
|
) and
|
||||||
trg.getField() = f and
|
trg.getField() = f and
|
||||||
super.getRhs() = rhs
|
super.getRhs() = rhs
|
||||||
@@ -227,7 +220,7 @@ module ControlFlow {
|
|||||||
exists(IR::ElementTarget trg | trg = super.getLhs() |
|
exists(IR::ElementTarget trg | trg = super.getLhs() |
|
||||||
(
|
(
|
||||||
trg.getBase() = base or
|
trg.getBase() = base or
|
||||||
trg.getBase() = IR::implicitDerefInstruction(base.(IR::EvalInstruction).getExpr())
|
trg.getBase() = MkImplicitDeref(base.(IR::EvalInstruction).getExpr())
|
||||||
) and
|
) and
|
||||||
trg.getIndex() = index and
|
trg.getIndex() = index and
|
||||||
super.getRhs() = rhs
|
super.getRhs() = rhs
|
||||||
@@ -257,19 +250,11 @@ module ControlFlow {
|
|||||||
* A control-flow node recording the fact that a certain expression has a known
|
* A control-flow node recording the fact that a certain expression has a known
|
||||||
* Boolean value at this point in the program.
|
* Boolean value at this point in the program.
|
||||||
*/
|
*/
|
||||||
class ConditionGuardNode extends IR::Instruction {
|
class ConditionGuardNode extends IR::Instruction, MkConditionGuardNode {
|
||||||
Expr cond;
|
Expr cond;
|
||||||
boolean outcome;
|
boolean outcome;
|
||||||
|
|
||||||
ConditionGuardNode() {
|
ConditionGuardNode() { this = MkConditionGuardNode(cond, outcome) }
|
||||||
isBranchConditionRoot(cond) and
|
|
||||||
this.isAfterTrue(cond) and
|
|
||||||
outcome = true
|
|
||||||
or
|
|
||||||
isBranchConditionRoot(cond) and
|
|
||||||
this.isAfterFalse(cond) and
|
|
||||||
outcome = false
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate ensuresAux(Expr expr, boolean b) {
|
private predicate ensuresAux(Expr expr, boolean b) {
|
||||||
expr = cond and b = outcome
|
expr = cond and b = outcome
|
||||||
@@ -335,17 +320,21 @@ module ControlFlow {
|
|||||||
boolean getOutcome() { result = outcome }
|
boolean getOutcome() { result = outcome }
|
||||||
|
|
||||||
override Root getRoot() { result.isRootOf(cond) }
|
override Root getRoot() { result.isRootOf(cond) }
|
||||||
|
|
||||||
|
override string toString() { result = cond + " is " + outcome }
|
||||||
|
|
||||||
|
override Location getLocation() { result = cond.getLocation() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the entry node of function `root`.
|
* Gets the entry node of function or file `root`.
|
||||||
*/
|
*/
|
||||||
EntryNode entryNode(Root root) { result.getEnclosingCallable() = root }
|
Node entryNode(Root root) { result = MkEntryNode(root) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the exit node of function `root`.
|
* Gets the exit node of function or file `root`.
|
||||||
*/
|
*/
|
||||||
ExitNode exitNode(Root root) { result.getEnclosingCallable() = root }
|
Node exitNode(Root root) { result = MkExitNode(root) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the function `f` may return without panicking, exiting the process, or looping forever.
|
* Holds if the function `f` may return without panicking, exiting the process, or looping forever.
|
||||||
@@ -353,12 +342,7 @@ module ControlFlow {
|
|||||||
* This is defined conservatively, and so may also hold of a function that in fact
|
* This is defined conservatively, and so may also hold of a function that in fact
|
||||||
* cannot return normally, but never fails to hold of a function that can return normally.
|
* cannot return normally, but never fails to hold of a function that can return normally.
|
||||||
*/
|
*/
|
||||||
predicate mayReturnNormally(FuncDecl f) {
|
predicate mayReturnNormally(FuncDecl f) { CFG::mayReturnNormally(f.getBody()) }
|
||||||
exists(GoCfg::ControlFlow::NormalExitNode exit |
|
|
||||||
exit.getEnclosingCallable() = f and
|
|
||||||
exists(exit.getAPredecessor())
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `pred` is the node for the case `testExpr` in an expression
|
* Holds if `pred` is the node for the case `testExpr` in an expression
|
||||||
@@ -368,18 +352,10 @@ module ControlFlow {
|
|||||||
predicate isSwitchCaseTestPassingEdge(
|
predicate isSwitchCaseTestPassingEdge(
|
||||||
ControlFlow::Node pred, ControlFlow::Node succ, Expr switchExpr, Expr testExpr
|
ControlFlow::Node pred, ControlFlow::Node succ, Expr switchExpr, Expr testExpr
|
||||||
) {
|
) {
|
||||||
exists(ExpressionSwitchStmt ess, CaseClause cc, int i |
|
CFG::isSwitchCaseTestPassingEdge(pred, succ, switchExpr, testExpr)
|
||||||
ess.getExpr() = switchExpr and
|
|
||||||
cc = ess.getACase() and
|
|
||||||
testExpr = cc.getExpr(i) and
|
|
||||||
pred.isAfter(testExpr) and
|
|
||||||
succ.isFirstNodeOf(cc.getStmt(0))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ControlFlowNode = ControlFlow::Node;
|
class ControlFlowNode = ControlFlow::Node;
|
||||||
|
|
||||||
class CfgScope = GoCfg::CfgScope;
|
|
||||||
|
|
||||||
class Write = ControlFlow::WriteNode;
|
class Write = ControlFlow::WriteNode;
|
||||||
|
|||||||
2133
go/ql/lib/semmle/go/controlflow/ControlFlowGraphImpl.qll
Normal file
2133
go/ql/lib/semmle/go/controlflow/ControlFlowGraphImpl.qll
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -200,7 +200,7 @@ private ControlFlow::Node mostRecentSideEffect(ControlFlow::Node entry, ControlF
|
|||||||
|
|
||||||
cached
|
cached
|
||||||
private ControlFlow::Node mostRecentSideEffectUnique(ControlFlow::Node node) {
|
private ControlFlow::Node mostRecentSideEffectUnique(ControlFlow::Node node) {
|
||||||
result = unique( | | mostRecentSideEffect(getControlFlowEntry(node), node))
|
result = unique( | | mostRecentSideEffect(_, node))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Used to represent the "global value number" of an expression. */
|
/** Used to represent the "global value number" of an expression. */
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ module;
|
|||||||
import go
|
import go
|
||||||
private import codeql.ssa.Ssa as SsaImplCommon
|
private import codeql.ssa.Ssa as SsaImplCommon
|
||||||
private import semmle.go.controlflow.BasicBlocks as BasicBlocks
|
private import semmle.go.controlflow.BasicBlocks as BasicBlocks
|
||||||
private import semmle.go.controlflow.ControlFlowGraphShared
|
|
||||||
|
|
||||||
private class BasicBlock = BasicBlocks::BasicBlock;
|
private class BasicBlock = BasicBlocks::BasicBlock;
|
||||||
|
|
||||||
@@ -39,7 +38,7 @@ private module Internal {
|
|||||||
/** Holds if the `i`th node of `bb` in function `f` is an entry node. */
|
/** Holds if the `i`th node of `bb` in function `f` is an entry node. */
|
||||||
private predicate entryNode(FuncDef f, BasicBlock bb, int i) {
|
private predicate entryNode(FuncDef f, BasicBlock bb, int i) {
|
||||||
f = bb.getScope() and
|
f = bb.getScope() and
|
||||||
bb.getNode(i).(ControlFlow::Node).isEntryNode()
|
bb.getNode(i).isEntryNode()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -111,7 +110,7 @@ private module Internal {
|
|||||||
v.isCaptured() and
|
v.isCaptured() and
|
||||||
exists(FuncDef f |
|
exists(FuncDef f |
|
||||||
f = bb.getScope() and
|
f = bb.getScope() and
|
||||||
bb.getLastNode().(ControlFlow::Node).isExitNode() and
|
bb.getLastNode().isExitNode() and
|
||||||
i = bb.length() - 1 and
|
i = bb.length() - 1 and
|
||||||
certain = false
|
certain = false
|
||||||
|
|
|
|
||||||
@@ -127,7 +126,7 @@ private module Internal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
import Internal
|
import Internal
|
||||||
import SsaImplCommon::Make<Location, GoCfg::Cfg, SsaInput> as Impl
|
import SsaImplCommon::Make<Location, BasicBlocks::Cfg, SsaInput> as Impl
|
||||||
|
|
||||||
final class Definition = Impl::Definition;
|
final class Definition = Impl::Definition;
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ module Glog {
|
|||||||
/** Holds if this function takes a format string. */
|
/** Holds if this function takes a format string. */
|
||||||
predicate formatter() { format = "f" }
|
predicate formatter() { format = "f" }
|
||||||
|
|
||||||
override predicate mustNotReturnNormally() { level = "Fatal" or level = "Exit" }
|
override predicate mayReturnNormally() { level != "Fatal" and level != "Exit" }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class StringFormatter extends StringOps::Formatting::Range instanceof GlogFunction {
|
private class StringFormatter extends StringOps::Formatting::Range instanceof GlogFunction {
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ module Logrus {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate mustNotReturnNormally() {
|
override predicate mayReturnNormally() {
|
||||||
exists(string level, string suffix | level = ["Fatal", "Panic"] |
|
not exists(string level, string suffix | level = ["Fatal", "Panic"] |
|
||||||
this.getName() = level + suffix
|
this.getName() = level + suffix
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ module Revel {
|
|||||||
|
|
||||||
private IR::EvalInstruction skipImplicitFieldReads(IR::Instruction insn) {
|
private IR::EvalInstruction skipImplicitFieldReads(IR::Instruction insn) {
|
||||||
result = insn or
|
result = insn or
|
||||||
result = skipImplicitFieldReads(insn.(IR::ImplicitFieldReadInstruction).getBaseInstruction())
|
result = skipImplicitFieldReads(insn.(IR::ImplicitFieldReadInstruction).getBase())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A call to `Controller.Render`. */
|
/** A call to `Controller.Render`. */
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ module Zap {
|
|||||||
this.hasQualifiedName(packagePath(), "SugaredLogger", "Fatal" + getSuffix())
|
this.hasQualifiedName(packagePath(), "SugaredLogger", "Fatal" + getSuffix())
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate mustNotReturnNormally() { any() }
|
override predicate mayReturnNormally() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A Zap logging function which always panics. */
|
/** A Zap logging function which always panics. */
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ module Log {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate mustNotReturnNormally() { any() }
|
override predicate mayReturnNormally() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A log function which must panic. */
|
/** A log function which must panic. */
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ module Os {
|
|||||||
private class Exit extends Function {
|
private class Exit extends Function {
|
||||||
Exit() { this.hasQualifiedName("os", "Exit") }
|
Exit() { this.hasQualifiedName("os", "Exit") }
|
||||||
|
|
||||||
override predicate mustNotReturnNormally() { any() }
|
override predicate mayReturnNormally() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
// These models are not implemented using Models-as-Data because they represent reverse flow.
|
// These models are not implemented using Models-as-Data because they represent reverse flow.
|
||||||
|
|||||||
@@ -14,36 +14,11 @@
|
|||||||
|
|
||||||
import go
|
import go
|
||||||
|
|
||||||
/**
|
ControlFlow::Node nonGuardPredecessor(ControlFlow::Node nd) {
|
||||||
* Holds if `s` is reachable, that is, the control-flow graph contains a node for it.
|
exists(ControlFlow::Node pred | pred = nd.getAPredecessor() |
|
||||||
*
|
if pred instanceof ControlFlow::ConditionGuardNode
|
||||||
* The shared control-flow library does not create control-flow nodes for dead code, so an
|
then result = nonGuardPredecessor(pred)
|
||||||
* unreachable statement has no first control-flow node.
|
else result = pred
|
||||||
*/
|
|
||||||
predicate isReachable(Stmt s) { exists(s.getFirstControlFlowNode()) }
|
|
||||||
|
|
||||||
/** Gets the statement immediately preceding `s` in a statement list, if any. */
|
|
||||||
Stmt getPreviousStmt(Stmt s) {
|
|
||||||
exists(BlockStmt b, int i | s = b.getStmt(i) and result = b.getStmt(i - 1))
|
|
||||||
or
|
|
||||||
exists(CaseClause c, int i | s = c.getStmt(i) and result = c.getStmt(i - 1))
|
|
||||||
or
|
|
||||||
exists(CommClause c, int i | s = c.getStmt(i) and result = c.getStmt(i - 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `s` is unreachable but the code that would precede it in the control-flow graph is
|
|
||||||
* reachable, so that `s` is the first unreachable statement in a run of dead code.
|
|
||||||
*/
|
|
||||||
predicate firstUnreachableStmt(Stmt s) {
|
|
||||||
not isReachable(s) and
|
|
||||||
not s instanceof EmptyStmt and
|
|
||||||
(
|
|
||||||
// a statement whose preceding statement in the same list is reachable
|
|
||||||
isReachable(getPreviousStmt(s))
|
|
||||||
or
|
|
||||||
// the post statement of a `for` loop whose body is entered
|
|
||||||
exists(ForStmt f | s = f.getPost() and isReachable(f.getBody().getAStmt()))
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,13 +63,18 @@ predicate allowlist(Stmt s) {
|
|||||||
forall(Expr retval | retval = ret.getAnExpr() | isAllowedReturnValue(retval))
|
forall(Expr retval | retval = ret.getAnExpr() | isAllowedReturnValue(retval))
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
// statements deliberately made unreachable by a constant condition, such as the code
|
// statements in an `if false { ... }` and similar
|
||||||
// following `if true { return }`
|
exists(IfStmt is, ControlFlow::ConditionGuardNode iffalse, Expr cond, boolean b |
|
||||||
exists(getPreviousStmt(s).(IfStmt).getCond().getBoolValue())
|
iffalse.getCondition() = is.getCond() and
|
||||||
|
iffalse = s.getFirstControlFlowNode().getAPredecessor() and
|
||||||
|
cond.getBoolValue() = b and
|
||||||
|
iffalse.ensures(DataFlow::exprNode(cond), b.booleanNot())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
from Stmt s
|
from Stmt s, ControlFlow::Node fst
|
||||||
where
|
where
|
||||||
firstUnreachableStmt(s) and
|
fst = s.getFirstControlFlowNode() and
|
||||||
|
not exists(nonGuardPredecessor(fst)) and
|
||||||
not allowlist(s)
|
not allowlist(s)
|
||||||
select s, "This statement is unreachable."
|
select s, "This statement is unreachable."
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
| main.go:23:3:23:21 | assign:0 ... = ... | main.go:23:17:23:21 | "200" |
|
| main.go:23:3:23:13 | assignment to field Status | main.go:23:17:23:21 | "200" |
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
| file://:0:0:0:0 | [summary param] -1 in Clone |
|
| file://:0:0:0:0 | [summary param] -1 in Clone |
|
||||||
| file://:0:0:0:0 | [summary param] -1 in Write |
|
| file://:0:0:0:0 | [summary param] -1 in Write |
|
||||||
| file://:0:0:0:0 | [summary param] -1 in WriteProxy |
|
| file://:0:0:0:0 | [summary param] -1 in WriteProxy |
|
||||||
| main.go:18:103:26:1 | SSA def(req) |
|
| main.go:18:12:18:14 | SSA def(req) |
|
||||||
| main.go:18:103:26:1 | arg:0 block statement |
|
| main.go:18:12:18:14 | argument corresponding to req |
|
||||||
| main.go:20:5:20:7 | req |
|
| main.go:20:5:20:7 | req |
|
||||||
| main.go:20:5:20:7 | req [postupdate] |
|
| main.go:20:5:20:7 | req [postupdate] |
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
| main.go:29:2:29:31 | assign:0 ... := ... | main.go:29:9:29:31 | call to test1 |
|
| main.go:29:2:29:4 | assignment to err | main.go:29:9:29:31 | call to test1 |
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
| main.go:10:2:12:3 | extract:0 ... := ... | This Pam transaction may not be secure. |
|
| main.go:10:2:12:3 | ... := ...[0] | This Pam transaction may not be secure. |
|
||||||
@@ -8,23 +8,23 @@
|
|||||||
edges
|
edges
|
||||||
| DivideByZero.go:10:12:10:16 | selection of URL | DivideByZero.go:10:12:10:24 | call to Query | provenance | Src:MaD:1 MaD:2 |
|
| DivideByZero.go:10:12:10:16 | selection of URL | DivideByZero.go:10:12:10:24 | call to Query | provenance | Src:MaD:1 MaD:2 |
|
||||||
| DivideByZero.go:10:12:10:24 | call to Query | DivideByZero.go:11:27:11:32 | param1 | provenance | |
|
| DivideByZero.go:10:12:10:24 | call to Query | DivideByZero.go:11:27:11:32 | param1 | provenance | |
|
||||||
| DivideByZero.go:11:2:11:33 | extract:0 ... := ... | DivideByZero.go:12:16:12:20 | value | provenance | |
|
| DivideByZero.go:11:2:11:33 | ... := ...[0] | DivideByZero.go:12:16:12:20 | value | provenance | |
|
||||||
| DivideByZero.go:11:27:11:32 | param1 | DivideByZero.go:11:2:11:33 | extract:0 ... := ... | provenance | Config |
|
| DivideByZero.go:11:27:11:32 | param1 | DivideByZero.go:11:2:11:33 | ... := ...[0] | provenance | Config |
|
||||||
| DivideByZero.go:17:12:17:16 | selection of URL | DivideByZero.go:17:12:17:24 | call to Query | provenance | Src:MaD:1 MaD:2 |
|
| DivideByZero.go:17:12:17:16 | selection of URL | DivideByZero.go:17:12:17:24 | call to Query | provenance | Src:MaD:1 MaD:2 |
|
||||||
| DivideByZero.go:17:12:17:24 | call to Query | DivideByZero.go:18:11:18:24 | type conversion | provenance | |
|
| DivideByZero.go:17:12:17:24 | call to Query | DivideByZero.go:18:11:18:24 | type conversion | provenance | |
|
||||||
| DivideByZero.go:18:11:18:24 | type conversion | DivideByZero.go:19:16:19:20 | value | provenance | |
|
| DivideByZero.go:18:11:18:24 | type conversion | DivideByZero.go:19:16:19:20 | value | provenance | |
|
||||||
| DivideByZero.go:24:12:24:16 | selection of URL | DivideByZero.go:24:12:24:24 | call to Query | provenance | Src:MaD:1 MaD:2 |
|
| DivideByZero.go:24:12:24:16 | selection of URL | DivideByZero.go:24:12:24:24 | call to Query | provenance | Src:MaD:1 MaD:2 |
|
||||||
| DivideByZero.go:24:12:24:24 | call to Query | DivideByZero.go:25:31:25:36 | param1 | provenance | |
|
| DivideByZero.go:24:12:24:24 | call to Query | DivideByZero.go:25:31:25:36 | param1 | provenance | |
|
||||||
| DivideByZero.go:25:2:25:45 | extract:0 ... := ... | DivideByZero.go:26:16:26:20 | value | provenance | |
|
| DivideByZero.go:25:2:25:45 | ... := ...[0] | DivideByZero.go:26:16:26:20 | value | provenance | |
|
||||||
| DivideByZero.go:25:31:25:36 | param1 | DivideByZero.go:25:2:25:45 | extract:0 ... := ... | provenance | Config |
|
| DivideByZero.go:25:31:25:36 | param1 | DivideByZero.go:25:2:25:45 | ... := ...[0] | provenance | Config |
|
||||||
| DivideByZero.go:31:12:31:16 | selection of URL | DivideByZero.go:31:12:31:24 | call to Query | provenance | Src:MaD:1 MaD:2 |
|
| DivideByZero.go:31:12:31:16 | selection of URL | DivideByZero.go:31:12:31:24 | call to Query | provenance | Src:MaD:1 MaD:2 |
|
||||||
| DivideByZero.go:31:12:31:24 | call to Query | DivideByZero.go:32:33:32:38 | param1 | provenance | |
|
| DivideByZero.go:31:12:31:24 | call to Query | DivideByZero.go:32:33:32:38 | param1 | provenance | |
|
||||||
| DivideByZero.go:32:2:32:43 | extract:0 ... := ... | DivideByZero.go:33:16:33:20 | value | provenance | |
|
| DivideByZero.go:32:2:32:43 | ... := ...[0] | DivideByZero.go:33:16:33:20 | value | provenance | |
|
||||||
| DivideByZero.go:32:33:32:38 | param1 | DivideByZero.go:32:2:32:43 | extract:0 ... := ... | provenance | Config |
|
| DivideByZero.go:32:33:32:38 | param1 | DivideByZero.go:32:2:32:43 | ... := ...[0] | provenance | Config |
|
||||||
| DivideByZero.go:38:12:38:16 | selection of URL | DivideByZero.go:38:12:38:24 | call to Query | provenance | Src:MaD:1 MaD:2 |
|
| DivideByZero.go:38:12:38:16 | selection of URL | DivideByZero.go:38:12:38:24 | call to Query | provenance | Src:MaD:1 MaD:2 |
|
||||||
| DivideByZero.go:38:12:38:24 | call to Query | DivideByZero.go:39:32:39:37 | param1 | provenance | |
|
| DivideByZero.go:38:12:38:24 | call to Query | DivideByZero.go:39:32:39:37 | param1 | provenance | |
|
||||||
| DivideByZero.go:39:2:39:46 | extract:0 ... := ... | DivideByZero.go:40:16:40:20 | value | provenance | |
|
| DivideByZero.go:39:2:39:46 | ... := ...[0] | DivideByZero.go:40:16:40:20 | value | provenance | |
|
||||||
| DivideByZero.go:39:32:39:37 | param1 | DivideByZero.go:39:2:39:46 | extract:0 ... := ... | provenance | Config |
|
| DivideByZero.go:39:32:39:37 | param1 | DivideByZero.go:39:2:39:46 | ... := ...[0] | provenance | Config |
|
||||||
| DivideByZero.go:54:12:54:16 | selection of URL | DivideByZero.go:54:12:54:24 | call to Query | provenance | Src:MaD:1 MaD:2 |
|
| DivideByZero.go:54:12:54:16 | selection of URL | DivideByZero.go:54:12:54:24 | call to Query | provenance | Src:MaD:1 MaD:2 |
|
||||||
| DivideByZero.go:54:12:54:24 | call to Query | DivideByZero.go:55:11:55:24 | type conversion | provenance | |
|
| DivideByZero.go:54:12:54:24 | call to Query | DivideByZero.go:55:11:55:24 | type conversion | provenance | |
|
||||||
| DivideByZero.go:55:11:55:24 | type conversion | DivideByZero.go:57:17:57:21 | value | provenance | |
|
| DivideByZero.go:55:11:55:24 | type conversion | DivideByZero.go:57:17:57:21 | value | provenance | |
|
||||||
@@ -34,7 +34,7 @@ models
|
|||||||
nodes
|
nodes
|
||||||
| DivideByZero.go:10:12:10:16 | selection of URL | semmle.label | selection of URL |
|
| DivideByZero.go:10:12:10:16 | selection of URL | semmle.label | selection of URL |
|
||||||
| DivideByZero.go:10:12:10:24 | call to Query | semmle.label | call to Query |
|
| DivideByZero.go:10:12:10:24 | call to Query | semmle.label | call to Query |
|
||||||
| DivideByZero.go:11:2:11:33 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| DivideByZero.go:11:2:11:33 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| DivideByZero.go:11:27:11:32 | param1 | semmle.label | param1 |
|
| DivideByZero.go:11:27:11:32 | param1 | semmle.label | param1 |
|
||||||
| DivideByZero.go:12:16:12:20 | value | semmle.label | value |
|
| DivideByZero.go:12:16:12:20 | value | semmle.label | value |
|
||||||
| DivideByZero.go:17:12:17:16 | selection of URL | semmle.label | selection of URL |
|
| DivideByZero.go:17:12:17:16 | selection of URL | semmle.label | selection of URL |
|
||||||
@@ -43,17 +43,17 @@ nodes
|
|||||||
| DivideByZero.go:19:16:19:20 | value | semmle.label | value |
|
| DivideByZero.go:19:16:19:20 | value | semmle.label | value |
|
||||||
| DivideByZero.go:24:12:24:16 | selection of URL | semmle.label | selection of URL |
|
| DivideByZero.go:24:12:24:16 | selection of URL | semmle.label | selection of URL |
|
||||||
| DivideByZero.go:24:12:24:24 | call to Query | semmle.label | call to Query |
|
| DivideByZero.go:24:12:24:24 | call to Query | semmle.label | call to Query |
|
||||||
| DivideByZero.go:25:2:25:45 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| DivideByZero.go:25:2:25:45 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| DivideByZero.go:25:31:25:36 | param1 | semmle.label | param1 |
|
| DivideByZero.go:25:31:25:36 | param1 | semmle.label | param1 |
|
||||||
| DivideByZero.go:26:16:26:20 | value | semmle.label | value |
|
| DivideByZero.go:26:16:26:20 | value | semmle.label | value |
|
||||||
| DivideByZero.go:31:12:31:16 | selection of URL | semmle.label | selection of URL |
|
| DivideByZero.go:31:12:31:16 | selection of URL | semmle.label | selection of URL |
|
||||||
| DivideByZero.go:31:12:31:24 | call to Query | semmle.label | call to Query |
|
| DivideByZero.go:31:12:31:24 | call to Query | semmle.label | call to Query |
|
||||||
| DivideByZero.go:32:2:32:43 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| DivideByZero.go:32:2:32:43 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| DivideByZero.go:32:33:32:38 | param1 | semmle.label | param1 |
|
| DivideByZero.go:32:33:32:38 | param1 | semmle.label | param1 |
|
||||||
| DivideByZero.go:33:16:33:20 | value | semmle.label | value |
|
| DivideByZero.go:33:16:33:20 | value | semmle.label | value |
|
||||||
| DivideByZero.go:38:12:38:16 | selection of URL | semmle.label | selection of URL |
|
| DivideByZero.go:38:12:38:16 | selection of URL | semmle.label | selection of URL |
|
||||||
| DivideByZero.go:38:12:38:24 | call to Query | semmle.label | call to Query |
|
| DivideByZero.go:38:12:38:24 | call to Query | semmle.label | call to Query |
|
||||||
| DivideByZero.go:39:2:39:46 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| DivideByZero.go:39:2:39:46 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| DivideByZero.go:39:32:39:37 | param1 | semmle.label | param1 |
|
| DivideByZero.go:39:32:39:37 | param1 | semmle.label | param1 |
|
||||||
| DivideByZero.go:40:16:40:20 | value | semmle.label | value |
|
| DivideByZero.go:40:16:40:20 | value | semmle.label | value |
|
||||||
| DivideByZero.go:54:12:54:16 | selection of URL | semmle.label | selection of URL |
|
| DivideByZero.go:54:12:54:16 | selection of URL | semmle.label | selection of URL |
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ edges
|
|||||||
| Dsn.go:28:102:28:109 | index expression | Dsn.go:28:11:28:110 | []type{args} [array] | provenance | |
|
| Dsn.go:28:102:28:109 | index expression | Dsn.go:28:11:28:110 | []type{args} [array] | provenance | |
|
||||||
| Dsn.go:28:102:28:109 | index expression | Dsn.go:28:11:28:110 | call to Sprintf | provenance | FunctionModel |
|
| Dsn.go:28:102:28:109 | index expression | Dsn.go:28:11:28:110 | call to Sprintf | provenance | FunctionModel |
|
||||||
| Dsn.go:63:9:63:11 | cfg [postupdate] [pointer] | Dsn.go:67:102:67:104 | cfg [pointer] | provenance | |
|
| Dsn.go:63:9:63:11 | cfg [postupdate] [pointer] | Dsn.go:67:102:67:104 | cfg [pointer] | provenance | |
|
||||||
| Dsn.go:63:9:63:11 | implicit-deref cfg [postupdate] | Dsn.go:63:9:63:11 | cfg [postupdate] [pointer] | provenance | |
|
| Dsn.go:63:9:63:11 | implicit dereference [postupdate] | Dsn.go:63:9:63:11 | cfg [postupdate] [pointer] | provenance | |
|
||||||
| Dsn.go:63:9:63:11 | implicit-deref cfg [postupdate] | Dsn.go:67:102:67:108 | selection of dsn | provenance | |
|
| Dsn.go:63:9:63:11 | implicit dereference [postupdate] | Dsn.go:67:102:67:108 | selection of dsn | provenance | |
|
||||||
| Dsn.go:63:19:63:25 | selection of Args | Dsn.go:63:19:63:29 | slice expression | provenance | Src:MaD:1 |
|
| Dsn.go:63:19:63:25 | selection of Args | Dsn.go:63:19:63:29 | slice expression | provenance | Src:MaD:1 |
|
||||||
| Dsn.go:63:19:63:29 | slice expression | Dsn.go:63:9:63:11 | implicit-deref cfg [postupdate] | provenance | FunctionModel |
|
| Dsn.go:63:19:63:29 | slice expression | Dsn.go:63:9:63:11 | implicit dereference [postupdate] | provenance | FunctionModel |
|
||||||
| Dsn.go:67:11:67:109 | []type{args} [array] | Dsn.go:67:11:67:109 | call to Sprintf | provenance | MaD:2 |
|
| Dsn.go:67:11:67:109 | []type{args} [array] | Dsn.go:67:11:67:109 | call to Sprintf | provenance | MaD:2 |
|
||||||
| Dsn.go:67:11:67:109 | call to Sprintf | Dsn.go:68:29:68:33 | dbDSN | provenance | |
|
| Dsn.go:67:11:67:109 | call to Sprintf | Dsn.go:68:29:68:33 | dbDSN | provenance | |
|
||||||
| Dsn.go:67:102:67:104 | cfg [pointer] | Dsn.go:67:102:67:104 | implicit-deref cfg | provenance | |
|
| Dsn.go:67:102:67:104 | cfg [pointer] | Dsn.go:67:102:67:104 | implicit dereference | provenance | |
|
||||||
| Dsn.go:67:102:67:104 | implicit-deref cfg | Dsn.go:67:102:67:108 | selection of dsn | provenance | |
|
| Dsn.go:67:102:67:104 | implicit dereference | Dsn.go:67:102:67:108 | selection of dsn | provenance | |
|
||||||
| Dsn.go:67:102:67:108 | selection of dsn | Dsn.go:67:11:67:109 | []type{args} [array] | provenance | |
|
| Dsn.go:67:102:67:108 | selection of dsn | Dsn.go:67:11:67:109 | []type{args} [array] | provenance | |
|
||||||
| Dsn.go:67:102:67:108 | selection of dsn | Dsn.go:67:11:67:109 | call to Sprintf | provenance | FunctionModel |
|
| Dsn.go:67:102:67:108 | selection of dsn | Dsn.go:67:11:67:109 | call to Sprintf | provenance | FunctionModel |
|
||||||
models
|
models
|
||||||
@@ -28,13 +28,13 @@ nodes
|
|||||||
| Dsn.go:28:102:28:109 | index expression | semmle.label | index expression |
|
| Dsn.go:28:102:28:109 | index expression | semmle.label | index expression |
|
||||||
| Dsn.go:29:29:29:33 | dbDSN | semmle.label | dbDSN |
|
| Dsn.go:29:29:29:33 | dbDSN | semmle.label | dbDSN |
|
||||||
| Dsn.go:63:9:63:11 | cfg [postupdate] [pointer] | semmle.label | cfg [postupdate] [pointer] |
|
| Dsn.go:63:9:63:11 | cfg [postupdate] [pointer] | semmle.label | cfg [postupdate] [pointer] |
|
||||||
| Dsn.go:63:9:63:11 | implicit-deref cfg [postupdate] | semmle.label | implicit-deref cfg [postupdate] |
|
| Dsn.go:63:9:63:11 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
|
||||||
| Dsn.go:63:19:63:25 | selection of Args | semmle.label | selection of Args |
|
| Dsn.go:63:19:63:25 | selection of Args | semmle.label | selection of Args |
|
||||||
| Dsn.go:63:19:63:29 | slice expression | semmle.label | slice expression |
|
| Dsn.go:63:19:63:29 | slice expression | semmle.label | slice expression |
|
||||||
| Dsn.go:67:11:67:109 | []type{args} [array] | semmle.label | []type{args} [array] |
|
| Dsn.go:67:11:67:109 | []type{args} [array] | semmle.label | []type{args} [array] |
|
||||||
| Dsn.go:67:11:67:109 | call to Sprintf | semmle.label | call to Sprintf |
|
| Dsn.go:67:11:67:109 | call to Sprintf | semmle.label | call to Sprintf |
|
||||||
| Dsn.go:67:102:67:104 | cfg [pointer] | semmle.label | cfg [pointer] |
|
| Dsn.go:67:102:67:104 | cfg [pointer] | semmle.label | cfg [pointer] |
|
||||||
| Dsn.go:67:102:67:104 | implicit-deref cfg | semmle.label | implicit-deref cfg |
|
| Dsn.go:67:102:67:104 | implicit dereference | semmle.label | implicit dereference |
|
||||||
| Dsn.go:67:102:67:108 | selection of dsn | semmle.label | selection of dsn |
|
| Dsn.go:67:102:67:108 | selection of dsn | semmle.label | selection of dsn |
|
||||||
| Dsn.go:68:29:68:33 | dbDSN | semmle.label | dbDSN |
|
| Dsn.go:68:29:68:33 | dbDSN | semmle.label | dbDSN |
|
||||||
subpaths
|
subpaths
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ edges
|
|||||||
| builtin.go:112:21:112:31 | call to Referer | builtin.go:115:15:115:28 | untrustedInput | provenance | Src:MaD:8 |
|
| builtin.go:112:21:112:31 | call to Referer | builtin.go:115:15:115:28 | untrustedInput | provenance | Src:MaD:8 |
|
||||||
| builtin.go:130:21:130:31 | call to Referer | builtin.go:133:38:133:51 | untrustedInput | provenance | Src:MaD:8 |
|
| builtin.go:130:21:130:31 | call to Referer | builtin.go:133:38:133:51 | untrustedInput | provenance | Src:MaD:8 |
|
||||||
| builtin.go:151:16:151:36 | call to FormValue | builtin.go:154:13:154:22 | unsafehost | provenance | Src:MaD:7 |
|
| builtin.go:151:16:151:36 | call to FormValue | builtin.go:154:13:154:22 | unsafehost | provenance | Src:MaD:7 |
|
||||||
| builtin.go:154:2:154:4 | implicit-deref url [postupdate] | builtin.go:154:2:154:4 | url [postupdate] | provenance | |
|
| builtin.go:154:2:154:4 | implicit dereference [postupdate] | builtin.go:154:2:154:4 | url [postupdate] | provenance | |
|
||||||
| builtin.go:154:2:154:4 | url [postupdate] | builtin.go:156:21:156:23 | url | provenance | |
|
| builtin.go:154:2:154:4 | url [postupdate] | builtin.go:156:21:156:23 | url | provenance | |
|
||||||
| builtin.go:154:13:154:22 | unsafehost | builtin.go:154:2:154:4 | implicit-deref url [postupdate] | provenance | Config |
|
| builtin.go:154:13:154:22 | unsafehost | builtin.go:154:2:154:4 | implicit dereference [postupdate] | provenance | Config |
|
||||||
| builtin.go:154:13:154:22 | unsafehost | builtin.go:154:2:154:4 | url [postupdate] | provenance | Config |
|
| builtin.go:154:13:154:22 | unsafehost | builtin.go:154:2:154:4 | url [postupdate] | provenance | Config |
|
||||||
| builtin.go:156:21:156:23 | url | builtin.go:156:21:156:32 | call to String | provenance | MaD:12 |
|
| builtin.go:156:21:156:23 | url | builtin.go:156:21:156:32 | call to String | provenance | MaD:12 |
|
||||||
| new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:31:48:31:56 | selection of word | provenance | Src:MaD:3 |
|
| new-tests.go:26:26:26:30 | &... [postupdate] | new-tests.go:31:48:31:56 | selection of word | provenance | Src:MaD:3 |
|
||||||
@@ -43,8 +43,8 @@ edges
|
|||||||
| new-tests.go:35:49:35:57 | selection of word | new-tests.go:35:12:35:58 | call to Sprintf | provenance | FunctionModel |
|
| new-tests.go:35:49:35:57 | selection of word | new-tests.go:35:12:35:58 | call to Sprintf | provenance | FunctionModel |
|
||||||
| new-tests.go:39:18:39:30 | call to Param | new-tests.go:47:11:47:46 | ...+... | provenance | Src:MaD:1 |
|
| new-tests.go:39:18:39:30 | call to Param | new-tests.go:47:11:47:46 | ...+... | provenance | Src:MaD:1 |
|
||||||
| new-tests.go:49:18:49:30 | call to Query | new-tests.go:50:11:50:46 | ...+... | provenance | Src:MaD:2 |
|
| new-tests.go:49:18:49:30 | call to Query | new-tests.go:50:11:50:46 | ...+... | provenance | Src:MaD:2 |
|
||||||
| new-tests.go:62:2:62:39 | extract:0 ... := ... | new-tests.go:63:17:63:23 | reqBody | provenance | |
|
| new-tests.go:62:2:62:39 | ... := ...[0] | new-tests.go:63:17:63:23 | reqBody | provenance | |
|
||||||
| new-tests.go:62:31:62:38 | selection of Body | new-tests.go:62:2:62:39 | extract:0 ... := ... | provenance | Src:MaD:6 MaD:13 |
|
| new-tests.go:62:31:62:38 | selection of Body | new-tests.go:62:2:62:39 | ... := ...[0] | provenance | Src:MaD:6 MaD:13 |
|
||||||
| new-tests.go:63:17:63:23 | reqBody | new-tests.go:63:26:63:30 | &... [postupdate] | provenance | MaD:10 |
|
| new-tests.go:63:17:63:23 | reqBody | new-tests.go:63:26:63:30 | &... [postupdate] | provenance | MaD:10 |
|
||||||
| new-tests.go:63:26:63:30 | &... [postupdate] | new-tests.go:68:48:68:56 | selection of word | provenance | |
|
| new-tests.go:63:26:63:30 | &... [postupdate] | new-tests.go:68:48:68:56 | selection of word | provenance | |
|
||||||
| new-tests.go:63:26:63:30 | &... [postupdate] | new-tests.go:69:48:69:56 | selection of safe | provenance | |
|
| new-tests.go:63:26:63:30 | &... [postupdate] | new-tests.go:69:48:69:56 | selection of safe | provenance | |
|
||||||
@@ -95,7 +95,7 @@ nodes
|
|||||||
| builtin.go:130:21:130:31 | call to Referer | semmle.label | call to Referer |
|
| builtin.go:130:21:130:31 | call to Referer | semmle.label | call to Referer |
|
||||||
| builtin.go:133:38:133:51 | untrustedInput | semmle.label | untrustedInput |
|
| builtin.go:133:38:133:51 | untrustedInput | semmle.label | untrustedInput |
|
||||||
| builtin.go:151:16:151:36 | call to FormValue | semmle.label | call to FormValue |
|
| builtin.go:151:16:151:36 | call to FormValue | semmle.label | call to FormValue |
|
||||||
| builtin.go:154:2:154:4 | implicit-deref url [postupdate] | semmle.label | implicit-deref url [postupdate] |
|
| builtin.go:154:2:154:4 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
|
||||||
| builtin.go:154:2:154:4 | url [postupdate] | semmle.label | url [postupdate] |
|
| builtin.go:154:2:154:4 | url [postupdate] | semmle.label | url [postupdate] |
|
||||||
| builtin.go:154:13:154:22 | unsafehost | semmle.label | unsafehost |
|
| builtin.go:154:13:154:22 | unsafehost | semmle.label | unsafehost |
|
||||||
| builtin.go:156:21:156:23 | url | semmle.label | url |
|
| builtin.go:156:21:156:23 | url | semmle.label | url |
|
||||||
@@ -114,7 +114,7 @@ nodes
|
|||||||
| new-tests.go:47:11:47:46 | ...+... | semmle.label | ...+... |
|
| new-tests.go:47:11:47:46 | ...+... | semmle.label | ...+... |
|
||||||
| new-tests.go:49:18:49:30 | call to Query | semmle.label | call to Query |
|
| new-tests.go:49:18:49:30 | call to Query | semmle.label | call to Query |
|
||||||
| new-tests.go:50:11:50:46 | ...+... | semmle.label | ...+... |
|
| new-tests.go:50:11:50:46 | ...+... | semmle.label | ...+... |
|
||||||
| new-tests.go:62:2:62:39 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| new-tests.go:62:2:62:39 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| new-tests.go:62:31:62:38 | selection of Body | semmle.label | selection of Body |
|
| new-tests.go:62:31:62:38 | selection of Body | semmle.label | selection of Body |
|
||||||
| new-tests.go:63:17:63:23 | reqBody | semmle.label | reqBody |
|
| new-tests.go:63:17:63:23 | reqBody | semmle.label | reqBody |
|
||||||
| new-tests.go:63:26:63:30 | &... [postupdate] | semmle.label | &... [postupdate] |
|
| new-tests.go:63:26:63:30 | &... [postupdate] | semmle.label | &... [postupdate] |
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ edges
|
|||||||
| WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | provenance | |
|
| WrongUsageOfUnsafe.go:166:33:166:57 | type conversion | WrongUsageOfUnsafe.go:166:16:166:58 | type conversion | provenance | |
|
||||||
| WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | provenance | |
|
| WrongUsageOfUnsafe.go:189:31:189:55 | type conversion | WrongUsageOfUnsafe.go:189:16:189:56 | type conversion | provenance | |
|
||||||
| WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | provenance | |
|
| WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | provenance | |
|
||||||
| WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | WrongUsageOfUnsafe.go:236:53:245:1 | SSA def(req) | provenance | |
|
| WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | WrongUsageOfUnsafe.go:236:21:236:23 | SSA def(req) | provenance | |
|
||||||
| WrongUsageOfUnsafe.go:236:53:245:1 | SSA def(req) | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | provenance | |
|
| WrongUsageOfUnsafe.go:236:21:236:23 | SSA def(req) | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | provenance | |
|
||||||
| WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | provenance | |
|
| WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | provenance | |
|
||||||
| WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | provenance | |
|
| WrongUsageOfUnsafe.go:274:25:274:49 | type conversion | WrongUsageOfUnsafe.go:274:16:274:50 | type conversion | provenance | |
|
||||||
| WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | provenance | |
|
| WrongUsageOfUnsafe.go:292:23:292:47 | type conversion | WrongUsageOfUnsafe.go:292:16:292:48 | type conversion | provenance | |
|
||||||
@@ -51,7 +51,7 @@ nodes
|
|||||||
| WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | semmle.label | type conversion |
|
| WrongUsageOfUnsafe.go:211:16:211:61 | type conversion | semmle.label | type conversion |
|
||||||
| WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | semmle.label | type conversion |
|
| WrongUsageOfUnsafe.go:211:31:211:60 | type conversion | semmle.label | type conversion |
|
||||||
| WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | semmle.label | type conversion |
|
| WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | semmle.label | type conversion |
|
||||||
| WrongUsageOfUnsafe.go:236:53:245:1 | SSA def(req) | semmle.label | SSA def(req) |
|
| WrongUsageOfUnsafe.go:236:21:236:23 | SSA def(req) | semmle.label | SSA def(req) |
|
||||||
| WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | semmle.label | type conversion |
|
| WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | semmle.label | type conversion |
|
||||||
| WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | semmle.label | type conversion |
|
| WrongUsageOfUnsafe.go:256:16:256:53 | type conversion | semmle.label | type conversion |
|
||||||
| WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | semmle.label | type conversion |
|
| WrongUsageOfUnsafe.go:256:28:256:52 | type conversion | semmle.label | type conversion |
|
||||||
|
|||||||
@@ -1,156 +1,64 @@
|
|||||||
nodes
|
nodes
|
||||||
edges
|
edges
|
||||||
| conversions.go:0:0:0:0 | After conversions.go | conversions.go:0:0:0:0 | Normal Exit |
|
| conversions.go:0:0:0:0 | entry | conversions.go:3:1:3:15 | skip |
|
||||||
| conversions.go:0:0:0:0 | Entry | conversions.go:0:0:0:0 | conversions.go |
|
| conversions.go:3:1:3:15 | skip | conversions.go:5:6:5:8 | skip |
|
||||||
| conversions.go:0:0:0:0 | Normal Exit | conversions.go:0:0:0:0 | Exit |
|
| conversions.go:5:1:5:29 | entry | conversions.go:5:10:5:10 | argument corresponding to _ |
|
||||||
| conversions.go:0:0:0:0 | conversions.go | conversions.go:3:1:3:15 | import declaration |
|
| conversions.go:5:1:5:29 | function declaration | conversions.go:7:6:7:9 | skip |
|
||||||
| conversions.go:3:1:3:15 | After import declaration | conversions.go:5:1:5:29 | Before function declaration |
|
| conversions.go:5:6:5:8 | skip | conversions.go:5:1:5:29 | function declaration |
|
||||||
| conversions.go:3:1:3:15 | import declaration | conversions.go:3:8:3:15 | import specifier |
|
| conversions.go:5:10:5:10 | argument corresponding to _ | conversions.go:5:10:5:10 | initialization of _ |
|
||||||
| conversions.go:3:8:3:15 | import specifier | conversions.go:3:1:3:15 | After import declaration |
|
| conversions.go:5:10:5:10 | initialization of _ | conversions.go:5:28:5:29 | skip |
|
||||||
| conversions.go:5:1:5:29 | After function declaration | conversions.go:7:1:26:1 | Before function declaration |
|
| conversions.go:5:28:5:29 | skip | conversions.go:5:1:5:29 | exit |
|
||||||
| conversions.go:5:1:5:29 | Before function declaration | conversions.go:5:1:5:29 | function declaration |
|
| conversions.go:7:1:26:1 | entry | conversions.go:8:6:8:6 | skip |
|
||||||
| conversions.go:5:1:5:29 | Entry | conversions.go:5:28:5:29 | block statement |
|
| conversions.go:7:1:26:1 | function declaration | conversions.go:0:0:0:0 | exit |
|
||||||
| conversions.go:5:1:5:29 | Normal Exit | conversions.go:5:1:5:29 | Exit |
|
| conversions.go:7:6:7:9 | skip | conversions.go:7:1:26:1 | function declaration |
|
||||||
| conversions.go:5:1:5:29 | function declaration | conversions.go:5:1:5:29 | After function declaration |
|
| conversions.go:8:6:8:6 | assignment to a | conversions.go:10:2:10:2 | skip |
|
||||||
| conversions.go:5:28:5:29 | After block statement | conversions.go:5:1:5:29 | Normal Exit |
|
| conversions.go:8:6:8:6 | skip | conversions.go:8:6:8:6 | zero value for a |
|
||||||
| conversions.go:5:28:5:29 | arg:0 block statement | conversions.go:5:28:5:29 | param-init:0 block statement |
|
| conversions.go:8:6:8:6 | zero value for a | conversions.go:8:6:8:6 | assignment to a |
|
||||||
| conversions.go:5:28:5:29 | block statement | conversions.go:5:28:5:29 | arg:0 block statement |
|
| conversions.go:10:2:10:2 | assignment to b | conversions.go:11:2:11:4 | use |
|
||||||
| conversions.go:5:28:5:29 | param-init:0 block statement | conversions.go:5:28:5:29 | After block statement |
|
| conversions.go:10:2:10:2 | skip | conversions.go:10:7:10:16 | selection of Add |
|
||||||
| conversions.go:7:1:26:1 | After function declaration | conversions.go:0:0:0:0 | After conversions.go |
|
| conversions.go:10:7:10:16 | selection of Add | conversions.go:10:18:10:18 | a |
|
||||||
| conversions.go:7:1:26:1 | Before function declaration | conversions.go:7:1:26:1 | function declaration |
|
| conversions.go:10:7:10:23 | call to Add | conversions.go:10:2:10:2 | assignment to b |
|
||||||
| conversions.go:7:1:26:1 | Entry | conversions.go:7:13:26:1 | block statement |
|
| conversions.go:10:18:10:18 | a | conversions.go:10:21:10:22 | 10 |
|
||||||
| conversions.go:7:1:26:1 | Exceptional Exit | conversions.go:7:1:26:1 | Exit |
|
| conversions.go:10:21:10:22 | 10 | conversions.go:10:7:10:23 | call to Add |
|
||||||
| conversions.go:7:1:26:1 | Normal Exit | conversions.go:7:1:26:1 | Exit |
|
| conversions.go:11:2:11:4 | use | conversions.go:11:6:11:6 | b |
|
||||||
| conversions.go:7:1:26:1 | function declaration | conversions.go:7:1:26:1 | After function declaration |
|
| conversions.go:11:2:11:7 | call to use | conversions.go:7:1:26:1 | exit |
|
||||||
| conversions.go:7:13:26:1 | After block statement | conversions.go:7:1:26:1 | Normal Exit |
|
| conversions.go:11:2:11:7 | call to use | conversions.go:13:6:13:8 | skip |
|
||||||
| conversions.go:7:13:26:1 | block statement | conversions.go:8:2:8:21 | declaration statement |
|
| conversions.go:11:6:11:6 | b | conversions.go:11:2:11:7 | call to use |
|
||||||
| conversions.go:8:2:8:21 | After declaration statement | conversions.go:10:2:10:23 | ... := ... |
|
| conversions.go:13:6:13:8 | assignment to arr | conversions.go:14:2:14:6 | skip |
|
||||||
| conversions.go:8:2:8:21 | After variable declaration | conversions.go:8:2:8:21 | After declaration statement |
|
| conversions.go:13:6:13:8 | skip | conversions.go:13:6:13:8 | zero value for arr |
|
||||||
| conversions.go:8:2:8:21 | declaration statement | conversions.go:8:2:8:21 | variable declaration |
|
| conversions.go:13:6:13:8 | zero value for arr | conversions.go:13:6:13:8 | assignment to arr |
|
||||||
| conversions.go:8:2:8:21 | variable declaration | conversions.go:8:6:8:21 | value declaration specifier |
|
| conversions.go:14:2:14:6 | assignment to slice | conversions.go:17:2:17:4 | skip |
|
||||||
| conversions.go:8:6:8:21 | After value declaration specifier | conversions.go:8:2:8:21 | After variable declaration |
|
| conversions.go:14:2:14:6 | skip | conversions.go:14:11:14:22 | selection of Slice |
|
||||||
| conversions.go:8:6:8:21 | assign:0 value declaration specifier | conversions.go:8:6:8:21 | After value declaration specifier |
|
| conversions.go:14:11:14:22 | selection of Slice | conversions.go:14:24:14:26 | arr |
|
||||||
| conversions.go:8:6:8:21 | value declaration specifier | conversions.go:8:6:8:21 | zero-init:0 value declaration specifier |
|
| conversions.go:14:11:14:31 | call to Slice | conversions.go:14:2:14:6 | assignment to slice |
|
||||||
| conversions.go:8:6:8:21 | zero-init:0 value declaration specifier | conversions.go:8:6:8:21 | assign:0 value declaration specifier |
|
| conversions.go:14:24:14:26 | arr | conversions.go:14:29:14:30 | 20 |
|
||||||
| conversions.go:10:2:10:23 | ... := ... | conversions.go:10:7:10:23 | Before call to Add |
|
| conversions.go:14:29:14:30 | 20 | conversions.go:14:11:14:31 | call to Slice |
|
||||||
| conversions.go:10:2:10:23 | After ... := ... | conversions.go:11:2:11:7 | expression statement |
|
| conversions.go:17:2:17:4 | assignment to ptr | conversions.go:18:2:18:4 | use |
|
||||||
| conversions.go:10:2:10:23 | assign:0 ... := ... | conversions.go:10:2:10:23 | After ... := ... |
|
| conversions.go:17:2:17:4 | skip | conversions.go:17:20:17:24 | slice |
|
||||||
| conversions.go:10:7:10:16 | After selection of Add | conversions.go:10:18:10:18 | Before a |
|
| conversions.go:17:9:17:25 | type conversion | conversions.go:7:1:26:1 | exit |
|
||||||
| conversions.go:10:7:10:16 | Before selection of Add | conversions.go:10:7:10:16 | selection of Add |
|
| conversions.go:17:9:17:25 | type conversion | conversions.go:17:2:17:4 | assignment to ptr |
|
||||||
| conversions.go:10:7:10:16 | selection of Add | conversions.go:10:7:10:16 | After selection of Add |
|
| conversions.go:17:20:17:24 | slice | conversions.go:17:9:17:25 | type conversion |
|
||||||
| conversions.go:10:7:10:23 | After call to Add | conversions.go:10:2:10:23 | assign:0 ... := ... |
|
| conversions.go:18:2:18:4 | use | conversions.go:18:6:18:8 | ptr |
|
||||||
| conversions.go:10:7:10:23 | Before call to Add | conversions.go:10:7:10:16 | Before selection of Add |
|
| conversions.go:18:2:18:9 | call to use | conversions.go:7:1:26:1 | exit |
|
||||||
| conversions.go:10:7:10:23 | call to Add | conversions.go:10:7:10:23 | After call to Add |
|
| conversions.go:18:2:18:9 | call to use | conversions.go:21:2:21:4 | skip |
|
||||||
| conversions.go:10:18:10:18 | After a | conversions.go:10:21:10:22 | Before 10 |
|
| conversions.go:18:6:18:8 | ptr | conversions.go:18:2:18:9 | call to use |
|
||||||
| conversions.go:10:18:10:18 | Before a | conversions.go:10:18:10:18 | a |
|
| conversions.go:21:2:21:4 | assignment to str | conversions.go:22:2:22:6 | skip |
|
||||||
| conversions.go:10:18:10:18 | a | conversions.go:10:18:10:18 | After a |
|
| conversions.go:21:2:21:4 | skip | conversions.go:21:9:21:18 | "a string" |
|
||||||
| conversions.go:10:21:10:22 | 10 | conversions.go:10:21:10:22 | After 10 |
|
| conversions.go:21:9:21:18 | "a string" | conversions.go:21:2:21:4 | assignment to str |
|
||||||
| conversions.go:10:21:10:22 | After 10 | conversions.go:10:7:10:23 | call to Add |
|
| conversions.go:22:2:22:6 | assignment to bytes | conversions.go:23:2:23:4 | use |
|
||||||
| conversions.go:10:21:10:22 | Before 10 | conversions.go:10:21:10:22 | 10 |
|
| conversions.go:22:2:22:6 | skip | conversions.go:22:18:22:20 | str |
|
||||||
| conversions.go:11:2:11:4 | After use | conversions.go:11:6:11:6 | Before b |
|
| conversions.go:22:11:22:21 | type conversion | conversions.go:22:2:22:6 | assignment to bytes |
|
||||||
| conversions.go:11:2:11:4 | Before use | conversions.go:11:2:11:4 | use |
|
| conversions.go:22:18:22:20 | str | conversions.go:22:11:22:21 | type conversion |
|
||||||
| conversions.go:11:2:11:4 | use | conversions.go:11:2:11:4 | After use |
|
| conversions.go:23:2:23:4 | use | conversions.go:23:6:23:10 | bytes |
|
||||||
| conversions.go:11:2:11:7 | After call to use | conversions.go:11:2:11:7 | After expression statement |
|
| conversions.go:23:2:23:11 | call to use | conversions.go:7:1:26:1 | exit |
|
||||||
| conversions.go:11:2:11:7 | After expression statement | conversions.go:13:2:13:13 | declaration statement |
|
| conversions.go:23:2:23:11 | call to use | conversions.go:24:2:24:6 | skip |
|
||||||
| conversions.go:11:2:11:7 | Before call to use | conversions.go:11:2:11:4 | Before use |
|
| conversions.go:23:6:23:10 | bytes | conversions.go:23:2:23:11 | call to use |
|
||||||
| conversions.go:11:2:11:7 | call to use | conversions.go:7:1:26:1 | Exceptional Exit |
|
| conversions.go:24:2:24:6 | assignment to runes | conversions.go:25:2:25:4 | use |
|
||||||
| conversions.go:11:2:11:7 | call to use | conversions.go:11:2:11:7 | After call to use |
|
| conversions.go:24:2:24:6 | skip | conversions.go:24:18:24:20 | str |
|
||||||
| conversions.go:11:2:11:7 | expression statement | conversions.go:11:2:11:7 | Before call to use |
|
| conversions.go:24:11:24:21 | type conversion | conversions.go:24:2:24:6 | assignment to runes |
|
||||||
| conversions.go:11:6:11:6 | After b | conversions.go:11:2:11:7 | call to use |
|
| conversions.go:24:18:24:20 | str | conversions.go:24:11:24:21 | type conversion |
|
||||||
| conversions.go:11:6:11:6 | Before b | conversions.go:11:6:11:6 | b |
|
| conversions.go:25:2:25:4 | use | conversions.go:25:6:25:10 | runes |
|
||||||
| conversions.go:11:6:11:6 | b | conversions.go:11:6:11:6 | After b |
|
| conversions.go:25:2:25:11 | call to use | conversions.go:7:1:26:1 | exit |
|
||||||
| conversions.go:13:2:13:13 | After declaration statement | conversions.go:14:2:14:31 | ... := ... |
|
| conversions.go:25:6:25:10 | runes | conversions.go:25:2:25:11 | call to use |
|
||||||
| conversions.go:13:2:13:13 | After variable declaration | conversions.go:13:2:13:13 | After declaration statement |
|
|
||||||
| conversions.go:13:2:13:13 | declaration statement | conversions.go:13:2:13:13 | variable declaration |
|
|
||||||
| conversions.go:13:2:13:13 | variable declaration | conversions.go:13:6:13:13 | value declaration specifier |
|
|
||||||
| conversions.go:13:6:13:13 | After value declaration specifier | conversions.go:13:2:13:13 | After variable declaration |
|
|
||||||
| conversions.go:13:6:13:13 | assign:0 value declaration specifier | conversions.go:13:6:13:13 | After value declaration specifier |
|
|
||||||
| conversions.go:13:6:13:13 | value declaration specifier | conversions.go:13:6:13:13 | zero-init:0 value declaration specifier |
|
|
||||||
| conversions.go:13:6:13:13 | zero-init:0 value declaration specifier | conversions.go:13:6:13:13 | assign:0 value declaration specifier |
|
|
||||||
| conversions.go:14:2:14:31 | ... := ... | conversions.go:14:11:14:31 | Before call to Slice |
|
|
||||||
| conversions.go:14:2:14:31 | After ... := ... | conversions.go:17:2:17:25 | ... := ... |
|
|
||||||
| conversions.go:14:2:14:31 | assign:0 ... := ... | conversions.go:14:2:14:31 | After ... := ... |
|
|
||||||
| conversions.go:14:11:14:22 | After selection of Slice | conversions.go:14:24:14:26 | Before arr |
|
|
||||||
| conversions.go:14:11:14:22 | Before selection of Slice | conversions.go:14:11:14:22 | selection of Slice |
|
|
||||||
| conversions.go:14:11:14:22 | selection of Slice | conversions.go:14:11:14:22 | After selection of Slice |
|
|
||||||
| conversions.go:14:11:14:31 | After call to Slice | conversions.go:14:2:14:31 | assign:0 ... := ... |
|
|
||||||
| conversions.go:14:11:14:31 | Before call to Slice | conversions.go:14:11:14:22 | Before selection of Slice |
|
|
||||||
| conversions.go:14:11:14:31 | call to Slice | conversions.go:14:11:14:31 | After call to Slice |
|
|
||||||
| conversions.go:14:24:14:26 | After arr | conversions.go:14:29:14:30 | Before 20 |
|
|
||||||
| conversions.go:14:24:14:26 | Before arr | conversions.go:14:24:14:26 | arr |
|
|
||||||
| conversions.go:14:24:14:26 | arr | conversions.go:14:24:14:26 | After arr |
|
|
||||||
| conversions.go:14:29:14:30 | 20 | conversions.go:14:29:14:30 | After 20 |
|
|
||||||
| conversions.go:14:29:14:30 | After 20 | conversions.go:14:11:14:31 | call to Slice |
|
|
||||||
| conversions.go:14:29:14:30 | Before 20 | conversions.go:14:29:14:30 | 20 |
|
|
||||||
| conversions.go:17:2:17:25 | ... := ... | conversions.go:17:9:17:25 | Before type conversion |
|
|
||||||
| conversions.go:17:2:17:25 | After ... := ... | conversions.go:18:2:18:9 | expression statement |
|
|
||||||
| conversions.go:17:2:17:25 | assign:0 ... := ... | conversions.go:17:2:17:25 | After ... := ... |
|
|
||||||
| conversions.go:17:9:17:25 | After type conversion | conversions.go:17:2:17:25 | assign:0 ... := ... |
|
|
||||||
| conversions.go:17:9:17:25 | Before type conversion | conversions.go:17:20:17:24 | Before slice |
|
|
||||||
| conversions.go:17:9:17:25 | type conversion | conversions.go:7:1:26:1 | Exceptional Exit |
|
|
||||||
| conversions.go:17:9:17:25 | type conversion | conversions.go:17:9:17:25 | After type conversion |
|
|
||||||
| conversions.go:17:20:17:24 | After slice | conversions.go:17:9:17:25 | type conversion |
|
|
||||||
| conversions.go:17:20:17:24 | Before slice | conversions.go:17:20:17:24 | slice |
|
|
||||||
| conversions.go:17:20:17:24 | slice | conversions.go:17:20:17:24 | After slice |
|
|
||||||
| conversions.go:18:2:18:4 | After use | conversions.go:18:6:18:8 | Before ptr |
|
|
||||||
| conversions.go:18:2:18:4 | Before use | conversions.go:18:2:18:4 | use |
|
|
||||||
| conversions.go:18:2:18:4 | use | conversions.go:18:2:18:4 | After use |
|
|
||||||
| conversions.go:18:2:18:9 | After call to use | conversions.go:18:2:18:9 | After expression statement |
|
|
||||||
| conversions.go:18:2:18:9 | After expression statement | conversions.go:21:2:21:18 | ... := ... |
|
|
||||||
| conversions.go:18:2:18:9 | Before call to use | conversions.go:18:2:18:4 | Before use |
|
|
||||||
| conversions.go:18:2:18:9 | call to use | conversions.go:7:1:26:1 | Exceptional Exit |
|
|
||||||
| conversions.go:18:2:18:9 | call to use | conversions.go:18:2:18:9 | After call to use |
|
|
||||||
| conversions.go:18:2:18:9 | expression statement | conversions.go:18:2:18:9 | Before call to use |
|
|
||||||
| conversions.go:18:6:18:8 | After ptr | conversions.go:18:2:18:9 | call to use |
|
|
||||||
| conversions.go:18:6:18:8 | Before ptr | conversions.go:18:6:18:8 | ptr |
|
|
||||||
| conversions.go:18:6:18:8 | ptr | conversions.go:18:6:18:8 | After ptr |
|
|
||||||
| conversions.go:21:2:21:18 | ... := ... | conversions.go:21:9:21:18 | Before "a string" |
|
|
||||||
| conversions.go:21:2:21:18 | After ... := ... | conversions.go:22:2:22:21 | ... := ... |
|
|
||||||
| conversions.go:21:2:21:18 | assign:0 ... := ... | conversions.go:21:2:21:18 | After ... := ... |
|
|
||||||
| conversions.go:21:9:21:18 | "a string" | conversions.go:21:9:21:18 | After "a string" |
|
|
||||||
| conversions.go:21:9:21:18 | After "a string" | conversions.go:21:2:21:18 | assign:0 ... := ... |
|
|
||||||
| conversions.go:21:9:21:18 | Before "a string" | conversions.go:21:9:21:18 | "a string" |
|
|
||||||
| conversions.go:22:2:22:21 | ... := ... | conversions.go:22:11:22:21 | Before type conversion |
|
|
||||||
| conversions.go:22:2:22:21 | After ... := ... | conversions.go:23:2:23:11 | expression statement |
|
|
||||||
| conversions.go:22:2:22:21 | assign:0 ... := ... | conversions.go:22:2:22:21 | After ... := ... |
|
|
||||||
| conversions.go:22:11:22:21 | After type conversion | conversions.go:22:2:22:21 | assign:0 ... := ... |
|
|
||||||
| conversions.go:22:11:22:21 | Before type conversion | conversions.go:22:18:22:20 | Before str |
|
|
||||||
| conversions.go:22:11:22:21 | type conversion | conversions.go:22:11:22:21 | After type conversion |
|
|
||||||
| conversions.go:22:18:22:20 | After str | conversions.go:22:11:22:21 | type conversion |
|
|
||||||
| conversions.go:22:18:22:20 | Before str | conversions.go:22:18:22:20 | str |
|
|
||||||
| conversions.go:22:18:22:20 | str | conversions.go:22:18:22:20 | After str |
|
|
||||||
| conversions.go:23:2:23:4 | After use | conversions.go:23:6:23:10 | Before bytes |
|
|
||||||
| conversions.go:23:2:23:4 | Before use | conversions.go:23:2:23:4 | use |
|
|
||||||
| conversions.go:23:2:23:4 | use | conversions.go:23:2:23:4 | After use |
|
|
||||||
| conversions.go:23:2:23:11 | After call to use | conversions.go:23:2:23:11 | After expression statement |
|
|
||||||
| conversions.go:23:2:23:11 | After expression statement | conversions.go:24:2:24:21 | ... := ... |
|
|
||||||
| conversions.go:23:2:23:11 | Before call to use | conversions.go:23:2:23:4 | Before use |
|
|
||||||
| conversions.go:23:2:23:11 | call to use | conversions.go:7:1:26:1 | Exceptional Exit |
|
|
||||||
| conversions.go:23:2:23:11 | call to use | conversions.go:23:2:23:11 | After call to use |
|
|
||||||
| conversions.go:23:2:23:11 | expression statement | conversions.go:23:2:23:11 | Before call to use |
|
|
||||||
| conversions.go:23:6:23:10 | After bytes | conversions.go:23:2:23:11 | call to use |
|
|
||||||
| conversions.go:23:6:23:10 | Before bytes | conversions.go:23:6:23:10 | bytes |
|
|
||||||
| conversions.go:23:6:23:10 | bytes | conversions.go:23:6:23:10 | After bytes |
|
|
||||||
| conversions.go:24:2:24:21 | ... := ... | conversions.go:24:11:24:21 | Before type conversion |
|
|
||||||
| conversions.go:24:2:24:21 | After ... := ... | conversions.go:25:2:25:11 | expression statement |
|
|
||||||
| conversions.go:24:2:24:21 | assign:0 ... := ... | conversions.go:24:2:24:21 | After ... := ... |
|
|
||||||
| conversions.go:24:11:24:21 | After type conversion | conversions.go:24:2:24:21 | assign:0 ... := ... |
|
|
||||||
| conversions.go:24:11:24:21 | Before type conversion | conversions.go:24:18:24:20 | Before str |
|
|
||||||
| conversions.go:24:11:24:21 | type conversion | conversions.go:24:11:24:21 | After type conversion |
|
|
||||||
| conversions.go:24:18:24:20 | After str | conversions.go:24:11:24:21 | type conversion |
|
|
||||||
| conversions.go:24:18:24:20 | Before str | conversions.go:24:18:24:20 | str |
|
|
||||||
| conversions.go:24:18:24:20 | str | conversions.go:24:18:24:20 | After str |
|
|
||||||
| conversions.go:25:2:25:4 | After use | conversions.go:25:6:25:10 | Before runes |
|
|
||||||
| conversions.go:25:2:25:4 | Before use | conversions.go:25:2:25:4 | use |
|
|
||||||
| conversions.go:25:2:25:4 | use | conversions.go:25:2:25:4 | After use |
|
|
||||||
| conversions.go:25:2:25:11 | After call to use | conversions.go:25:2:25:11 | After expression statement |
|
|
||||||
| conversions.go:25:2:25:11 | After expression statement | conversions.go:7:13:26:1 | After block statement |
|
|
||||||
| conversions.go:25:2:25:11 | Before call to use | conversions.go:25:2:25:4 | Before use |
|
|
||||||
| conversions.go:25:2:25:11 | call to use | conversions.go:7:1:26:1 | Exceptional Exit |
|
|
||||||
| conversions.go:25:2:25:11 | call to use | conversions.go:25:2:25:11 | After call to use |
|
|
||||||
| conversions.go:25:2:25:11 | expression statement | conversions.go:25:2:25:11 | Before call to use |
|
|
||||||
| conversions.go:25:6:25:10 | After runes | conversions.go:25:2:25:11 | call to use |
|
|
||||||
| conversions.go:25:6:25:10 | Before runes | conversions.go:25:6:25:10 | runes |
|
|
||||||
| conversions.go:25:6:25:10 | runes | conversions.go:25:6:25:10 | After runes |
|
|
||||||
#select
|
#select
|
||||||
| |
|
| |
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
| test.go:9:2:9:16 | extract:0 ... := ... | test.go:9:13:9:16 | <-... | 0 | file://:0:0:0:0 | bool |
|
| test.go:9:2:9:16 | ... := ...[0] | test.go:9:13:9:16 | <-... | 0 | file://:0:0:0:0 | bool |
|
||||||
| test.go:9:2:9:16 | extract:1 ... := ... | test.go:9:13:9:16 | <-... | 1 | file://:0:0:0:0 | bool |
|
| test.go:9:2:9:16 | ... := ...[1] | test.go:9:13:9:16 | <-... | 1 | file://:0:0:0:0 | bool |
|
||||||
| test.go:15:2:15:20 | extract:0 ... := ... | test.go:15:13:15:20 | index expression | 0 | file://:0:0:0:0 | string |
|
| test.go:15:2:15:20 | ... := ...[0] | test.go:15:13:15:20 | index expression | 0 | file://:0:0:0:0 | string |
|
||||||
| test.go:15:2:15:20 | extract:1 ... := ... | test.go:15:13:15:20 | index expression | 1 | file://:0:0:0:0 | bool |
|
| test.go:15:2:15:20 | ... := ...[1] | test.go:15:13:15:20 | index expression | 1 | file://:0:0:0:0 | bool |
|
||||||
| test.go:21:2:21:22 | extract:0 ... := ... | test.go:21:13:21:22 | type assertion | 0 | file://:0:0:0:0 | string |
|
| test.go:21:2:21:22 | ... := ...[0] | test.go:21:13:21:22 | type assertion | 0 | file://:0:0:0:0 | string |
|
||||||
| test.go:21:2:21:22 | extract:1 ... := ... | test.go:21:13:21:22 | type assertion | 1 | file://:0:0:0:0 | bool |
|
| test.go:21:2:21:22 | ... := ...[1] | test.go:21:13:21:22 | type assertion | 1 | file://:0:0:0:0 | bool |
|
||||||
|
| test.go:29:2:29:7 | call to f[0] | test.go:29:4:29:6 | call to g | 0 | file://:0:0:0:0 | int |
|
||||||
|
| test.go:29:2:29:7 | call to f[1] | test.go:29:4:29:6 | call to g | 1 | file://:0:0:0:0 | int |
|
||||||
|
| test.go:33:2:33:7 | call to f[0] | test.go:33:4:33:6 | call to v | 0 | file://:0:0:0:0 | int |
|
||||||
|
| test.go:33:2:33:7 | call to f[1] | test.go:33:4:33:6 | call to v | 1 | file://:0:0:0:0 | int |
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
| main.go:6:2:6:2 | x | main.go:24:2:24:9 | increment statement |
|
| main.go:6:2:6:2 | x | main.go:24:2:24:9 | increment statement |
|
||||||
| main.go:13:7:13:10 | recv | main.go:13:27:15:1 | param-init:-1 block statement |
|
| main.go:13:7:13:10 | recv | main.go:13:7:13:10 | initialization of recv |
|
||||||
| main.go:17:10:17:10 | x | main.go:17:32:21:1 | param-init:0 block statement |
|
| main.go:17:10:17:10 | x | main.go:17:10:17:10 | initialization of x |
|
||||||
| main.go:17:26:17:26 | y | main.go:17:32:21:1 | param-init:1 block statement |
|
| main.go:17:26:17:26 | y | main.go:17:26:17:26 | initialization of y |
|
||||||
| main.go:23:7:23:10 | recv | main.go:23:23:25:1 | param-init:-1 block statement |
|
| main.go:23:7:23:10 | recv | main.go:23:7:23:10 | initialization of recv |
|
||||||
| types.go:33:22:33:22 | a | types.go:33:34:35:1 | param-init:0 block statement |
|
| types.go:33:22:33:22 | a | types.go:33:22:33:22 | initialization of a |
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ func logSomething(entry *logrus.Entry) {
|
|||||||
entry.Traceln(text) // $ logger=text
|
entry.Traceln(text) // $ logger=text
|
||||||
}
|
}
|
||||||
|
|
||||||
func logrusCalls(selector int) {
|
func logrusCalls() {
|
||||||
err := errors.New("Error")
|
err := errors.New("Error")
|
||||||
var fields logrus.Fields = nil
|
var fields logrus.Fields = nil
|
||||||
var fn logrus.LogFunction = nil
|
var fn logrus.LogFunction = nil
|
||||||
@@ -27,15 +27,11 @@ func logrusCalls(selector int) {
|
|||||||
tmp = logrus.WithFields(fields) // $ logger=fields
|
tmp = logrus.WithFields(fields) // $ logger=fields
|
||||||
logSomething(tmp)
|
logSomething(tmp)
|
||||||
|
|
||||||
logrus.Error(text) // $ logger=text
|
logrus.Error(text) // $ logger=text
|
||||||
logrus.Infof(fmt, text) // $ logger=fmt logger=text
|
logrus.Fatalf(fmt, text) // $ logger=fmt logger=text
|
||||||
if selector == 0 {
|
logrus.Panicln(text) // $ logger=text
|
||||||
logrus.Fatalf(fmt, text) // $ logger=fmt logger=text
|
logrus.Infof(fmt, text) // $ logger=fmt logger=text
|
||||||
} else if selector == 1 {
|
logrus.FatalFn(fn) // $ logger=fn
|
||||||
logrus.Panicln(text) // $ logger=text
|
|
||||||
} else if selector == 2 {
|
|
||||||
logrus.FatalFn(fn) // $ logger=fn
|
|
||||||
}
|
|
||||||
|
|
||||||
// components corresponding to the format specifier "%T" are not considered vulnerable
|
// components corresponding to the format specifier "%T" are not considered vulnerable
|
||||||
logrus.Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
logrus.Infof("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ var v []byte
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
glogTest(len(v))
|
glogTest(len(v))
|
||||||
stdlib(len(v))
|
stdlib()
|
||||||
slogTest()
|
slogTest()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,69 +4,37 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func stdlib(selector int) {
|
func stdlib() {
|
||||||
var logger log.Logger
|
var logger log.Logger
|
||||||
logger.SetPrefix("prefix: ")
|
logger.SetPrefix("prefix: ")
|
||||||
switch selector {
|
logger.Fatal(text) // $ logger=text
|
||||||
case 0:
|
logger.Fatalf(fmt, text) // $ logger=fmt logger=text
|
||||||
logger.Fatal(text) // $ logger=text
|
logger.Fatalln(text) // $ logger=text
|
||||||
case 1:
|
logger.Panic(text) // $ logger=text
|
||||||
logger.Fatalf(fmt, text) // $ logger=fmt logger=text
|
logger.Panicf(fmt, text) // $ logger=fmt logger=text
|
||||||
case 2:
|
logger.Panicln(text) // $ logger=text
|
||||||
logger.Fatalln(text) // $ logger=text
|
logger.Print(text) // $ logger=text
|
||||||
case 3:
|
logger.Printf(fmt, text) // $ logger=fmt logger=text
|
||||||
logger.Panic(text) // $ logger=text
|
logger.Println(text) // $ logger=text
|
||||||
case 4:
|
|
||||||
logger.Panicf(fmt, text) // $ logger=fmt logger=text
|
|
||||||
case 5:
|
|
||||||
logger.Panicln(text) // $ logger=text
|
|
||||||
case 6:
|
|
||||||
logger.Print(text) // $ logger=text
|
|
||||||
case 7:
|
|
||||||
logger.Printf(fmt, text) // $ logger=fmt logger=text
|
|
||||||
case 8:
|
|
||||||
logger.Println(text) // $ logger=text
|
|
||||||
}
|
|
||||||
|
|
||||||
// components corresponding to the format specifier "%T" are not considered vulnerable
|
// components corresponding to the format specifier "%T" are not considered vulnerable
|
||||||
switch selector {
|
logger.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
case 9:
|
logger.Panicf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
logger.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
logger.Printf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
case 10:
|
|
||||||
logger.Panicf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
|
||||||
case 11:
|
|
||||||
logger.Printf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
|
||||||
}
|
|
||||||
|
|
||||||
log.SetPrefix("prefix: ")
|
log.SetPrefix("prefix: ")
|
||||||
switch selector {
|
log.Fatal(text) // $ logger=text
|
||||||
case 12:
|
log.Fatalf(fmt, text) // $ logger=fmt logger=text
|
||||||
log.Fatal(text) // $ logger=text
|
log.Fatalln(text) // $ logger=text
|
||||||
case 13:
|
log.Panic(text) // $ logger=text
|
||||||
log.Fatalf(fmt, text) // $ logger=fmt logger=text
|
log.Panicf(fmt, text) // $ logger=fmt logger=text
|
||||||
case 14:
|
log.Panicln(text) // $ logger=text
|
||||||
log.Fatalln(text) // $ logger=text
|
log.Print(text) // $ logger=text
|
||||||
case 15:
|
log.Printf(fmt, text) // $ logger=fmt logger=text
|
||||||
log.Panic(text) // $ logger=text
|
log.Println(text) // $ logger=text
|
||||||
case 16:
|
|
||||||
log.Panicf(fmt, text) // $ logger=fmt logger=text
|
|
||||||
case 17:
|
|
||||||
log.Panicln(text) // $ logger=text
|
|
||||||
case 18:
|
|
||||||
log.Print(text) // $ logger=text
|
|
||||||
case 19:
|
|
||||||
log.Printf(fmt, text) // $ logger=fmt logger=text
|
|
||||||
case 20:
|
|
||||||
log.Println(text) // $ logger=text
|
|
||||||
}
|
|
||||||
|
|
||||||
// components corresponding to the format specifier "%T" are not considered vulnerable
|
// components corresponding to the format specifier "%T" are not considered vulnerable
|
||||||
switch selector {
|
log.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
case 21:
|
log.Panicf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
log.Fatalf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
log.Printf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
||||||
case 22:
|
|
||||||
log.Panicf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
|
||||||
case 23:
|
|
||||||
log.Printf("%s: found type %T", text, v) // $ logger="%s: found type %T" logger=text type-logger=v
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,3 @@
|
|||||||
| epilogues.go:115:6:115:22 | epiRecoverUnnamed | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.epiRecoverUnnamed |
|
|
||||||
| file://:0:0:0:0 | Exit | os.Exit |
|
| file://:0:0:0:0 | Exit | os.Exit |
|
||||||
| file://:0:0:0:0 | Fatal | log.Fatal |
|
| file://:0:0:0:0 | Fatal | log.Fatal |
|
||||||
| file://:0:0:0:0 | Fatal | log.Logger.Fatal |
|
| file://:0:0:0:0 | Fatal | log.Logger.Fatal |
|
||||||
@@ -19,3 +18,4 @@
|
|||||||
| stmts7.go:10:6:10:15 | canRecover | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.canRecover |
|
| stmts7.go:10:6:10:15 | canRecover | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.canRecover |
|
||||||
| stmts.go:10:6:10:10 | test5 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.test5 |
|
| stmts.go:10:6:10:10 | test5 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.test5 |
|
||||||
| stmts.go:46:6:46:10 | test6 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.test6 |
|
| stmts.go:46:6:46:10 | test6 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.test6 |
|
||||||
|
| stmts.go:112:6:112:10 | test9 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph.test9 |
|
||||||
|
|||||||
@@ -1,118 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// epiLogger has methods with both pointer and value receivers, used to check
|
|
||||||
// that the receiver and arguments of a deferred call are evaluated at the
|
|
||||||
// `defer` statement rather than in the function epilogue.
|
|
||||||
type epiLogger struct {
|
|
||||||
prefix string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *epiLogger) log(msg string, code int) {
|
|
||||||
fmt.Println(l.prefix, msg, code)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l epiLogger) logValue(msg string) {
|
|
||||||
fmt.Println(l.prefix, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
// epiRecover recovers from a panic. It is used as a deferred function so we can
|
|
||||||
// check that control flow returns to the result-read nodes and the normal exit
|
|
||||||
// node after recovering.
|
|
||||||
func epiRecover() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
fmt.Println("recovered:", r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// epiPlain has no named result variable and a single `return` with a child
|
|
||||||
// expression.
|
|
||||||
func epiPlain(x int) int {
|
|
||||||
return x * 2
|
|
||||||
}
|
|
||||||
|
|
||||||
// epiVoid has no named result variable and no `return` statement at all.
|
|
||||||
func epiVoid() {
|
|
||||||
fmt.Println("void")
|
|
||||||
}
|
|
||||||
|
|
||||||
// epiNamedMixed has named result variables and a mix of a bare `return` (no
|
|
||||||
// child expressions) and a `return` with child expressions.
|
|
||||||
func epiNamedMixed(x int) (result int, err error) {
|
|
||||||
if x < 0 {
|
|
||||||
result = -x
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return x, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// epiNamedBareOnly has a named result variable and only a bare `return`.
|
|
||||||
func epiNamedBareOnly(x int) (n int) {
|
|
||||||
n = x + 1
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// epiDeferReceiverArgs has a deferred call with a (pointer) receiver and
|
|
||||||
// arguments that are expressions, so we can check the receiver `l` and the
|
|
||||||
// arguments `"count"` and `len(items)` are evaluated at the `defer` statement.
|
|
||||||
func epiDeferReceiverArgs(l *epiLogger, items []int) {
|
|
||||||
defer l.log("count", len(items))
|
|
||||||
fmt.Println("processing", len(items))
|
|
||||||
}
|
|
||||||
|
|
||||||
// epiDeferValueReceiver has deferred calls with a value receiver and an
|
|
||||||
// address-of receiver, both with arguments evaluated at the `defer` statement.
|
|
||||||
func epiDeferValueReceiver(prefix string) {
|
|
||||||
l := epiLogger{prefix: prefix}
|
|
||||||
defer l.logValue("bye")
|
|
||||||
defer (&l).log("ptr", 7)
|
|
||||||
fmt.Println("body")
|
|
||||||
}
|
|
||||||
|
|
||||||
// epiDeferFuncLit has a deferred function literal with parameters, so we can
|
|
||||||
// check that the arguments `"done"` and `x+1` are evaluated at the `defer`
|
|
||||||
// statement and that control flow enters the function literal body when it is
|
|
||||||
// invoked at the function epilogue.
|
|
||||||
func epiDeferFuncLit(x int) {
|
|
||||||
defer func(label string, n int) {
|
|
||||||
fmt.Println(label, n)
|
|
||||||
}("done", x+1)
|
|
||||||
fmt.Println("body", x)
|
|
||||||
}
|
|
||||||
|
|
||||||
// epiRecoverNamed has a named result variable and a deferred closure containing
|
|
||||||
// `recover()`. After recovering on the panic path, control flow should return
|
|
||||||
// to the result-read nodes and the normal exit node.
|
|
||||||
func epiRecoverNamed(x int) (result int) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
result = -1
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if x < 0 {
|
|
||||||
panic("neg")
|
|
||||||
}
|
|
||||||
result = x * x
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// epiRecoverNamedBare has named result variables, a deferred function
|
|
||||||
// containing `recover()`, and only bare `return` statements.
|
|
||||||
func epiRecoverNamedBare(x int) (ok bool, n int) {
|
|
||||||
defer epiRecover()
|
|
||||||
if x == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n = x
|
|
||||||
ok = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// epiRecoverUnnamed has no named result variables and a deferred function
|
|
||||||
// containing `recover()`; after recovering, control flow should reach the
|
|
||||||
// normal exit node directly (there are no result-read nodes).
|
|
||||||
func epiRecoverUnnamed() {
|
|
||||||
defer epiRecover()
|
|
||||||
panic("boom")
|
|
||||||
}
|
|
||||||
@@ -4,9 +4,9 @@ invalidModelRow
|
|||||||
| test.go:40:8:40:15 | call to Src2 | qltest |
|
| test.go:40:8:40:15 | call to Src2 | qltest |
|
||||||
| test.go:40:8:40:15 | call to Src2 | qltest-w-subtypes |
|
| test.go:40:8:40:15 | call to Src2 | qltest-w-subtypes |
|
||||||
| test.go:41:8:41:16 | call to Src2 | qltest-w-subtypes |
|
| test.go:41:8:41:16 | call to Src2 | qltest-w-subtypes |
|
||||||
| test.go:42:2:42:21 | extract:0 ... = ... | qltest |
|
| test.go:42:2:42:21 | ... = ...[0] | qltest |
|
||||||
| test.go:42:2:42:21 | extract:1 ... = ... | qltest-w-subtypes |
|
| test.go:42:2:42:21 | ... = ...[1] | qltest-w-subtypes |
|
||||||
| test.go:43:2:43:22 | extract:1 ... = ... | qltest-w-subtypes |
|
| test.go:43:2:43:22 | ... = ...[1] | qltest-w-subtypes |
|
||||||
| test.go:44:11:44:13 | arg [postupdate] | qltest-arg |
|
| test.go:44:11:44:13 | arg [postupdate] | qltest-arg |
|
||||||
| test.go:59:9:59:16 | call to Src1 | qltest |
|
| test.go:59:9:59:16 | call to Src1 | qltest |
|
||||||
| test.go:102:46:102:53 | call to Src1 | qltest |
|
| test.go:102:46:102:53 | call to Src1 | qltest |
|
||||||
@@ -22,4 +22,4 @@ invalidModelRow
|
|||||||
| test.go:187:24:187:31 | call to Src1 | qltest |
|
| test.go:187:24:187:31 | call to Src1 | qltest |
|
||||||
| test.go:191:24:191:31 | call to Src1 | qltest |
|
| test.go:191:24:191:31 | call to Src1 | qltest |
|
||||||
| test.go:209:10:209:28 | selection of SourceVariable | qltest |
|
| test.go:209:10:209:28 | selection of SourceVariable | qltest |
|
||||||
| test.go:216:37:218:1 | SSA def(src) | qltest |
|
| test.go:216:15:216:17 | SSA def(src) | qltest |
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
invalidModelRow
|
invalidModelRow
|
||||||
#select
|
#select
|
||||||
| test.go:17:23:17:25 | arg | test.go:17:10:17:26 | call to StepArgRes |
|
| test.go:17:23:17:25 | arg | test.go:17:10:17:26 | call to StepArgRes |
|
||||||
| test.go:18:27:18:29 | arg | test.go:18:2:18:30 | extract:1 ... = ... |
|
| test.go:18:27:18:29 | arg | test.go:18:2:18:30 | ... = ...[1] |
|
||||||
| test.go:19:15:19:17 | arg | test.go:19:20:19:23 | arg1 [postupdate] |
|
| test.go:19:15:19:17 | arg | test.go:19:20:19:23 | arg1 [postupdate] |
|
||||||
| test.go:21:16:21:18 | arg | test.go:21:2:21:2 | t [postupdate] |
|
| test.go:21:16:21:18 | arg | test.go:21:2:21:2 | t [postupdate] |
|
||||||
| test.go:22:10:22:10 | t | test.go:22:10:22:24 | call to StepQualRes |
|
| test.go:22:10:22:10 | t | test.go:22:10:22:24 | call to StepQualRes |
|
||||||
| test.go:23:2:23:2 | t | test.go:23:16:23:18 | arg [postupdate] |
|
| test.go:23:2:23:2 | t | test.go:23:16:23:18 | arg [postupdate] |
|
||||||
| test.go:24:32:24:34 | arg | test.go:24:10:24:35 | call to StepArgResNoQual |
|
| test.go:24:32:24:34 | arg | test.go:24:10:24:35 | call to StepArgResNoQual |
|
||||||
| test.go:61:25:61:27 | src | test.go:61:12:61:28 | call to StepArgRes |
|
| test.go:61:25:61:27 | src | test.go:61:12:61:28 | call to StepArgRes |
|
||||||
| test.go:64:29:64:31 | src | test.go:64:2:64:32 | extract:1 ... := ... |
|
| test.go:64:29:64:31 | src | test.go:64:2:64:32 | ... := ...[1] |
|
||||||
| test.go:68:15:68:17 | src | test.go:68:20:68:25 | taint3 [postupdate] |
|
| test.go:68:15:68:17 | src | test.go:68:20:68:25 | taint3 [postupdate] |
|
||||||
| test.go:76:21:76:23 | src | test.go:76:2:76:7 | taint4 [postupdate] |
|
| test.go:76:21:76:23 | src | test.go:76:2:76:7 | taint4 [postupdate] |
|
||||||
| test.go:79:13:79:25 | type assertion | test.go:79:12:79:40 | call to StepQualRes |
|
| test.go:79:13:79:25 | type assertion | test.go:79:12:79:40 | call to StepQualRes |
|
||||||
|
|||||||
@@ -1,40 +1,42 @@
|
|||||||
| main.go:6:2:6:5 | implicit-one increment statement | main.go:14:7:14:7 | 1 |
|
| main.go:6:2:6:5 | 1 | main.go:14:7:14:7 | 1 |
|
||||||
| main.go:10:2:10:7 | SSA def(x) | main.go:10:7:10:7 | 0 |
|
| main.go:10:2:10:2 | SSA def(x) | main.go:10:7:10:7 | 0 |
|
||||||
| main.go:10:7:10:7 | 0 | main.go:10:7:10:7 | 0 |
|
| main.go:10:7:10:7 | 0 | main.go:10:7:10:7 | 0 |
|
||||||
| main.go:11:6:11:10 | SSA def(y) | main.go:10:7:10:7 | 0 |
|
| main.go:11:6:11:6 | SSA def(y) | main.go:10:7:10:7 | 0 |
|
||||||
| main.go:11:6:11:10 | zero-init:0 value declaration specifier | main.go:10:7:10:7 | 0 |
|
| main.go:11:6:11:6 | zero value for y | main.go:10:7:10:7 | 0 |
|
||||||
| main.go:12:2:12:18 | call to Println | main.go:12:2:12:18 | call to Println |
|
| main.go:12:2:12:18 | call to Println | main.go:12:2:12:18 | call to Println |
|
||||||
| main.go:12:14:12:14 | x | main.go:10:7:10:7 | 0 |
|
| main.go:12:14:12:14 | x | main.go:10:7:10:7 | 0 |
|
||||||
| main.go:12:17:12:17 | y | main.go:10:7:10:7 | 0 |
|
| main.go:12:17:12:17 | y | main.go:10:7:10:7 | 0 |
|
||||||
| main.go:14:2:14:7 | SSA def(z) | main.go:14:7:14:7 | 1 |
|
| main.go:14:2:14:2 | SSA def(z) | main.go:14:7:14:7 | 1 |
|
||||||
| main.go:14:7:14:7 | 1 | main.go:14:7:14:7 | 1 |
|
| main.go:14:7:14:7 | 1 | main.go:14:7:14:7 | 1 |
|
||||||
| main.go:15:2:15:9 | call to bump | main.go:15:2:15:9 | call to bump |
|
| main.go:15:2:15:9 | call to bump | main.go:15:2:15:9 | call to bump |
|
||||||
| main.go:16:2:16:21 | call to Println | main.go:16:2:16:21 | call to Println |
|
| main.go:16:2:16:21 | call to Println | main.go:16:2:16:21 | call to Println |
|
||||||
| main.go:16:14:16:14 | x | main.go:10:7:10:7 | 0 |
|
| main.go:16:14:16:14 | x | main.go:10:7:10:7 | 0 |
|
||||||
| main.go:16:17:16:17 | y | main.go:10:7:10:7 | 0 |
|
| main.go:16:17:16:17 | y | main.go:10:7:10:7 | 0 |
|
||||||
| main.go:18:2:18:24 | SSA def(ss) | main.go:18:8:18:24 | call to make |
|
| main.go:18:2:18:3 | SSA def(ss) | main.go:18:8:18:24 | call to make |
|
||||||
| main.go:18:8:18:24 | call to make | main.go:18:8:18:24 | call to make |
|
| main.go:18:8:18:24 | call to make | main.go:18:8:18:24 | call to make |
|
||||||
| main.go:18:23:18:23 | 3 | main.go:18:23:18:23 | 3 |
|
| main.go:18:23:18:23 | 3 | main.go:18:23:18:23 | 3 |
|
||||||
| main.go:19:5:19:5 | 2 | main.go:19:5:19:5 | 2 |
|
| main.go:19:5:19:5 | 2 | main.go:19:5:19:5 | 2 |
|
||||||
| main.go:19:10:19:24 | "Hello, world!" | main.go:19:10:19:24 | "Hello, world!" |
|
| main.go:19:10:19:24 | "Hello, world!" | main.go:19:10:19:24 | "Hello, world!" |
|
||||||
| main.go:20:2:20:16 | call to Println | main.go:20:2:20:16 | call to Println |
|
| main.go:20:2:20:16 | call to Println | main.go:20:2:20:16 | call to Println |
|
||||||
| main.go:23:23:26:1 | result-read:0 block statement | main.go:24:8:24:8 | 4 |
|
| main.go:23:14:23:16 | implicit read of res | main.go:24:8:24:8 | 4 |
|
||||||
| main.go:24:2:24:8 | SSA def(res) | main.go:24:8:24:8 | 4 |
|
| main.go:23:14:23:16 | zero value for res | main.go:10:7:10:7 | 0 |
|
||||||
|
| main.go:24:2:24:4 | SSA def(res) | main.go:24:8:24:8 | 4 |
|
||||||
| main.go:24:8:24:8 | 4 | main.go:24:8:24:8 | 4 |
|
| main.go:24:8:24:8 | 4 | main.go:24:8:24:8 | 4 |
|
||||||
| main.go:28:24:31:1 | result-read:0 block statement | main.go:29:8:29:8 | 5 |
|
| main.go:28:15:28:17 | implicit read of res | main.go:30:9:30:9 | 6 |
|
||||||
| main.go:29:2:29:8 | SSA def(res) | main.go:29:8:29:8 | 5 |
|
| main.go:28:15:28:17 | zero value for res | main.go:10:7:10:7 | 0 |
|
||||||
| main.go:29:8:29:8 | 5 | main.go:29:8:29:8 | 5 |
|
| main.go:29:8:29:8 | 5 | main.go:29:8:29:8 | 5 |
|
||||||
| main.go:30:9:30:9 | 6 | main.go:30:9:30:9 | 6 |
|
| main.go:30:9:30:9 | 6 | main.go:30:9:30:9 | 6 |
|
||||||
| main.go:34:2:34:8 | SSA def(res) | main.go:34:8:34:8 | 7 |
|
| main.go:30:9:30:9 | SSA def(res) | main.go:30:9:30:9 | 6 |
|
||||||
|
| main.go:33:15:33:17 | zero value for res | main.go:10:7:10:7 | 0 |
|
||||||
| main.go:34:8:34:8 | 7 | main.go:34:8:34:8 | 7 |
|
| main.go:34:8:34:8 | 7 | main.go:34:8:34:8 | 7 |
|
||||||
| main.go:35:8:37:4 | function call | main.go:35:8:37:4 | function call |
|
| main.go:35:8:37:4 | function call | main.go:35:8:37:4 | function call |
|
||||||
| main.go:36:3:36:9 | SSA def(res) | main.go:36:9:36:9 | 8 |
|
| main.go:36:3:36:5 | SSA def(res) | main.go:36:9:36:9 | 8 |
|
||||||
| main.go:36:9:36:9 | 8 | main.go:36:9:36:9 | 8 |
|
| main.go:36:9:36:9 | 8 | main.go:36:9:36:9 | 8 |
|
||||||
| main.go:38:9:38:9 | 9 | main.go:38:9:38:9 | 9 |
|
| main.go:38:9:38:9 | 9 | main.go:38:9:38:9 | 9 |
|
||||||
|
| main.go:38:9:38:9 | SSA def(res) | main.go:38:9:38:9 | 9 |
|
||||||
| regressions.go:5:11:5:31 | call to Sizeof | regressions.go:5:11:5:31 | call to Sizeof |
|
| regressions.go:5:11:5:31 | call to Sizeof | regressions.go:5:11:5:31 | call to Sizeof |
|
||||||
| regressions.go:5:25:5:30 | call to test | regressions.go:5:25:5:30 | call to test |
|
|
||||||
| regressions.go:7:11:7:15 | false | regressions.go:7:11:7:15 | false |
|
| regressions.go:7:11:7:15 | false | regressions.go:7:11:7:15 | false |
|
||||||
| regressions.go:9:12:9:12 | d | regressions.go:7:11:7:15 | false |
|
| regressions.go:9:11:9:12 | !... | regressions.go:11:11:11:14 | true |
|
||||||
| regressions.go:11:11:11:14 | true | regressions.go:11:11:11:14 | true |
|
| regressions.go:11:11:11:14 | true | regressions.go:11:11:11:14 | true |
|
||||||
| regressions.go:30:9:30:22 | call to getPayload | regressions.go:30:9:30:22 | call to getPayload |
|
| regressions.go:30:9:30:22 | call to getPayload | regressions.go:30:9:30:22 | call to getPayload |
|
||||||
| regressions.go:30:26:30:39 | call to getPayload | regressions.go:30:26:30:39 | call to getPayload |
|
| regressions.go:30:26:30:39 | call to getPayload | regressions.go:30:26:30:39 | call to getPayload |
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
| tst.go:19:10:19:14 | index expression | tst.go:19:10:19:11 | xs | tst.go:19:13:19:13 | 1 |
|
| tst.go:19:10:19:14 | index expression | tst.go:19:10:19:11 | xs | tst.go:19:13:19:13 | 1 |
|
||||||
| tst.go:20:10:20:14 | index expression | tst.go:20:10:20:11 | implicit-deref ps | tst.go:20:13:20:13 | 1 |
|
| tst.go:20:10:20:14 | index expression | tst.go:20:10:20:11 | implicit dereference | tst.go:20:13:20:13 | 1 |
|
||||||
| tst.go:20:10:20:14 | index expression | tst.go:20:10:20:11 | ps | tst.go:20:13:20:13 | 1 |
|
| tst.go:20:10:20:14 | index expression | tst.go:20:10:20:11 | ps | tst.go:20:13:20:13 | 1 |
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
| tst.go:8:8:8:10 | selection of f | tst.go:8:8:8:8 | implicit-deref t | tst.go:4:2:4:2 | f |
|
| tst.go:8:8:8:10 | selection of f | tst.go:8:8:8:8 | implicit dereference | tst.go:4:2:4:2 | f |
|
||||||
| tst.go:8:8:8:10 | selection of f | tst.go:8:8:8:8 | t | tst.go:4:2:4:2 | f |
|
| tst.go:8:8:8:10 | selection of f | tst.go:8:8:8:8 | t | tst.go:4:2:4:2 | f |
|
||||||
| tst.go:13:9:13:11 | selection of f | tst.go:13:9:13:9 | t | tst.go:4:2:4:2 | f |
|
| tst.go:13:9:13:11 | selection of f | tst.go:13:9:13:9 | t | tst.go:4:2:4:2 | f |
|
||||||
| tst.go:17:8:17:10 | selection of f | tst.go:17:8:17:8 | x | tst.go:4:2:4:2 | f |
|
| tst.go:17:8:17:10 | selection of f | tst.go:17:8:17:8 | x | tst.go:4:2:4:2 | f |
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
| tst.go:9:9:9:13 | selection of get | tst.go:9:9:9:9 | implicit-deref t | tst.go:12:12:12:14 | get |
|
| tst.go:9:9:9:13 | selection of get | tst.go:9:9:9:9 | implicit dereference | tst.go:12:12:12:14 | get |
|
||||||
| tst.go:9:9:9:13 | selection of get | tst.go:9:9:9:9 | t | tst.go:12:12:12:14 | get |
|
| tst.go:9:9:9:13 | selection of get | tst.go:9:9:9:9 | t | tst.go:12:12:12:14 | get |
|
||||||
| tst.go:18:2:18:7 | selection of bump | tst.go:18:2:18:2 | x | tst.go:7:13:7:16 | bump |
|
| tst.go:18:2:18:7 | selection of bump | tst.go:18:2:18:2 | x | tst.go:7:13:7:16 | bump |
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
| tst.go:19:2:19:14 | assign:0 ... = ... | tst.go:19:2:19:3 | xs [postupdate] | tst.go:19:5:19:5 | 0 | tst.go:19:10:19:14 | index expression |
|
| tst.go:19:2:19:6 | assignment to element | tst.go:19:2:19:3 | xs [postupdate] | tst.go:19:5:19:5 | 0 | tst.go:19:10:19:14 | index expression |
|
||||||
| tst.go:20:2:20:14 | assign:0 ... = ... | tst.go:20:2:20:3 | implicit-deref ps [postupdate] | tst.go:20:5:20:5 | 0 | tst.go:20:10:20:14 | index expression |
|
| tst.go:20:2:20:6 | assignment to element | tst.go:20:2:20:3 | implicit dereference [postupdate] | tst.go:20:5:20:5 | 0 | tst.go:20:10:20:14 | index expression |
|
||||||
| tst.go:20:2:20:14 | assign:0 ... = ... | tst.go:20:2:20:3 | ps [postupdate] | tst.go:20:5:20:5 | 0 | tst.go:20:10:20:14 | index expression |
|
| tst.go:20:2:20:6 | assignment to element | tst.go:20:2:20:3 | ps [postupdate] | tst.go:20:5:20:5 | 0 | tst.go:20:10:20:14 | index expression |
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
| tst.go:8:2:8:14 | assign:0 ... = ... | tst.go:8:2:8:2 | implicit-deref t [postupdate] | tst.go:4:2:4:2 | f | tst.go:8:8:8:14 | ...+... |
|
| tst.go:8:2:8:4 | assignment to field f | tst.go:8:2:8:2 | implicit dereference [postupdate] | tst.go:4:2:4:2 | f | tst.go:8:8:8:14 | ...+... |
|
||||||
| tst.go:8:2:8:14 | assign:0 ... = ... | tst.go:8:2:8:2 | t [postupdate] | tst.go:4:2:4:2 | f | tst.go:8:8:8:14 | ...+... |
|
| tst.go:8:2:8:4 | assignment to field f | tst.go:8:2:8:2 | t [postupdate] | tst.go:4:2:4:2 | f | tst.go:8:8:8:14 | ...+... |
|
||||||
| tst.go:17:2:17:14 | assign:0 ... = ... | tst.go:17:2:17:2 | x [postupdate] | tst.go:4:2:4:2 | f | tst.go:17:8:17:14 | ...+... |
|
| tst.go:17:2:17:4 | assignment to field f | tst.go:17:2:17:2 | x [postupdate] | tst.go:4:2:4:2 | f | tst.go:17:8:17:14 | ...+... |
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
| test.go:34:16:34:20 | param | test.go:33:11:33:27 | call to QueryParams | test.go:34:16:34:20 | param | Cross-site scripting vulnerability due to $@. | test.go:33:11:33:27 | call to QueryParams | user-provided value | test.go:0:0:0:0 | test.go | |
|
| test.go:34:16:34:20 | param | test.go:33:11:33:27 | call to QueryParams | test.go:34:16:34:20 | param | Cross-site scripting vulnerability due to $@. | test.go:33:11:33:27 | call to QueryParams | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||||
| test.go:40:16:40:19 | qstr | test.go:39:10:39:26 | call to QueryString | test.go:40:16:40:19 | qstr | Cross-site scripting vulnerability due to $@. | test.go:39:10:39:26 | call to QueryString | user-provided value | test.go:0:0:0:0 | test.go | |
|
| test.go:40:16:40:19 | qstr | test.go:39:10:39:26 | call to QueryString | test.go:40:16:40:19 | qstr | Cross-site scripting vulnerability due to $@. | test.go:39:10:39:26 | call to QueryString | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||||
| test.go:46:16:46:18 | val | test.go:45:9:45:34 | call to FormValue | test.go:46:16:46:18 | val | Cross-site scripting vulnerability due to $@. | test.go:45:9:45:34 | call to FormValue | user-provided value | test.go:0:0:0:0 | test.go | |
|
| test.go:46:16:46:18 | val | test.go:45:9:45:34 | call to FormValue | test.go:46:16:46:18 | val | Cross-site scripting vulnerability due to $@. | test.go:45:9:45:34 | call to FormValue | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||||
| test.go:52:16:52:37 | index expression | test.go:51:2:51:30 | extract:0 ... := ... | test.go:52:16:52:37 | index expression | Cross-site scripting vulnerability due to $@. | test.go:51:2:51:30 | extract:0 ... := ... | user-provided value | test.go:0:0:0:0 | test.go | |
|
| test.go:52:16:52:37 | index expression | test.go:51:2:51:30 | ... := ...[0] | test.go:52:16:52:37 | index expression | Cross-site scripting vulnerability due to $@. | test.go:51:2:51:30 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||||
| test.go:61:20:61:25 | buffer | test.go:57:2:57:46 | extract:0 ... := ... | test.go:61:20:61:25 | buffer | Cross-site scripting vulnerability due to $@. | test.go:57:2:57:46 | extract:0 ... := ... | user-provided value | test.go:0:0:0:0 | test.go | |
|
| test.go:61:20:61:25 | buffer | test.go:57:2:57:46 | ... := ...[0] | test.go:61:20:61:25 | buffer | Cross-site scripting vulnerability due to $@. | test.go:57:2:57:46 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||||
| test.go:67:16:67:41 | index expression | test.go:66:2:66:31 | extract:0 ... := ... | test.go:67:16:67:41 | index expression | Cross-site scripting vulnerability due to $@. | test.go:66:2:66:31 | extract:0 ... := ... | user-provided value | test.go:0:0:0:0 | test.go | |
|
| test.go:67:16:67:41 | index expression | test.go:66:2:66:31 | ... := ...[0] | test.go:67:16:67:41 | index expression | Cross-site scripting vulnerability due to $@. | test.go:66:2:66:31 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||||
| test.go:77:20:77:25 | buffer | test.go:72:2:72:31 | extract:0 ... := ... | test.go:77:20:77:25 | buffer | Cross-site scripting vulnerability due to $@. | test.go:72:2:72:31 | extract:0 ... := ... | user-provided value | test.go:0:0:0:0 | test.go | |
|
| test.go:77:20:77:25 | buffer | test.go:72:2:72:31 | ... := ...[0] | test.go:77:20:77:25 | buffer | Cross-site scripting vulnerability due to $@. | test.go:72:2:72:31 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||||
| test.go:83:16:83:24 | selection of Value | test.go:82:2:82:32 | extract:0 ... := ... | test.go:83:16:83:24 | selection of Value | Cross-site scripting vulnerability due to $@. | test.go:82:2:82:32 | extract:0 ... := ... | user-provided value | test.go:0:0:0:0 | test.go | |
|
| test.go:83:16:83:24 | selection of Value | test.go:82:2:82:32 | ... := ...[0] | test.go:83:16:83:24 | selection of Value | Cross-site scripting vulnerability due to $@. | test.go:82:2:82:32 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||||
| test.go:89:16:89:31 | selection of Value | test.go:88:13:88:25 | call to Cookies | test.go:89:16:89:31 | selection of Value | Cross-site scripting vulnerability due to $@. | test.go:88:13:88:25 | call to Cookies | user-provided value | test.go:0:0:0:0 | test.go | |
|
| test.go:89:16:89:31 | selection of Value | test.go:88:13:88:25 | call to Cookies | test.go:89:16:89:31 | selection of Value | Cross-site scripting vulnerability due to $@. | test.go:88:13:88:25 | call to Cookies | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||||
| test.go:100:16:100:21 | selection of s | test.go:99:11:99:15 | &... [postupdate] | test.go:100:16:100:21 | selection of s | Cross-site scripting vulnerability due to $@. | test.go:99:11:99:15 | &... [postupdate] | user-provided value | test.go:0:0:0:0 | test.go | |
|
| test.go:100:16:100:21 | selection of s | test.go:99:11:99:15 | &... [postupdate] | test.go:100:16:100:21 | selection of s | Cross-site scripting vulnerability due to $@. | test.go:99:11:99:15 | &... [postupdate] | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||||
| test.go:114:16:114:42 | type assertion | test.go:113:21:113:42 | call to Param | test.go:114:16:114:42 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:113:21:113:42 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | |
|
| test.go:114:16:114:42 | type assertion | test.go:113:21:113:42 | call to Param | test.go:114:16:114:42 | type assertion | Cross-site scripting vulnerability due to $@. | test.go:113:21:113:42 | call to Param | user-provided value | test.go:0:0:0:0 | test.go | |
|
||||||
@@ -25,23 +25,23 @@ edges
|
|||||||
| test.go:33:11:33:27 | call to QueryParams | test.go:34:16:34:20 | param | provenance | Src:MaD:11 |
|
| test.go:33:11:33:27 | call to QueryParams | test.go:34:16:34:20 | param | provenance | Src:MaD:11 |
|
||||||
| test.go:39:10:39:26 | call to QueryString | test.go:40:16:40:19 | qstr | provenance | Src:MaD:12 |
|
| test.go:39:10:39:26 | call to QueryString | test.go:40:16:40:19 | qstr | provenance | Src:MaD:12 |
|
||||||
| test.go:45:9:45:34 | call to FormValue | test.go:46:16:46:18 | val | provenance | Src:MaD:6 |
|
| test.go:45:9:45:34 | call to FormValue | test.go:46:16:46:18 | val | provenance | Src:MaD:6 |
|
||||||
| test.go:51:2:51:30 | extract:0 ... := ... | test.go:52:16:52:37 | index expression | provenance | Src:MaD:5 |
|
| test.go:51:2:51:30 | ... := ...[0] | test.go:52:16:52:37 | index expression | provenance | Src:MaD:5 |
|
||||||
| test.go:57:2:57:46 | extract:0 ... := ... | test.go:58:13:58:22 | fileHeader | provenance | Src:MaD:4 |
|
| test.go:57:2:57:46 | ... := ...[0] | test.go:58:13:58:22 | fileHeader | provenance | Src:MaD:4 |
|
||||||
| test.go:58:2:58:29 | extract:0 ... := ... | test.go:60:2:60:5 | file | provenance | |
|
| test.go:58:2:58:29 | ... := ...[0] | test.go:60:2:60:5 | file | provenance | |
|
||||||
| test.go:58:13:58:22 | fileHeader | test.go:58:2:58:29 | extract:0 ... := ... | provenance | MaD:17 |
|
| test.go:58:13:58:22 | fileHeader | test.go:58:2:58:29 | ... := ...[0] | provenance | MaD:17 |
|
||||||
| test.go:60:2:60:5 | file | test.go:60:12:60:17 | buffer [postupdate] | provenance | MaD:15 |
|
| test.go:60:2:60:5 | file | test.go:60:12:60:17 | buffer [postupdate] | provenance | MaD:15 |
|
||||||
| test.go:60:2:60:5 | file | test.go:60:12:60:17 | buffer [postupdate] | provenance | MaD:16 |
|
| test.go:60:2:60:5 | file | test.go:60:12:60:17 | buffer [postupdate] | provenance | MaD:16 |
|
||||||
| test.go:60:2:60:5 | file | test.go:60:12:60:17 | buffer [postupdate] | provenance | MaD:18 |
|
| test.go:60:2:60:5 | file | test.go:60:12:60:17 | buffer [postupdate] | provenance | MaD:18 |
|
||||||
| test.go:60:12:60:17 | buffer [postupdate] | test.go:61:20:61:25 | buffer | provenance | |
|
| test.go:60:12:60:17 | buffer [postupdate] | test.go:61:20:61:25 | buffer | provenance | |
|
||||||
| test.go:66:2:66:31 | extract:0 ... := ... | test.go:67:16:67:41 | index expression | provenance | Src:MaD:7 |
|
| test.go:66:2:66:31 | ... := ...[0] | test.go:67:16:67:41 | index expression | provenance | Src:MaD:7 |
|
||||||
| test.go:72:2:72:31 | extract:0 ... := ... | test.go:74:13:74:22 | fileHeader | provenance | Src:MaD:7 |
|
| test.go:72:2:72:31 | ... := ...[0] | test.go:74:13:74:22 | fileHeader | provenance | Src:MaD:7 |
|
||||||
| test.go:74:2:74:29 | extract:0 ... := ... | test.go:76:2:76:5 | file | provenance | |
|
| test.go:74:2:74:29 | ... := ...[0] | test.go:76:2:76:5 | file | provenance | |
|
||||||
| test.go:74:13:74:22 | fileHeader | test.go:74:2:74:29 | extract:0 ... := ... | provenance | MaD:17 |
|
| test.go:74:13:74:22 | fileHeader | test.go:74:2:74:29 | ... := ...[0] | provenance | MaD:17 |
|
||||||
| test.go:76:2:76:5 | file | test.go:76:12:76:17 | buffer [postupdate] | provenance | MaD:15 |
|
| test.go:76:2:76:5 | file | test.go:76:12:76:17 | buffer [postupdate] | provenance | MaD:15 |
|
||||||
| test.go:76:2:76:5 | file | test.go:76:12:76:17 | buffer [postupdate] | provenance | MaD:16 |
|
| test.go:76:2:76:5 | file | test.go:76:12:76:17 | buffer [postupdate] | provenance | MaD:16 |
|
||||||
| test.go:76:2:76:5 | file | test.go:76:12:76:17 | buffer [postupdate] | provenance | MaD:18 |
|
| test.go:76:2:76:5 | file | test.go:76:12:76:17 | buffer [postupdate] | provenance | MaD:18 |
|
||||||
| test.go:76:12:76:17 | buffer [postupdate] | test.go:77:20:77:25 | buffer | provenance | |
|
| test.go:76:12:76:17 | buffer [postupdate] | test.go:77:20:77:25 | buffer | provenance | |
|
||||||
| test.go:82:2:82:32 | extract:0 ... := ... | test.go:83:16:83:24 | selection of Value | provenance | Src:MaD:2 |
|
| test.go:82:2:82:32 | ... := ...[0] | test.go:83:16:83:24 | selection of Value | provenance | Src:MaD:2 |
|
||||||
| test.go:88:13:88:25 | call to Cookies | test.go:89:16:89:31 | selection of Value | provenance | Src:MaD:3 |
|
| test.go:88:13:88:25 | call to Cookies | test.go:89:16:89:31 | selection of Value | provenance | Src:MaD:3 |
|
||||||
| test.go:99:11:99:15 | &... [postupdate] | test.go:100:16:100:21 | selection of s | provenance | Src:MaD:1 |
|
| test.go:99:11:99:15 | &... [postupdate] | test.go:100:16:100:21 | selection of s | provenance | Src:MaD:1 |
|
||||||
| test.go:113:2:113:4 | ctx [postupdate] | test.go:114:16:114:18 | ctx | provenance | |
|
| test.go:113:2:113:4 | ctx [postupdate] | test.go:114:16:114:18 | ctx | provenance | |
|
||||||
@@ -88,23 +88,23 @@ nodes
|
|||||||
| test.go:40:16:40:19 | qstr | semmle.label | qstr |
|
| test.go:40:16:40:19 | qstr | semmle.label | qstr |
|
||||||
| test.go:45:9:45:34 | call to FormValue | semmle.label | call to FormValue |
|
| test.go:45:9:45:34 | call to FormValue | semmle.label | call to FormValue |
|
||||||
| test.go:46:16:46:18 | val | semmle.label | val |
|
| test.go:46:16:46:18 | val | semmle.label | val |
|
||||||
| test.go:51:2:51:30 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| test.go:51:2:51:30 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| test.go:52:16:52:37 | index expression | semmle.label | index expression |
|
| test.go:52:16:52:37 | index expression | semmle.label | index expression |
|
||||||
| test.go:57:2:57:46 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| test.go:57:2:57:46 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| test.go:58:2:58:29 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| test.go:58:2:58:29 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| test.go:58:13:58:22 | fileHeader | semmle.label | fileHeader |
|
| test.go:58:13:58:22 | fileHeader | semmle.label | fileHeader |
|
||||||
| test.go:60:2:60:5 | file | semmle.label | file |
|
| test.go:60:2:60:5 | file | semmle.label | file |
|
||||||
| test.go:60:12:60:17 | buffer [postupdate] | semmle.label | buffer [postupdate] |
|
| test.go:60:12:60:17 | buffer [postupdate] | semmle.label | buffer [postupdate] |
|
||||||
| test.go:61:20:61:25 | buffer | semmle.label | buffer |
|
| test.go:61:20:61:25 | buffer | semmle.label | buffer |
|
||||||
| test.go:66:2:66:31 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| test.go:66:2:66:31 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| test.go:67:16:67:41 | index expression | semmle.label | index expression |
|
| test.go:67:16:67:41 | index expression | semmle.label | index expression |
|
||||||
| test.go:72:2:72:31 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| test.go:72:2:72:31 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| test.go:74:2:74:29 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| test.go:74:2:74:29 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| test.go:74:13:74:22 | fileHeader | semmle.label | fileHeader |
|
| test.go:74:13:74:22 | fileHeader | semmle.label | fileHeader |
|
||||||
| test.go:76:2:76:5 | file | semmle.label | file |
|
| test.go:76:2:76:5 | file | semmle.label | file |
|
||||||
| test.go:76:12:76:17 | buffer [postupdate] | semmle.label | buffer [postupdate] |
|
| test.go:76:12:76:17 | buffer [postupdate] | semmle.label | buffer [postupdate] |
|
||||||
| test.go:77:20:77:25 | buffer | semmle.label | buffer |
|
| test.go:77:20:77:25 | buffer | semmle.label | buffer |
|
||||||
| test.go:82:2:82:32 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| test.go:82:2:82:32 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| test.go:83:16:83:24 | selection of Value | semmle.label | selection of Value |
|
| test.go:83:16:83:24 | selection of Value | semmle.label | selection of Value |
|
||||||
| test.go:88:13:88:25 | call to Cookies | semmle.label | call to Cookies |
|
| test.go:88:13:88:25 | call to Cookies | semmle.label | call to Cookies |
|
||||||
| test.go:89:16:89:31 | selection of Value | semmle.label | selection of Value |
|
| test.go:89:16:89:31 | selection of Value | semmle.label | selection of Value |
|
||||||
|
|||||||
@@ -7,18 +7,18 @@
|
|||||||
| Gin.go:58:10:58:25 | call to Param |
|
| Gin.go:58:10:58:25 | call to Param |
|
||||||
| Gin.go:62:10:62:34 | call to GetStringSlice |
|
| Gin.go:62:10:62:34 | call to GetStringSlice |
|
||||||
| Gin.go:66:10:66:29 | call to GetString |
|
| Gin.go:66:10:66:29 | call to GetString |
|
||||||
| Gin.go:70:3:70:28 | extract:0 ... := ... |
|
| Gin.go:70:3:70:28 | ... := ...[0] |
|
||||||
| Gin.go:74:10:74:23 | call to ClientIP |
|
| Gin.go:74:10:74:23 | call to ClientIP |
|
||||||
| Gin.go:78:10:78:26 | call to ContentType |
|
| Gin.go:78:10:78:26 | call to ContentType |
|
||||||
| Gin.go:82:3:82:29 | extract:0 ... := ... |
|
| Gin.go:82:3:82:29 | ... := ...[0] |
|
||||||
| Gin.go:86:3:86:36 | extract:0 ... := ... |
|
| Gin.go:86:3:86:36 | ... := ...[0] |
|
||||||
| Gin.go:90:3:90:31 | extract:0 ... := ... |
|
| Gin.go:90:3:90:31 | ... := ...[0] |
|
||||||
| Gin.go:94:3:94:39 | extract:0 ... := ... |
|
| Gin.go:94:3:94:39 | ... := ...[0] |
|
||||||
| Gin.go:98:3:98:34 | extract:0 ... := ... |
|
| Gin.go:98:3:98:34 | ... := ...[0] |
|
||||||
| Gin.go:102:10:102:52 | call to DefaultPostForm |
|
| Gin.go:102:10:102:52 | call to DefaultPostForm |
|
||||||
| Gin.go:106:10:106:49 | call to DefaultQuery |
|
| Gin.go:106:10:106:49 | call to DefaultQuery |
|
||||||
| Gin.go:110:3:110:37 | extract:0 ... := ... |
|
| Gin.go:110:3:110:37 | ... := ...[0] |
|
||||||
| Gin.go:114:3:114:34 | extract:0 ... := ... |
|
| Gin.go:114:3:114:34 | ... := ...[0] |
|
||||||
| Gin.go:118:10:118:32 | call to GetStringMap |
|
| Gin.go:118:10:118:32 | call to GetStringMap |
|
||||||
| Gin.go:122:10:122:38 | call to GetStringMapString |
|
| Gin.go:122:10:122:38 | call to GetStringMapString |
|
||||||
| Gin.go:126:10:126:43 | call to GetStringMapStringSlice |
|
| Gin.go:126:10:126:43 | call to GetStringMapStringSlice |
|
||||||
|
|||||||
@@ -6,18 +6,18 @@ models
|
|||||||
| 5 | Source: github.com/emicklei/go-restful; Request; true; ReadEntity; ; ; Argument[0]; remote; manual |
|
| 5 | Source: github.com/emicklei/go-restful; Request; true; ReadEntity; ; ; Argument[0]; remote; manual |
|
||||||
edges
|
edges
|
||||||
| gorestful.go:15:15:15:44 | call to QueryParameters | gorestful.go:15:15:15:47 | index expression | provenance | Src:MaD:4 Sink:MaD:1 |
|
| gorestful.go:15:15:15:44 | call to QueryParameters | gorestful.go:15:15:15:47 | index expression | provenance | Src:MaD:4 Sink:MaD:1 |
|
||||||
| gorestful.go:17:2:17:39 | extract:0 ... := ... | gorestful.go:18:15:18:17 | val | provenance | Src:MaD:2 Sink:MaD:1 |
|
| gorestful.go:17:2:17:39 | ... := ...[0] | gorestful.go:18:15:18:17 | val | provenance | Src:MaD:2 Sink:MaD:1 |
|
||||||
| gorestful.go:21:15:21:38 | call to PathParameters | gorestful.go:21:15:21:45 | index expression | provenance | Src:MaD:3 Sink:MaD:1 |
|
| gorestful.go:21:15:21:38 | call to PathParameters | gorestful.go:21:15:21:45 | index expression | provenance | Src:MaD:3 Sink:MaD:1 |
|
||||||
| gorestful.go:23:21:23:24 | &... [postupdate] | gorestful.go:24:15:24:21 | selection of cmd | provenance | Src:MaD:5 Sink:MaD:1 |
|
| gorestful.go:23:21:23:24 | &... [postupdate] | gorestful.go:24:15:24:21 | selection of cmd | provenance | Src:MaD:5 Sink:MaD:1 |
|
||||||
| gorestful_v2.go:15:15:15:44 | call to QueryParameters | gorestful_v2.go:15:15:15:47 | index expression | provenance | Src:MaD:4 Sink:MaD:1 |
|
| gorestful_v2.go:15:15:15:44 | call to QueryParameters | gorestful_v2.go:15:15:15:47 | index expression | provenance | Src:MaD:4 Sink:MaD:1 |
|
||||||
| gorestful_v2.go:17:2:17:39 | extract:0 ... := ... | gorestful_v2.go:18:15:18:17 | val | provenance | Src:MaD:2 Sink:MaD:1 |
|
| gorestful_v2.go:17:2:17:39 | ... := ...[0] | gorestful_v2.go:18:15:18:17 | val | provenance | Src:MaD:2 Sink:MaD:1 |
|
||||||
| gorestful_v2.go:21:15:21:38 | call to PathParameters | gorestful_v2.go:21:15:21:45 | index expression | provenance | Src:MaD:3 Sink:MaD:1 |
|
| gorestful_v2.go:21:15:21:38 | call to PathParameters | gorestful_v2.go:21:15:21:45 | index expression | provenance | Src:MaD:3 Sink:MaD:1 |
|
||||||
| gorestful_v2.go:23:21:23:24 | &... [postupdate] | gorestful_v2.go:24:15:24:21 | selection of cmd | provenance | Src:MaD:5 Sink:MaD:1 |
|
| gorestful_v2.go:23:21:23:24 | &... [postupdate] | gorestful_v2.go:24:15:24:21 | selection of cmd | provenance | Src:MaD:5 Sink:MaD:1 |
|
||||||
nodes
|
nodes
|
||||||
| gorestful.go:15:15:15:44 | call to QueryParameters | semmle.label | call to QueryParameters |
|
| gorestful.go:15:15:15:44 | call to QueryParameters | semmle.label | call to QueryParameters |
|
||||||
| gorestful.go:15:15:15:47 | index expression | semmle.label | index expression |
|
| gorestful.go:15:15:15:47 | index expression | semmle.label | index expression |
|
||||||
| gorestful.go:16:15:16:43 | call to QueryParameter | semmle.label | call to QueryParameter |
|
| gorestful.go:16:15:16:43 | call to QueryParameter | semmle.label | call to QueryParameter |
|
||||||
| gorestful.go:17:2:17:39 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| gorestful.go:17:2:17:39 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| gorestful.go:18:15:18:17 | val | semmle.label | val |
|
| gorestful.go:18:15:18:17 | val | semmle.label | val |
|
||||||
| gorestful.go:19:15:19:44 | call to HeaderParameter | semmle.label | call to HeaderParameter |
|
| gorestful.go:19:15:19:44 | call to HeaderParameter | semmle.label | call to HeaderParameter |
|
||||||
| gorestful.go:20:15:20:42 | call to PathParameter | semmle.label | call to PathParameter |
|
| gorestful.go:20:15:20:42 | call to PathParameter | semmle.label | call to PathParameter |
|
||||||
@@ -28,7 +28,7 @@ nodes
|
|||||||
| gorestful_v2.go:15:15:15:44 | call to QueryParameters | semmle.label | call to QueryParameters |
|
| gorestful_v2.go:15:15:15:44 | call to QueryParameters | semmle.label | call to QueryParameters |
|
||||||
| gorestful_v2.go:15:15:15:47 | index expression | semmle.label | index expression |
|
| gorestful_v2.go:15:15:15:47 | index expression | semmle.label | index expression |
|
||||||
| gorestful_v2.go:16:15:16:43 | call to QueryParameter | semmle.label | call to QueryParameter |
|
| gorestful_v2.go:16:15:16:43 | call to QueryParameter | semmle.label | call to QueryParameter |
|
||||||
| gorestful_v2.go:17:2:17:39 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| gorestful_v2.go:17:2:17:39 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| gorestful_v2.go:18:15:18:17 | val | semmle.label | val |
|
| gorestful_v2.go:18:15:18:17 | val | semmle.label | val |
|
||||||
| gorestful_v2.go:19:15:19:44 | call to HeaderParameter | semmle.label | call to HeaderParameter |
|
| gorestful_v2.go:19:15:19:44 | call to HeaderParameter | semmle.label | call to HeaderParameter |
|
||||||
| gorestful_v2.go:20:15:20:42 | call to PathParameter | semmle.label | call to PathParameter |
|
| gorestful_v2.go:20:15:20:42 | call to PathParameter | semmle.label | call to PathParameter |
|
||||||
@@ -41,14 +41,14 @@ invalidModelRow
|
|||||||
#select
|
#select
|
||||||
| gorestful.go:15:15:15:47 | index expression | gorestful.go:15:15:15:44 | call to QueryParameters | gorestful.go:15:15:15:47 | index expression | This command depends on $@. | gorestful.go:15:15:15:44 | call to QueryParameters | a user-provided value |
|
| gorestful.go:15:15:15:47 | index expression | gorestful.go:15:15:15:44 | call to QueryParameters | gorestful.go:15:15:15:47 | index expression | This command depends on $@. | gorestful.go:15:15:15:44 | call to QueryParameters | a user-provided value |
|
||||||
| gorestful.go:16:15:16:43 | call to QueryParameter | gorestful.go:16:15:16:43 | call to QueryParameter | gorestful.go:16:15:16:43 | call to QueryParameter | This command depends on $@. | gorestful.go:16:15:16:43 | call to QueryParameter | a user-provided value |
|
| gorestful.go:16:15:16:43 | call to QueryParameter | gorestful.go:16:15:16:43 | call to QueryParameter | gorestful.go:16:15:16:43 | call to QueryParameter | This command depends on $@. | gorestful.go:16:15:16:43 | call to QueryParameter | a user-provided value |
|
||||||
| gorestful.go:18:15:18:17 | val | gorestful.go:17:2:17:39 | extract:0 ... := ... | gorestful.go:18:15:18:17 | val | This command depends on $@. | gorestful.go:17:2:17:39 | extract:0 ... := ... | a user-provided value |
|
| gorestful.go:18:15:18:17 | val | gorestful.go:17:2:17:39 | ... := ...[0] | gorestful.go:18:15:18:17 | val | This command depends on $@. | gorestful.go:17:2:17:39 | ... := ...[0] | a user-provided value |
|
||||||
| gorestful.go:19:15:19:44 | call to HeaderParameter | gorestful.go:19:15:19:44 | call to HeaderParameter | gorestful.go:19:15:19:44 | call to HeaderParameter | This command depends on $@. | gorestful.go:19:15:19:44 | call to HeaderParameter | a user-provided value |
|
| gorestful.go:19:15:19:44 | call to HeaderParameter | gorestful.go:19:15:19:44 | call to HeaderParameter | gorestful.go:19:15:19:44 | call to HeaderParameter | This command depends on $@. | gorestful.go:19:15:19:44 | call to HeaderParameter | a user-provided value |
|
||||||
| gorestful.go:20:15:20:42 | call to PathParameter | gorestful.go:20:15:20:42 | call to PathParameter | gorestful.go:20:15:20:42 | call to PathParameter | This command depends on $@. | gorestful.go:20:15:20:42 | call to PathParameter | a user-provided value |
|
| gorestful.go:20:15:20:42 | call to PathParameter | gorestful.go:20:15:20:42 | call to PathParameter | gorestful.go:20:15:20:42 | call to PathParameter | This command depends on $@. | gorestful.go:20:15:20:42 | call to PathParameter | a user-provided value |
|
||||||
| gorestful.go:21:15:21:45 | index expression | gorestful.go:21:15:21:38 | call to PathParameters | gorestful.go:21:15:21:45 | index expression | This command depends on $@. | gorestful.go:21:15:21:38 | call to PathParameters | a user-provided value |
|
| gorestful.go:21:15:21:45 | index expression | gorestful.go:21:15:21:38 | call to PathParameters | gorestful.go:21:15:21:45 | index expression | This command depends on $@. | gorestful.go:21:15:21:38 | call to PathParameters | a user-provided value |
|
||||||
| gorestful.go:24:15:24:21 | selection of cmd | gorestful.go:23:21:23:24 | &... [postupdate] | gorestful.go:24:15:24:21 | selection of cmd | This command depends on $@. | gorestful.go:23:21:23:24 | &... [postupdate] | a user-provided value |
|
| gorestful.go:24:15:24:21 | selection of cmd | gorestful.go:23:21:23:24 | &... [postupdate] | gorestful.go:24:15:24:21 | selection of cmd | This command depends on $@. | gorestful.go:23:21:23:24 | &... [postupdate] | a user-provided value |
|
||||||
| gorestful_v2.go:15:15:15:47 | index expression | gorestful_v2.go:15:15:15:44 | call to QueryParameters | gorestful_v2.go:15:15:15:47 | index expression | This command depends on $@. | gorestful_v2.go:15:15:15:44 | call to QueryParameters | a user-provided value |
|
| gorestful_v2.go:15:15:15:47 | index expression | gorestful_v2.go:15:15:15:44 | call to QueryParameters | gorestful_v2.go:15:15:15:47 | index expression | This command depends on $@. | gorestful_v2.go:15:15:15:44 | call to QueryParameters | a user-provided value |
|
||||||
| gorestful_v2.go:16:15:16:43 | call to QueryParameter | gorestful_v2.go:16:15:16:43 | call to QueryParameter | gorestful_v2.go:16:15:16:43 | call to QueryParameter | This command depends on $@. | gorestful_v2.go:16:15:16:43 | call to QueryParameter | a user-provided value |
|
| gorestful_v2.go:16:15:16:43 | call to QueryParameter | gorestful_v2.go:16:15:16:43 | call to QueryParameter | gorestful_v2.go:16:15:16:43 | call to QueryParameter | This command depends on $@. | gorestful_v2.go:16:15:16:43 | call to QueryParameter | a user-provided value |
|
||||||
| gorestful_v2.go:18:15:18:17 | val | gorestful_v2.go:17:2:17:39 | extract:0 ... := ... | gorestful_v2.go:18:15:18:17 | val | This command depends on $@. | gorestful_v2.go:17:2:17:39 | extract:0 ... := ... | a user-provided value |
|
| gorestful_v2.go:18:15:18:17 | val | gorestful_v2.go:17:2:17:39 | ... := ...[0] | gorestful_v2.go:18:15:18:17 | val | This command depends on $@. | gorestful_v2.go:17:2:17:39 | ... := ...[0] | a user-provided value |
|
||||||
| gorestful_v2.go:19:15:19:44 | call to HeaderParameter | gorestful_v2.go:19:15:19:44 | call to HeaderParameter | gorestful_v2.go:19:15:19:44 | call to HeaderParameter | This command depends on $@. | gorestful_v2.go:19:15:19:44 | call to HeaderParameter | a user-provided value |
|
| gorestful_v2.go:19:15:19:44 | call to HeaderParameter | gorestful_v2.go:19:15:19:44 | call to HeaderParameter | gorestful_v2.go:19:15:19:44 | call to HeaderParameter | This command depends on $@. | gorestful_v2.go:19:15:19:44 | call to HeaderParameter | a user-provided value |
|
||||||
| gorestful_v2.go:20:15:20:42 | call to PathParameter | gorestful_v2.go:20:15:20:42 | call to PathParameter | gorestful_v2.go:20:15:20:42 | call to PathParameter | This command depends on $@. | gorestful_v2.go:20:15:20:42 | call to PathParameter | a user-provided value |
|
| gorestful_v2.go:20:15:20:42 | call to PathParameter | gorestful_v2.go:20:15:20:42 | call to PathParameter | gorestful_v2.go:20:15:20:42 | call to PathParameter | This command depends on $@. | gorestful_v2.go:20:15:20:42 | call to PathParameter | a user-provided value |
|
||||||
| gorestful_v2.go:21:15:21:45 | index expression | gorestful_v2.go:21:15:21:38 | call to PathParameters | gorestful_v2.go:21:15:21:45 | index expression | This command depends on $@. | gorestful_v2.go:21:15:21:38 | call to PathParameters | a user-provided value |
|
| gorestful_v2.go:21:15:21:45 | index expression | gorestful_v2.go:21:15:21:38 | call to PathParameters | gorestful_v2.go:21:15:21:45 | index expression | This command depends on $@. | gorestful_v2.go:21:15:21:38 | call to PathParameters | a user-provided value |
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
#select
|
#select
|
||||||
| EndToEnd.go:95:20:95:49 | call to Get | EndToEnd.go:95:20:95:27 | selection of Params | EndToEnd.go:95:20:95:49 | call to Get | This path to an untrusted URL redirection depends on a $@. | EndToEnd.go:95:20:95:27 | selection of Params | user-provided value |
|
| EndToEnd.go:95:20:95:49 | call to Get | EndToEnd.go:95:20:95:27 | selection of Params | EndToEnd.go:95:20:95:49 | call to Get | This path to an untrusted URL redirection depends on a $@. | EndToEnd.go:95:20:95:27 | selection of Params | user-provided value |
|
||||||
edges
|
edges
|
||||||
| EndToEnd.go:95:20:95:27 | implicit-deref selection of Params | EndToEnd.go:95:20:95:27 | selection of Params [postupdate] | provenance | Config |
|
| EndToEnd.go:95:20:95:27 | implicit dereference | EndToEnd.go:95:20:95:27 | selection of Params [postupdate] | provenance | Config |
|
||||||
| EndToEnd.go:95:20:95:27 | implicit-deref selection of Params | EndToEnd.go:95:20:95:32 | selection of Form | provenance | Config |
|
| EndToEnd.go:95:20:95:27 | implicit dereference | EndToEnd.go:95:20:95:32 | selection of Form | provenance | Config |
|
||||||
| EndToEnd.go:95:20:95:27 | selection of Params | EndToEnd.go:95:20:95:27 | implicit-deref selection of Params | provenance | Src:MaD:2 Config |
|
| EndToEnd.go:95:20:95:27 | selection of Params | EndToEnd.go:95:20:95:27 | implicit dereference | provenance | Src:MaD:2 Config |
|
||||||
| EndToEnd.go:95:20:95:27 | selection of Params | EndToEnd.go:95:20:95:32 | selection of Form | provenance | Src:MaD:2 Config |
|
| EndToEnd.go:95:20:95:27 | selection of Params | EndToEnd.go:95:20:95:32 | selection of Form | provenance | Src:MaD:2 Config |
|
||||||
| EndToEnd.go:95:20:95:27 | selection of Params [postupdate] | EndToEnd.go:95:20:95:27 | implicit-deref selection of Params | provenance | Config |
|
| EndToEnd.go:95:20:95:27 | selection of Params [postupdate] | EndToEnd.go:95:20:95:27 | implicit dereference | provenance | Config |
|
||||||
| EndToEnd.go:95:20:95:32 | selection of Form | EndToEnd.go:95:20:95:49 | call to Get | provenance | Config Sink:MaD:1 |
|
| EndToEnd.go:95:20:95:32 | selection of Form | EndToEnd.go:95:20:95:49 | call to Get | provenance | Config Sink:MaD:1 |
|
||||||
models
|
models
|
||||||
| 1 | Sink: group:revel; Controller; true; Redirect; ; ; Argument[0]; url-redirection; manual |
|
| 1 | Sink: group:revel; Controller; true; Redirect; ; ; Argument[0]; url-redirection; manual |
|
||||||
| 2 | Source: group:revel; Controller; true; Params; ; ; ; remote; manual |
|
| 2 | Source: group:revel; Controller; true; Params; ; ; ; remote; manual |
|
||||||
nodes
|
nodes
|
||||||
| EndToEnd.go:95:20:95:27 | implicit-deref selection of Params | semmle.label | implicit-deref selection of Params |
|
| EndToEnd.go:95:20:95:27 | implicit dereference | semmle.label | implicit dereference |
|
||||||
| EndToEnd.go:95:20:95:27 | selection of Params | semmle.label | selection of Params |
|
| EndToEnd.go:95:20:95:27 | selection of Params | semmle.label | selection of Params |
|
||||||
| EndToEnd.go:95:20:95:27 | selection of Params [postupdate] | semmle.label | selection of Params [postupdate] |
|
| EndToEnd.go:95:20:95:27 | selection of Params [postupdate] | semmle.label | selection of Params [postupdate] |
|
||||||
| EndToEnd.go:95:20:95:32 | selection of Form | semmle.label | selection of Form |
|
| EndToEnd.go:95:20:95:32 | selection of Form | semmle.label | selection of Form |
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
invalidModelRow
|
invalidModelRow
|
||||||
#select
|
#select
|
||||||
| crypto.go:9:14:9:31 | call to NewCipher | crypto.go:9:2:9:31 | extract:0 ... := ... |
|
| crypto.go:9:14:9:31 | call to NewCipher | crypto.go:9:2:9:31 | ... := ...[0] |
|
||||||
| crypto.go:9:14:9:31 | call to NewCipher | crypto.go:9:2:9:31 | extract:1 ... := ... |
|
| crypto.go:9:14:9:31 | call to NewCipher | crypto.go:9:2:9:31 | ... := ...[1] |
|
||||||
| crypto.go:10:15:10:34 | call to NewGCM | crypto.go:10:2:10:34 | extract:0 ... := ... |
|
| crypto.go:10:15:10:34 | call to NewGCM | crypto.go:10:2:10:34 | ... := ...[0] |
|
||||||
| crypto.go:10:15:10:34 | call to NewGCM | crypto.go:10:2:10:34 | extract:1 ... := ... |
|
| crypto.go:10:15:10:34 | call to NewGCM | crypto.go:10:2:10:34 | ... := ...[1] |
|
||||||
| crypto.go:11:18:11:57 | call to Open | crypto.go:11:2:11:57 | extract:0 ... := ... |
|
| crypto.go:11:18:11:57 | call to Open | crypto.go:11:2:11:57 | ... := ...[0] |
|
||||||
| crypto.go:11:18:11:57 | call to Open | crypto.go:11:2:11:57 | extract:1 ... := ... |
|
| crypto.go:11:18:11:57 | call to Open | crypto.go:11:2:11:57 | ... := ...[1] |
|
||||||
| crypto.go:11:42:11:51 | ciphertext | crypto.go:11:2:11:57 | extract:0 ... := ... |
|
| crypto.go:11:42:11:51 | ciphertext | crypto.go:11:2:11:57 | ... := ...[0] |
|
||||||
| io.go:14:31:14:43 | "some string" | io.go:14:13:14:44 | call to NewReader |
|
| io.go:14:31:14:43 | "some string" | io.go:14:13:14:44 | call to NewReader |
|
||||||
| io.go:16:23:16:27 | &... | io.go:16:24:16:27 | buf1 [postupdate] |
|
| io.go:16:23:16:27 | &... | io.go:16:24:16:27 | buf1 [postupdate] |
|
||||||
| io.go:16:23:16:27 | &... [postupdate] | io.go:16:24:16:27 | buf1 [postupdate] |
|
| io.go:16:23:16:27 | &... [postupdate] | io.go:16:24:16:27 | buf1 [postupdate] |
|
||||||
@@ -31,9 +31,9 @@ invalidModelRow
|
|||||||
| io.go:33:20:33:23 | buf1 | io.go:33:19:33:23 | &... |
|
| io.go:33:20:33:23 | buf1 | io.go:33:19:33:23 | &... |
|
||||||
| io.go:33:20:33:23 | buf1 [postupdate] | io.go:33:19:33:23 | &... |
|
| io.go:33:20:33:23 | buf1 [postupdate] | io.go:33:19:33:23 | &... |
|
||||||
| io.go:35:16:35:21 | reader | io.go:35:12:35:13 | w2 [postupdate] |
|
| io.go:35:16:35:21 | reader | io.go:35:12:35:13 | w2 [postupdate] |
|
||||||
| io.go:39:11:39:19 | call to Pipe | io.go:39:3:39:19 | extract:0 ... := ... |
|
| io.go:39:11:39:19 | call to Pipe | io.go:39:3:39:19 | ... := ...[0] |
|
||||||
| io.go:39:11:39:19 | call to Pipe | io.go:39:3:39:19 | extract:1 ... := ... |
|
| io.go:39:11:39:19 | call to Pipe | io.go:39:3:39:19 | ... := ...[1] |
|
||||||
| io.go:40:14:40:14 | w [postupdate] | io.go:39:3:39:19 | extract:0 ... := ... |
|
| io.go:40:14:40:14 | w [postupdate] | io.go:39:3:39:19 | ... := ...[0] |
|
||||||
| io.go:40:17:40:31 | "some string\\n" | io.go:40:14:40:14 | w [postupdate] |
|
| io.go:40:17:40:31 | "some string\\n" | io.go:40:14:40:14 | w [postupdate] |
|
||||||
| io.go:43:16:43:16 | r | io.go:43:3:43:5 | buf [postupdate] |
|
| io.go:43:16:43:16 | r | io.go:43:3:43:5 | buf [postupdate] |
|
||||||
| io.go:44:13:44:15 | buf | io.go:44:13:44:24 | call to String |
|
| io.go:44:13:44:15 | buf | io.go:44:13:44:24 | call to String |
|
||||||
@@ -74,35 +74,35 @@ invalidModelRow
|
|||||||
| io.go:101:26:101:38 | "some string" | io.go:101:8:101:39 | call to NewReader |
|
| io.go:101:26:101:38 | "some string" | io.go:101:8:101:39 | call to NewReader |
|
||||||
| io.go:102:3:102:3 | r | io.go:102:13:102:21 | selection of Stdout [postupdate] |
|
| io.go:102:3:102:3 | r | io.go:102:13:102:21 | selection of Stdout [postupdate] |
|
||||||
| io.go:108:30:108:42 | "some string" | io.go:108:12:108:43 | call to NewReader |
|
| io.go:108:30:108:42 | "some string" | io.go:108:12:108:43 | call to NewReader |
|
||||||
| io.go:109:12:109:33 | call to ReadAll | io.go:109:2:109:33 | extract:0 ... := ... |
|
| io.go:109:12:109:33 | call to ReadAll | io.go:109:2:109:33 | ... := ...[0] |
|
||||||
| io.go:109:12:109:33 | call to ReadAll | io.go:109:2:109:33 | extract:1 ... := ... |
|
| io.go:109:12:109:33 | call to ReadAll | io.go:109:2:109:33 | ... := ...[1] |
|
||||||
| io.go:109:27:109:32 | reader | io.go:109:2:109:33 | extract:0 ... := ... |
|
| io.go:109:27:109:32 | reader | io.go:109:2:109:33 | ... := ...[0] |
|
||||||
| io.go:110:18:110:20 | buf | io.go:110:2:110:10 | selection of Stdout [postupdate] |
|
| io.go:110:18:110:20 | buf | io.go:110:2:110:10 | selection of Stdout [postupdate] |
|
||||||
| main.go:11:12:11:26 | call to Marshal | main.go:11:2:11:26 | extract:0 ... := ... |
|
| main.go:11:12:11:26 | call to Marshal | main.go:11:2:11:26 | ... := ...[0] |
|
||||||
| main.go:11:12:11:26 | call to Marshal | main.go:11:2:11:26 | extract:1 ... := ... |
|
| main.go:11:12:11:26 | call to Marshal | main.go:11:2:11:26 | ... := ...[1] |
|
||||||
| main.go:11:25:11:25 | v | main.go:11:2:11:26 | extract:0 ... := ... |
|
| main.go:11:25:11:25 | v | main.go:11:2:11:26 | ... := ...[0] |
|
||||||
| main.go:13:14:13:52 | call to MarshalIndent | main.go:13:2:13:52 | extract:0 ... := ... |
|
| main.go:13:14:13:52 | call to MarshalIndent | main.go:13:2:13:52 | ... := ...[0] |
|
||||||
| main.go:13:14:13:52 | call to MarshalIndent | main.go:13:2:13:52 | extract:1 ... := ... |
|
| main.go:13:14:13:52 | call to MarshalIndent | main.go:13:2:13:52 | ... := ...[1] |
|
||||||
| main.go:13:33:13:33 | v | main.go:13:2:13:52 | extract:0 ... := ... |
|
| main.go:13:33:13:33 | v | main.go:13:2:13:52 | ... := ...[0] |
|
||||||
| main.go:13:36:13:45 | "/*JSON*/" | main.go:13:2:13:52 | extract:0 ... := ... |
|
| main.go:13:36:13:45 | "/*JSON*/" | main.go:13:2:13:52 | ... := ...[0] |
|
||||||
| main.go:13:48:13:51 | " " | main.go:13:2:13:52 | extract:0 ... := ... |
|
| main.go:13:48:13:51 | " " | main.go:13:2:13:52 | ... := ...[0] |
|
||||||
| main.go:14:25:14:25 | b | main.go:14:9:14:41 | slice literal |
|
| main.go:14:25:14:25 | b | main.go:14:9:14:41 | slice literal |
|
||||||
| main.go:14:28:14:30 | err | main.go:14:9:14:41 | slice literal |
|
| main.go:14:28:14:30 | err | main.go:14:9:14:41 | slice literal |
|
||||||
| main.go:14:33:14:34 | b2 | main.go:14:9:14:41 | slice literal |
|
| main.go:14:33:14:34 | b2 | main.go:14:9:14:41 | slice literal |
|
||||||
| main.go:14:37:14:40 | err2 | main.go:14:9:14:41 | slice literal |
|
| main.go:14:37:14:40 | err2 | main.go:14:9:14:41 | slice literal |
|
||||||
| main.go:19:18:19:42 | call to DecodeString | main.go:19:2:19:42 | extract:0 ... := ... |
|
| main.go:19:18:19:42 | call to DecodeString | main.go:19:2:19:42 | ... := ...[0] |
|
||||||
| main.go:19:18:19:42 | call to DecodeString | main.go:19:2:19:42 | extract:1 ... := ... |
|
| main.go:19:18:19:42 | call to DecodeString | main.go:19:2:19:42 | ... := ...[1] |
|
||||||
| main.go:19:35:19:41 | encoded | main.go:19:2:19:42 | extract:0 ... := ... |
|
| main.go:19:35:19:41 | encoded | main.go:19:2:19:42 | ... := ...[0] |
|
||||||
| main.go:23:25:23:31 | decoded | main.go:23:9:23:48 | slice literal |
|
| main.go:23:25:23:31 | decoded | main.go:23:9:23:48 | slice literal |
|
||||||
| main.go:23:34:23:36 | err | main.go:23:9:23:48 | slice literal |
|
| main.go:23:34:23:36 | err | main.go:23:9:23:48 | slice literal |
|
||||||
| main.go:23:39:23:47 | reEncoded | main.go:23:9:23:48 | slice literal |
|
| main.go:23:39:23:47 | reEncoded | main.go:23:9:23:48 | slice literal |
|
||||||
| main.go:28:2:28:4 | implicit-deref req | main.go:28:2:28:4 | req [postupdate] |
|
| main.go:28:2:28:4 | implicit dereference | main.go:28:2:28:4 | req [postupdate] |
|
||||||
| main.go:28:2:28:4 | implicit-deref req | main.go:28:2:28:9 | selection of Body |
|
| main.go:28:2:28:4 | implicit dereference | main.go:28:2:28:9 | selection of Body |
|
||||||
| main.go:28:2:28:4 | req | main.go:28:2:28:4 | implicit-deref req |
|
| main.go:28:2:28:4 | req | main.go:28:2:28:4 | implicit dereference |
|
||||||
| main.go:28:2:28:4 | req [postupdate] | main.go:28:2:28:4 | implicit-deref req |
|
| main.go:28:2:28:4 | req [postupdate] | main.go:28:2:28:4 | implicit dereference |
|
||||||
| main.go:28:2:28:9 | selection of Body | main.go:28:16:28:16 | b [postupdate] |
|
| main.go:28:2:28:9 | selection of Body | main.go:28:16:28:16 | b [postupdate] |
|
||||||
| main.go:34:2:34:4 | implicit-deref req | main.go:34:2:34:4 | req [postupdate] |
|
| main.go:34:2:34:4 | implicit dereference | main.go:34:2:34:4 | req [postupdate] |
|
||||||
| main.go:34:2:34:4 | implicit-deref req | main.go:34:2:34:9 | selection of Body |
|
| main.go:34:2:34:4 | implicit dereference | main.go:34:2:34:9 | selection of Body |
|
||||||
| main.go:34:2:34:4 | req | main.go:34:2:34:4 | implicit-deref req |
|
| main.go:34:2:34:4 | req | main.go:34:2:34:4 | implicit dereference |
|
||||||
| main.go:34:2:34:4 | req [postupdate] | main.go:34:2:34:4 | implicit-deref req |
|
| main.go:34:2:34:4 | req [postupdate] | main.go:34:2:34:4 | implicit dereference |
|
||||||
| main.go:34:2:34:9 | selection of Body | main.go:34:16:34:16 | b [postupdate] |
|
| main.go:34:2:34:9 | selection of Body | main.go:34:16:34:16 | b [postupdate] |
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
#select
|
#select
|
||||||
| server/main.go:30:38:30:48 | selection of Text | rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | server/main.go:30:38:30:48 | selection of Text | The $@ of this request depends on a $@. | server/main.go:30:38:30:48 | selection of Text | URL | rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | user-provided value |
|
| server/main.go:30:38:30:48 | selection of Text | rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | server/main.go:30:38:30:48 | selection of Text | The $@ of this request depends on a $@. | server/main.go:30:38:30:48 | selection of Text | URL | rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | user-provided value |
|
||||||
| server/main.go:30:38:30:48 | selection of Text | server/main.go:19:109:38:1 | SSA def(params) | server/main.go:30:38:30:48 | selection of Text | The $@ of this request depends on a $@. | server/main.go:30:38:30:48 | selection of Text | URL | server/main.go:19:109:38:1 | SSA def(params) | user-provided value |
|
| server/main.go:30:38:30:48 | selection of Text | server/main.go:19:56:19:61 | SSA def(params) | server/main.go:30:38:30:48 | selection of Text | The $@ of this request depends on a $@. | server/main.go:30:38:30:48 | selection of Text | URL | server/main.go:19:56:19:61 | SSA def(params) | user-provided value |
|
||||||
edges
|
edges
|
||||||
| client/main.go:16:35:16:78 | &... | server/main.go:19:109:38:1 | SSA def(params) | provenance | |
|
| client/main.go:16:35:16:78 | &... | server/main.go:19:56:19:61 | SSA def(params) | provenance | |
|
||||||
| client/main.go:16:35:16:78 | &... [postupdate] | client/main.go:16:35:16:78 | &... | provenance | |
|
| client/main.go:16:35:16:78 | &... [postupdate] | client/main.go:16:35:16:78 | &... | provenance | |
|
||||||
| rpc/notes/service.twirp.go:538:2:538:33 | extract:0 ... := ... | rpc/notes/service.twirp.go:544:27:544:29 | buf | provenance | |
|
| rpc/notes/service.twirp.go:538:2:538:33 | ... := ...[0] | rpc/notes/service.twirp.go:544:27:544:29 | buf | provenance | |
|
||||||
| rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | rpc/notes/service.twirp.go:538:2:538:33 | extract:0 ... := ... | provenance | Src:MaD:1 MaD:3 |
|
| rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | rpc/notes/service.twirp.go:538:2:538:33 | ... := ...[0] | provenance | Src:MaD:1 MaD:3 |
|
||||||
| rpc/notes/service.twirp.go:544:27:544:29 | buf | rpc/notes/service.twirp.go:544:32:544:41 | reqContent [postupdate] | provenance | MaD:2 |
|
| rpc/notes/service.twirp.go:544:27:544:29 | buf | rpc/notes/service.twirp.go:544:32:544:41 | reqContent [postupdate] | provenance | MaD:2 |
|
||||||
| rpc/notes/service.twirp.go:544:32:544:41 | reqContent [postupdate] | rpc/notes/service.twirp.go:574:2:577:2 | SSA def(reqContent) | provenance | |
|
| rpc/notes/service.twirp.go:544:32:544:41 | reqContent [postupdate] | rpc/notes/service.twirp.go:574:2:577:2 | SSA def(reqContent) | provenance | |
|
||||||
| rpc/notes/service.twirp.go:574:2:577:2 | SSA def(reqContent) | rpc/notes/service.twirp.go:576:35:576:44 | reqContent | provenance | |
|
| rpc/notes/service.twirp.go:574:2:577:2 | SSA def(reqContent) | rpc/notes/service.twirp.go:576:35:576:44 | reqContent | provenance | |
|
||||||
| rpc/notes/service.twirp.go:576:35:576:44 | reqContent | server/main.go:19:109:38:1 | SSA def(params) | provenance | |
|
| rpc/notes/service.twirp.go:576:35:576:44 | reqContent | server/main.go:19:56:19:61 | SSA def(params) | provenance | |
|
||||||
| server/main.go:19:109:38:1 | SSA def(params) | server/main.go:19:109:38:1 | SSA def(params) [Return] | provenance | |
|
| server/main.go:19:56:19:61 | SSA def(params) | server/main.go:19:56:19:61 | SSA def(params) [Return] | provenance | |
|
||||||
| server/main.go:19:109:38:1 | SSA def(params) | server/main.go:30:38:30:48 | selection of Text | provenance | |
|
| server/main.go:19:56:19:61 | SSA def(params) | server/main.go:30:38:30:48 | selection of Text | provenance | |
|
||||||
| server/main.go:19:109:38:1 | SSA def(params) | server/main.go:30:38:30:48 | selection of Text | provenance | |
|
| server/main.go:19:56:19:61 | SSA def(params) | server/main.go:30:38:30:48 | selection of Text | provenance | |
|
||||||
| server/main.go:19:109:38:1 | SSA def(params) [Return] | client/main.go:16:35:16:78 | &... [postupdate] | provenance | |
|
| server/main.go:19:56:19:61 | SSA def(params) [Return] | client/main.go:16:35:16:78 | &... [postupdate] | provenance | |
|
||||||
models
|
models
|
||||||
| 1 | Source: net/http; Request; true; Body; ; ; ; remote; manual |
|
| 1 | Source: net/http; Request; true; Body; ; ; ; remote; manual |
|
||||||
| 2 | Summary: google.golang.org/protobuf/proto; ; false; Unmarshal; ; ; Argument[0]; Argument[1]; taint; manual |
|
| 2 | Summary: google.golang.org/protobuf/proto; ; false; Unmarshal; ; ; Argument[0]; Argument[1]; taint; manual |
|
||||||
@@ -21,17 +21,14 @@ models
|
|||||||
nodes
|
nodes
|
||||||
| client/main.go:16:35:16:78 | &... | semmle.label | &... |
|
| client/main.go:16:35:16:78 | &... | semmle.label | &... |
|
||||||
| client/main.go:16:35:16:78 | &... [postupdate] | semmle.label | &... [postupdate] |
|
| client/main.go:16:35:16:78 | &... [postupdate] | semmle.label | &... [postupdate] |
|
||||||
| rpc/notes/service.twirp.go:538:2:538:33 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| rpc/notes/service.twirp.go:538:2:538:33 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | semmle.label | selection of Body |
|
| rpc/notes/service.twirp.go:538:25:538:32 | selection of Body | semmle.label | selection of Body |
|
||||||
| rpc/notes/service.twirp.go:544:27:544:29 | buf | semmle.label | buf |
|
| rpc/notes/service.twirp.go:544:27:544:29 | buf | semmle.label | buf |
|
||||||
| rpc/notes/service.twirp.go:544:32:544:41 | reqContent [postupdate] | semmle.label | reqContent [postupdate] |
|
| rpc/notes/service.twirp.go:544:32:544:41 | reqContent [postupdate] | semmle.label | reqContent [postupdate] |
|
||||||
| rpc/notes/service.twirp.go:574:2:577:2 | SSA def(reqContent) | semmle.label | SSA def(reqContent) |
|
| rpc/notes/service.twirp.go:574:2:577:2 | SSA def(reqContent) | semmle.label | SSA def(reqContent) |
|
||||||
| rpc/notes/service.twirp.go:576:35:576:44 | reqContent | semmle.label | reqContent |
|
| rpc/notes/service.twirp.go:576:35:576:44 | reqContent | semmle.label | reqContent |
|
||||||
| server/main.go:19:109:38:1 | SSA def(params) | semmle.label | SSA def(params) |
|
| server/main.go:19:56:19:61 | SSA def(params) | semmle.label | SSA def(params) |
|
||||||
| server/main.go:19:109:38:1 | SSA def(params) | semmle.label | SSA def(params) |
|
| server/main.go:19:56:19:61 | SSA def(params) | semmle.label | SSA def(params) |
|
||||||
| server/main.go:19:109:38:1 | SSA def(params) [Return] | semmle.label | SSA def(params) [Return] |
|
| server/main.go:19:56:19:61 | SSA def(params) [Return] | semmle.label | SSA def(params) [Return] |
|
||||||
| server/main.go:30:38:30:48 | selection of Text | semmle.label | selection of Text |
|
| server/main.go:30:38:30:48 | selection of Text | semmle.label | selection of Text |
|
||||||
subpaths
|
subpaths
|
||||||
testFailures
|
|
||||||
| server/main.go:19:109:38:1 | SSA def(params) | Unexpected result: Source |
|
|
||||||
| server/main.go:19:111:19:154 | comment | Missing result: Source |
|
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
| tests.go:61:30:61:35 | result | $@ may be nil at this dereference because $@ may not have been checked. | tests.go:59:2:59:30 | SSA def(result) | result | tests.go:59:2:59:30 | SSA def(err) | err |
|
| tests.go:61:30:61:35 | result | $@ may be nil at this dereference because $@ may not have been checked. | tests.go:59:2:59:7 | SSA def(result) | result | tests.go:59:10:59:12 | SSA def(err) | err |
|
||||||
| tests.go:243:27:243:32 | result | $@ may be nil at this dereference because $@ may not have been checked. | tests.go:241:2:241:37 | SSA def(result) | result | tests.go:241:2:241:37 | SSA def(err) | err |
|
| tests.go:243:27:243:32 | result | $@ may be nil at this dereference because $@ may not have been checked. | tests.go:241:2:241:7 | SSA def(result) | result | tests.go:241:10:241:12 | SSA def(err) | err |
|
||||||
|
|||||||
@@ -1,52 +1,52 @@
|
|||||||
#select
|
#select
|
||||||
| tests.go:10:8:10:8 | f | tests.go:32:5:32:78 | extract:0 ... := ... | tests.go:10:8:10:8 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:32:15:32:78 | call to OpenFile | call to OpenFile |
|
| tests.go:10:8:10:8 | f | tests.go:32:5:32:78 | ... := ...[0] | tests.go:10:8:10:8 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:32:15:32:78 | call to OpenFile | call to OpenFile |
|
||||||
| tests.go:10:8:10:8 | f | tests.go:46:5:46:76 | extract:0 ... := ... | tests.go:10:8:10:8 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:46:15:46:76 | call to OpenFile | call to OpenFile |
|
| tests.go:10:8:10:8 | f | tests.go:46:5:46:76 | ... := ...[0] | tests.go:10:8:10:8 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:46:15:46:76 | call to OpenFile | call to OpenFile |
|
||||||
| tests.go:15:3:15:3 | f | tests.go:32:5:32:78 | extract:0 ... := ... | tests.go:15:3:15:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:32:15:32:78 | call to OpenFile | call to OpenFile |
|
| tests.go:15:3:15:3 | f | tests.go:32:5:32:78 | ... := ...[0] | tests.go:15:3:15:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:32:15:32:78 | call to OpenFile | call to OpenFile |
|
||||||
| tests.go:15:3:15:3 | f | tests.go:46:5:46:76 | extract:0 ... := ... | tests.go:15:3:15:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:46:15:46:76 | call to OpenFile | call to OpenFile |
|
| tests.go:15:3:15:3 | f | tests.go:46:5:46:76 | ... := ...[0] | tests.go:15:3:15:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:46:15:46:76 | call to OpenFile | call to OpenFile |
|
||||||
| tests.go:57:3:57:3 | f | tests.go:55:5:55:78 | extract:0 ... := ... | tests.go:57:3:57:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:55:15:55:78 | call to OpenFile | call to OpenFile |
|
| tests.go:57:3:57:3 | f | tests.go:55:5:55:78 | ... := ...[0] | tests.go:57:3:57:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:55:15:55:78 | call to OpenFile | call to OpenFile |
|
||||||
| tests.go:69:3:69:3 | f | tests.go:67:5:67:76 | extract:0 ... := ... | tests.go:69:3:69:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:67:15:67:76 | call to OpenFile | call to OpenFile |
|
| tests.go:69:3:69:3 | f | tests.go:67:5:67:76 | ... := ...[0] | tests.go:69:3:69:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:67:15:67:76 | call to OpenFile | call to OpenFile |
|
||||||
| tests.go:126:9:126:9 | f | tests.go:124:5:124:78 | extract:0 ... := ... | tests.go:126:9:126:9 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:124:15:124:78 | call to OpenFile | call to OpenFile |
|
| tests.go:126:9:126:9 | f | tests.go:124:5:124:78 | ... := ...[0] | tests.go:126:9:126:9 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:124:15:124:78 | call to OpenFile | call to OpenFile |
|
||||||
| tests.go:145:3:145:3 | f | tests.go:141:5:141:78 | extract:0 ... := ... | tests.go:145:3:145:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:141:15:141:78 | call to OpenFile | call to OpenFile |
|
| tests.go:145:3:145:3 | f | tests.go:141:5:141:78 | ... := ...[0] | tests.go:145:3:145:3 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:141:15:141:78 | call to OpenFile | call to OpenFile |
|
||||||
| tests.go:166:8:166:8 | f | tests.go:162:2:162:74 | extract:0 ... := ... | tests.go:166:8:166:8 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:162:12:162:74 | call to OpenFile | call to OpenFile |
|
| tests.go:166:8:166:8 | f | tests.go:162:2:162:74 | ... := ...[0] | tests.go:166:8:166:8 | f | File handle may be writable as a result of data flow from a $@ and closing it may result in data loss upon failure, which is not handled explicitly. | tests.go:162:12:162:74 | call to OpenFile | call to OpenFile |
|
||||||
edges
|
edges
|
||||||
| tests.go:9:36:11:1 | SSA def(f) | tests.go:10:8:10:8 | f | provenance | |
|
| tests.go:9:24:9:24 | SSA def(f) | tests.go:10:8:10:8 | f | provenance | |
|
||||||
| tests.go:13:44:19:1 | SSA def(f) | tests.go:14:13:16:2 | SSA def(f) | provenance | |
|
| tests.go:13:32:13:32 | SSA def(f) | tests.go:14:13:16:2 | SSA def(f) | provenance | |
|
||||||
| tests.go:14:13:16:2 | SSA def(f) | tests.go:15:3:15:3 | f | provenance | |
|
| tests.go:14:13:16:2 | SSA def(f) | tests.go:15:3:15:3 | f | provenance | |
|
||||||
| tests.go:32:5:32:78 | extract:0 ... := ... | tests.go:33:21:33:21 | f | provenance | Src:MaD:1 |
|
| tests.go:32:5:32:78 | ... := ...[0] | tests.go:33:21:33:21 | f | provenance | Src:MaD:1 |
|
||||||
| tests.go:32:5:32:78 | extract:0 ... := ... | tests.go:34:29:34:29 | f | provenance | Src:MaD:1 |
|
| tests.go:32:5:32:78 | ... := ...[0] | tests.go:34:29:34:29 | f | provenance | Src:MaD:1 |
|
||||||
| tests.go:33:21:33:21 | f | tests.go:9:36:11:1 | SSA def(f) | provenance | |
|
| tests.go:33:21:33:21 | f | tests.go:9:24:9:24 | SSA def(f) | provenance | |
|
||||||
| tests.go:34:29:34:29 | f | tests.go:13:44:19:1 | SSA def(f) | provenance | |
|
| tests.go:34:29:34:29 | f | tests.go:13:32:13:32 | SSA def(f) | provenance | |
|
||||||
| tests.go:46:5:46:76 | extract:0 ... := ... | tests.go:47:21:47:21 | f | provenance | Src:MaD:1 |
|
| tests.go:46:5:46:76 | ... := ...[0] | tests.go:47:21:47:21 | f | provenance | Src:MaD:1 |
|
||||||
| tests.go:46:5:46:76 | extract:0 ... := ... | tests.go:48:29:48:29 | f | provenance | Src:MaD:1 |
|
| tests.go:46:5:46:76 | ... := ...[0] | tests.go:48:29:48:29 | f | provenance | Src:MaD:1 |
|
||||||
| tests.go:47:21:47:21 | f | tests.go:9:36:11:1 | SSA def(f) | provenance | |
|
| tests.go:47:21:47:21 | f | tests.go:9:24:9:24 | SSA def(f) | provenance | |
|
||||||
| tests.go:48:29:48:29 | f | tests.go:13:44:19:1 | SSA def(f) | provenance | |
|
| tests.go:48:29:48:29 | f | tests.go:13:32:13:32 | SSA def(f) | provenance | |
|
||||||
| tests.go:55:5:55:78 | extract:0 ... := ... | tests.go:57:3:57:3 | f | provenance | Src:MaD:1 |
|
| tests.go:55:5:55:78 | ... := ...[0] | tests.go:57:3:57:3 | f | provenance | Src:MaD:1 |
|
||||||
| tests.go:67:5:67:76 | extract:0 ... := ... | tests.go:69:3:69:3 | f | provenance | Src:MaD:1 |
|
| tests.go:67:5:67:76 | ... := ...[0] | tests.go:69:3:69:3 | f | provenance | Src:MaD:1 |
|
||||||
| tests.go:124:5:124:78 | extract:0 ... := ... | tests.go:126:9:126:9 | f | provenance | Src:MaD:1 |
|
| tests.go:124:5:124:78 | ... := ...[0] | tests.go:126:9:126:9 | f | provenance | Src:MaD:1 |
|
||||||
| tests.go:141:5:141:78 | extract:0 ... := ... | tests.go:145:3:145:3 | f | provenance | Src:MaD:1 |
|
| tests.go:141:5:141:78 | ... := ...[0] | tests.go:145:3:145:3 | f | provenance | Src:MaD:1 |
|
||||||
| tests.go:162:2:162:74 | extract:0 ... := ... | tests.go:166:8:166:8 | f | provenance | Src:MaD:1 |
|
| tests.go:162:2:162:74 | ... := ...[0] | tests.go:166:8:166:8 | f | provenance | Src:MaD:1 |
|
||||||
models
|
models
|
||||||
| 1 | Source: os; ; false; OpenFile; ; ; ReturnValue[0]; file; manual |
|
| 1 | Source: os; ; false; OpenFile; ; ; ReturnValue[0]; file; manual |
|
||||||
nodes
|
nodes
|
||||||
| tests.go:9:36:11:1 | SSA def(f) | semmle.label | SSA def(f) |
|
| tests.go:9:24:9:24 | SSA def(f) | semmle.label | SSA def(f) |
|
||||||
| tests.go:10:8:10:8 | f | semmle.label | f |
|
| tests.go:10:8:10:8 | f | semmle.label | f |
|
||||||
| tests.go:13:44:19:1 | SSA def(f) | semmle.label | SSA def(f) |
|
| tests.go:13:32:13:32 | SSA def(f) | semmle.label | SSA def(f) |
|
||||||
| tests.go:14:13:16:2 | SSA def(f) | semmle.label | SSA def(f) |
|
| tests.go:14:13:16:2 | SSA def(f) | semmle.label | SSA def(f) |
|
||||||
| tests.go:15:3:15:3 | f | semmle.label | f |
|
| tests.go:15:3:15:3 | f | semmle.label | f |
|
||||||
| tests.go:32:5:32:78 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| tests.go:32:5:32:78 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| tests.go:33:21:33:21 | f | semmle.label | f |
|
| tests.go:33:21:33:21 | f | semmle.label | f |
|
||||||
| tests.go:34:29:34:29 | f | semmle.label | f |
|
| tests.go:34:29:34:29 | f | semmle.label | f |
|
||||||
| tests.go:46:5:46:76 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| tests.go:46:5:46:76 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| tests.go:47:21:47:21 | f | semmle.label | f |
|
| tests.go:47:21:47:21 | f | semmle.label | f |
|
||||||
| tests.go:48:29:48:29 | f | semmle.label | f |
|
| tests.go:48:29:48:29 | f | semmle.label | f |
|
||||||
| tests.go:55:5:55:78 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| tests.go:55:5:55:78 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| tests.go:57:3:57:3 | f | semmle.label | f |
|
| tests.go:57:3:57:3 | f | semmle.label | f |
|
||||||
| tests.go:67:5:67:76 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| tests.go:67:5:67:76 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| tests.go:69:3:69:3 | f | semmle.label | f |
|
| tests.go:69:3:69:3 | f | semmle.label | f |
|
||||||
| tests.go:124:5:124:78 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| tests.go:124:5:124:78 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| tests.go:126:9:126:9 | f | semmle.label | f |
|
| tests.go:126:9:126:9 | f | semmle.label | f |
|
||||||
| tests.go:141:5:141:78 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| tests.go:141:5:141:78 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| tests.go:145:3:145:3 | f | semmle.label | f |
|
| tests.go:145:3:145:3 | f | semmle.label | f |
|
||||||
| tests.go:162:2:162:74 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| tests.go:162:2:162:74 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| tests.go:166:8:166:8 | f | semmle.label | f |
|
| tests.go:166:8:166:8 | f | semmle.label | f |
|
||||||
subpaths
|
subpaths
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
| DeadStoreOfField.go:8:2:8:10 | assign:0 ... = ... | This assignment to val is useless since its value is never read. |
|
| DeadStoreOfField.go:8:2:8:6 | assignment to field val | This assignment to val is useless since its value is never read. |
|
||||||
|
|||||||
@@ -5,18 +5,18 @@
|
|||||||
| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | Unresolved path from an archive header, which may point outside the archive root, is used in $@. | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | symlink creation |
|
| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | Unresolved path from an archive header, which may point outside the archive root, is used in $@. | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | symlink creation |
|
||||||
| UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | Unresolved path from an archive header, which may point outside the archive root, is used in $@. | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | symlink creation |
|
| UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | Unresolved path from an archive header, which may point outside the archive root, is used in $@. | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | symlink creation |
|
||||||
edges
|
edges
|
||||||
| UnsafeUnzipSymlink.go:111:46:113:1 | SSA def(fileName) | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | provenance | Sink:MaD:1 |
|
| UnsafeUnzipSymlink.go:111:19:111:26 | SSA def(linkName) | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | provenance | Sink:MaD:1 |
|
||||||
| UnsafeUnzipSymlink.go:111:46:113:1 | SSA def(linkName) | UnsafeUnzipSymlink.go:112:13:112:20 | linkName | provenance | Sink:MaD:1 |
|
| UnsafeUnzipSymlink.go:111:29:111:36 | SSA def(fileName) | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | provenance | Sink:MaD:1 |
|
||||||
| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | UnsafeUnzipSymlink.go:111:46:113:1 | SSA def(linkName) | provenance | |
|
| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | UnsafeUnzipSymlink.go:111:19:111:26 | SSA def(linkName) | provenance | |
|
||||||
| UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:111:46:113:1 | SSA def(fileName) | provenance | |
|
| UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:111:29:111:36 | SSA def(fileName) | provenance | |
|
||||||
models
|
models
|
||||||
| 1 | Sink: os; ; false; Symlink; ; ; Argument[0..1]; path-injection; manual |
|
| 1 | Sink: os; ; false; Symlink; ; ; Argument[0..1]; path-injection; manual |
|
||||||
nodes
|
nodes
|
||||||
| UnsafeUnzipSymlink.go:31:15:31:29 | selection of Linkname | semmle.label | selection of Linkname |
|
| UnsafeUnzipSymlink.go:31:15:31:29 | selection of Linkname | semmle.label | selection of Linkname |
|
||||||
| UnsafeUnzipSymlink.go:31:32:31:42 | selection of Name | semmle.label | selection of Name |
|
| UnsafeUnzipSymlink.go:31:32:31:42 | selection of Name | semmle.label | selection of Name |
|
||||||
| UnsafeUnzipSymlink.go:43:25:43:35 | selection of Name | semmle.label | selection of Name |
|
| UnsafeUnzipSymlink.go:43:25:43:35 | selection of Name | semmle.label | selection of Name |
|
||||||
| UnsafeUnzipSymlink.go:111:46:113:1 | SSA def(fileName) | semmle.label | SSA def(fileName) |
|
| UnsafeUnzipSymlink.go:111:19:111:26 | SSA def(linkName) | semmle.label | SSA def(linkName) |
|
||||||
| UnsafeUnzipSymlink.go:111:46:113:1 | SSA def(linkName) | semmle.label | SSA def(linkName) |
|
| UnsafeUnzipSymlink.go:111:29:111:36 | SSA def(fileName) | semmle.label | SSA def(fileName) |
|
||||||
| UnsafeUnzipSymlink.go:112:13:112:20 | linkName | semmle.label | linkName |
|
| UnsafeUnzipSymlink.go:112:13:112:20 | linkName | semmle.label | linkName |
|
||||||
| UnsafeUnzipSymlink.go:112:23:112:30 | fileName | semmle.label | fileName |
|
| UnsafeUnzipSymlink.go:112:23:112:30 | fileName | semmle.label | fileName |
|
||||||
| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | semmle.label | selection of Linkname |
|
| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | semmle.label | selection of Linkname |
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
#select
|
#select
|
||||||
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | extract:0 ... := ... | UnsafeUnzipSymlinkGood.go:72:3:72:25 | extract:0 ... := ... | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | Unsanitized archive entry, which may contain '..', is used in a $@. | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | file system operation |
|
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | Unsanitized archive entry, which may contain '..', is used in a $@. | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | file system operation |
|
||||||
| ZipSlip.go:11:2:15:2 | extract:1 range statement | ZipSlip.go:11:2:15:2 | extract:1 range statement | ZipSlip.go:14:20:14:20 | p | Unsanitized archive entry, which may contain '..', is used in a $@. | ZipSlip.go:14:20:14:20 | p | file system operation |
|
| ZipSlip.go:11:2:15:2 | range statement[1] | ZipSlip.go:11:2:15:2 | range statement[1] | ZipSlip.go:14:20:14:20 | p | Unsanitized archive entry, which may contain '..', is used in a $@. | ZipSlip.go:14:20:14:20 | p | file system operation |
|
||||||
| tarslip.go:15:2:15:30 | extract:0 ... := ... | tarslip.go:15:2:15:30 | extract:0 ... := ... | tarslip.go:16:14:16:34 | call to Dir | Unsanitized archive entry, which may contain '..', is used in a $@. | tarslip.go:16:14:16:34 | call to Dir | file system operation |
|
| tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:16:14:16:34 | call to Dir | Unsanitized archive entry, which may contain '..', is used in a $@. | tarslip.go:16:14:16:34 | call to Dir | file system operation |
|
||||||
| tst.go:23:2:43:2 | extract:1 range statement | tst.go:23:2:43:2 | extract:1 range statement | tst.go:29:20:29:23 | path | Unsanitized archive entry, which may contain '..', is used in a $@. | tst.go:29:20:29:23 | path | file system operation |
|
| tst.go:23:2:43:2 | range statement[1] | tst.go:23:2:43:2 | range statement[1] | tst.go:29:20:29:23 | path | Unsanitized archive entry, which may contain '..', is used in a $@. | tst.go:29:20:29:23 | path | file system operation |
|
||||||
edges
|
edges
|
||||||
| UnsafeUnzipSymlinkGood.go:52:55:67:1 | SSA def(candidate) | UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | provenance | |
|
| UnsafeUnzipSymlinkGood.go:52:24:52:32 | SSA def(candidate) | UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | provenance | |
|
||||||
| UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | provenance | FunctionModel Sink:MaD:3 |
|
| UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | provenance | FunctionModel Sink:MaD:3 |
|
||||||
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | extract:0 ... := ... | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | provenance | |
|
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | provenance | |
|
||||||
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | extract:0 ... := ... | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | provenance | |
|
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | provenance | |
|
||||||
| UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | UnsafeUnzipSymlinkGood.go:52:55:67:1 | SSA def(candidate) | provenance | |
|
| UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | UnsafeUnzipSymlinkGood.go:52:24:52:32 | SSA def(candidate) | provenance | |
|
||||||
| UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | UnsafeUnzipSymlinkGood.go:52:55:67:1 | SSA def(candidate) | provenance | |
|
| UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | UnsafeUnzipSymlinkGood.go:52:24:52:32 | SSA def(candidate) | provenance | |
|
||||||
| ZipSlip.go:11:2:15:2 | extract:1 range statement | ZipSlip.go:12:24:12:29 | selection of Name | provenance | |
|
| ZipSlip.go:11:2:15:2 | range statement[1] | ZipSlip.go:12:24:12:29 | selection of Name | provenance | |
|
||||||
| ZipSlip.go:12:3:12:30 | extract:0 ... := ... | ZipSlip.go:14:20:14:20 | p | provenance | Sink:MaD:1 |
|
| ZipSlip.go:12:3:12:30 | ... := ...[0] | ZipSlip.go:14:20:14:20 | p | provenance | Sink:MaD:1 |
|
||||||
| ZipSlip.go:12:24:12:29 | selection of Name | ZipSlip.go:12:3:12:30 | extract:0 ... := ... | provenance | MaD:4 |
|
| ZipSlip.go:12:24:12:29 | selection of Name | ZipSlip.go:12:3:12:30 | ... := ...[0] | provenance | MaD:4 |
|
||||||
| tarslip.go:15:2:15:30 | extract:0 ... := ... | tarslip.go:16:23:16:33 | selection of Name | provenance | |
|
| tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:16:23:16:33 | selection of Name | provenance | |
|
||||||
| tarslip.go:16:23:16:33 | selection of Name | tarslip.go:16:14:16:34 | call to Dir | provenance | MaD:5 Sink:MaD:2 |
|
| tarslip.go:16:23:16:33 | selection of Name | tarslip.go:16:14:16:34 | call to Dir | provenance | MaD:5 Sink:MaD:2 |
|
||||||
| tst.go:23:2:43:2 | extract:1 range statement | tst.go:29:20:29:23 | path | provenance | Sink:MaD:1 |
|
| tst.go:23:2:43:2 | range statement[1] | tst.go:29:20:29:23 | path | provenance | Sink:MaD:1 |
|
||||||
models
|
models
|
||||||
| 1 | Sink: io/ioutil; ; false; WriteFile; ; ; Argument[0]; path-injection; manual |
|
| 1 | Sink: io/ioutil; ; false; WriteFile; ; ; Argument[0]; path-injection; manual |
|
||||||
| 2 | Sink: os; ; false; MkdirAll; ; ; Argument[0]; path-injection; manual |
|
| 2 | Sink: os; ; false; MkdirAll; ; ; Argument[0]; path-injection; manual |
|
||||||
@@ -23,19 +23,19 @@ models
|
|||||||
| 4 | Summary: path/filepath; ; false; Abs; ; ; Argument[0]; ReturnValue[0]; taint; manual |
|
| 4 | Summary: path/filepath; ; false; Abs; ; ; Argument[0]; ReturnValue[0]; taint; manual |
|
||||||
| 5 | Summary: path; ; false; Dir; ; ; Argument[0]; ReturnValue; taint; manual |
|
| 5 | Summary: path; ; false; Dir; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||||
nodes
|
nodes
|
||||||
| UnsafeUnzipSymlinkGood.go:52:55:67:1 | SSA def(candidate) | semmle.label | SSA def(candidate) |
|
| UnsafeUnzipSymlinkGood.go:52:24:52:32 | SSA def(candidate) | semmle.label | SSA def(candidate) |
|
||||||
| UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | semmle.label | call to Join |
|
| UnsafeUnzipSymlinkGood.go:61:31:61:62 | call to Join | semmle.label | call to Join |
|
||||||
| UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | semmle.label | candidate |
|
| UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | semmle.label | candidate |
|
||||||
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | semmle.label | selection of Linkname |
|
| UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | semmle.label | selection of Linkname |
|
||||||
| UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | semmle.label | selection of Name |
|
| UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | semmle.label | selection of Name |
|
||||||
| ZipSlip.go:11:2:15:2 | extract:1 range statement | semmle.label | extract:1 range statement |
|
| ZipSlip.go:11:2:15:2 | range statement[1] | semmle.label | range statement[1] |
|
||||||
| ZipSlip.go:12:3:12:30 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| ZipSlip.go:12:3:12:30 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| ZipSlip.go:12:24:12:29 | selection of Name | semmle.label | selection of Name |
|
| ZipSlip.go:12:24:12:29 | selection of Name | semmle.label | selection of Name |
|
||||||
| ZipSlip.go:14:20:14:20 | p | semmle.label | p |
|
| ZipSlip.go:14:20:14:20 | p | semmle.label | p |
|
||||||
| tarslip.go:15:2:15:30 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| tarslip.go:15:2:15:30 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| tarslip.go:16:14:16:34 | call to Dir | semmle.label | call to Dir |
|
| tarslip.go:16:14:16:34 | call to Dir | semmle.label | call to Dir |
|
||||||
| tarslip.go:16:23:16:33 | selection of Name | semmle.label | selection of Name |
|
| tarslip.go:16:23:16:33 | selection of Name | semmle.label | selection of Name |
|
||||||
| tst.go:23:2:43:2 | extract:1 range statement | semmle.label | extract:1 range statement |
|
| tst.go:23:2:43:2 | range statement[1] | semmle.label | range statement[1] |
|
||||||
| tst.go:29:20:29:23 | path | semmle.label | path |
|
| tst.go:29:20:29:23 | path | semmle.label | path |
|
||||||
subpaths
|
subpaths
|
||||||
|
|||||||
@@ -31,16 +31,16 @@ edges
|
|||||||
| SqlInjection.go:11:3:11:17 | call to Query | SqlInjection.go:11:3:11:29 | index expression | provenance | |
|
| SqlInjection.go:11:3:11:17 | call to Query | SqlInjection.go:11:3:11:29 | index expression | provenance | |
|
||||||
| SqlInjection.go:11:3:11:29 | index expression | SqlInjection.go:10:7:11:30 | []type{args} [array] | provenance | |
|
| SqlInjection.go:11:3:11:29 | index expression | SqlInjection.go:10:7:11:30 | []type{args} [array] | provenance | |
|
||||||
| SqlInjection.go:11:3:11:29 | index expression | SqlInjection.go:10:7:11:30 | call to Sprintf | provenance | FunctionModel |
|
| SqlInjection.go:11:3:11:29 | index expression | SqlInjection.go:10:7:11:30 | call to Sprintf | provenance | FunctionModel |
|
||||||
| issue48.go:17:2:17:33 | extract:0 ... := ... | issue48.go:18:17:18:17 | b | provenance | |
|
| issue48.go:17:2:17:33 | ... := ...[0] | issue48.go:18:17:18:17 | b | provenance | |
|
||||||
| issue48.go:17:25:17:32 | selection of Body | issue48.go:17:2:17:33 | extract:0 ... := ... | provenance | Src:MaD:17 MaD:24 |
|
| issue48.go:17:25:17:32 | selection of Body | issue48.go:17:2:17:33 | ... := ...[0] | provenance | Src:MaD:17 MaD:24 |
|
||||||
| issue48.go:18:17:18:17 | b | issue48.go:18:20:18:39 | &... [postupdate] | provenance | MaD:22 |
|
| issue48.go:18:17:18:17 | b | issue48.go:18:20:18:39 | &... [postupdate] | provenance | MaD:22 |
|
||||||
| issue48.go:18:20:18:39 | &... [postupdate] | issue48.go:21:3:21:33 | index expression | provenance | |
|
| issue48.go:18:20:18:39 | &... [postupdate] | issue48.go:21:3:21:33 | index expression | provenance | |
|
||||||
| issue48.go:20:8:21:34 | []type{args} [array] | issue48.go:20:8:21:34 | call to Sprintf | provenance | MaD:23 |
|
| issue48.go:20:8:21:34 | []type{args} [array] | issue48.go:20:8:21:34 | call to Sprintf | provenance | MaD:23 |
|
||||||
| issue48.go:20:8:21:34 | call to Sprintf | issue48.go:22:11:22:12 | q3 | provenance | Sink:MaD:1 |
|
| issue48.go:20:8:21:34 | call to Sprintf | issue48.go:22:11:22:12 | q3 | provenance | Sink:MaD:1 |
|
||||||
| issue48.go:21:3:21:33 | index expression | issue48.go:20:8:21:34 | []type{args} [array] | provenance | |
|
| issue48.go:21:3:21:33 | index expression | issue48.go:20:8:21:34 | []type{args} [array] | provenance | |
|
||||||
| issue48.go:21:3:21:33 | index expression | issue48.go:20:8:21:34 | call to Sprintf | provenance | FunctionModel |
|
| issue48.go:21:3:21:33 | index expression | issue48.go:20:8:21:34 | call to Sprintf | provenance | FunctionModel |
|
||||||
| issue48.go:27:2:27:34 | extract:0 ... := ... | issue48.go:28:17:28:18 | b2 | provenance | |
|
| issue48.go:27:2:27:34 | ... := ...[0] | issue48.go:28:17:28:18 | b2 | provenance | |
|
||||||
| issue48.go:27:26:27:33 | selection of Body | issue48.go:27:2:27:34 | extract:0 ... := ... | provenance | Src:MaD:17 MaD:24 |
|
| issue48.go:27:26:27:33 | selection of Body | issue48.go:27:2:27:34 | ... := ...[0] | provenance | Src:MaD:17 MaD:24 |
|
||||||
| issue48.go:28:17:28:18 | b2 | issue48.go:28:21:28:41 | &... [postupdate] | provenance | MaD:22 |
|
| issue48.go:28:17:28:18 | b2 | issue48.go:28:21:28:41 | &... [postupdate] | provenance | MaD:22 |
|
||||||
| issue48.go:28:21:28:41 | &... [postupdate] | issue48.go:31:3:31:31 | selection of Category | provenance | |
|
| issue48.go:28:21:28:41 | &... [postupdate] | issue48.go:31:3:31:31 | selection of Category | provenance | |
|
||||||
| issue48.go:30:8:31:32 | []type{args} [array] | issue48.go:30:8:31:32 | call to Sprintf | provenance | MaD:23 |
|
| issue48.go:30:8:31:32 | []type{args} [array] | issue48.go:30:8:31:32 | call to Sprintf | provenance | MaD:23 |
|
||||||
@@ -72,19 +72,19 @@ edges
|
|||||||
| main.go:30:13:30:39 | index expression | main.go:28:18:31:2 | struct literal [Category] | provenance | |
|
| main.go:30:13:30:39 | index expression | main.go:28:18:31:2 | struct literal [Category] | provenance | |
|
||||||
| main.go:33:7:34:23 | []type{args} [array] | main.go:33:7:34:23 | call to Sprintf | provenance | MaD:23 |
|
| main.go:33:7:34:23 | []type{args} [array] | main.go:33:7:34:23 | call to Sprintf | provenance | MaD:23 |
|
||||||
| main.go:33:7:34:23 | call to Sprintf | main.go:35:11:35:11 | q | provenance | Sink:MaD:1 |
|
| main.go:33:7:34:23 | call to Sprintf | main.go:35:11:35:11 | q | provenance | Sink:MaD:1 |
|
||||||
| main.go:34:3:34:13 | RequestData [pointer, Category] | main.go:34:3:34:13 | implicit-deref RequestData [Category] | provenance | |
|
| main.go:34:3:34:13 | RequestData [pointer, Category] | main.go:34:3:34:13 | implicit dereference [Category] | provenance | |
|
||||||
| main.go:34:3:34:13 | implicit-deref RequestData [Category] | main.go:34:3:34:22 | selection of Category | provenance | |
|
| main.go:34:3:34:13 | implicit dereference [Category] | main.go:34:3:34:22 | selection of Category | provenance | |
|
||||||
| main.go:34:3:34:22 | selection of Category | main.go:33:7:34:23 | []type{args} [array] | provenance | |
|
| main.go:34:3:34:22 | selection of Category | main.go:33:7:34:23 | []type{args} [array] | provenance | |
|
||||||
| main.go:34:3:34:22 | selection of Category | main.go:33:7:34:23 | call to Sprintf | provenance | FunctionModel |
|
| main.go:34:3:34:22 | selection of Category | main.go:33:7:34:23 | call to Sprintf | provenance | FunctionModel |
|
||||||
| main.go:40:2:40:12 | RequestData [postupdate] [pointer, Category] | main.go:43:3:43:13 | RequestData [pointer, Category] | provenance | |
|
| main.go:40:2:40:12 | RequestData [postupdate] [pointer, Category] | main.go:43:3:43:13 | RequestData [pointer, Category] | provenance | |
|
||||||
| main.go:40:2:40:12 | implicit-deref RequestData [postupdate] [Category] | main.go:40:2:40:12 | RequestData [postupdate] [pointer, Category] | provenance | |
|
| main.go:40:2:40:12 | implicit dereference [postupdate] [Category] | main.go:40:2:40:12 | RequestData [postupdate] [pointer, Category] | provenance | |
|
||||||
| main.go:40:25:40:31 | selection of URL | main.go:40:25:40:39 | call to Query | provenance | Src:MaD:21 MaD:26 |
|
| main.go:40:25:40:31 | selection of URL | main.go:40:25:40:39 | call to Query | provenance | Src:MaD:21 MaD:26 |
|
||||||
| main.go:40:25:40:39 | call to Query | main.go:40:25:40:51 | index expression | provenance | |
|
| main.go:40:25:40:39 | call to Query | main.go:40:25:40:51 | index expression | provenance | |
|
||||||
| main.go:40:25:40:51 | index expression | main.go:40:2:40:12 | implicit-deref RequestData [postupdate] [Category] | provenance | |
|
| main.go:40:25:40:51 | index expression | main.go:40:2:40:12 | implicit dereference [postupdate] [Category] | provenance | |
|
||||||
| main.go:42:7:43:23 | []type{args} [array] | main.go:42:7:43:23 | call to Sprintf | provenance | MaD:23 |
|
| main.go:42:7:43:23 | []type{args} [array] | main.go:42:7:43:23 | call to Sprintf | provenance | MaD:23 |
|
||||||
| main.go:42:7:43:23 | call to Sprintf | main.go:44:11:44:11 | q | provenance | Sink:MaD:1 |
|
| main.go:42:7:43:23 | call to Sprintf | main.go:44:11:44:11 | q | provenance | Sink:MaD:1 |
|
||||||
| main.go:43:3:43:13 | RequestData [pointer, Category] | main.go:43:3:43:13 | implicit-deref RequestData [Category] | provenance | |
|
| main.go:43:3:43:13 | RequestData [pointer, Category] | main.go:43:3:43:13 | implicit dereference [Category] | provenance | |
|
||||||
| main.go:43:3:43:13 | implicit-deref RequestData [Category] | main.go:43:3:43:22 | selection of Category | provenance | |
|
| main.go:43:3:43:13 | implicit dereference [Category] | main.go:43:3:43:22 | selection of Category | provenance | |
|
||||||
| main.go:43:3:43:22 | selection of Category | main.go:42:7:43:23 | []type{args} [array] | provenance | |
|
| main.go:43:3:43:22 | selection of Category | main.go:42:7:43:23 | []type{args} [array] | provenance | |
|
||||||
| main.go:43:3:43:22 | selection of Category | main.go:42:7:43:23 | call to Sprintf | provenance | FunctionModel |
|
| main.go:43:3:43:22 | selection of Category | main.go:42:7:43:23 | call to Sprintf | provenance | FunctionModel |
|
||||||
| main.go:49:3:49:14 | star expression [postupdate] [Category] | main.go:49:4:49:14 | RequestData [postupdate] [pointer, Category] | provenance | |
|
| main.go:49:3:49:14 | star expression [postupdate] [Category] | main.go:49:4:49:14 | RequestData [postupdate] [pointer, Category] | provenance | |
|
||||||
@@ -94,8 +94,8 @@ edges
|
|||||||
| main.go:49:28:49:54 | index expression | main.go:49:3:49:14 | star expression [postupdate] [Category] | provenance | |
|
| main.go:49:28:49:54 | index expression | main.go:49:3:49:14 | star expression [postupdate] [Category] | provenance | |
|
||||||
| main.go:51:7:52:23 | []type{args} [array] | main.go:51:7:52:23 | call to Sprintf | provenance | MaD:23 |
|
| main.go:51:7:52:23 | []type{args} [array] | main.go:51:7:52:23 | call to Sprintf | provenance | MaD:23 |
|
||||||
| main.go:51:7:52:23 | call to Sprintf | main.go:53:11:53:11 | q | provenance | Sink:MaD:1 |
|
| main.go:51:7:52:23 | call to Sprintf | main.go:53:11:53:11 | q | provenance | Sink:MaD:1 |
|
||||||
| main.go:52:3:52:13 | RequestData [pointer, Category] | main.go:52:3:52:13 | implicit-deref RequestData [Category] | provenance | |
|
| main.go:52:3:52:13 | RequestData [pointer, Category] | main.go:52:3:52:13 | implicit dereference [Category] | provenance | |
|
||||||
| main.go:52:3:52:13 | implicit-deref RequestData [Category] | main.go:52:3:52:22 | selection of Category | provenance | |
|
| main.go:52:3:52:13 | implicit dereference [Category] | main.go:52:3:52:22 | selection of Category | provenance | |
|
||||||
| main.go:52:3:52:22 | selection of Category | main.go:51:7:52:23 | []type{args} [array] | provenance | |
|
| main.go:52:3:52:22 | selection of Category | main.go:51:7:52:23 | []type{args} [array] | provenance | |
|
||||||
| main.go:52:3:52:22 | selection of Category | main.go:51:7:52:23 | call to Sprintf | provenance | FunctionModel |
|
| main.go:52:3:52:22 | selection of Category | main.go:51:7:52:23 | call to Sprintf | provenance | FunctionModel |
|
||||||
| main.go:58:3:58:14 | star expression [postupdate] [Category] | main.go:58:4:58:14 | RequestData [postupdate] [pointer, Category] | provenance | |
|
| main.go:58:3:58:14 | star expression [postupdate] [Category] | main.go:58:4:58:14 | RequestData [postupdate] [pointer, Category] | provenance | |
|
||||||
@@ -161,7 +161,7 @@ nodes
|
|||||||
| SqlInjection.go:11:3:11:17 | call to Query | semmle.label | call to Query |
|
| SqlInjection.go:11:3:11:17 | call to Query | semmle.label | call to Query |
|
||||||
| SqlInjection.go:11:3:11:29 | index expression | semmle.label | index expression |
|
| SqlInjection.go:11:3:11:29 | index expression | semmle.label | index expression |
|
||||||
| SqlInjection.go:12:11:12:11 | q | semmle.label | q |
|
| SqlInjection.go:12:11:12:11 | q | semmle.label | q |
|
||||||
| issue48.go:17:2:17:33 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| issue48.go:17:2:17:33 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| issue48.go:17:25:17:32 | selection of Body | semmle.label | selection of Body |
|
| issue48.go:17:25:17:32 | selection of Body | semmle.label | selection of Body |
|
||||||
| issue48.go:18:17:18:17 | b | semmle.label | b |
|
| issue48.go:18:17:18:17 | b | semmle.label | b |
|
||||||
| issue48.go:18:20:18:39 | &... [postupdate] | semmle.label | &... [postupdate] |
|
| issue48.go:18:20:18:39 | &... [postupdate] | semmle.label | &... [postupdate] |
|
||||||
@@ -169,7 +169,7 @@ nodes
|
|||||||
| issue48.go:20:8:21:34 | call to Sprintf | semmle.label | call to Sprintf |
|
| issue48.go:20:8:21:34 | call to Sprintf | semmle.label | call to Sprintf |
|
||||||
| issue48.go:21:3:21:33 | index expression | semmle.label | index expression |
|
| issue48.go:21:3:21:33 | index expression | semmle.label | index expression |
|
||||||
| issue48.go:22:11:22:12 | q3 | semmle.label | q3 |
|
| issue48.go:22:11:22:12 | q3 | semmle.label | q3 |
|
||||||
| issue48.go:27:2:27:34 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| issue48.go:27:2:27:34 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| issue48.go:27:26:27:33 | selection of Body | semmle.label | selection of Body |
|
| issue48.go:27:26:27:33 | selection of Body | semmle.label | selection of Body |
|
||||||
| issue48.go:28:17:28:18 | b2 | semmle.label | b2 |
|
| issue48.go:28:17:28:18 | b2 | semmle.label | b2 |
|
||||||
| issue48.go:28:21:28:41 | &... [postupdate] | semmle.label | &... [postupdate] |
|
| issue48.go:28:21:28:41 | &... [postupdate] | semmle.label | &... [postupdate] |
|
||||||
@@ -204,18 +204,18 @@ nodes
|
|||||||
| main.go:33:7:34:23 | []type{args} [array] | semmle.label | []type{args} [array] |
|
| main.go:33:7:34:23 | []type{args} [array] | semmle.label | []type{args} [array] |
|
||||||
| main.go:33:7:34:23 | call to Sprintf | semmle.label | call to Sprintf |
|
| main.go:33:7:34:23 | call to Sprintf | semmle.label | call to Sprintf |
|
||||||
| main.go:34:3:34:13 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] |
|
| main.go:34:3:34:13 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] |
|
||||||
| main.go:34:3:34:13 | implicit-deref RequestData [Category] | semmle.label | implicit-deref RequestData [Category] |
|
| main.go:34:3:34:13 | implicit dereference [Category] | semmle.label | implicit dereference [Category] |
|
||||||
| main.go:34:3:34:22 | selection of Category | semmle.label | selection of Category |
|
| main.go:34:3:34:22 | selection of Category | semmle.label | selection of Category |
|
||||||
| main.go:35:11:35:11 | q | semmle.label | q |
|
| main.go:35:11:35:11 | q | semmle.label | q |
|
||||||
| main.go:40:2:40:12 | RequestData [postupdate] [pointer, Category] | semmle.label | RequestData [postupdate] [pointer, Category] |
|
| main.go:40:2:40:12 | RequestData [postupdate] [pointer, Category] | semmle.label | RequestData [postupdate] [pointer, Category] |
|
||||||
| main.go:40:2:40:12 | implicit-deref RequestData [postupdate] [Category] | semmle.label | implicit-deref RequestData [postupdate] [Category] |
|
| main.go:40:2:40:12 | implicit dereference [postupdate] [Category] | semmle.label | implicit dereference [postupdate] [Category] |
|
||||||
| main.go:40:25:40:31 | selection of URL | semmle.label | selection of URL |
|
| main.go:40:25:40:31 | selection of URL | semmle.label | selection of URL |
|
||||||
| main.go:40:25:40:39 | call to Query | semmle.label | call to Query |
|
| main.go:40:25:40:39 | call to Query | semmle.label | call to Query |
|
||||||
| main.go:40:25:40:51 | index expression | semmle.label | index expression |
|
| main.go:40:25:40:51 | index expression | semmle.label | index expression |
|
||||||
| main.go:42:7:43:23 | []type{args} [array] | semmle.label | []type{args} [array] |
|
| main.go:42:7:43:23 | []type{args} [array] | semmle.label | []type{args} [array] |
|
||||||
| main.go:42:7:43:23 | call to Sprintf | semmle.label | call to Sprintf |
|
| main.go:42:7:43:23 | call to Sprintf | semmle.label | call to Sprintf |
|
||||||
| main.go:43:3:43:13 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] |
|
| main.go:43:3:43:13 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] |
|
||||||
| main.go:43:3:43:13 | implicit-deref RequestData [Category] | semmle.label | implicit-deref RequestData [Category] |
|
| main.go:43:3:43:13 | implicit dereference [Category] | semmle.label | implicit dereference [Category] |
|
||||||
| main.go:43:3:43:22 | selection of Category | semmle.label | selection of Category |
|
| main.go:43:3:43:22 | selection of Category | semmle.label | selection of Category |
|
||||||
| main.go:44:11:44:11 | q | semmle.label | q |
|
| main.go:44:11:44:11 | q | semmle.label | q |
|
||||||
| main.go:49:3:49:14 | star expression [postupdate] [Category] | semmle.label | star expression [postupdate] [Category] |
|
| main.go:49:3:49:14 | star expression [postupdate] [Category] | semmle.label | star expression [postupdate] [Category] |
|
||||||
@@ -226,7 +226,7 @@ nodes
|
|||||||
| main.go:51:7:52:23 | []type{args} [array] | semmle.label | []type{args} [array] |
|
| main.go:51:7:52:23 | []type{args} [array] | semmle.label | []type{args} [array] |
|
||||||
| main.go:51:7:52:23 | call to Sprintf | semmle.label | call to Sprintf |
|
| main.go:51:7:52:23 | call to Sprintf | semmle.label | call to Sprintf |
|
||||||
| main.go:52:3:52:13 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] |
|
| main.go:52:3:52:13 | RequestData [pointer, Category] | semmle.label | RequestData [pointer, Category] |
|
||||||
| main.go:52:3:52:13 | implicit-deref RequestData [Category] | semmle.label | implicit-deref RequestData [Category] |
|
| main.go:52:3:52:13 | implicit dereference [Category] | semmle.label | implicit dereference [Category] |
|
||||||
| main.go:52:3:52:22 | selection of Category | semmle.label | selection of Category |
|
| main.go:52:3:52:22 | selection of Category | semmle.label | selection of Category |
|
||||||
| main.go:53:11:53:11 | q | semmle.label | q |
|
| main.go:53:11:53:11 | q | semmle.label | q |
|
||||||
| main.go:58:3:58:14 | star expression [postupdate] [Category] | semmle.label | star expression [postupdate] [Category] |
|
| main.go:58:3:58:14 | star expression [postupdate] [Category] | semmle.label | star expression [postupdate] [Category] |
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
#select
|
#select
|
||||||
| StringBreak.go:15:47:15:57 | versionJSON | StringBreak.go:11:2:11:40 | extract:0 ... := ... | StringBreak.go:15:47:15:57 | versionJSON | If this $@ contains a single quote, it could break out of the enclosing quotes. | StringBreak.go:11:2:11:40 | extract:0 ... := ... | JSON value |
|
| StringBreak.go:15:47:15:57 | versionJSON | StringBreak.go:11:2:11:40 | ... := ...[0] | StringBreak.go:15:47:15:57 | versionJSON | If this $@ contains a single quote, it could break out of the enclosing quotes. | StringBreak.go:11:2:11:40 | ... := ...[0] | JSON value |
|
||||||
| StringBreakMismatched.go:18:26:18:32 | escaped | StringBreakMismatched.go:13:2:13:40 | extract:0 ... := ... | StringBreakMismatched.go:18:26:18:32 | escaped | If this $@ contains a single quote, it could break out of the enclosing quotes. | StringBreakMismatched.go:13:2:13:40 | extract:0 ... := ... | JSON value |
|
| StringBreakMismatched.go:18:26:18:32 | escaped | StringBreakMismatched.go:13:2:13:40 | ... := ...[0] | StringBreakMismatched.go:18:26:18:32 | escaped | If this $@ contains a single quote, it could break out of the enclosing quotes. | StringBreakMismatched.go:13:2:13:40 | ... := ...[0] | JSON value |
|
||||||
| StringBreakMismatched.go:30:27:30:33 | escaped | StringBreakMismatched.go:25:2:25:40 | extract:0 ... := ... | StringBreakMismatched.go:30:27:30:33 | escaped | If this $@ contains a double quote, it could break out of the enclosing quotes. | StringBreakMismatched.go:25:2:25:40 | extract:0 ... := ... | JSON value |
|
| StringBreakMismatched.go:30:27:30:33 | escaped | StringBreakMismatched.go:25:2:25:40 | ... := ...[0] | StringBreakMismatched.go:30:27:30:33 | escaped | If this $@ contains a double quote, it could break out of the enclosing quotes. | StringBreakMismatched.go:25:2:25:40 | ... := ...[0] | JSON value |
|
||||||
edges
|
edges
|
||||||
| StringBreak.go:11:2:11:40 | extract:0 ... := ... | StringBreak.go:15:47:15:57 | versionJSON | provenance | |
|
| StringBreak.go:11:2:11:40 | ... := ...[0] | StringBreak.go:15:47:15:57 | versionJSON | provenance | |
|
||||||
| StringBreakMismatched.go:13:2:13:40 | extract:0 ... := ... | StringBreakMismatched.go:14:29:14:47 | type conversion | provenance | |
|
| StringBreakMismatched.go:13:2:13:40 | ... := ...[0] | StringBreakMismatched.go:14:29:14:47 | type conversion | provenance | |
|
||||||
| StringBreakMismatched.go:14:13:14:62 | call to Replace | StringBreakMismatched.go:18:26:18:32 | escaped | provenance | |
|
| StringBreakMismatched.go:14:13:14:62 | call to Replace | StringBreakMismatched.go:18:26:18:32 | escaped | provenance | |
|
||||||
| StringBreakMismatched.go:14:29:14:47 | type conversion | StringBreakMismatched.go:14:13:14:62 | call to Replace | provenance | MaD:1 |
|
| StringBreakMismatched.go:14:29:14:47 | type conversion | StringBreakMismatched.go:14:13:14:62 | call to Replace | provenance | MaD:1 |
|
||||||
| StringBreakMismatched.go:25:2:25:40 | extract:0 ... := ... | StringBreakMismatched.go:26:29:26:47 | type conversion | provenance | |
|
| StringBreakMismatched.go:25:2:25:40 | ... := ...[0] | StringBreakMismatched.go:26:29:26:47 | type conversion | provenance | |
|
||||||
| StringBreakMismatched.go:26:13:26:61 | call to Replace | StringBreakMismatched.go:30:27:30:33 | escaped | provenance | |
|
| StringBreakMismatched.go:26:13:26:61 | call to Replace | StringBreakMismatched.go:30:27:30:33 | escaped | provenance | |
|
||||||
| StringBreakMismatched.go:26:29:26:47 | type conversion | StringBreakMismatched.go:26:13:26:61 | call to Replace | provenance | MaD:1 |
|
| StringBreakMismatched.go:26:29:26:47 | type conversion | StringBreakMismatched.go:26:13:26:61 | call to Replace | provenance | MaD:1 |
|
||||||
models
|
models
|
||||||
| 1 | Summary: strings; ; false; Replace; ; ; Argument[0]; ReturnValue; taint; manual |
|
| 1 | Summary: strings; ; false; Replace; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||||
nodes
|
nodes
|
||||||
| StringBreak.go:11:2:11:40 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| StringBreak.go:11:2:11:40 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| StringBreak.go:15:47:15:57 | versionJSON | semmle.label | versionJSON |
|
| StringBreak.go:15:47:15:57 | versionJSON | semmle.label | versionJSON |
|
||||||
| StringBreakMismatched.go:13:2:13:40 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| StringBreakMismatched.go:13:2:13:40 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| StringBreakMismatched.go:14:13:14:62 | call to Replace | semmle.label | call to Replace |
|
| StringBreakMismatched.go:14:13:14:62 | call to Replace | semmle.label | call to Replace |
|
||||||
| StringBreakMismatched.go:14:29:14:47 | type conversion | semmle.label | type conversion |
|
| StringBreakMismatched.go:14:29:14:47 | type conversion | semmle.label | type conversion |
|
||||||
| StringBreakMismatched.go:18:26:18:32 | escaped | semmle.label | escaped |
|
| StringBreakMismatched.go:18:26:18:32 | escaped | semmle.label | escaped |
|
||||||
| StringBreakMismatched.go:25:2:25:40 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| StringBreakMismatched.go:25:2:25:40 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| StringBreakMismatched.go:26:13:26:61 | call to Replace | semmle.label | call to Replace |
|
| StringBreakMismatched.go:26:13:26:61 | call to Replace | semmle.label | call to Replace |
|
||||||
| StringBreakMismatched.go:26:29:26:47 | type conversion | semmle.label | type conversion |
|
| StringBreakMismatched.go:26:29:26:47 | type conversion | semmle.label | type conversion |
|
||||||
| StringBreakMismatched.go:30:27:30:33 | escaped | semmle.label | escaped |
|
| StringBreakMismatched.go:30:27:30:33 | escaped | semmle.label | escaped |
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
#select
|
#select
|
||||||
| AllocationSizeOverflow.go:10:10:10:22 | call to len | AllocationSizeOverflow.go:6:2:6:33 | extract:0 ... := ... | AllocationSizeOverflow.go:10:10:10:22 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | AllocationSizeOverflow.go:11:25:11:28 | size | allocation | AllocationSizeOverflow.go:6:2:6:33 | extract:0 ... := ... | potentially large value |
|
| AllocationSizeOverflow.go:10:10:10:22 | call to len | AllocationSizeOverflow.go:6:2:6:33 | ... := ...[0] | AllocationSizeOverflow.go:10:10:10:22 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | AllocationSizeOverflow.go:11:25:11:28 | size | allocation | AllocationSizeOverflow.go:6:2:6:33 | ... := ...[0] | potentially large value |
|
||||||
| tst2.go:10:22:10:30 | call to len | tst2.go:9:2:9:37 | extract:0 ... := ... | tst2.go:10:22:10:30 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst2.go:10:22:10:32 | ...+... | allocation | tst2.go:9:2:9:37 | extract:0 ... := ... | potentially large value |
|
| tst2.go:10:22:10:30 | call to len | tst2.go:9:2:9:37 | ... := ...[0] | tst2.go:10:22:10:30 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst2.go:10:22:10:32 | ...+... | allocation | tst2.go:9:2:9:37 | ... := ...[0] | potentially large value |
|
||||||
| tst2.go:15:22:15:30 | call to len | tst2.go:14:2:14:29 | extract:0 ... := ... | tst2.go:15:22:15:30 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst2.go:15:22:15:32 | ...+... | allocation | tst2.go:14:2:14:29 | extract:0 ... := ... | potentially large value |
|
| tst2.go:15:22:15:30 | call to len | tst2.go:14:2:14:29 | ... := ...[0] | tst2.go:15:22:15:30 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst2.go:15:22:15:32 | ...+... | allocation | tst2.go:14:2:14:29 | ... := ...[0] | potentially large value |
|
||||||
| tst3.go:7:22:7:34 | call to len | tst3.go:6:2:6:31 | extract:0 ... := ... | tst3.go:7:22:7:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst3.go:7:22:7:36 | ...+... | allocation | tst3.go:6:2:6:31 | extract:0 ... := ... | potentially large value |
|
| tst3.go:7:22:7:34 | call to len | tst3.go:6:2:6:31 | ... := ...[0] | tst3.go:7:22:7:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst3.go:7:22:7:36 | ...+... | allocation | tst3.go:6:2:6:31 | ... := ...[0] | potentially large value |
|
||||||
| tst3.go:24:16:24:28 | call to len | tst3.go:6:2:6:31 | extract:0 ... := ... | tst3.go:24:16:24:28 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst3.go:27:24:27:32 | newlength | allocation | tst3.go:6:2:6:31 | extract:0 ... := ... | potentially large value |
|
| tst3.go:24:16:24:28 | call to len | tst3.go:6:2:6:31 | ... := ...[0] | tst3.go:24:16:24:28 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst3.go:27:24:27:32 | newlength | allocation | tst3.go:6:2:6:31 | ... := ...[0] | potentially large value |
|
||||||
| tst3.go:32:16:32:28 | call to len | tst3.go:6:2:6:31 | extract:0 ... := ... | tst3.go:32:16:32:28 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst3.go:36:23:36:31 | newlength | allocation | tst3.go:6:2:6:31 | extract:0 ... := ... | potentially large value |
|
| tst3.go:32:16:32:28 | call to len | tst3.go:6:2:6:31 | ... := ...[0] | tst3.go:32:16:32:28 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst3.go:36:23:36:31 | newlength | allocation | tst3.go:6:2:6:31 | ... := ...[0] | potentially large value |
|
||||||
| tst.go:15:22:15:34 | call to len | tst.go:14:2:14:30 | extract:0 ... = ... | tst.go:15:22:15:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:15:22:15:36 | ...+... | allocation | tst.go:14:2:14:30 | extract:0 ... = ... | potentially large value |
|
| tst.go:15:22:15:34 | call to len | tst.go:14:2:14:30 | ... = ...[0] | tst.go:15:22:15:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:15:22:15:36 | ...+... | allocation | tst.go:14:2:14:30 | ... = ...[0] | potentially large value |
|
||||||
| tst.go:21:22:21:34 | call to len | tst.go:20:2:20:31 | extract:0 ... = ... | tst.go:21:22:21:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:21:22:21:36 | ...+... | allocation | tst.go:20:2:20:31 | extract:0 ... = ... | potentially large value |
|
| tst.go:21:22:21:34 | call to len | tst.go:20:2:20:31 | ... = ...[0] | tst.go:21:22:21:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:21:22:21:36 | ...+... | allocation | tst.go:20:2:20:31 | ... = ...[0] | potentially large value |
|
||||||
| tst.go:27:26:27:38 | call to len | tst.go:26:2:26:31 | extract:0 ... = ... | tst.go:27:26:27:38 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:27:26:27:40 | ...+... | allocation | tst.go:26:2:26:31 | extract:0 ... = ... | potentially large value |
|
| tst.go:27:26:27:38 | call to len | tst.go:26:2:26:31 | ... = ...[0] | tst.go:27:26:27:38 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:27:26:27:40 | ...+... | allocation | tst.go:26:2:26:31 | ... = ...[0] | potentially large value |
|
||||||
| tst.go:35:22:35:34 | call to len | tst.go:34:2:34:30 | extract:0 ... = ... | tst.go:35:22:35:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:35:22:35:36 | ...+... | allocation | tst.go:34:2:34:30 | extract:0 ... = ... | potentially large value |
|
| tst.go:35:22:35:34 | call to len | tst.go:34:2:34:30 | ... = ...[0] | tst.go:35:22:35:34 | call to len | This operation, which is used in an $@, involves a $@ and might overflow. | tst.go:35:22:35:36 | ...+... | allocation | tst.go:34:2:34:30 | ... = ...[0] | potentially large value |
|
||||||
edges
|
edges
|
||||||
| AllocationSizeOverflow.go:6:2:6:33 | extract:0 ... := ... | AllocationSizeOverflow.go:10:14:10:21 | jsonData | provenance | |
|
| AllocationSizeOverflow.go:6:2:6:33 | ... := ...[0] | AllocationSizeOverflow.go:10:14:10:21 | jsonData | provenance | |
|
||||||
| AllocationSizeOverflow.go:10:14:10:21 | jsonData | AllocationSizeOverflow.go:10:10:10:22 | call to len | provenance | Config |
|
| AllocationSizeOverflow.go:10:14:10:21 | jsonData | AllocationSizeOverflow.go:10:10:10:22 | call to len | provenance | Config |
|
||||||
| tst2.go:9:2:9:37 | extract:0 ... := ... | tst2.go:10:26:10:29 | data | provenance | Src:MaD:1 |
|
| tst2.go:9:2:9:37 | ... := ...[0] | tst2.go:10:26:10:29 | data | provenance | Src:MaD:1 |
|
||||||
| tst2.go:10:26:10:29 | data | tst2.go:10:22:10:30 | call to len | provenance | Config |
|
| tst2.go:10:26:10:29 | data | tst2.go:10:22:10:30 | call to len | provenance | Config |
|
||||||
| tst2.go:14:2:14:29 | extract:0 ... := ... | tst2.go:15:26:15:29 | data | provenance | |
|
| tst2.go:14:2:14:29 | ... := ...[0] | tst2.go:15:26:15:29 | data | provenance | |
|
||||||
| tst2.go:15:26:15:29 | data | tst2.go:15:22:15:30 | call to len | provenance | Config |
|
| tst2.go:15:26:15:29 | data | tst2.go:15:22:15:30 | call to len | provenance | Config |
|
||||||
| tst3.go:6:2:6:31 | extract:0 ... := ... | tst3.go:7:26:7:33 | jsonData | provenance | |
|
| tst3.go:6:2:6:31 | ... := ...[0] | tst3.go:7:26:7:33 | jsonData | provenance | |
|
||||||
| tst3.go:7:26:7:33 | jsonData | tst3.go:7:22:7:34 | call to len | provenance | Config |
|
| tst3.go:7:26:7:33 | jsonData | tst3.go:7:22:7:34 | call to len | provenance | Config |
|
||||||
| tst3.go:7:26:7:33 | jsonData | tst3.go:9:32:9:39 | jsonData | provenance | |
|
| tst3.go:7:26:7:33 | jsonData | tst3.go:9:32:9:39 | jsonData | provenance | |
|
||||||
| tst3.go:9:32:9:39 | jsonData | tst3.go:11:9:11:16 | jsonData | provenance | |
|
| tst3.go:9:32:9:39 | jsonData | tst3.go:11:9:11:16 | jsonData | provenance | |
|
||||||
@@ -25,27 +25,27 @@ edges
|
|||||||
| tst3.go:24:20:24:27 | jsonData | tst3.go:24:16:24:28 | call to len | provenance | Config |
|
| tst3.go:24:20:24:27 | jsonData | tst3.go:24:16:24:28 | call to len | provenance | Config |
|
||||||
| tst3.go:24:20:24:27 | jsonData | tst3.go:32:20:32:27 | jsonData | provenance | |
|
| tst3.go:24:20:24:27 | jsonData | tst3.go:32:20:32:27 | jsonData | provenance | |
|
||||||
| tst3.go:32:20:32:27 | jsonData | tst3.go:32:16:32:28 | call to len | provenance | Config |
|
| tst3.go:32:20:32:27 | jsonData | tst3.go:32:16:32:28 | call to len | provenance | Config |
|
||||||
| tst.go:14:2:14:30 | extract:0 ... = ... | tst.go:15:26:15:33 | jsonData | provenance | |
|
| tst.go:14:2:14:30 | ... = ...[0] | tst.go:15:26:15:33 | jsonData | provenance | |
|
||||||
| tst.go:15:26:15:33 | jsonData | tst.go:15:22:15:34 | call to len | provenance | Config |
|
| tst.go:15:26:15:33 | jsonData | tst.go:15:22:15:34 | call to len | provenance | Config |
|
||||||
| tst.go:20:2:20:31 | extract:0 ... = ... | tst.go:21:26:21:33 | jsonData | provenance | |
|
| tst.go:20:2:20:31 | ... = ...[0] | tst.go:21:26:21:33 | jsonData | provenance | |
|
||||||
| tst.go:21:26:21:33 | jsonData | tst.go:21:22:21:34 | call to len | provenance | Config |
|
| tst.go:21:26:21:33 | jsonData | tst.go:21:22:21:34 | call to len | provenance | Config |
|
||||||
| tst.go:26:2:26:31 | extract:0 ... = ... | tst.go:27:30:27:37 | jsonData | provenance | |
|
| tst.go:26:2:26:31 | ... = ...[0] | tst.go:27:30:27:37 | jsonData | provenance | |
|
||||||
| tst.go:27:30:27:37 | jsonData | tst.go:27:26:27:38 | call to len | provenance | Config |
|
| tst.go:27:30:27:37 | jsonData | tst.go:27:26:27:38 | call to len | provenance | Config |
|
||||||
| tst.go:34:2:34:30 | extract:0 ... = ... | tst.go:35:26:35:33 | jsonData | provenance | |
|
| tst.go:34:2:34:30 | ... = ...[0] | tst.go:35:26:35:33 | jsonData | provenance | |
|
||||||
| tst.go:35:26:35:33 | jsonData | tst.go:35:22:35:34 | call to len | provenance | Config |
|
| tst.go:35:26:35:33 | jsonData | tst.go:35:22:35:34 | call to len | provenance | Config |
|
||||||
models
|
models
|
||||||
| 1 | Source: io/ioutil; ; false; ReadFile; ; ; ReturnValue[0]; file; manual |
|
| 1 | Source: io/ioutil; ; false; ReadFile; ; ; ReturnValue[0]; file; manual |
|
||||||
nodes
|
nodes
|
||||||
| AllocationSizeOverflow.go:6:2:6:33 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| AllocationSizeOverflow.go:6:2:6:33 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| AllocationSizeOverflow.go:10:10:10:22 | call to len | semmle.label | call to len |
|
| AllocationSizeOverflow.go:10:10:10:22 | call to len | semmle.label | call to len |
|
||||||
| AllocationSizeOverflow.go:10:14:10:21 | jsonData | semmle.label | jsonData |
|
| AllocationSizeOverflow.go:10:14:10:21 | jsonData | semmle.label | jsonData |
|
||||||
| tst2.go:9:2:9:37 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| tst2.go:9:2:9:37 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| tst2.go:10:22:10:30 | call to len | semmle.label | call to len |
|
| tst2.go:10:22:10:30 | call to len | semmle.label | call to len |
|
||||||
| tst2.go:10:26:10:29 | data | semmle.label | data |
|
| tst2.go:10:26:10:29 | data | semmle.label | data |
|
||||||
| tst2.go:14:2:14:29 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| tst2.go:14:2:14:29 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| tst2.go:15:22:15:30 | call to len | semmle.label | call to len |
|
| tst2.go:15:22:15:30 | call to len | semmle.label | call to len |
|
||||||
| tst2.go:15:26:15:29 | data | semmle.label | data |
|
| tst2.go:15:26:15:29 | data | semmle.label | data |
|
||||||
| tst3.go:6:2:6:31 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| tst3.go:6:2:6:31 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| tst3.go:7:22:7:34 | call to len | semmle.label | call to len |
|
| tst3.go:7:22:7:34 | call to len | semmle.label | call to len |
|
||||||
| tst3.go:7:26:7:33 | jsonData | semmle.label | jsonData |
|
| tst3.go:7:26:7:33 | jsonData | semmle.label | jsonData |
|
||||||
| tst3.go:9:32:9:39 | jsonData | semmle.label | jsonData |
|
| tst3.go:9:32:9:39 | jsonData | semmle.label | jsonData |
|
||||||
@@ -55,16 +55,16 @@ nodes
|
|||||||
| tst3.go:24:20:24:27 | jsonData | semmle.label | jsonData |
|
| tst3.go:24:20:24:27 | jsonData | semmle.label | jsonData |
|
||||||
| tst3.go:32:16:32:28 | call to len | semmle.label | call to len |
|
| tst3.go:32:16:32:28 | call to len | semmle.label | call to len |
|
||||||
| tst3.go:32:20:32:27 | jsonData | semmle.label | jsonData |
|
| tst3.go:32:20:32:27 | jsonData | semmle.label | jsonData |
|
||||||
| tst.go:14:2:14:30 | extract:0 ... = ... | semmle.label | extract:0 ... = ... |
|
| tst.go:14:2:14:30 | ... = ...[0] | semmle.label | ... = ...[0] |
|
||||||
| tst.go:15:22:15:34 | call to len | semmle.label | call to len |
|
| tst.go:15:22:15:34 | call to len | semmle.label | call to len |
|
||||||
| tst.go:15:26:15:33 | jsonData | semmle.label | jsonData |
|
| tst.go:15:26:15:33 | jsonData | semmle.label | jsonData |
|
||||||
| tst.go:20:2:20:31 | extract:0 ... = ... | semmle.label | extract:0 ... = ... |
|
| tst.go:20:2:20:31 | ... = ...[0] | semmle.label | ... = ...[0] |
|
||||||
| tst.go:21:22:21:34 | call to len | semmle.label | call to len |
|
| tst.go:21:22:21:34 | call to len | semmle.label | call to len |
|
||||||
| tst.go:21:26:21:33 | jsonData | semmle.label | jsonData |
|
| tst.go:21:26:21:33 | jsonData | semmle.label | jsonData |
|
||||||
| tst.go:26:2:26:31 | extract:0 ... = ... | semmle.label | extract:0 ... = ... |
|
| tst.go:26:2:26:31 | ... = ...[0] | semmle.label | ... = ...[0] |
|
||||||
| tst.go:27:26:27:38 | call to len | semmle.label | call to len |
|
| tst.go:27:26:27:38 | call to len | semmle.label | call to len |
|
||||||
| tst.go:27:30:27:37 | jsonData | semmle.label | jsonData |
|
| tst.go:27:30:27:37 | jsonData | semmle.label | jsonData |
|
||||||
| tst.go:34:2:34:30 | extract:0 ... = ... | semmle.label | extract:0 ... = ... |
|
| tst.go:34:2:34:30 | ... = ...[0] | semmle.label | ... = ...[0] |
|
||||||
| tst.go:35:22:35:34 | call to len | semmle.label | call to len |
|
| tst.go:35:22:35:34 | call to len | semmle.label | call to len |
|
||||||
| tst.go:35:26:35:33 | jsonData | semmle.label | jsonData |
|
| tst.go:35:26:35:33 | jsonData | semmle.label | jsonData |
|
||||||
subpaths
|
subpaths
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
| DisabledCertificateCheck.go:10:32:10:55 | lit-init key-value pair | InsecureSkipVerify should not be used in production code. |
|
| DisabledCertificateCheck.go:10:32:10:55 | init of key-value pair | InsecureSkipVerify should not be used in production code. |
|
||||||
| main.go:9:2:9:30 | assign:0 ... = ... | InsecureSkipVerify should not be used in production code. |
|
| main.go:9:2:9:23 | assignment to field InsecureSkipVerify | InsecureSkipVerify should not be used in production code. |
|
||||||
| main.go:57:21:57:44 | lit-init key-value pair | InsecureSkipVerify should not be used in production code. |
|
| main.go:57:21:57:44 | init of key-value pair | InsecureSkipVerify should not be used in production code. |
|
||||||
| main.go:62:32:62:55 | lit-init key-value pair | InsecureSkipVerify should not be used in production code. |
|
| main.go:62:32:62:55 | init of key-value pair | InsecureSkipVerify should not be used in production code. |
|
||||||
|
|||||||
@@ -1,85 +1,80 @@
|
|||||||
#select
|
#select
|
||||||
| klog.go:23:15:23:20 | header | klog.go:21:30:21:37 | selection of Header | klog.go:23:15:23:20 | header | $@ flows to a logging call. | klog.go:21:30:21:37 | selection of Header | Sensitive data returned by HTTP request headers |
|
| klog.go:23:15:23:20 | header | klog.go:21:30:21:37 | selection of Header | klog.go:23:15:23:20 | header | $@ flows to a logging call. | klog.go:21:30:21:37 | selection of Header | Sensitive data returned by HTTP request headers |
|
||||||
| klog.go:29:13:29:41 | call to Get | klog.go:29:13:29:20 | selection of Header | klog.go:29:13:29:41 | call to Get | $@ flows to a logging call. | klog.go:29:13:29:20 | selection of Header | Sensitive data returned by HTTP request headers |
|
| klog.go:29:13:29:41 | call to Get | klog.go:29:13:29:20 | selection of Header | klog.go:29:13:29:41 | call to Get | $@ flows to a logging call. | klog.go:29:13:29:20 | selection of Header | Sensitive data returned by HTTP request headers |
|
||||||
| main.go:19:12:19:19 | password | main.go:17:2:17:23 | SSA def(password) | main.go:19:12:19:19 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:19:12:19:19 | password | main.go:17:2:17:9 | SSA def(password) | main.go:19:12:19:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:20:19:20:26 | password | main.go:17:2:17:23 | SSA def(password) | main.go:20:19:20:26 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:20:19:20:26 | password | main.go:17:2:17:9 | SSA def(password) | main.go:20:19:20:26 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:21:13:21:20 | password | main.go:17:2:17:23 | SSA def(password) | main.go:21:13:21:20 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:21:13:21:20 | password | main.go:17:2:17:9 | SSA def(password) | main.go:21:13:21:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:22:14:22:21 | password | main.go:17:2:17:23 | SSA def(password) | main.go:22:14:22:21 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:22:14:22:21 | password | main.go:17:2:17:9 | SSA def(password) | main.go:22:14:22:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:24:13:24:20 | password | main.go:17:2:17:23 | SSA def(password) | main.go:24:13:24:20 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:24:13:24:20 | password | main.go:17:2:17:9 | SSA def(password) | main.go:24:13:24:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:27:20:27:27 | password | main.go:17:2:17:23 | SSA def(password) | main.go:27:20:27:27 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:27:20:27:27 | password | main.go:17:2:17:9 | SSA def(password) | main.go:27:20:27:27 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:30:14:30:21 | password | main.go:17:2:17:23 | SSA def(password) | main.go:30:14:30:21 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:30:14:30:21 | password | main.go:17:2:17:9 | SSA def(password) | main.go:30:14:30:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:33:15:33:22 | password | main.go:17:2:17:23 | SSA def(password) | main.go:33:15:33:22 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:33:15:33:22 | password | main.go:17:2:17:9 | SSA def(password) | main.go:33:15:33:22 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:36:13:36:20 | password | main.go:17:2:17:23 | SSA def(password) | main.go:36:13:36:20 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:36:13:36:20 | password | main.go:17:2:17:9 | SSA def(password) | main.go:36:13:36:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:39:20:39:27 | password | main.go:17:2:17:23 | SSA def(password) | main.go:39:20:39:27 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:39:20:39:27 | password | main.go:17:2:17:9 | SSA def(password) | main.go:39:20:39:27 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:42:14:42:21 | password | main.go:17:2:17:23 | SSA def(password) | main.go:42:14:42:21 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:42:14:42:21 | password | main.go:17:2:17:9 | SSA def(password) | main.go:42:14:42:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:45:15:45:22 | password | main.go:17:2:17:23 | SSA def(password) | main.go:45:15:45:22 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:45:15:45:22 | password | main.go:17:2:17:9 | SSA def(password) | main.go:45:15:45:22 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:47:16:47:23 | password | main.go:17:2:17:23 | SSA def(password) | main.go:47:16:47:23 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:47:16:47:23 | password | main.go:17:2:17:9 | SSA def(password) | main.go:47:16:47:23 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:51:10:51:17 | password | main.go:17:2:17:23 | SSA def(password) | main.go:51:10:51:17 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:51:10:51:17 | password | main.go:17:2:17:9 | SSA def(password) | main.go:51:10:51:17 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:52:17:52:24 | password | main.go:17:2:17:23 | SSA def(password) | main.go:52:17:52:24 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:52:17:52:24 | password | main.go:17:2:17:9 | SSA def(password) | main.go:52:17:52:24 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:53:11:53:18 | password | main.go:17:2:17:23 | SSA def(password) | main.go:53:11:53:18 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:53:11:53:18 | password | main.go:17:2:17:9 | SSA def(password) | main.go:53:11:53:18 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:54:12:54:19 | password | main.go:17:2:17:23 | SSA def(password) | main.go:54:12:54:19 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:54:12:54:19 | password | main.go:17:2:17:9 | SSA def(password) | main.go:54:12:54:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:56:11:56:18 | password | main.go:17:2:17:23 | SSA def(password) | main.go:56:11:56:18 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:56:11:56:18 | password | main.go:17:2:17:9 | SSA def(password) | main.go:56:11:56:18 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:59:18:59:25 | password | main.go:17:2:17:23 | SSA def(password) | main.go:59:18:59:25 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:59:18:59:25 | password | main.go:17:2:17:9 | SSA def(password) | main.go:59:18:59:25 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:62:12:62:19 | password | main.go:17:2:17:23 | SSA def(password) | main.go:62:12:62:19 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:62:12:62:19 | password | main.go:17:2:17:9 | SSA def(password) | main.go:62:12:62:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:65:13:65:20 | password | main.go:17:2:17:23 | SSA def(password) | main.go:65:13:65:20 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:65:13:65:20 | password | main.go:17:2:17:9 | SSA def(password) | main.go:65:13:65:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:68:11:68:18 | password | main.go:17:2:17:23 | SSA def(password) | main.go:68:11:68:18 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:68:11:68:18 | password | main.go:17:2:17:9 | SSA def(password) | main.go:68:11:68:18 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:71:18:71:25 | password | main.go:17:2:17:23 | SSA def(password) | main.go:71:18:71:25 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:71:18:71:25 | password | main.go:17:2:17:9 | SSA def(password) | main.go:71:18:71:25 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:74:12:74:19 | password | main.go:17:2:17:23 | SSA def(password) | main.go:74:12:74:19 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:74:12:74:19 | password | main.go:17:2:17:9 | SSA def(password) | main.go:74:12:74:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:77:13:77:20 | password | main.go:17:2:17:23 | SSA def(password) | main.go:77:13:77:20 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:77:13:77:20 | password | main.go:17:2:17:9 | SSA def(password) | main.go:77:13:77:20 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:79:14:79:21 | password | main.go:17:2:17:23 | SSA def(password) | main.go:79:14:79:21 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:79:14:79:21 | password | main.go:17:2:17:9 | SSA def(password) | main.go:79:14:79:21 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:82:12:82:19 | password | main.go:17:2:17:23 | SSA def(password) | main.go:82:12:82:19 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:82:12:82:19 | password | main.go:17:2:17:9 | SSA def(password) | main.go:82:12:82:19 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:83:17:83:24 | password | main.go:17:2:17:23 | SSA def(password) | main.go:83:17:83:24 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:83:17:83:24 | password | main.go:17:2:17:9 | SSA def(password) | main.go:83:17:83:24 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:87:29:87:34 | fields | main.go:17:2:17:23 | SSA def(password) | main.go:87:29:87:34 | fields | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:87:29:87:34 | fields | main.go:17:2:17:9 | SSA def(password) | main.go:87:29:87:34 | fields | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| main.go:90:35:90:42 | password | main.go:17:2:17:23 | SSA def(password) | main.go:90:35:90:42 | password | $@ flows to a logging call. | main.go:17:2:17:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| main.go:90:35:90:42 | password | main.go:17:2:17:9 | SSA def(password) | main.go:90:35:90:42 | password | $@ flows to a logging call. | main.go:17:2:17:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| overrides.go:13:14:13:23 | call to String | overrides.go:8:2:8:40 | SSA def(password) | overrides.go:13:14:13:23 | call to String | $@ flows to a logging call. | overrides.go:8:2:8:40 | SSA def(password) | Sensitive data returned by an access to password |
|
| overrides.go:13:14:13:23 | call to String | overrides.go:8:2:8:9 | SSA def(password) | overrides.go:13:14:13:23 | call to String | $@ flows to a logging call. | overrides.go:8:2:8:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| passwords.go:9:14:9:14 | x | passwords.go:21:2:21:23 | SSA def(password) | passwords.go:9:14:9:14 | x | $@ flows to a logging call. | passwords.go:21:2:21:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| passwords.go:9:14:9:14 | x | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:9:14:9:14 | x | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| passwords.go:25:14:25:21 | password | passwords.go:21:2:21:23 | SSA def(password) | passwords.go:25:14:25:21 | password | $@ flows to a logging call. | passwords.go:21:2:21:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| passwords.go:25:14:25:21 | password | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:25:14:25:21 | password | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | $@ flows to a logging call. | passwords.go:26:14:26:23 | selection of password | Sensitive data returned by an access to password |
|
| passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | passwords.go:26:14:26:23 | selection of password | $@ flows to a logging call. | passwords.go:26:14:26:23 | selection of password | Sensitive data returned by an access to password |
|
||||||
| passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | $@ flows to a logging call. | passwords.go:27:14:27:26 | call to getPassword | Sensitive data returned by a call to getPassword |
|
| passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | passwords.go:27:14:27:26 | call to getPassword | $@ flows to a logging call. | passwords.go:27:14:27:26 | call to getPassword | Sensitive data returned by a call to getPassword |
|
||||||
| passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | $@ flows to a logging call. | passwords.go:28:14:28:28 | call to getPassword | Sensitive data returned by a call to getPassword |
|
| passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | passwords.go:28:14:28:28 | call to getPassword | $@ flows to a logging call. | passwords.go:28:14:28:28 | call to getPassword | Sensitive data returned by a call to getPassword |
|
||||||
| passwords.go:33:13:33:20 | password | passwords.go:21:2:21:23 | SSA def(password) | passwords.go:33:13:33:20 | password | $@ flows to a logging call. | passwords.go:21:2:21:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| passwords.go:33:13:33:20 | password | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:33:13:33:20 | password | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| passwords.go:36:14:36:35 | ...+... | passwords.go:21:2:21:23 | SSA def(password) | passwords.go:36:14:36:35 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| passwords.go:36:14:36:35 | ...+... | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:36:14:36:35 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| passwords.go:41:14:41:17 | obj1 | passwords.go:39:3:39:13 | key-value pair | passwords.go:41:14:41:17 | obj1 | $@ flows to a logging call. | passwords.go:39:3:39:13 | key-value pair | Sensitive data returned by an access to password |
|
|
||||||
| passwords.go:41:14:41:17 | obj1 | passwords.go:39:13:39:13 | x | passwords.go:41:14:41:17 | obj1 | $@ flows to a logging call. | passwords.go:39:13:39:13 | x | Sensitive data returned by an access to password |
|
| passwords.go:41:14:41:17 | obj1 | passwords.go:39:13:39:13 | x | passwords.go:41:14:41:17 | obj1 | $@ flows to a logging call. | passwords.go:39:13:39:13 | x | Sensitive data returned by an access to password |
|
||||||
| passwords.go:46:14:46:17 | obj2 | passwords.go:21:2:21:23 | SSA def(password) | passwords.go:46:14:46:17 | obj2 | $@ flows to a logging call. | passwords.go:21:2:21:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| passwords.go:46:14:46:17 | obj2 | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:46:14:46:17 | obj2 | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| passwords.go:53:14:53:27 | fixed_password | passwords.go:52:2:52:44 | SSA def(fixed_password) | passwords.go:53:14:53:27 | fixed_password | $@ flows to a logging call. | passwords.go:52:2:52:44 | SSA def(fixed_password) | Sensitive data returned by an access to fixed_password |
|
| passwords.go:53:14:53:27 | fixed_password | passwords.go:52:2:52:15 | SSA def(fixed_password) | passwords.go:53:14:53:27 | fixed_password | $@ flows to a logging call. | passwords.go:52:2:52:15 | SSA def(fixed_password) | Sensitive data returned by an access to fixed_password |
|
||||||
| passwords.go:65:14:65:44 | struct literal | passwords.go:65:25:65:43 | key-value pair | passwords.go:65:14:65:44 | struct literal | $@ flows to a logging call. | passwords.go:65:25:65:43 | key-value pair | Sensitive data returned by an access to password |
|
|
||||||
| passwords.go:91:14:91:26 | utilityObject | passwords.go:89:3:89:36 | key-value pair | passwords.go:91:14:91:26 | utilityObject | $@ flows to a logging call. | passwords.go:89:3:89:36 | key-value pair | Sensitive data returned by an access to passwordSet |
|
|
||||||
| passwords.go:91:14:91:26 | utilityObject | passwords.go:89:16:89:36 | call to make | passwords.go:91:14:91:26 | utilityObject | $@ flows to a logging call. | passwords.go:89:16:89:36 | call to make | Sensitive data returned by an access to passwordSet |
|
| passwords.go:91:14:91:26 | utilityObject | passwords.go:89:16:89:36 | call to make | passwords.go:91:14:91:26 | utilityObject | $@ flows to a logging call. | passwords.go:89:16:89:36 | call to make | Sensitive data returned by an access to passwordSet |
|
||||||
| passwords.go:94:23:94:28 | secret | passwords.go:21:2:21:23 | SSA def(password) | passwords.go:94:23:94:28 | secret | $@ flows to a logging call. | passwords.go:21:2:21:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| passwords.go:94:23:94:28 | secret | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:94:23:94:28 | secret | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| passwords.go:104:15:104:40 | ...+... | passwords.go:21:2:21:23 | SSA def(password) | passwords.go:104:15:104:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| passwords.go:104:15:104:40 | ...+... | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:104:15:104:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| passwords.go:110:16:110:41 | ...+... | passwords.go:21:2:21:23 | SSA def(password) | passwords.go:110:16:110:41 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| passwords.go:110:16:110:41 | ...+... | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:110:16:110:41 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| passwords.go:115:15:115:40 | ...+... | passwords.go:21:2:21:23 | SSA def(password) | passwords.go:115:15:115:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| passwords.go:115:15:115:40 | ...+... | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:115:15:115:40 | ...+... | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| passwords.go:119:14:119:45 | ...+... | passwords.go:118:6:118:50 | SSA def(password1) | passwords.go:119:14:119:45 | ...+... | $@ flows to a logging call. | passwords.go:118:6:118:50 | SSA def(password1) | Sensitive data returned by an access to password1 |
|
| passwords.go:119:14:119:45 | ...+... | passwords.go:118:6:118:14 | SSA def(password1) | passwords.go:119:14:119:45 | ...+... | $@ flows to a logging call. | passwords.go:118:6:118:14 | SSA def(password1) | Sensitive data returned by an access to password1 |
|
||||||
| passwords.go:129:14:129:19 | config | passwords.go:21:2:21:23 | SSA def(password) | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:21:2:21:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| passwords.go:129:14:129:19 | config | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| passwords.go:129:14:129:19 | config | passwords.go:123:3:123:14 | key-value pair | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:123:3:123:14 | key-value pair | Sensitive data returned by an access to password |
|
|
||||||
| passwords.go:129:14:129:19 | config | passwords.go:123:13:123:14 | x3 | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:123:13:123:14 | x3 | Sensitive data returned by an access to password |
|
| passwords.go:129:14:129:19 | config | passwords.go:123:13:123:14 | x3 | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:123:13:123:14 | x3 | Sensitive data returned by an access to password |
|
||||||
| passwords.go:129:14:129:19 | config | passwords.go:126:13:126:25 | call to getPassword | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:126:13:126:25 | call to getPassword | Sensitive data returned by a call to getPassword |
|
| passwords.go:129:14:129:19 | config | passwords.go:126:13:126:25 | call to getPassword | passwords.go:129:14:129:19 | config | $@ flows to a logging call. | passwords.go:126:13:126:25 | call to getPassword | Sensitive data returned by a call to getPassword |
|
||||||
| passwords.go:130:14:130:21 | selection of x | passwords.go:21:2:21:23 | SSA def(password) | passwords.go:130:14:130:21 | selection of x | $@ flows to a logging call. | passwords.go:21:2:21:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| passwords.go:130:14:130:21 | selection of x | passwords.go:21:2:21:9 | SSA def(password) | passwords.go:130:14:130:21 | selection of x | $@ flows to a logging call. | passwords.go:21:2:21:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| passwords.go:131:14:131:21 | selection of y | passwords.go:126:13:126:25 | call to getPassword | passwords.go:131:14:131:21 | selection of y | $@ flows to a logging call. | passwords.go:126:13:126:25 | call to getPassword | Sensitive data returned by a call to getPassword |
|
| passwords.go:131:14:131:21 | selection of y | passwords.go:126:13:126:25 | call to getPassword | passwords.go:131:14:131:21 | selection of y | $@ flows to a logging call. | passwords.go:126:13:126:25 | call to getPassword | Sensitive data returned by a call to getPassword |
|
||||||
| protobuf.go:14:14:14:35 | call to GetDescription | protobuf.go:9:2:9:23 | SSA def(password) | protobuf.go:14:14:14:35 | call to GetDescription | $@ flows to a logging call. | protobuf.go:9:2:9:23 | SSA def(password) | Sensitive data returned by an access to password |
|
| protobuf.go:14:14:14:35 | call to GetDescription | protobuf.go:9:2:9:9 | SSA def(password) | protobuf.go:14:14:14:35 | call to GetDescription | $@ flows to a logging call. | protobuf.go:9:2:9:9 | SSA def(password) | Sensitive data returned by an access to password |
|
||||||
| server1.go:19:15:19:19 | user3 | server1.go:17:4:17:63 | key-value pair | server1.go:19:15:19:19 | user3 | $@ flows to a logging call. | server1.go:17:4:17:63 | key-value pair | Sensitive data returned by an access to password |
|
|
||||||
edges
|
edges
|
||||||
| klog.go:21:3:26:3 | extract:1 range statement | klog.go:22:27:22:33 | headers | provenance | |
|
| klog.go:21:3:26:3 | range statement[1] | klog.go:22:27:22:33 | headers | provenance | |
|
||||||
| klog.go:21:30:21:37 | selection of Header | klog.go:21:3:26:3 | extract:1 range statement | provenance | Src:MaD:11 Config |
|
| klog.go:21:30:21:37 | selection of Header | klog.go:21:3:26:3 | range statement[1] | provenance | Src:MaD:11 Config |
|
||||||
| klog.go:22:4:25:4 | extract:1 range statement | klog.go:23:15:23:20 | header | provenance | |
|
| klog.go:22:4:25:4 | range statement[1] | klog.go:23:15:23:20 | header | provenance | |
|
||||||
| klog.go:22:27:22:33 | headers | klog.go:22:4:25:4 | extract:1 range statement | provenance | Config |
|
| klog.go:22:27:22:33 | headers | klog.go:22:4:25:4 | range statement[1] | provenance | Config |
|
||||||
| klog.go:29:13:29:20 | selection of Header | klog.go:29:13:29:41 | call to Get | provenance | Src:MaD:11 Config |
|
| klog.go:29:13:29:20 | selection of Header | klog.go:29:13:29:41 | call to Get | provenance | Src:MaD:11 Config |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | main.go:19:12:19:19 | password | provenance | |
|
| main.go:17:2:17:9 | SSA def(password) | main.go:19:12:19:19 | password | provenance | |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | main.go:20:19:20:26 | password | provenance | |
|
| main.go:17:2:17:9 | SSA def(password) | main.go:20:19:20:26 | password | provenance | |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | main.go:21:13:21:20 | password | provenance | Sink:MaD:6 |
|
| main.go:17:2:17:9 | SSA def(password) | main.go:21:13:21:20 | password | provenance | Sink:MaD:6 |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | main.go:22:14:22:21 | password | provenance | |
|
| main.go:17:2:17:9 | SSA def(password) | main.go:22:14:22:21 | password | provenance | |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | main.go:24:13:24:20 | password | provenance | |
|
| main.go:17:2:17:9 | SSA def(password) | main.go:24:13:24:20 | password | provenance | |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | main.go:27:20:27:27 | password | provenance | |
|
| main.go:17:2:17:9 | SSA def(password) | main.go:27:20:27:27 | password | provenance | |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | main.go:30:14:30:21 | password | provenance | Sink:MaD:3 |
|
| main.go:17:2:17:9 | SSA def(password) | main.go:30:14:30:21 | password | provenance | Sink:MaD:3 |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | main.go:33:15:33:22 | password | provenance | |
|
| main.go:17:2:17:9 | SSA def(password) | main.go:33:15:33:22 | password | provenance | |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | main.go:36:13:36:20 | password | provenance | |
|
| main.go:17:2:17:9 | SSA def(password) | main.go:36:13:36:20 | password | provenance | |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | main.go:39:20:39:27 | password | provenance | |
|
| main.go:17:2:17:9 | SSA def(password) | main.go:39:20:39:27 | password | provenance | |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | main.go:42:14:42:21 | password | provenance | Sink:MaD:5 |
|
| main.go:17:2:17:9 | SSA def(password) | main.go:42:14:42:21 | password | provenance | Sink:MaD:5 |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | main.go:45:15:45:22 | password | provenance | |
|
| main.go:17:2:17:9 | SSA def(password) | main.go:45:15:45:22 | password | provenance | |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | main.go:47:16:47:23 | password | provenance | Sink:MaD:4 |
|
| main.go:17:2:17:9 | SSA def(password) | main.go:47:16:47:23 | password | provenance | Sink:MaD:4 |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | main.go:51:10:51:17 | password | provenance | |
|
| main.go:17:2:17:9 | SSA def(password) | main.go:51:10:51:17 | password | provenance | |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | main.go:51:10:51:17 | password | provenance | |
|
| main.go:17:2:17:9 | SSA def(password) | main.go:51:10:51:17 | password | provenance | |
|
||||||
| main.go:51:10:51:17 | password | main.go:52:17:52:24 | password | provenance | |
|
| main.go:51:10:51:17 | password | main.go:52:17:52:24 | password | provenance | |
|
||||||
| main.go:51:10:51:17 | password | main.go:52:17:52:24 | password | provenance | |
|
| main.go:51:10:51:17 | password | main.go:52:17:52:24 | password | provenance | |
|
||||||
| main.go:52:17:52:24 | password | main.go:53:11:53:18 | password | provenance | |
|
| main.go:52:17:52:24 | password | main.go:53:11:53:18 | password | provenance | |
|
||||||
@@ -102,18 +97,17 @@ edges
|
|||||||
| main.go:86:2:86:7 | fields [postupdate] | main.go:87:29:87:34 | fields | provenance | Sink:MaD:2 |
|
| main.go:86:2:86:7 | fields [postupdate] | main.go:87:29:87:34 | fields | provenance | Sink:MaD:2 |
|
||||||
| main.go:86:19:86:26 | password | main.go:86:2:86:7 | fields [postupdate] | provenance | Config |
|
| main.go:86:19:86:26 | password | main.go:86:2:86:7 | fields [postupdate] | provenance | Config |
|
||||||
| main.go:86:19:86:26 | password | main.go:90:35:90:42 | password | provenance | Sink:MaD:1 |
|
| main.go:86:19:86:26 | password | main.go:90:35:90:42 | password | provenance | Sink:MaD:1 |
|
||||||
| overrides.go:8:2:8:40 | SSA def(password) | overrides.go:9:9:9:16 | password | provenance | |
|
| overrides.go:8:2:8:9 | SSA def(password) | overrides.go:9:9:9:16 | password | provenance | |
|
||||||
| overrides.go:9:9:9:16 | password | overrides.go:13:14:13:23 | call to String | provenance | |
|
| overrides.go:9:9:9:16 | password | overrides.go:13:14:13:23 | call to String | provenance | |
|
||||||
| passwords.go:8:22:10:1 | SSA def(x) | passwords.go:9:14:9:14 | x | provenance | |
|
| passwords.go:8:12:8:12 | SSA def(x) | passwords.go:9:14:9:14 | x | provenance | |
|
||||||
| passwords.go:21:2:21:23 | SSA def(password) | passwords.go:25:14:25:21 | password | provenance | |
|
| passwords.go:21:2:21:9 | SSA def(password) | passwords.go:25:14:25:21 | password | provenance | |
|
||||||
| passwords.go:21:2:21:23 | SSA def(password) | passwords.go:30:8:30:15 | password | provenance | |
|
| passwords.go:21:2:21:9 | SSA def(password) | passwords.go:30:8:30:15 | password | provenance | |
|
||||||
| passwords.go:21:2:21:23 | SSA def(password) | passwords.go:33:13:33:20 | password | provenance | |
|
| passwords.go:21:2:21:9 | SSA def(password) | passwords.go:33:13:33:20 | password | provenance | |
|
||||||
| passwords.go:21:2:21:23 | SSA def(password) | passwords.go:36:28:36:35 | password | provenance | |
|
| passwords.go:21:2:21:9 | SSA def(password) | passwords.go:36:28:36:35 | password | provenance | |
|
||||||
| passwords.go:30:8:30:15 | password | passwords.go:8:22:10:1 | SSA def(x) | provenance | |
|
| passwords.go:30:8:30:15 | password | passwords.go:8:12:8:12 | SSA def(x) | provenance | |
|
||||||
| passwords.go:36:28:36:35 | password | passwords.go:36:14:36:35 | ...+... | provenance | Config |
|
| passwords.go:36:28:36:35 | password | passwords.go:36:14:36:35 | ...+... | provenance | Config |
|
||||||
| passwords.go:36:28:36:35 | password | passwords.go:44:6:44:13 | password | provenance | |
|
| passwords.go:36:28:36:35 | password | passwords.go:44:6:44:13 | password | provenance | |
|
||||||
| passwords.go:38:10:40:2 | struct literal | passwords.go:41:14:41:17 | obj1 | provenance | |
|
| passwords.go:38:10:40:2 | struct literal | passwords.go:41:14:41:17 | obj1 | provenance | |
|
||||||
| passwords.go:39:3:39:13 | key-value pair | passwords.go:38:10:40:2 | struct literal | provenance | Config |
|
|
||||||
| passwords.go:39:13:39:13 | x | passwords.go:38:10:40:2 | struct literal | provenance | Config |
|
| passwords.go:39:13:39:13 | x | passwords.go:38:10:40:2 | struct literal | provenance | Config |
|
||||||
| passwords.go:43:10:45:2 | struct literal | passwords.go:46:14:46:17 | obj2 | provenance | |
|
| passwords.go:43:10:45:2 | struct literal | passwords.go:46:14:46:17 | obj2 | provenance | |
|
||||||
| passwords.go:44:6:44:13 | password | passwords.go:43:10:45:2 | struct literal | provenance | Config |
|
| passwords.go:44:6:44:13 | password | passwords.go:43:10:45:2 | struct literal | provenance | Config |
|
||||||
@@ -123,10 +117,8 @@ edges
|
|||||||
| passwords.go:50:11:50:18 | password | passwords.go:110:34:110:41 | password | provenance | |
|
| passwords.go:50:11:50:18 | password | passwords.go:110:34:110:41 | password | provenance | |
|
||||||
| passwords.go:50:11:50:18 | password | passwords.go:115:33:115:40 | password | provenance | |
|
| passwords.go:50:11:50:18 | password | passwords.go:115:33:115:40 | password | provenance | |
|
||||||
| passwords.go:50:11:50:18 | password | passwords.go:125:13:125:20 | password | provenance | |
|
| passwords.go:50:11:50:18 | password | passwords.go:125:13:125:20 | password | provenance | |
|
||||||
| passwords.go:52:2:52:44 | SSA def(fixed_password) | passwords.go:53:14:53:27 | fixed_password | provenance | |
|
| passwords.go:52:2:52:15 | SSA def(fixed_password) | passwords.go:53:14:53:27 | fixed_password | provenance | |
|
||||||
| passwords.go:65:25:65:43 | key-value pair | passwords.go:65:14:65:44 | struct literal | provenance | Config |
|
|
||||||
| passwords.go:88:19:90:2 | struct literal | passwords.go:91:14:91:26 | utilityObject | provenance | |
|
| passwords.go:88:19:90:2 | struct literal | passwords.go:91:14:91:26 | utilityObject | provenance | |
|
||||||
| passwords.go:89:3:89:36 | key-value pair | passwords.go:88:19:90:2 | struct literal | provenance | Config |
|
|
||||||
| passwords.go:89:16:89:36 | call to make | passwords.go:88:19:90:2 | struct literal | provenance | Config |
|
| passwords.go:89:16:89:36 | call to make | passwords.go:88:19:90:2 | struct literal | provenance | Config |
|
||||||
| passwords.go:104:33:104:40 | password | passwords.go:104:15:104:40 | ...+... | provenance | Config |
|
| passwords.go:104:33:104:40 | password | passwords.go:104:15:104:40 | ...+... | provenance | Config |
|
||||||
| passwords.go:104:33:104:40 | password | passwords.go:110:34:110:41 | password | provenance | |
|
| passwords.go:104:33:104:40 | password | passwords.go:110:34:110:41 | password | provenance | |
|
||||||
@@ -137,13 +129,12 @@ edges
|
|||||||
| passwords.go:110:34:110:41 | password | passwords.go:125:13:125:20 | password | provenance | |
|
| passwords.go:110:34:110:41 | password | passwords.go:125:13:125:20 | password | provenance | |
|
||||||
| passwords.go:115:33:115:40 | password | passwords.go:115:15:115:40 | ...+... | provenance | Config |
|
| passwords.go:115:33:115:40 | password | passwords.go:115:15:115:40 | ...+... | provenance | Config |
|
||||||
| passwords.go:115:33:115:40 | password | passwords.go:125:13:125:20 | password | provenance | |
|
| passwords.go:115:33:115:40 | password | passwords.go:125:13:125:20 | password | provenance | |
|
||||||
| passwords.go:118:6:118:50 | SSA def(password1) | passwords.go:119:28:119:36 | password1 | provenance | |
|
| passwords.go:118:6:118:14 | SSA def(password1) | passwords.go:119:28:119:36 | password1 | provenance | |
|
||||||
| passwords.go:119:28:119:36 | password1 | passwords.go:119:28:119:45 | call to String | provenance | Config |
|
| passwords.go:119:28:119:36 | password1 | passwords.go:119:28:119:45 | call to String | provenance | Config |
|
||||||
| passwords.go:119:28:119:45 | call to String | passwords.go:119:14:119:45 | ...+... | provenance | Config |
|
| passwords.go:119:28:119:45 | call to String | passwords.go:119:14:119:45 | ...+... | provenance | Config |
|
||||||
| passwords.go:122:12:127:2 | struct literal | passwords.go:129:14:129:19 | config | provenance | |
|
| passwords.go:122:12:127:2 | struct literal | passwords.go:129:14:129:19 | config | provenance | |
|
||||||
| passwords.go:122:12:127:2 | struct literal [x] | passwords.go:130:14:130:19 | config [x] | provenance | |
|
| passwords.go:122:12:127:2 | struct literal [x] | passwords.go:130:14:130:19 | config [x] | provenance | |
|
||||||
| passwords.go:122:12:127:2 | struct literal [y] | passwords.go:131:14:131:19 | config [y] | provenance | |
|
| passwords.go:122:12:127:2 | struct literal [y] | passwords.go:131:14:131:19 | config [y] | provenance | |
|
||||||
| passwords.go:123:3:123:14 | key-value pair | passwords.go:122:12:127:2 | struct literal | provenance | Config |
|
|
||||||
| passwords.go:123:13:123:14 | x3 | passwords.go:122:12:127:2 | struct literal | provenance | Config |
|
| passwords.go:123:13:123:14 | x3 | passwords.go:122:12:127:2 | struct literal | provenance | Config |
|
||||||
| passwords.go:125:13:125:20 | password | passwords.go:122:12:127:2 | struct literal | provenance | Config |
|
| passwords.go:125:13:125:20 | password | passwords.go:122:12:127:2 | struct literal | provenance | Config |
|
||||||
| passwords.go:125:13:125:20 | password | passwords.go:122:12:127:2 | struct literal [x] | provenance | |
|
| passwords.go:125:13:125:20 | password | passwords.go:122:12:127:2 | struct literal [x] | provenance | |
|
||||||
@@ -151,17 +142,15 @@ edges
|
|||||||
| passwords.go:126:13:126:25 | call to getPassword | passwords.go:122:12:127:2 | struct literal [y] | provenance | |
|
| passwords.go:126:13:126:25 | call to getPassword | passwords.go:122:12:127:2 | struct literal [y] | provenance | |
|
||||||
| passwords.go:130:14:130:19 | config [x] | passwords.go:130:14:130:21 | selection of x | provenance | |
|
| passwords.go:130:14:130:19 | config [x] | passwords.go:130:14:130:21 | selection of x | provenance | |
|
||||||
| passwords.go:131:14:131:19 | config [y] | passwords.go:131:14:131:21 | selection of y | provenance | |
|
| passwords.go:131:14:131:19 | config [y] | passwords.go:131:14:131:21 | selection of y | provenance | |
|
||||||
| protobuf.go:9:2:9:23 | SSA def(password) | protobuf.go:12:22:12:29 | password | provenance | |
|
| protobuf.go:9:2:9:9 | SSA def(password) | protobuf.go:12:22:12:29 | password | provenance | |
|
||||||
| protobuf.go:12:2:12:6 | implicit-deref query [postupdate] [Description] | protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | provenance | |
|
| protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | provenance | |
|
||||||
| protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | protobuf.go:14:14:14:18 | query [pointer, Description] | provenance | |
|
| protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | protobuf.go:14:14:14:18 | query [pointer, Description] | provenance | |
|
||||||
| protobuf.go:12:22:12:29 | password | protobuf.go:12:2:12:6 | implicit-deref query [postupdate] [Description] | provenance | |
|
| protobuf.go:12:22:12:29 | password | protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | provenance | |
|
||||||
| protobuf.go:14:14:14:18 | query [pointer, Description] | protobuf.go:14:14:14:35 | call to GetDescription | provenance | |
|
| protobuf.go:14:14:14:18 | query [pointer, Description] | protobuf.go:14:14:14:35 | call to GetDescription | provenance | |
|
||||||
| protobuf.go:14:14:14:18 | query [pointer, Description] | protos/query/query.pb.go:117:41:122:1 | SSA def(x) [pointer, Description] | provenance | |
|
| protobuf.go:14:14:14:18 | query [pointer, Description] | protos/query/query.pb.go:117:7:117:7 | SSA def(x) [pointer, Description] | provenance | |
|
||||||
| protos/query/query.pb.go:117:41:122:1 | SSA def(x) [pointer, Description] | protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | provenance | |
|
| protos/query/query.pb.go:117:7:117:7 | SSA def(x) [pointer, Description] | protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | provenance | |
|
||||||
| protos/query/query.pb.go:119:10:119:10 | implicit-deref x [Description] | protos/query/query.pb.go:119:10:119:22 | selection of Description | provenance | |
|
| protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] | protos/query/query.pb.go:119:10:119:22 | selection of Description | provenance | |
|
||||||
| protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | protos/query/query.pb.go:119:10:119:10 | implicit-deref x [Description] | provenance | |
|
| protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] | provenance | |
|
||||||
| server1.go:16:15:18:3 | struct literal | server1.go:19:15:19:19 | user3 | provenance | |
|
|
||||||
| server1.go:17:4:17:63 | key-value pair | server1.go:16:15:18:3 | struct literal | provenance | Config |
|
|
||||||
models
|
models
|
||||||
| 1 | Sink: group:logrus; ; false; WithField; ; ; Argument[0..1]; log-injection; manual |
|
| 1 | Sink: group:logrus; ; false; WithField; ; ; Argument[0..1]; log-injection; manual |
|
||||||
| 2 | Sink: group:logrus; ; false; WithFields; ; ; Argument[0]; log-injection; manual |
|
| 2 | Sink: group:logrus; ; false; WithFields; ; ; Argument[0]; log-injection; manual |
|
||||||
@@ -175,14 +164,14 @@ models
|
|||||||
| 10 | Sink: log; Logger; true; Printf; ; ; Argument[0..1]; log-injection; manual |
|
| 10 | Sink: log; Logger; true; Printf; ; ; Argument[0..1]; log-injection; manual |
|
||||||
| 11 | Source: net/http; Request; true; Header; ; ; ; remote; manual |
|
| 11 | Source: net/http; Request; true; Header; ; ; ; remote; manual |
|
||||||
nodes
|
nodes
|
||||||
| klog.go:21:3:26:3 | extract:1 range statement | semmle.label | extract:1 range statement |
|
| klog.go:21:3:26:3 | range statement[1] | semmle.label | range statement[1] |
|
||||||
| klog.go:21:30:21:37 | selection of Header | semmle.label | selection of Header |
|
| klog.go:21:30:21:37 | selection of Header | semmle.label | selection of Header |
|
||||||
| klog.go:22:4:25:4 | extract:1 range statement | semmle.label | extract:1 range statement |
|
| klog.go:22:4:25:4 | range statement[1] | semmle.label | range statement[1] |
|
||||||
| klog.go:22:27:22:33 | headers | semmle.label | headers |
|
| klog.go:22:27:22:33 | headers | semmle.label | headers |
|
||||||
| klog.go:23:15:23:20 | header | semmle.label | header |
|
| klog.go:23:15:23:20 | header | semmle.label | header |
|
||||||
| klog.go:29:13:29:20 | selection of Header | semmle.label | selection of Header |
|
| klog.go:29:13:29:20 | selection of Header | semmle.label | selection of Header |
|
||||||
| klog.go:29:13:29:41 | call to Get | semmle.label | call to Get |
|
| klog.go:29:13:29:41 | call to Get | semmle.label | call to Get |
|
||||||
| main.go:17:2:17:23 | SSA def(password) | semmle.label | SSA def(password) |
|
| main.go:17:2:17:9 | SSA def(password) | semmle.label | SSA def(password) |
|
||||||
| main.go:19:12:19:19 | password | semmle.label | password |
|
| main.go:19:12:19:19 | password | semmle.label | password |
|
||||||
| main.go:20:19:20:26 | password | semmle.label | password |
|
| main.go:20:19:20:26 | password | semmle.label | password |
|
||||||
| main.go:21:13:21:20 | password | semmle.label | password |
|
| main.go:21:13:21:20 | password | semmle.label | password |
|
||||||
@@ -220,12 +209,12 @@ nodes
|
|||||||
| main.go:86:19:86:26 | password | semmle.label | password |
|
| main.go:86:19:86:26 | password | semmle.label | password |
|
||||||
| main.go:87:29:87:34 | fields | semmle.label | fields |
|
| main.go:87:29:87:34 | fields | semmle.label | fields |
|
||||||
| main.go:90:35:90:42 | password | semmle.label | password |
|
| main.go:90:35:90:42 | password | semmle.label | password |
|
||||||
| overrides.go:8:2:8:40 | SSA def(password) | semmle.label | SSA def(password) |
|
| overrides.go:8:2:8:9 | SSA def(password) | semmle.label | SSA def(password) |
|
||||||
| overrides.go:9:9:9:16 | password | semmle.label | password |
|
| overrides.go:9:9:9:16 | password | semmle.label | password |
|
||||||
| overrides.go:13:14:13:23 | call to String | semmle.label | call to String |
|
| overrides.go:13:14:13:23 | call to String | semmle.label | call to String |
|
||||||
| passwords.go:8:22:10:1 | SSA def(x) | semmle.label | SSA def(x) |
|
| passwords.go:8:12:8:12 | SSA def(x) | semmle.label | SSA def(x) |
|
||||||
| passwords.go:9:14:9:14 | x | semmle.label | x |
|
| passwords.go:9:14:9:14 | x | semmle.label | x |
|
||||||
| passwords.go:21:2:21:23 | SSA def(password) | semmle.label | SSA def(password) |
|
| passwords.go:21:2:21:9 | SSA def(password) | semmle.label | SSA def(password) |
|
||||||
| passwords.go:25:14:25:21 | password | semmle.label | password |
|
| passwords.go:25:14:25:21 | password | semmle.label | password |
|
||||||
| passwords.go:26:14:26:23 | selection of password | semmle.label | selection of password |
|
| passwords.go:26:14:26:23 | selection of password | semmle.label | selection of password |
|
||||||
| passwords.go:27:14:27:26 | call to getPassword | semmle.label | call to getPassword |
|
| passwords.go:27:14:27:26 | call to getPassword | semmle.label | call to getPassword |
|
||||||
@@ -235,19 +224,15 @@ nodes
|
|||||||
| passwords.go:36:14:36:35 | ...+... | semmle.label | ...+... |
|
| passwords.go:36:14:36:35 | ...+... | semmle.label | ...+... |
|
||||||
| passwords.go:36:28:36:35 | password | semmle.label | password |
|
| passwords.go:36:28:36:35 | password | semmle.label | password |
|
||||||
| passwords.go:38:10:40:2 | struct literal | semmle.label | struct literal |
|
| passwords.go:38:10:40:2 | struct literal | semmle.label | struct literal |
|
||||||
| passwords.go:39:3:39:13 | key-value pair | semmle.label | key-value pair |
|
|
||||||
| passwords.go:39:13:39:13 | x | semmle.label | x |
|
| passwords.go:39:13:39:13 | x | semmle.label | x |
|
||||||
| passwords.go:41:14:41:17 | obj1 | semmle.label | obj1 |
|
| passwords.go:41:14:41:17 | obj1 | semmle.label | obj1 |
|
||||||
| passwords.go:43:10:45:2 | struct literal | semmle.label | struct literal |
|
| passwords.go:43:10:45:2 | struct literal | semmle.label | struct literal |
|
||||||
| passwords.go:44:6:44:13 | password | semmle.label | password |
|
| passwords.go:44:6:44:13 | password | semmle.label | password |
|
||||||
| passwords.go:46:14:46:17 | obj2 | semmle.label | obj2 |
|
| passwords.go:46:14:46:17 | obj2 | semmle.label | obj2 |
|
||||||
| passwords.go:50:11:50:18 | password | semmle.label | password |
|
| passwords.go:50:11:50:18 | password | semmle.label | password |
|
||||||
| passwords.go:52:2:52:44 | SSA def(fixed_password) | semmle.label | SSA def(fixed_password) |
|
| passwords.go:52:2:52:15 | SSA def(fixed_password) | semmle.label | SSA def(fixed_password) |
|
||||||
| passwords.go:53:14:53:27 | fixed_password | semmle.label | fixed_password |
|
| passwords.go:53:14:53:27 | fixed_password | semmle.label | fixed_password |
|
||||||
| passwords.go:65:14:65:44 | struct literal | semmle.label | struct literal |
|
|
||||||
| passwords.go:65:25:65:43 | key-value pair | semmle.label | key-value pair |
|
|
||||||
| passwords.go:88:19:90:2 | struct literal | semmle.label | struct literal |
|
| passwords.go:88:19:90:2 | struct literal | semmle.label | struct literal |
|
||||||
| passwords.go:89:3:89:36 | key-value pair | semmle.label | key-value pair |
|
|
||||||
| passwords.go:89:16:89:36 | call to make | semmle.label | call to make |
|
| passwords.go:89:16:89:36 | call to make | semmle.label | call to make |
|
||||||
| passwords.go:91:14:91:26 | utilityObject | semmle.label | utilityObject |
|
| passwords.go:91:14:91:26 | utilityObject | semmle.label | utilityObject |
|
||||||
| passwords.go:94:23:94:28 | secret | semmle.label | secret |
|
| passwords.go:94:23:94:28 | secret | semmle.label | secret |
|
||||||
@@ -257,14 +242,13 @@ nodes
|
|||||||
| passwords.go:110:34:110:41 | password | semmle.label | password |
|
| passwords.go:110:34:110:41 | password | semmle.label | password |
|
||||||
| passwords.go:115:15:115:40 | ...+... | semmle.label | ...+... |
|
| passwords.go:115:15:115:40 | ...+... | semmle.label | ...+... |
|
||||||
| passwords.go:115:33:115:40 | password | semmle.label | password |
|
| passwords.go:115:33:115:40 | password | semmle.label | password |
|
||||||
| passwords.go:118:6:118:50 | SSA def(password1) | semmle.label | SSA def(password1) |
|
| passwords.go:118:6:118:14 | SSA def(password1) | semmle.label | SSA def(password1) |
|
||||||
| passwords.go:119:14:119:45 | ...+... | semmle.label | ...+... |
|
| passwords.go:119:14:119:45 | ...+... | semmle.label | ...+... |
|
||||||
| passwords.go:119:28:119:36 | password1 | semmle.label | password1 |
|
| passwords.go:119:28:119:36 | password1 | semmle.label | password1 |
|
||||||
| passwords.go:119:28:119:45 | call to String | semmle.label | call to String |
|
| passwords.go:119:28:119:45 | call to String | semmle.label | call to String |
|
||||||
| passwords.go:122:12:127:2 | struct literal | semmle.label | struct literal |
|
| passwords.go:122:12:127:2 | struct literal | semmle.label | struct literal |
|
||||||
| passwords.go:122:12:127:2 | struct literal [x] | semmle.label | struct literal [x] |
|
| passwords.go:122:12:127:2 | struct literal [x] | semmle.label | struct literal [x] |
|
||||||
| passwords.go:122:12:127:2 | struct literal [y] | semmle.label | struct literal [y] |
|
| passwords.go:122:12:127:2 | struct literal [y] | semmle.label | struct literal [y] |
|
||||||
| passwords.go:123:3:123:14 | key-value pair | semmle.label | key-value pair |
|
|
||||||
| passwords.go:123:13:123:14 | x3 | semmle.label | x3 |
|
| passwords.go:123:13:123:14 | x3 | semmle.label | x3 |
|
||||||
| passwords.go:125:13:125:20 | password | semmle.label | password |
|
| passwords.go:125:13:125:20 | password | semmle.label | password |
|
||||||
| passwords.go:126:13:126:25 | call to getPassword | semmle.label | call to getPassword |
|
| passwords.go:126:13:126:25 | call to getPassword | semmle.label | call to getPassword |
|
||||||
@@ -273,23 +257,15 @@ nodes
|
|||||||
| passwords.go:130:14:130:21 | selection of x | semmle.label | selection of x |
|
| passwords.go:130:14:130:21 | selection of x | semmle.label | selection of x |
|
||||||
| passwords.go:131:14:131:19 | config [y] | semmle.label | config [y] |
|
| passwords.go:131:14:131:19 | config [y] | semmle.label | config [y] |
|
||||||
| passwords.go:131:14:131:21 | selection of y | semmle.label | selection of y |
|
| passwords.go:131:14:131:21 | selection of y | semmle.label | selection of y |
|
||||||
| protobuf.go:9:2:9:23 | SSA def(password) | semmle.label | SSA def(password) |
|
| protobuf.go:9:2:9:9 | SSA def(password) | semmle.label | SSA def(password) |
|
||||||
| protobuf.go:12:2:12:6 | implicit-deref query [postupdate] [Description] | semmle.label | implicit-deref query [postupdate] [Description] |
|
| protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | semmle.label | implicit dereference [postupdate] [Description] |
|
||||||
| protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | semmle.label | query [postupdate] [pointer, Description] |
|
| protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | semmle.label | query [postupdate] [pointer, Description] |
|
||||||
| protobuf.go:12:22:12:29 | password | semmle.label | password |
|
| protobuf.go:12:22:12:29 | password | semmle.label | password |
|
||||||
| protobuf.go:14:14:14:18 | query [pointer, Description] | semmle.label | query [pointer, Description] |
|
| protobuf.go:14:14:14:18 | query [pointer, Description] | semmle.label | query [pointer, Description] |
|
||||||
| protobuf.go:14:14:14:35 | call to GetDescription | semmle.label | call to GetDescription |
|
| protobuf.go:14:14:14:35 | call to GetDescription | semmle.label | call to GetDescription |
|
||||||
| protos/query/query.pb.go:117:41:122:1 | SSA def(x) [pointer, Description] | semmle.label | SSA def(x) [pointer, Description] |
|
| protos/query/query.pb.go:117:7:117:7 | SSA def(x) [pointer, Description] | semmle.label | SSA def(x) [pointer, Description] |
|
||||||
| protos/query/query.pb.go:119:10:119:10 | implicit-deref x [Description] | semmle.label | implicit-deref x [Description] |
|
| protos/query/query.pb.go:119:10:119:10 | implicit dereference [Description] | semmle.label | implicit dereference [Description] |
|
||||||
| protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | semmle.label | x [pointer, Description] |
|
| protos/query/query.pb.go:119:10:119:10 | x [pointer, Description] | semmle.label | x [pointer, Description] |
|
||||||
| protos/query/query.pb.go:119:10:119:22 | selection of Description | semmle.label | selection of Description |
|
| protos/query/query.pb.go:119:10:119:22 | selection of Description | semmle.label | selection of Description |
|
||||||
| server1.go:16:15:18:3 | struct literal | semmle.label | struct literal |
|
|
||||||
| server1.go:17:4:17:63 | key-value pair | semmle.label | key-value pair |
|
|
||||||
| server1.go:19:15:19:19 | user3 | semmle.label | user3 |
|
|
||||||
subpaths
|
subpaths
|
||||||
| protobuf.go:14:14:14:18 | query [pointer, Description] | protos/query/query.pb.go:117:41:122:1 | SSA def(x) [pointer, Description] | protos/query/query.pb.go:119:10:119:22 | selection of Description | protobuf.go:14:14:14:35 | call to GetDescription |
|
| protobuf.go:14:14:14:18 | query [pointer, Description] | protos/query/query.pb.go:117:7:117:7 | SSA def(x) [pointer, Description] | protos/query/query.pb.go:119:10:119:22 | selection of Description | protobuf.go:14:14:14:35 | call to GetDescription |
|
||||||
testFailures
|
|
||||||
| passwords.go:65:14:65:44 | struct literal | Unexpected result: Alert |
|
|
||||||
| passwords.go:65:25:65:43 | key-value pair | Unexpected result: Alert |
|
|
||||||
| server1.go:17:4:17:63 | key-value pair | Unexpected result: Source |
|
|
||||||
| server1.go:19:15:19:19 | user3 | Unexpected result: Alert |
|
|
||||||
|
|||||||
@@ -8,18 +8,18 @@ edges
|
|||||||
| InsecureHostKeyCallbackExample.go:31:14:34:4 | type conversion | InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | provenance | |
|
| InsecureHostKeyCallbackExample.go:31:14:34:4 | type conversion | InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | provenance | |
|
||||||
| InsecureHostKeyCallbackExample.go:32:3:34:3 | function literal | InsecureHostKeyCallbackExample.go:31:14:34:4 | type conversion | provenance | |
|
| InsecureHostKeyCallbackExample.go:32:3:34:3 | function literal | InsecureHostKeyCallbackExample.go:31:14:34:4 | type conversion | provenance | |
|
||||||
| InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal | InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | provenance | |
|
| InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal | InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | provenance | |
|
||||||
| InsecureHostKeyCallbackExample.go:58:69:64:1 | SSA def(callback) | InsecureHostKeyCallbackExample.go:62:20:62:27 | callback | provenance | |
|
| InsecureHostKeyCallbackExample.go:58:39:58:46 | SSA def(callback) | InsecureHostKeyCallbackExample.go:62:20:62:27 | callback | provenance | |
|
||||||
| InsecureHostKeyCallbackExample.go:68:78:80:1 | SSA def(callback) | InsecureHostKeyCallbackExample.go:78:28:78:35 | callback | provenance | |
|
| InsecureHostKeyCallbackExample.go:68:48:68:55 | SSA def(callback) | InsecureHostKeyCallbackExample.go:78:28:78:35 | callback | provenance | |
|
||||||
| InsecureHostKeyCallbackExample.go:94:3:94:43 | extract:0 ... := ... | InsecureHostKeyCallbackExample.go:95:28:95:35 | callback | provenance | |
|
| InsecureHostKeyCallbackExample.go:94:3:94:43 | ... := ...[0] | InsecureHostKeyCallbackExample.go:95:28:95:35 | callback | provenance | |
|
||||||
| InsecureHostKeyCallbackExample.go:102:22:105:4 | type conversion | InsecureHostKeyCallbackExample.go:107:35:107:50 | insecureCallback | provenance | |
|
| InsecureHostKeyCallbackExample.go:102:22:105:4 | type conversion | InsecureHostKeyCallbackExample.go:107:35:107:50 | insecureCallback | provenance | |
|
||||||
| InsecureHostKeyCallbackExample.go:103:3:105:3 | function literal | InsecureHostKeyCallbackExample.go:102:22:105:4 | type conversion | provenance | |
|
| InsecureHostKeyCallbackExample.go:103:3:105:3 | function literal | InsecureHostKeyCallbackExample.go:102:22:105:4 | type conversion | provenance | |
|
||||||
| InsecureHostKeyCallbackExample.go:107:35:107:50 | insecureCallback | InsecureHostKeyCallbackExample.go:58:69:64:1 | SSA def(callback) | provenance | |
|
| InsecureHostKeyCallbackExample.go:107:35:107:50 | insecureCallback | InsecureHostKeyCallbackExample.go:58:39:58:46 | SSA def(callback) | provenance | |
|
||||||
| InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion | InsecureHostKeyCallbackExample.go:117:35:117:59 | potentiallySecureCallback | provenance | |
|
| InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion | InsecureHostKeyCallbackExample.go:117:35:117:59 | potentiallySecureCallback | provenance | |
|
||||||
| InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion | InsecureHostKeyCallbackExample.go:120:44:120:68 | potentiallySecureCallback | provenance | |
|
| InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion | InsecureHostKeyCallbackExample.go:120:44:120:68 | potentiallySecureCallback | provenance | |
|
||||||
| InsecureHostKeyCallbackExample.go:110:3:115:3 | function literal | InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion | provenance | |
|
| InsecureHostKeyCallbackExample.go:110:3:115:3 | function literal | InsecureHostKeyCallbackExample.go:109:31:115:4 | type conversion | provenance | |
|
||||||
| InsecureHostKeyCallbackExample.go:117:35:117:59 | potentiallySecureCallback | InsecureHostKeyCallbackExample.go:58:69:64:1 | SSA def(callback) | provenance | |
|
| InsecureHostKeyCallbackExample.go:117:35:117:59 | potentiallySecureCallback | InsecureHostKeyCallbackExample.go:58:39:58:46 | SSA def(callback) | provenance | |
|
||||||
| InsecureHostKeyCallbackExample.go:118:35:118:61 | call to InsecureIgnoreHostKey | InsecureHostKeyCallbackExample.go:58:69:64:1 | SSA def(callback) | provenance | |
|
| InsecureHostKeyCallbackExample.go:118:35:118:61 | call to InsecureIgnoreHostKey | InsecureHostKeyCallbackExample.go:58:39:58:46 | SSA def(callback) | provenance | |
|
||||||
| InsecureHostKeyCallbackExample.go:120:44:120:68 | potentiallySecureCallback | InsecureHostKeyCallbackExample.go:68:78:80:1 | SSA def(callback) | provenance | |
|
| InsecureHostKeyCallbackExample.go:120:44:120:68 | potentiallySecureCallback | InsecureHostKeyCallbackExample.go:68:48:68:55 | SSA def(callback) | provenance | |
|
||||||
nodes
|
nodes
|
||||||
| InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | semmle.label | type conversion |
|
| InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | semmle.label | type conversion |
|
||||||
| InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal | semmle.label | function literal |
|
| InsecureHostKeyCallbackExample.go:16:4:18:4 | function literal | semmle.label | function literal |
|
||||||
@@ -29,13 +29,13 @@ nodes
|
|||||||
| InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | semmle.label | callback |
|
| InsecureHostKeyCallbackExample.go:39:20:39:27 | callback | semmle.label | callback |
|
||||||
| InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal | semmle.label | function literal |
|
| InsecureHostKeyCallbackExample.go:45:3:47:3 | function literal | semmle.label | function literal |
|
||||||
| InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | semmle.label | type conversion |
|
| InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | semmle.label | type conversion |
|
||||||
| InsecureHostKeyCallbackExample.go:58:69:64:1 | SSA def(callback) | semmle.label | SSA def(callback) |
|
| InsecureHostKeyCallbackExample.go:58:39:58:46 | SSA def(callback) | semmle.label | SSA def(callback) |
|
||||||
| InsecureHostKeyCallbackExample.go:62:20:62:27 | callback | semmle.label | callback |
|
| InsecureHostKeyCallbackExample.go:62:20:62:27 | callback | semmle.label | callback |
|
||||||
| InsecureHostKeyCallbackExample.go:68:78:80:1 | SSA def(callback) | semmle.label | SSA def(callback) |
|
| InsecureHostKeyCallbackExample.go:68:48:68:55 | SSA def(callback) | semmle.label | SSA def(callback) |
|
||||||
| InsecureHostKeyCallbackExample.go:76:28:76:54 | call to InsecureIgnoreHostKey | semmle.label | call to InsecureIgnoreHostKey |
|
| InsecureHostKeyCallbackExample.go:76:28:76:54 | call to InsecureIgnoreHostKey | semmle.label | call to InsecureIgnoreHostKey |
|
||||||
| InsecureHostKeyCallbackExample.go:78:28:78:35 | callback | semmle.label | callback |
|
| InsecureHostKeyCallbackExample.go:78:28:78:35 | callback | semmle.label | callback |
|
||||||
| InsecureHostKeyCallbackExample.go:92:28:92:54 | call to InsecureIgnoreHostKey | semmle.label | call to InsecureIgnoreHostKey |
|
| InsecureHostKeyCallbackExample.go:92:28:92:54 | call to InsecureIgnoreHostKey | semmle.label | call to InsecureIgnoreHostKey |
|
||||||
| InsecureHostKeyCallbackExample.go:94:3:94:43 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| InsecureHostKeyCallbackExample.go:94:3:94:43 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| InsecureHostKeyCallbackExample.go:95:28:95:35 | callback | semmle.label | callback |
|
| InsecureHostKeyCallbackExample.go:95:28:95:35 | callback | semmle.label | callback |
|
||||||
| InsecureHostKeyCallbackExample.go:102:22:105:4 | type conversion | semmle.label | type conversion |
|
| InsecureHostKeyCallbackExample.go:102:22:105:4 | type conversion | semmle.label | type conversion |
|
||||||
| InsecureHostKeyCallbackExample.go:103:3:105:3 | function literal | semmle.label | function literal |
|
| InsecureHostKeyCallbackExample.go:103:3:105:3 | function literal | semmle.label | function literal |
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
#select
|
|
||||||
| InsufficientKeySize.go:9:31:9:34 | 1024 | InsufficientKeySize.go:9:31:9:34 | 1024 | InsufficientKeySize.go:9:31:9:34 | 1024 | The size of this RSA key should be at least 2048 bits. |
|
|
||||||
| InsufficientKeySize.go:14:31:14:34 | size | InsufficientKeySize.go:13:10:13:13 | 1024 | InsufficientKeySize.go:14:31:14:34 | size | The size of this RSA key should be at least 2048 bits. |
|
|
||||||
| InsufficientKeySize.go:26:31:26:34 | size | InsufficientKeySize.go:18:7:18:10 | 1024 | InsufficientKeySize.go:26:31:26:34 | size | The size of this RSA key should be at least 2048 bits. |
|
|
||||||
| InsufficientKeySize.go:32:32:32:38 | keyBits | InsufficientKeySize.go:30:13:30:16 | 1024 | InsufficientKeySize.go:32:32:32:38 | keyBits | The size of this RSA key should be at least 2048 bits. |
|
|
||||||
| InsufficientKeySize.go:47:32:47:38 | keyBits | InsufficientKeySize.go:44:13:44:16 | 1024 | InsufficientKeySize.go:47:32:47:38 | keyBits | The size of this RSA key should be at least 2048 bits. |
|
|
||||||
| InsufficientKeySize.go:67:31:67:37 | keyBits | InsufficientKeySize.go:61:21:61:24 | 1024 | InsufficientKeySize.go:67:31:67:37 | keyBits | The size of this RSA key should be at least 2048 bits. |
|
|
||||||
edges
|
edges
|
||||||
| InsufficientKeySize.go:13:10:13:13 | 1024 | InsufficientKeySize.go:14:31:14:34 | size | provenance | |
|
| InsufficientKeySize.go:13:10:13:13 | 1024 | InsufficientKeySize.go:14:31:14:34 | size | provenance | |
|
||||||
| InsufficientKeySize.go:18:7:18:10 | 1024 | InsufficientKeySize.go:25:21:27:1 | SSA def(size) | provenance | |
|
| InsufficientKeySize.go:18:7:18:10 | 1024 | InsufficientKeySize.go:25:11:25:14 | SSA def(size) | provenance | |
|
||||||
| InsufficientKeySize.go:25:21:27:1 | SSA def(size) | InsufficientKeySize.go:26:31:26:34 | size | provenance | |
|
| InsufficientKeySize.go:25:11:25:14 | SSA def(size) | InsufficientKeySize.go:26:31:26:34 | size | provenance | |
|
||||||
| InsufficientKeySize.go:30:13:30:16 | 1024 | InsufficientKeySize.go:32:32:32:38 | keyBits | provenance | |
|
| InsufficientKeySize.go:30:13:30:16 | 1024 | InsufficientKeySize.go:32:32:32:38 | keyBits | provenance | |
|
||||||
| InsufficientKeySize.go:44:13:44:16 | 1024 | InsufficientKeySize.go:47:32:47:38 | keyBits | provenance | |
|
| InsufficientKeySize.go:44:13:44:16 | 1024 | InsufficientKeySize.go:47:32:47:38 | keyBits | provenance | |
|
||||||
| InsufficientKeySize.go:61:21:61:24 | 1024 | InsufficientKeySize.go:67:31:67:37 | keyBits | provenance | |
|
| InsufficientKeySize.go:61:21:61:24 | 1024 | InsufficientKeySize.go:67:31:67:37 | keyBits | provenance | |
|
||||||
@@ -17,7 +10,7 @@ nodes
|
|||||||
| InsufficientKeySize.go:13:10:13:13 | 1024 | semmle.label | 1024 |
|
| InsufficientKeySize.go:13:10:13:13 | 1024 | semmle.label | 1024 |
|
||||||
| InsufficientKeySize.go:14:31:14:34 | size | semmle.label | size |
|
| InsufficientKeySize.go:14:31:14:34 | size | semmle.label | size |
|
||||||
| InsufficientKeySize.go:18:7:18:10 | 1024 | semmle.label | 1024 |
|
| InsufficientKeySize.go:18:7:18:10 | 1024 | semmle.label | 1024 |
|
||||||
| InsufficientKeySize.go:25:21:27:1 | SSA def(size) | semmle.label | SSA def(size) |
|
| InsufficientKeySize.go:25:11:25:14 | SSA def(size) | semmle.label | SSA def(size) |
|
||||||
| InsufficientKeySize.go:26:31:26:34 | size | semmle.label | size |
|
| InsufficientKeySize.go:26:31:26:34 | size | semmle.label | size |
|
||||||
| InsufficientKeySize.go:30:13:30:16 | 1024 | semmle.label | 1024 |
|
| InsufficientKeySize.go:30:13:30:16 | 1024 | semmle.label | 1024 |
|
||||||
| InsufficientKeySize.go:32:32:32:38 | keyBits | semmle.label | keyBits |
|
| InsufficientKeySize.go:32:32:32:38 | keyBits | semmle.label | keyBits |
|
||||||
@@ -26,3 +19,10 @@ nodes
|
|||||||
| InsufficientKeySize.go:61:21:61:24 | 1024 | semmle.label | 1024 |
|
| InsufficientKeySize.go:61:21:61:24 | 1024 | semmle.label | 1024 |
|
||||||
| InsufficientKeySize.go:67:31:67:37 | keyBits | semmle.label | keyBits |
|
| InsufficientKeySize.go:67:31:67:37 | keyBits | semmle.label | keyBits |
|
||||||
subpaths
|
subpaths
|
||||||
|
#select
|
||||||
|
| InsufficientKeySize.go:9:31:9:34 | 1024 | InsufficientKeySize.go:9:31:9:34 | 1024 | InsufficientKeySize.go:9:31:9:34 | 1024 | The size of this RSA key should be at least 2048 bits. |
|
||||||
|
| InsufficientKeySize.go:14:31:14:34 | size | InsufficientKeySize.go:13:10:13:13 | 1024 | InsufficientKeySize.go:14:31:14:34 | size | The size of this RSA key should be at least 2048 bits. |
|
||||||
|
| InsufficientKeySize.go:26:31:26:34 | size | InsufficientKeySize.go:18:7:18:10 | 1024 | InsufficientKeySize.go:26:31:26:34 | size | The size of this RSA key should be at least 2048 bits. |
|
||||||
|
| InsufficientKeySize.go:32:32:32:38 | keyBits | InsufficientKeySize.go:30:13:30:16 | 1024 | InsufficientKeySize.go:32:32:32:38 | keyBits | The size of this RSA key should be at least 2048 bits. |
|
||||||
|
| InsufficientKeySize.go:47:32:47:38 | keyBits | InsufficientKeySize.go:44:13:44:16 | 1024 | InsufficientKeySize.go:47:32:47:38 | keyBits | The size of this RSA key should be at least 2048 bits. |
|
||||||
|
| InsufficientKeySize.go:67:31:67:37 | keyBits | InsufficientKeySize.go:61:21:61:24 | 1024 | InsufficientKeySize.go:67:31:67:37 | keyBits | The size of this RSA key should be at least 2048 bits. |
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
| encryption.go:30:2:30:36 | call to Encrypt | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | extract:0 ... := ... | The cryptographic algorithm DES |
|
| encryption.go:30:2:30:36 | call to Encrypt | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | ... := ...[0] | The cryptographic algorithm DES |
|
||||||
| encryption.go:34:2:34:42 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | extract:0 ... := ... | The cryptographic algorithm DES |
|
| encryption.go:34:2:34:42 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | ... := ...[0] | The cryptographic algorithm DES |
|
||||||
| encryption.go:38:2:38:42 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | extract:0 ... := ... | The cryptographic algorithm DES |
|
| encryption.go:38:2:38:42 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | ... := ...[0] | The cryptographic algorithm DES |
|
||||||
| encryption.go:42:2:42:42 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | extract:0 ... := ... | The cryptographic algorithm DES |
|
| encryption.go:42:2:42:42 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | ... := ...[0] | The cryptographic algorithm DES |
|
||||||
| encryption.go:46:2:46:42 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | extract:0 ... := ... | The cryptographic algorithm DES |
|
| encryption.go:46:2:46:42 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | ... := ...[0] | The cryptographic algorithm DES |
|
||||||
| encryption.go:50:2:50:47 | call to CryptBlocks | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | extract:0 ... := ... | The cryptographic algorithm DES |
|
| encryption.go:50:2:50:47 | call to CryptBlocks | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | ... := ...[0] | The cryptographic algorithm DES |
|
||||||
| encryption.go:54:2:54:45 | call to XORKeyStream | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | extract:0 ... := ... | The cryptographic algorithm DES |
|
| encryption.go:54:2:54:45 | call to XORKeyStream | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | ... := ...[0] | The cryptographic algorithm DES |
|
||||||
| encryption.go:56:22:56:91 | struct literal | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | extract:0 ... := ... | The cryptographic algorithm DES |
|
| encryption.go:56:22:56:91 | struct literal | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | ... := ...[0] | The cryptographic algorithm DES |
|
||||||
| encryption.go:59:21:59:68 | &... [postupdate] | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | extract:0 ... := ... | The cryptographic algorithm DES |
|
| encryption.go:59:21:59:68 | &... [postupdate] | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | ... := ...[0] | The cryptographic algorithm DES |
|
||||||
| encryption.go:59:22:59:68 | struct literal | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | extract:0 ... := ... | The cryptographic algorithm DES |
|
| encryption.go:59:22:59:68 | struct literal | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | ... := ...[0] | The cryptographic algorithm DES |
|
||||||
| encryption.go:59:22:59:68 | struct literal [postupdate] | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | extract:0 ... := ... | The cryptographic algorithm DES |
|
| encryption.go:59:22:59:68 | struct literal [postupdate] | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | ... := ...[0] | The cryptographic algorithm DES |
|
||||||
| encryption.go:60:10:60:24 | ctrStreamWriter [postupdate] | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | extract:0 ... := ... | The cryptographic algorithm DES |
|
| encryption.go:60:10:60:24 | ctrStreamWriter [postupdate] | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | ... := ...[0] | The cryptographic algorithm DES |
|
||||||
| encryption.go:65:2:65:45 | call to XORKeyStream | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | extract:0 ... := ... | The cryptographic algorithm DES |
|
| encryption.go:65:2:65:45 | call to XORKeyStream | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | ... := ...[0] | The cryptographic algorithm DES |
|
||||||
| encryption.go:69:2:69:45 | call to XORKeyStream | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | extract:0 ... := ... | The cryptographic algorithm DES |
|
| encryption.go:69:2:69:45 | call to XORKeyStream | $@ is broken or weak, and should not be used. | encryption.go:28:2:28:31 | ... := ...[0] | The cryptographic algorithm DES |
|
||||||
| encryption.go:76:2:76:32 | call to Encrypt | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | extract:0 ... := ... | The cryptographic algorithm TRIPLEDES |
|
| encryption.go:76:2:76:32 | call to Encrypt | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | ... := ...[0] | The cryptographic algorithm TRIPLEDES |
|
||||||
| encryption.go:80:2:80:38 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | extract:0 ... := ... | The cryptographic algorithm TRIPLEDES |
|
| encryption.go:80:2:80:38 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | ... := ...[0] | The cryptographic algorithm TRIPLEDES |
|
||||||
| encryption.go:84:2:84:38 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | extract:0 ... := ... | The cryptographic algorithm TRIPLEDES |
|
| encryption.go:84:2:84:38 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | ... := ...[0] | The cryptographic algorithm TRIPLEDES |
|
||||||
| encryption.go:88:2:88:42 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | extract:0 ... := ... | The cryptographic algorithm TRIPLEDES |
|
| encryption.go:88:2:88:42 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | ... := ...[0] | The cryptographic algorithm TRIPLEDES |
|
||||||
| encryption.go:92:2:92:42 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | extract:0 ... := ... | The cryptographic algorithm TRIPLEDES |
|
| encryption.go:92:2:92:42 | call to Seal | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | ... := ...[0] | The cryptographic algorithm TRIPLEDES |
|
||||||
| encryption.go:96:2:96:43 | call to CryptBlocks | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | extract:0 ... := ... | The cryptographic algorithm TRIPLEDES |
|
| encryption.go:96:2:96:43 | call to CryptBlocks | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | ... := ...[0] | The cryptographic algorithm TRIPLEDES |
|
||||||
| encryption.go:100:2:100:41 | call to XORKeyStream | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | extract:0 ... := ... | The cryptographic algorithm TRIPLEDES |
|
| encryption.go:100:2:100:41 | call to XORKeyStream | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | ... := ...[0] | The cryptographic algorithm TRIPLEDES |
|
||||||
| encryption.go:102:22:102:87 | struct literal | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | extract:0 ... := ... | The cryptographic algorithm TRIPLEDES |
|
| encryption.go:102:22:102:87 | struct literal | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | ... := ...[0] | The cryptographic algorithm TRIPLEDES |
|
||||||
| encryption.go:105:21:105:68 | &... [postupdate] | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | extract:0 ... := ... | The cryptographic algorithm TRIPLEDES |
|
| encryption.go:105:21:105:68 | &... [postupdate] | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | ... := ...[0] | The cryptographic algorithm TRIPLEDES |
|
||||||
| encryption.go:105:22:105:68 | struct literal | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | extract:0 ... := ... | The cryptographic algorithm TRIPLEDES |
|
| encryption.go:105:22:105:68 | struct literal | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | ... := ...[0] | The cryptographic algorithm TRIPLEDES |
|
||||||
| encryption.go:105:22:105:68 | struct literal [postupdate] | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | extract:0 ... := ... | The cryptographic algorithm TRIPLEDES |
|
| encryption.go:105:22:105:68 | struct literal [postupdate] | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | ... := ...[0] | The cryptographic algorithm TRIPLEDES |
|
||||||
| encryption.go:106:10:106:24 | ctrStreamWriter [postupdate] | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | extract:0 ... := ... | The cryptographic algorithm TRIPLEDES |
|
| encryption.go:106:10:106:24 | ctrStreamWriter [postupdate] | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | ... := ...[0] | The cryptographic algorithm TRIPLEDES |
|
||||||
| encryption.go:111:2:111:45 | call to XORKeyStream | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | extract:0 ... := ... | The cryptographic algorithm TRIPLEDES |
|
| encryption.go:111:2:111:45 | call to XORKeyStream | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | ... := ...[0] | The cryptographic algorithm TRIPLEDES |
|
||||||
| encryption.go:115:2:115:45 | call to XORKeyStream | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | extract:0 ... := ... | The cryptographic algorithm TRIPLEDES |
|
| encryption.go:115:2:115:45 | call to XORKeyStream | $@ is broken or weak, and should not be used. | encryption.go:74:2:74:40 | ... := ...[0] | The cryptographic algorithm TRIPLEDES |
|
||||||
| encryption.go:166:2:166:33 | call to XORKeyStream | $@ is broken or weak, and should not be used. | encryption.go:166:2:166:33 | call to XORKeyStream | The cryptographic algorithm RC4 |
|
| encryption.go:166:2:166:33 | call to XORKeyStream | $@ is broken or weak, and should not be used. | encryption.go:166:2:166:33 | call to XORKeyStream | The cryptographic algorithm RC4 |
|
||||||
|
|||||||
@@ -5,15 +5,15 @@ edges
|
|||||||
| go-jose.v3.go:25:16:25:20 | selection of URL | go-jose.v3.go:25:16:25:28 | call to Query | provenance | Src:MaD:3 MaD:5 |
|
| go-jose.v3.go:25:16:25:20 | selection of URL | go-jose.v3.go:25:16:25:28 | call to Query | provenance | Src:MaD:3 MaD:5 |
|
||||||
| go-jose.v3.go:25:16:25:28 | call to Query | go-jose.v3.go:25:16:25:47 | call to Get | provenance | MaD:6 |
|
| go-jose.v3.go:25:16:25:28 | call to Query | go-jose.v3.go:25:16:25:47 | call to Get | provenance | MaD:6 |
|
||||||
| go-jose.v3.go:25:16:25:47 | call to Get | go-jose.v3.go:26:15:26:25 | signedToken | provenance | |
|
| go-jose.v3.go:25:16:25:47 | call to Get | go-jose.v3.go:26:15:26:25 | signedToken | provenance | |
|
||||||
| go-jose.v3.go:26:15:26:25 | signedToken | go-jose.v3.go:29:39:37:1 | SSA def(signedToken) | provenance | |
|
| go-jose.v3.go:26:15:26:25 | signedToken | go-jose.v3.go:29:19:29:29 | SSA def(signedToken) | provenance | |
|
||||||
| go-jose.v3.go:29:39:37:1 | SSA def(signedToken) | go-jose.v3.go:31:37:31:47 | signedToken | provenance | |
|
| go-jose.v3.go:29:19:29:29 | SSA def(signedToken) | go-jose.v3.go:31:37:31:47 | signedToken | provenance | |
|
||||||
| go-jose.v3.go:31:2:31:48 | extract:0 ... := ... | go-jose.v3.go:33:12:33:23 | DecodedToken | provenance | Sink:MaD:2 |
|
| go-jose.v3.go:31:2:31:48 | ... := ...[0] | go-jose.v3.go:33:12:33:23 | DecodedToken | provenance | Sink:MaD:2 |
|
||||||
| go-jose.v3.go:31:37:31:47 | signedToken | go-jose.v3.go:31:2:31:48 | extract:0 ... := ... | provenance | MaD:4 |
|
| go-jose.v3.go:31:37:31:47 | signedToken | go-jose.v3.go:31:2:31:48 | ... := ...[0] | provenance | MaD:4 |
|
||||||
| golang-jwt-v5.go:28:16:28:20 | selection of URL | golang-jwt-v5.go:28:16:28:28 | call to Query | provenance | Src:MaD:3 MaD:5 |
|
| golang-jwt-v5.go:28:16:28:20 | selection of URL | golang-jwt-v5.go:28:16:28:28 | call to Query | provenance | Src:MaD:3 MaD:5 |
|
||||||
| golang-jwt-v5.go:28:16:28:28 | call to Query | golang-jwt-v5.go:28:16:28:47 | call to Get | provenance | MaD:6 |
|
| golang-jwt-v5.go:28:16:28:28 | call to Query | golang-jwt-v5.go:28:16:28:47 | call to Get | provenance | MaD:6 |
|
||||||
| golang-jwt-v5.go:28:16:28:47 | call to Get | golang-jwt-v5.go:29:25:29:35 | signedToken | provenance | |
|
| golang-jwt-v5.go:28:16:28:47 | call to Get | golang-jwt-v5.go:29:25:29:35 | signedToken | provenance | |
|
||||||
| golang-jwt-v5.go:29:25:29:35 | signedToken | golang-jwt-v5.go:32:49:40:1 | SSA def(signedToken) | provenance | |
|
| golang-jwt-v5.go:29:25:29:35 | signedToken | golang-jwt-v5.go:32:29:32:39 | SSA def(signedToken) | provenance | |
|
||||||
| golang-jwt-v5.go:32:49:40:1 | SSA def(signedToken) | golang-jwt-v5.go:34:58:34:68 | signedToken | provenance | Sink:MaD:1 |
|
| golang-jwt-v5.go:32:29:32:39 | SSA def(signedToken) | golang-jwt-v5.go:34:58:34:68 | signedToken | provenance | Sink:MaD:1 |
|
||||||
models
|
models
|
||||||
| 1 | Sink: github.com/golang-jwt/jwt; Parser; true; ParseUnverified; ; ; Argument[0]; jwt; manual |
|
| 1 | Sink: github.com/golang-jwt/jwt; Parser; true; ParseUnverified; ; ; Argument[0]; jwt; manual |
|
||||||
| 2 | Sink: group:go-jose/jwt; JSONWebToken; true; UnsafeClaimsWithoutVerification; ; ; Argument[receiver]; jwt; manual |
|
| 2 | Sink: group:go-jose/jwt; JSONWebToken; true; UnsafeClaimsWithoutVerification; ; ; Argument[receiver]; jwt; manual |
|
||||||
@@ -26,14 +26,14 @@ nodes
|
|||||||
| go-jose.v3.go:25:16:25:28 | call to Query | semmle.label | call to Query |
|
| go-jose.v3.go:25:16:25:28 | call to Query | semmle.label | call to Query |
|
||||||
| go-jose.v3.go:25:16:25:47 | call to Get | semmle.label | call to Get |
|
| go-jose.v3.go:25:16:25:47 | call to Get | semmle.label | call to Get |
|
||||||
| go-jose.v3.go:26:15:26:25 | signedToken | semmle.label | signedToken |
|
| go-jose.v3.go:26:15:26:25 | signedToken | semmle.label | signedToken |
|
||||||
| go-jose.v3.go:29:39:37:1 | SSA def(signedToken) | semmle.label | SSA def(signedToken) |
|
| go-jose.v3.go:29:19:29:29 | SSA def(signedToken) | semmle.label | SSA def(signedToken) |
|
||||||
| go-jose.v3.go:31:2:31:48 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| go-jose.v3.go:31:2:31:48 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| go-jose.v3.go:31:37:31:47 | signedToken | semmle.label | signedToken |
|
| go-jose.v3.go:31:37:31:47 | signedToken | semmle.label | signedToken |
|
||||||
| go-jose.v3.go:33:12:33:23 | DecodedToken | semmle.label | DecodedToken |
|
| go-jose.v3.go:33:12:33:23 | DecodedToken | semmle.label | DecodedToken |
|
||||||
| golang-jwt-v5.go:28:16:28:20 | selection of URL | semmle.label | selection of URL |
|
| golang-jwt-v5.go:28:16:28:20 | selection of URL | semmle.label | selection of URL |
|
||||||
| golang-jwt-v5.go:28:16:28:28 | call to Query | semmle.label | call to Query |
|
| golang-jwt-v5.go:28:16:28:28 | call to Query | semmle.label | call to Query |
|
||||||
| golang-jwt-v5.go:28:16:28:47 | call to Get | semmle.label | call to Get |
|
| golang-jwt-v5.go:28:16:28:47 | call to Get | semmle.label | call to Get |
|
||||||
| golang-jwt-v5.go:29:25:29:35 | signedToken | semmle.label | signedToken |
|
| golang-jwt-v5.go:29:25:29:35 | signedToken | semmle.label | signedToken |
|
||||||
| golang-jwt-v5.go:32:49:40:1 | SSA def(signedToken) | semmle.label | SSA def(signedToken) |
|
| golang-jwt-v5.go:32:29:32:39 | SSA def(signedToken) | semmle.label | SSA def(signedToken) |
|
||||||
| golang-jwt-v5.go:34:58:34:68 | signedToken | semmle.label | signedToken |
|
| golang-jwt-v5.go:34:58:34:68 | signedToken | semmle.label | signedToken |
|
||||||
subpaths
|
subpaths
|
||||||
|
|||||||
@@ -1,76 +1,63 @@
|
|||||||
#select
|
#select
|
||||||
| BadRedirectCheck.go:4:23:4:37 | ...==... | BadRedirectCheck.go:3:39:8:1 | arg:0 block statement | main.go:11:25:11:45 | call to sanitizeUrl | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | BadRedirectCheck.go:3:39:8:1 | arg:0 block statement | this value | main.go:11:25:11:45 | call to sanitizeUrl | redirect |
|
| BadRedirectCheck.go:4:23:4:37 | ...==... | BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir | main.go:11:25:11:45 | call to sanitizeUrl | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir | this value | main.go:11:25:11:45 | call to sanitizeUrl | redirect |
|
||||||
| BadRedirectCheck.go:4:23:4:37 | ...==... | main.go:10:78:12:1 | arg:0 block statement | main.go:11:25:11:45 | call to sanitizeUrl | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:10:78:12:1 | arg:0 block statement | this value | main.go:11:25:11:45 | call to sanitizeUrl | redirect |
|
| BadRedirectCheck.go:4:23:4:37 | ...==... | main.go:10:18:10:25 | argument corresponding to redirect | main.go:11:25:11:45 | call to sanitizeUrl | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:10:18:10:25 | argument corresponding to redirect | this value | main.go:11:25:11:45 | call to sanitizeUrl | redirect |
|
||||||
| cves.go:11:26:11:38 | ...==... | cves.go:14:78:18:1 | arg:0 block statement | cves.go:16:26:16:28 | url | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | cves.go:14:78:18:1 | arg:0 block statement | this value | cves.go:16:26:16:28 | url | redirect |
|
| cves.go:11:26:11:38 | ...==... | cves.go:14:23:14:25 | argument corresponding to url | cves.go:16:26:16:28 | url | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | cves.go:14:23:14:25 | argument corresponding to url | this value | cves.go:16:26:16:28 | url | redirect |
|
||||||
| cves.go:34:6:34:37 | call to HasPrefix | cves.go:33:14:33:34 | call to Get | cves.go:37:25:37:32 | redirect | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | cves.go:33:14:33:34 | call to Get | this value | cves.go:37:25:37:32 | redirect | redirect |
|
| cves.go:34:6:34:37 | call to HasPrefix | cves.go:33:14:33:34 | call to Get | cves.go:37:25:37:32 | redirect | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | cves.go:33:14:33:34 | call to Get | this value | cves.go:37:25:37:32 | redirect | redirect |
|
||||||
| cves.go:42:6:42:37 | call to HasPrefix | cves.go:41:14:41:34 | call to Get | cves.go:45:25:45:32 | redirect | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | cves.go:41:14:41:34 | call to Get | this value | cves.go:45:25:45:32 | redirect | redirect |
|
| cves.go:42:6:42:37 | call to HasPrefix | cves.go:41:14:41:34 | call to Get | cves.go:45:25:45:32 | redirect | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | cves.go:41:14:41:34 | call to Get | this value | cves.go:45:25:45:32 | redirect | redirect |
|
||||||
| main.go:25:7:25:38 | call to HasPrefix | main.go:32:79:36:1 | arg:0 block statement | main.go:34:26:34:28 | url | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:32:79:36:1 | arg:0 block statement | this value | main.go:34:26:34:28 | url | redirect |
|
| main.go:25:7:25:38 | call to HasPrefix | main.go:32:24:32:26 | argument corresponding to url | main.go:34:26:34:28 | url | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:32:24:32:26 | argument corresponding to url | this value | main.go:34:26:34:28 | url | redirect |
|
||||||
| main.go:69:5:69:22 | ...!=... | main.go:68:41:74:1 | arg:0 block statement | main.go:77:25:77:39 | call to getTarget1 | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:68:41:74:1 | arg:0 block statement | this value | main.go:77:25:77:39 | call to getTarget1 | redirect |
|
| main.go:69:5:69:22 | ...!=... | main.go:68:17:68:24 | argument corresponding to redirect | main.go:77:25:77:39 | call to getTarget1 | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:68:17:68:24 | argument corresponding to redirect | this value | main.go:77:25:77:39 | call to getTarget1 | redirect |
|
||||||
| main.go:69:5:69:22 | ...!=... | main.go:76:74:78:1 | arg:0 block statement | main.go:77:25:77:39 | call to getTarget1 | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:76:74:78:1 | arg:0 block statement | this value | main.go:77:25:77:39 | call to getTarget1 | redirect |
|
| main.go:69:5:69:22 | ...!=... | main.go:76:19:76:21 | argument corresponding to url | main.go:77:25:77:39 | call to getTarget1 | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:76:19:76:21 | argument corresponding to url | this value | main.go:77:25:77:39 | call to getTarget1 | redirect |
|
||||||
| main.go:83:5:83:20 | ...!=... | main.go:87:9:87:14 | selection of Path | main.go:91:25:91:39 | call to getTarget2 | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:87:9:87:14 | selection of Path | this value | main.go:91:25:91:39 | call to getTarget2 | redirect |
|
| main.go:83:5:83:20 | ...!=... | main.go:87:9:87:14 | selection of Path | main.go:91:25:91:39 | call to getTarget2 | This is a check that $@, which flows into a $@, has a leading slash, but not that it does not have '/' or '\\' in its second position. | main.go:87:9:87:14 | selection of Path | this value | main.go:91:25:91:39 | call to getTarget2 | redirect |
|
||||||
edges
|
edges
|
||||||
| BadRedirectCheck.go:3:39:8:1 | SSA def(redir) | BadRedirectCheck.go:5:10:5:14 | redir | provenance | |
|
| BadRedirectCheck.go:3:18:3:22 | SSA def(redir) | BadRedirectCheck.go:5:10:5:14 | redir | provenance | |
|
||||||
| BadRedirectCheck.go:3:39:8:1 | arg:0 block statement | BadRedirectCheck.go:5:10:5:14 | redir | provenance | |
|
| BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir | BadRedirectCheck.go:5:10:5:14 | redir | provenance | |
|
||||||
| BadRedirectCheck.go:5:10:5:14 | redir | main.go:11:25:11:45 | call to sanitizeUrl | provenance | Sink:MaD:1 |
|
| BadRedirectCheck.go:5:10:5:14 | redir | main.go:11:25:11:45 | call to sanitizeUrl | provenance | Sink:MaD:1 |
|
||||||
| cves.go:14:78:18:1 | arg:0 block statement | cves.go:16:26:16:28 | url | provenance | Sink:MaD:1 |
|
| cves.go:14:23:14:25 | argument corresponding to url | cves.go:16:26:16:28 | url | provenance | Sink:MaD:1 |
|
||||||
| cves.go:33:14:33:34 | call to Get | cves.go:37:25:37:32 | redirect | provenance | Sink:MaD:1 |
|
| cves.go:33:14:33:34 | call to Get | cves.go:37:25:37:32 | redirect | provenance | Sink:MaD:1 |
|
||||||
| cves.go:41:14:41:34 | call to Get | cves.go:45:25:45:32 | redirect | provenance | Sink:MaD:1 |
|
| cves.go:41:14:41:34 | call to Get | cves.go:45:25:45:32 | redirect | provenance | Sink:MaD:1 |
|
||||||
| main.go:10:78:12:1 | arg:0 block statement | main.go:11:37:11:44 | redirect | provenance | |
|
| main.go:10:18:10:25 | argument corresponding to redirect | main.go:11:37:11:44 | redirect | provenance | |
|
||||||
| main.go:11:37:11:44 | redirect | BadRedirectCheck.go:3:39:8:1 | SSA def(redir) | provenance | |
|
| main.go:11:37:11:44 | redirect | BadRedirectCheck.go:3:18:3:22 | SSA def(redir) | provenance | |
|
||||||
| main.go:11:37:11:44 | redirect | main.go:11:25:11:45 | call to sanitizeUrl | provenance | Sink:MaD:1 |
|
| main.go:11:37:11:44 | redirect | main.go:11:25:11:45 | call to sanitizeUrl | provenance | Sink:MaD:1 |
|
||||||
| main.go:32:79:36:1 | arg:0 block statement | main.go:34:26:34:28 | url | provenance | Sink:MaD:1 |
|
| main.go:32:24:32:26 | argument corresponding to url | main.go:34:26:34:28 | url | provenance | Sink:MaD:1 |
|
||||||
| main.go:68:41:74:1 | SSA def(redirect) | main.go:73:20:73:27 | redirect | provenance | |
|
| main.go:68:17:68:24 | SSA def(redirect) | main.go:73:20:73:27 | redirect | provenance | |
|
||||||
| main.go:68:41:74:1 | arg:0 block statement | main.go:73:20:73:27 | redirect | provenance | |
|
| main.go:68:17:68:24 | argument corresponding to redirect | main.go:73:20:73:27 | redirect | provenance | |
|
||||||
| main.go:73:9:73:28 | call to Clean | main.go:77:25:77:39 | call to getTarget1 | provenance | Sink:MaD:1 |
|
| main.go:73:9:73:28 | call to Clean | main.go:77:25:77:39 | call to getTarget1 | provenance | Sink:MaD:1 |
|
||||||
| main.go:73:20:73:27 | redirect | main.go:73:9:73:28 | call to Clean | provenance | MaD:2 |
|
| main.go:73:20:73:27 | redirect | main.go:73:9:73:28 | call to Clean | provenance | MaD:2 |
|
||||||
| main.go:73:20:73:27 | redirect | main.go:73:9:73:28 | call to Clean | provenance | MaD:2 |
|
| main.go:73:20:73:27 | redirect | main.go:73:9:73:28 | call to Clean | provenance | MaD:2 |
|
||||||
| main.go:76:74:78:1 | arg:0 block statement | main.go:77:36:77:38 | url | provenance | |
|
| main.go:76:19:76:21 | argument corresponding to url | main.go:77:36:77:38 | url | provenance | |
|
||||||
| main.go:77:36:77:38 | url | main.go:68:41:74:1 | SSA def(redirect) | provenance | |
|
| main.go:77:36:77:38 | url | main.go:68:17:68:24 | SSA def(redirect) | provenance | |
|
||||||
| main.go:77:36:77:38 | url | main.go:77:25:77:39 | call to getTarget1 | provenance | MaD:2 Sink:MaD:1 |
|
| main.go:77:36:77:38 | url | main.go:77:25:77:39 | call to getTarget1 | provenance | MaD:2 Sink:MaD:1 |
|
||||||
| main.go:87:9:87:14 | selection of Path | main.go:91:25:91:39 | call to getTarget2 | provenance | Sink:MaD:1 |
|
| main.go:87:9:87:14 | selection of Path | main.go:91:25:91:39 | call to getTarget2 | provenance | Sink:MaD:1 |
|
||||||
models
|
models
|
||||||
| 1 | Sink: net/http; ; false; Redirect; ; ; Argument[2]; url-redirection[0]; manual |
|
| 1 | Sink: net/http; ; false; Redirect; ; ; Argument[2]; url-redirection[0]; manual |
|
||||||
| 2 | Summary: path; ; false; Clean; ; ; Argument[0]; ReturnValue; taint; manual |
|
| 2 | Summary: path; ; false; Clean; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||||
nodes
|
nodes
|
||||||
| BadRedirectCheck.go:3:39:8:1 | SSA def(redir) | semmle.label | SSA def(redir) |
|
| BadRedirectCheck.go:3:18:3:22 | SSA def(redir) | semmle.label | SSA def(redir) |
|
||||||
| BadRedirectCheck.go:3:39:8:1 | arg:0 block statement | semmle.label | arg:0 block statement |
|
| BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir | semmle.label | argument corresponding to redir |
|
||||||
| BadRedirectCheck.go:5:10:5:14 | redir | semmle.label | redir |
|
| BadRedirectCheck.go:5:10:5:14 | redir | semmle.label | redir |
|
||||||
| BadRedirectCheck.go:5:10:5:14 | redir | semmle.label | redir |
|
| BadRedirectCheck.go:5:10:5:14 | redir | semmle.label | redir |
|
||||||
| cves.go:14:78:18:1 | arg:0 block statement | semmle.label | arg:0 block statement |
|
| cves.go:14:23:14:25 | argument corresponding to url | semmle.label | argument corresponding to url |
|
||||||
| cves.go:16:26:16:28 | url | semmle.label | url |
|
| cves.go:16:26:16:28 | url | semmle.label | url |
|
||||||
| cves.go:33:14:33:34 | call to Get | semmle.label | call to Get |
|
| cves.go:33:14:33:34 | call to Get | semmle.label | call to Get |
|
||||||
| cves.go:37:25:37:32 | redirect | semmle.label | redirect |
|
| cves.go:37:25:37:32 | redirect | semmle.label | redirect |
|
||||||
| cves.go:41:14:41:34 | call to Get | semmle.label | call to Get |
|
| cves.go:41:14:41:34 | call to Get | semmle.label | call to Get |
|
||||||
| cves.go:45:25:45:32 | redirect | semmle.label | redirect |
|
| cves.go:45:25:45:32 | redirect | semmle.label | redirect |
|
||||||
| main.go:10:78:12:1 | arg:0 block statement | semmle.label | arg:0 block statement |
|
| main.go:10:18:10:25 | argument corresponding to redirect | semmle.label | argument corresponding to redirect |
|
||||||
| main.go:11:25:11:45 | call to sanitizeUrl | semmle.label | call to sanitizeUrl |
|
| main.go:11:25:11:45 | call to sanitizeUrl | semmle.label | call to sanitizeUrl |
|
||||||
| main.go:11:37:11:44 | redirect | semmle.label | redirect |
|
| main.go:11:37:11:44 | redirect | semmle.label | redirect |
|
||||||
| main.go:32:79:36:1 | arg:0 block statement | semmle.label | arg:0 block statement |
|
| main.go:32:24:32:26 | argument corresponding to url | semmle.label | argument corresponding to url |
|
||||||
| main.go:34:26:34:28 | url | semmle.label | url |
|
| main.go:34:26:34:28 | url | semmle.label | url |
|
||||||
| main.go:68:41:74:1 | SSA def(redirect) | semmle.label | SSA def(redirect) |
|
| main.go:68:17:68:24 | SSA def(redirect) | semmle.label | SSA def(redirect) |
|
||||||
| main.go:68:41:74:1 | arg:0 block statement | semmle.label | arg:0 block statement |
|
| main.go:68:17:68:24 | argument corresponding to redirect | semmle.label | argument corresponding to redirect |
|
||||||
| main.go:73:9:73:28 | call to Clean | semmle.label | call to Clean |
|
| main.go:73:9:73:28 | call to Clean | semmle.label | call to Clean |
|
||||||
| main.go:73:9:73:28 | call to Clean | semmle.label | call to Clean |
|
| main.go:73:9:73:28 | call to Clean | semmle.label | call to Clean |
|
||||||
| main.go:73:20:73:27 | redirect | semmle.label | redirect |
|
| main.go:73:20:73:27 | redirect | semmle.label | redirect |
|
||||||
| main.go:73:20:73:27 | redirect | semmle.label | redirect |
|
| main.go:73:20:73:27 | redirect | semmle.label | redirect |
|
||||||
| main.go:76:74:78:1 | arg:0 block statement | semmle.label | arg:0 block statement |
|
| main.go:76:19:76:21 | argument corresponding to url | semmle.label | argument corresponding to url |
|
||||||
| main.go:77:25:77:39 | call to getTarget1 | semmle.label | call to getTarget1 |
|
| main.go:77:25:77:39 | call to getTarget1 | semmle.label | call to getTarget1 |
|
||||||
| main.go:77:36:77:38 | url | semmle.label | url |
|
| main.go:77:36:77:38 | url | semmle.label | url |
|
||||||
| main.go:87:9:87:14 | selection of Path | semmle.label | selection of Path |
|
| main.go:87:9:87:14 | selection of Path | semmle.label | selection of Path |
|
||||||
| main.go:91:25:91:39 | call to getTarget2 | semmle.label | call to getTarget2 |
|
| main.go:91:25:91:39 | call to getTarget2 | semmle.label | call to getTarget2 |
|
||||||
subpaths
|
subpaths
|
||||||
| main.go:11:37:11:44 | redirect | BadRedirectCheck.go:3:39:8:1 | SSA def(redir) | BadRedirectCheck.go:5:10:5:14 | redir | main.go:11:25:11:45 | call to sanitizeUrl |
|
| main.go:11:37:11:44 | redirect | BadRedirectCheck.go:3:18:3:22 | SSA def(redir) | BadRedirectCheck.go:5:10:5:14 | redir | main.go:11:25:11:45 | call to sanitizeUrl |
|
||||||
| main.go:77:36:77:38 | url | main.go:68:41:74:1 | SSA def(redirect) | main.go:73:9:73:28 | call to Clean | main.go:77:25:77:39 | call to getTarget1 |
|
| main.go:77:36:77:38 | url | main.go:68:17:68:24 | SSA def(redirect) | main.go:73:9:73:28 | call to Clean | main.go:77:25:77:39 | call to getTarget1 |
|
||||||
testFailures
|
|
||||||
| BadRedirectCheck.go:3:39:8:1 | arg:0 block statement | Unexpected result: Source |
|
|
||||||
| BadRedirectCheck.go:3:41:3:51 | comment | Missing result: Source |
|
|
||||||
| cves.go:14:78:18:1 | arg:0 block statement | Unexpected result: Source |
|
|
||||||
| cves.go:14:80:14:90 | comment | Missing result: Source |
|
|
||||||
| main.go:10:78:12:1 | arg:0 block statement | Unexpected result: Source |
|
|
||||||
| main.go:10:80:10:90 | comment | Missing result: Source |
|
|
||||||
| main.go:32:79:36:1 | arg:0 block statement | Unexpected result: Source |
|
|
||||||
| main.go:32:81:32:91 | comment | Missing result: Source |
|
|
||||||
| main.go:68:41:74:1 | arg:0 block statement | Unexpected result: Source |
|
|
||||||
| main.go:68:43:68:53 | comment | Missing result: Source |
|
|
||||||
| main.go:76:74:78:1 | arg:0 block statement | Unexpected result: Source |
|
|
||||||
| main.go:76:76:76:86 | comment | Missing result: Source |
|
|
||||||
|
|||||||
@@ -30,16 +30,16 @@ edges
|
|||||||
| stdlib.go:71:23:71:37 | ...+... | stdlib.go:71:23:71:40 | ...+... | provenance | Config Sink:MaD:1 |
|
| stdlib.go:71:23:71:37 | ...+... | stdlib.go:71:23:71:40 | ...+... | provenance | Config Sink:MaD:1 |
|
||||||
| stdlib.go:93:13:93:18 | selection of Form | stdlib.go:93:13:93:32 | call to Get | provenance | Src:MaD:2 Config |
|
| stdlib.go:93:13:93:18 | selection of Form | stdlib.go:93:13:93:32 | call to Get | provenance | Src:MaD:2 Config |
|
||||||
| stdlib.go:93:13:93:32 | call to Get | stdlib.go:94:3:94:8 | target | provenance | |
|
| stdlib.go:93:13:93:32 | call to Get | stdlib.go:94:3:94:8 | target | provenance | |
|
||||||
| stdlib.go:94:3:94:8 | target | stdlib.go:94:3:94:25 | compound-rhs ... += ... | provenance | Config |
|
| stdlib.go:94:3:94:8 | target | stdlib.go:94:3:94:25 | ... += ... | provenance | Config |
|
||||||
| stdlib.go:94:3:94:25 | compound-rhs ... += ... | stdlib.go:96:23:96:28 | target | provenance | Sink:MaD:1 |
|
| stdlib.go:94:3:94:25 | ... += ... | stdlib.go:96:23:96:28 | target | provenance | Sink:MaD:1 |
|
||||||
| stdlib.go:116:4:116:4 | implicit-deref r [postupdate] [URL] | stdlib.go:116:4:116:4 | r [postupdate] [pointer, URL] | provenance | |
|
| stdlib.go:116:4:116:4 | implicit dereference [postupdate] [URL] | stdlib.go:116:4:116:4 | r [postupdate] [pointer, URL] | provenance | |
|
||||||
| stdlib.go:116:4:116:4 | r [postupdate] [pointer, URL] | stdlib.go:117:24:117:24 | r [pointer, URL] | provenance | |
|
| stdlib.go:116:4:116:4 | r [postupdate] [pointer, URL] | stdlib.go:117:24:117:24 | r [pointer, URL] | provenance | |
|
||||||
| stdlib.go:116:4:116:8 | implicit-deref selection of URL | stdlib.go:116:4:116:8 | selection of URL [postupdate] | provenance | Config |
|
| stdlib.go:116:4:116:8 | implicit dereference | stdlib.go:116:4:116:8 | selection of URL [postupdate] | provenance | Config |
|
||||||
| stdlib.go:116:4:116:8 | selection of URL | stdlib.go:116:4:116:8 | implicit-deref selection of URL | provenance | Src:MaD:4 Config |
|
| stdlib.go:116:4:116:8 | selection of URL | stdlib.go:116:4:116:8 | implicit dereference | provenance | Src:MaD:4 Config |
|
||||||
| stdlib.go:116:4:116:8 | selection of URL [postupdate] | stdlib.go:116:4:116:4 | implicit-deref r [postupdate] [URL] | provenance | |
|
| stdlib.go:116:4:116:8 | selection of URL [postupdate] | stdlib.go:116:4:116:4 | implicit dereference [postupdate] [URL] | provenance | |
|
||||||
| stdlib.go:116:4:116:8 | selection of URL [postupdate] | stdlib.go:116:4:116:8 | implicit-deref selection of URL | provenance | Config |
|
| stdlib.go:116:4:116:8 | selection of URL [postupdate] | stdlib.go:116:4:116:8 | implicit dereference | provenance | Config |
|
||||||
| stdlib.go:117:24:117:24 | implicit-deref r [URL] | stdlib.go:117:24:117:28 | selection of URL | provenance | |
|
| stdlib.go:117:24:117:24 | implicit dereference [URL] | stdlib.go:117:24:117:28 | selection of URL | provenance | |
|
||||||
| stdlib.go:117:24:117:24 | r [pointer, URL] | stdlib.go:117:24:117:24 | implicit-deref r [URL] | provenance | |
|
| stdlib.go:117:24:117:24 | r [pointer, URL] | stdlib.go:117:24:117:24 | implicit dereference [URL] | provenance | |
|
||||||
| stdlib.go:117:24:117:28 | selection of URL | stdlib.go:117:24:117:37 | call to String | provenance | Src:MaD:4 Config Sink:MaD:1 |
|
| stdlib.go:117:24:117:28 | selection of URL | stdlib.go:117:24:117:37 | call to String | provenance | Src:MaD:4 Config Sink:MaD:1 |
|
||||||
| stdlib.go:150:13:150:18 | selection of Form | stdlib.go:150:13:150:32 | call to Get | provenance | Src:MaD:2 Config |
|
| stdlib.go:150:13:150:18 | selection of Form | stdlib.go:150:13:150:32 | call to Get | provenance | Src:MaD:2 Config |
|
||||||
| stdlib.go:150:13:150:32 | call to Get | stdlib.go:156:23:156:28 | target | provenance | Sink:MaD:1 |
|
| stdlib.go:150:13:150:32 | call to Get | stdlib.go:156:23:156:28 | target | provenance | Sink:MaD:1 |
|
||||||
@@ -51,42 +51,42 @@ edges
|
|||||||
| stdlib.go:177:35:177:39 | selection of URL | stdlib.go:177:35:177:52 | call to RequestURI | provenance | Src:MaD:4 Config |
|
| stdlib.go:177:35:177:39 | selection of URL | stdlib.go:177:35:177:52 | call to RequestURI | provenance | Src:MaD:4 Config |
|
||||||
| stdlib.go:177:35:177:52 | call to RequestURI | stdlib.go:177:24:177:52 | ...+... | provenance | Config Sink:MaD:1 |
|
| stdlib.go:177:35:177:52 | call to RequestURI | stdlib.go:177:24:177:52 | ...+... | provenance | Config Sink:MaD:1 |
|
||||||
| stdlib.go:186:13:186:33 | call to FormValue | stdlib.go:188:23:188:28 | target | provenance | Src:MaD:3 Sink:MaD:1 |
|
| stdlib.go:186:13:186:33 | call to FormValue | stdlib.go:188:23:188:28 | target | provenance | Src:MaD:3 Sink:MaD:1 |
|
||||||
| stdlib.go:194:3:194:57 | extract:0 ... := ... | stdlib.go:196:23:196:28 | target | provenance | |
|
| stdlib.go:194:3:194:57 | ... := ...[0] | stdlib.go:196:23:196:28 | target | provenance | |
|
||||||
| stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:194:3:194:57 | extract:0 ... := ... | provenance | Src:MaD:3 Config |
|
| stdlib.go:194:36:194:56 | call to FormValue | stdlib.go:194:3:194:57 | ... := ...[0] | provenance | Src:MaD:3 Config |
|
||||||
| stdlib.go:196:23:196:28 | implicit-deref target | stdlib.go:196:23:196:28 | target [postupdate] | provenance | Config |
|
| stdlib.go:196:23:196:28 | implicit dereference | stdlib.go:196:23:196:28 | target [postupdate] | provenance | Config |
|
||||||
| stdlib.go:196:23:196:28 | implicit-deref target | stdlib.go:196:23:196:33 | selection of Path | provenance | Config Sink:MaD:1 |
|
| stdlib.go:196:23:196:28 | implicit dereference | stdlib.go:196:23:196:33 | selection of Path | provenance | Config Sink:MaD:1 |
|
||||||
| stdlib.go:196:23:196:28 | target | stdlib.go:196:23:196:28 | implicit-deref target | provenance | Config |
|
| stdlib.go:196:23:196:28 | target | stdlib.go:196:23:196:28 | implicit dereference | provenance | Config |
|
||||||
| stdlib.go:196:23:196:28 | target | stdlib.go:196:23:196:33 | selection of Path | provenance | Config Sink:MaD:1 |
|
| stdlib.go:196:23:196:28 | target | stdlib.go:196:23:196:33 | selection of Path | provenance | Config Sink:MaD:1 |
|
||||||
| stdlib.go:196:23:196:28 | target | stdlib.go:198:23:198:28 | target | provenance | |
|
| stdlib.go:196:23:196:28 | target | stdlib.go:198:23:198:28 | target | provenance | |
|
||||||
| stdlib.go:196:23:196:28 | target [postupdate] | stdlib.go:196:23:196:28 | implicit-deref target | provenance | Config |
|
| stdlib.go:196:23:196:28 | target [postupdate] | stdlib.go:196:23:196:28 | implicit dereference | provenance | Config |
|
||||||
| stdlib.go:196:23:196:28 | target [postupdate] | stdlib.go:198:23:198:28 | target | provenance | |
|
| stdlib.go:196:23:196:28 | target [postupdate] | stdlib.go:198:23:198:28 | target | provenance | |
|
||||||
| stdlib.go:198:23:198:28 | target | stdlib.go:198:23:198:42 | call to EscapedPath | provenance | Config Sink:MaD:1 |
|
| stdlib.go:198:23:198:28 | target | stdlib.go:198:23:198:42 | call to EscapedPath | provenance | Config Sink:MaD:1 |
|
||||||
| stdlib.go:210:3:210:3 | implicit-deref u [postupdate] | stdlib.go:210:3:210:3 | u [postupdate] | provenance | Config |
|
| stdlib.go:210:3:210:3 | implicit dereference [postupdate] | stdlib.go:210:3:210:3 | u [postupdate] | provenance | Config |
|
||||||
| stdlib.go:210:3:210:3 | implicit-deref u [postupdate] | stdlib.go:210:3:210:3 | u [postupdate] [pointer] | provenance | |
|
| stdlib.go:210:3:210:3 | implicit dereference [postupdate] | stdlib.go:210:3:210:3 | u [postupdate] [pointer] | provenance | |
|
||||||
| stdlib.go:210:3:210:3 | u [postupdate] | stdlib.go:212:23:212:23 | u | provenance | |
|
| stdlib.go:210:3:210:3 | u [postupdate] | stdlib.go:212:23:212:23 | u | provenance | |
|
||||||
| stdlib.go:210:3:210:3 | u [postupdate] [pointer] | stdlib.go:212:23:212:23 | u [pointer] | provenance | |
|
| stdlib.go:210:3:210:3 | u [postupdate] [pointer] | stdlib.go:212:23:212:23 | u [pointer] | provenance | |
|
||||||
| stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:210:3:210:3 | implicit-deref u [postupdate] | provenance | Src:MaD:3 Config |
|
| stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:210:3:210:3 | implicit dereference [postupdate] | provenance | Src:MaD:3 Config |
|
||||||
| stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:210:3:210:3 | u [postupdate] | provenance | Src:MaD:3 Config |
|
| stdlib.go:210:12:210:30 | call to FormValue | stdlib.go:210:3:210:3 | u [postupdate] | provenance | Src:MaD:3 Config |
|
||||||
| stdlib.go:212:23:212:23 | implicit-deref u | stdlib.go:212:23:212:23 | u [postupdate] | provenance | Config |
|
| stdlib.go:212:23:212:23 | implicit dereference | stdlib.go:212:23:212:23 | u [postupdate] | provenance | Config |
|
||||||
| stdlib.go:212:23:212:23 | implicit-deref u | stdlib.go:212:23:212:28 | selection of Path | provenance | Config Sink:MaD:1 |
|
| stdlib.go:212:23:212:23 | implicit dereference | stdlib.go:212:23:212:28 | selection of Path | provenance | Config Sink:MaD:1 |
|
||||||
| stdlib.go:212:23:212:23 | u | stdlib.go:212:23:212:23 | implicit-deref u | provenance | Config |
|
| stdlib.go:212:23:212:23 | u | stdlib.go:212:23:212:23 | implicit dereference | provenance | Config |
|
||||||
| stdlib.go:212:23:212:23 | u | stdlib.go:212:23:212:28 | selection of Path | provenance | Config Sink:MaD:1 |
|
| stdlib.go:212:23:212:23 | u | stdlib.go:212:23:212:28 | selection of Path | provenance | Config Sink:MaD:1 |
|
||||||
| stdlib.go:212:23:212:23 | u | stdlib.go:214:23:214:23 | u | provenance | |
|
| stdlib.go:212:23:212:23 | u | stdlib.go:214:23:214:23 | u | provenance | |
|
||||||
| stdlib.go:212:23:212:23 | u [pointer] | stdlib.go:212:23:212:23 | implicit-deref u | provenance | |
|
| stdlib.go:212:23:212:23 | u [pointer] | stdlib.go:212:23:212:23 | implicit dereference | provenance | |
|
||||||
| stdlib.go:212:23:212:23 | u [postupdate] | stdlib.go:212:23:212:23 | implicit-deref u | provenance | Config |
|
| stdlib.go:212:23:212:23 | u [postupdate] | stdlib.go:212:23:212:23 | implicit dereference | provenance | Config |
|
||||||
| stdlib.go:212:23:212:23 | u [postupdate] | stdlib.go:214:23:214:23 | u | provenance | |
|
| stdlib.go:212:23:212:23 | u [postupdate] | stdlib.go:214:23:214:23 | u | provenance | |
|
||||||
| stdlib.go:214:23:214:23 | u | stdlib.go:214:23:214:32 | call to String | provenance | Config Sink:MaD:1 |
|
| stdlib.go:214:23:214:23 | u | stdlib.go:214:23:214:32 | call to String | provenance | Config Sink:MaD:1 |
|
||||||
| stdlib.go:257:3:257:3 | implicit-deref u [postupdate] | stdlib.go:257:3:257:3 | u [postupdate] | provenance | Config |
|
| stdlib.go:257:3:257:3 | implicit dereference [postupdate] | stdlib.go:257:3:257:3 | u [postupdate] | provenance | Config |
|
||||||
| stdlib.go:257:3:257:3 | implicit-deref u [postupdate] | stdlib.go:257:3:257:3 | u [postupdate] [pointer] | provenance | |
|
| stdlib.go:257:3:257:3 | implicit dereference [postupdate] | stdlib.go:257:3:257:3 | u [postupdate] [pointer] | provenance | |
|
||||||
| stdlib.go:257:3:257:3 | u [postupdate] | stdlib.go:260:3:260:3 | u | provenance | |
|
| stdlib.go:257:3:257:3 | u [postupdate] | stdlib.go:260:3:260:3 | u | provenance | |
|
||||||
| stdlib.go:257:3:257:3 | u [postupdate] [pointer] | stdlib.go:260:3:260:3 | u [pointer] | provenance | |
|
| stdlib.go:257:3:257:3 | u [postupdate] [pointer] | stdlib.go:260:3:260:3 | u [pointer] | provenance | |
|
||||||
| stdlib.go:257:12:257:30 | call to FormValue | stdlib.go:257:3:257:3 | implicit-deref u [postupdate] | provenance | Src:MaD:3 Config |
|
| stdlib.go:257:12:257:30 | call to FormValue | stdlib.go:257:3:257:3 | implicit dereference [postupdate] | provenance | Src:MaD:3 Config |
|
||||||
| stdlib.go:257:12:257:30 | call to FormValue | stdlib.go:257:3:257:3 | u [postupdate] | provenance | Src:MaD:3 Config |
|
| stdlib.go:257:12:257:30 | call to FormValue | stdlib.go:257:3:257:3 | u [postupdate] | provenance | Src:MaD:3 Config |
|
||||||
| stdlib.go:260:3:260:3 | implicit-deref u | stdlib.go:260:3:260:3 | u [postupdate] | provenance | Config |
|
| stdlib.go:260:3:260:3 | implicit dereference | stdlib.go:260:3:260:3 | u [postupdate] | provenance | Config |
|
||||||
| stdlib.go:260:3:260:3 | u | stdlib.go:260:3:260:3 | implicit-deref u | provenance | Config |
|
| stdlib.go:260:3:260:3 | u | stdlib.go:260:3:260:3 | implicit dereference | provenance | Config |
|
||||||
| stdlib.go:260:3:260:3 | u | stdlib.go:261:23:261:23 | u | provenance | |
|
| stdlib.go:260:3:260:3 | u | stdlib.go:261:23:261:23 | u | provenance | |
|
||||||
| stdlib.go:260:3:260:3 | u [pointer] | stdlib.go:260:3:260:3 | implicit-deref u | provenance | |
|
| stdlib.go:260:3:260:3 | u [pointer] | stdlib.go:260:3:260:3 | implicit dereference | provenance | |
|
||||||
| stdlib.go:260:3:260:3 | u [postupdate] | stdlib.go:260:3:260:3 | implicit-deref u | provenance | Config |
|
| stdlib.go:260:3:260:3 | u [postupdate] | stdlib.go:260:3:260:3 | implicit dereference | provenance | Config |
|
||||||
| stdlib.go:260:3:260:3 | u [postupdate] | stdlib.go:261:23:261:23 | u | provenance | |
|
| stdlib.go:260:3:260:3 | u [postupdate] | stdlib.go:261:23:261:23 | u | provenance | |
|
||||||
| stdlib.go:261:23:261:23 | u | stdlib.go:261:23:261:32 | call to String | provenance | Config Sink:MaD:1 |
|
| stdlib.go:261:23:261:23 | u | stdlib.go:261:23:261:32 | call to String | provenance | Config Sink:MaD:1 |
|
||||||
models
|
models
|
||||||
@@ -118,14 +118,14 @@ nodes
|
|||||||
| stdlib.go:93:13:93:18 | selection of Form | semmle.label | selection of Form |
|
| stdlib.go:93:13:93:18 | selection of Form | semmle.label | selection of Form |
|
||||||
| stdlib.go:93:13:93:32 | call to Get | semmle.label | call to Get |
|
| stdlib.go:93:13:93:32 | call to Get | semmle.label | call to Get |
|
||||||
| stdlib.go:94:3:94:8 | target | semmle.label | target |
|
| stdlib.go:94:3:94:8 | target | semmle.label | target |
|
||||||
| stdlib.go:94:3:94:25 | compound-rhs ... += ... | semmle.label | compound-rhs ... += ... |
|
| stdlib.go:94:3:94:25 | ... += ... | semmle.label | ... += ... |
|
||||||
| stdlib.go:96:23:96:28 | target | semmle.label | target |
|
| stdlib.go:96:23:96:28 | target | semmle.label | target |
|
||||||
| stdlib.go:116:4:116:4 | implicit-deref r [postupdate] [URL] | semmle.label | implicit-deref r [postupdate] [URL] |
|
| stdlib.go:116:4:116:4 | implicit dereference [postupdate] [URL] | semmle.label | implicit dereference [postupdate] [URL] |
|
||||||
| stdlib.go:116:4:116:4 | r [postupdate] [pointer, URL] | semmle.label | r [postupdate] [pointer, URL] |
|
| stdlib.go:116:4:116:4 | r [postupdate] [pointer, URL] | semmle.label | r [postupdate] [pointer, URL] |
|
||||||
| stdlib.go:116:4:116:8 | implicit-deref selection of URL | semmle.label | implicit-deref selection of URL |
|
| stdlib.go:116:4:116:8 | implicit dereference | semmle.label | implicit dereference |
|
||||||
| stdlib.go:116:4:116:8 | selection of URL | semmle.label | selection of URL |
|
| stdlib.go:116:4:116:8 | selection of URL | semmle.label | selection of URL |
|
||||||
| stdlib.go:116:4:116:8 | selection of URL [postupdate] | semmle.label | selection of URL [postupdate] |
|
| stdlib.go:116:4:116:8 | selection of URL [postupdate] | semmle.label | selection of URL [postupdate] |
|
||||||
| stdlib.go:117:24:117:24 | implicit-deref r [URL] | semmle.label | implicit-deref r [URL] |
|
| stdlib.go:117:24:117:24 | implicit dereference [URL] | semmle.label | implicit dereference [URL] |
|
||||||
| stdlib.go:117:24:117:24 | r [pointer, URL] | semmle.label | r [pointer, URL] |
|
| stdlib.go:117:24:117:24 | r [pointer, URL] | semmle.label | r [pointer, URL] |
|
||||||
| stdlib.go:117:24:117:28 | selection of URL | semmle.label | selection of URL |
|
| stdlib.go:117:24:117:28 | selection of URL | semmle.label | selection of URL |
|
||||||
| stdlib.go:117:24:117:37 | call to String | semmle.label | call to String |
|
| stdlib.go:117:24:117:37 | call to String | semmle.label | call to String |
|
||||||
@@ -142,30 +142,30 @@ nodes
|
|||||||
| stdlib.go:177:35:177:52 | call to RequestURI | semmle.label | call to RequestURI |
|
| stdlib.go:177:35:177:52 | call to RequestURI | semmle.label | call to RequestURI |
|
||||||
| stdlib.go:186:13:186:33 | call to FormValue | semmle.label | call to FormValue |
|
| stdlib.go:186:13:186:33 | call to FormValue | semmle.label | call to FormValue |
|
||||||
| stdlib.go:188:23:188:28 | target | semmle.label | target |
|
| stdlib.go:188:23:188:28 | target | semmle.label | target |
|
||||||
| stdlib.go:194:3:194:57 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| stdlib.go:194:3:194:57 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| stdlib.go:194:36:194:56 | call to FormValue | semmle.label | call to FormValue |
|
| stdlib.go:194:36:194:56 | call to FormValue | semmle.label | call to FormValue |
|
||||||
| stdlib.go:196:23:196:28 | implicit-deref target | semmle.label | implicit-deref target |
|
| stdlib.go:196:23:196:28 | implicit dereference | semmle.label | implicit dereference |
|
||||||
| stdlib.go:196:23:196:28 | target | semmle.label | target |
|
| stdlib.go:196:23:196:28 | target | semmle.label | target |
|
||||||
| stdlib.go:196:23:196:28 | target [postupdate] | semmle.label | target [postupdate] |
|
| stdlib.go:196:23:196:28 | target [postupdate] | semmle.label | target [postupdate] |
|
||||||
| stdlib.go:196:23:196:33 | selection of Path | semmle.label | selection of Path |
|
| stdlib.go:196:23:196:33 | selection of Path | semmle.label | selection of Path |
|
||||||
| stdlib.go:198:23:198:28 | target | semmle.label | target |
|
| stdlib.go:198:23:198:28 | target | semmle.label | target |
|
||||||
| stdlib.go:198:23:198:42 | call to EscapedPath | semmle.label | call to EscapedPath |
|
| stdlib.go:198:23:198:42 | call to EscapedPath | semmle.label | call to EscapedPath |
|
||||||
| stdlib.go:210:3:210:3 | implicit-deref u [postupdate] | semmle.label | implicit-deref u [postupdate] |
|
| stdlib.go:210:3:210:3 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
|
||||||
| stdlib.go:210:3:210:3 | u [postupdate] | semmle.label | u [postupdate] |
|
| stdlib.go:210:3:210:3 | u [postupdate] | semmle.label | u [postupdate] |
|
||||||
| stdlib.go:210:3:210:3 | u [postupdate] [pointer] | semmle.label | u [postupdate] [pointer] |
|
| stdlib.go:210:3:210:3 | u [postupdate] [pointer] | semmle.label | u [postupdate] [pointer] |
|
||||||
| stdlib.go:210:12:210:30 | call to FormValue | semmle.label | call to FormValue |
|
| stdlib.go:210:12:210:30 | call to FormValue | semmle.label | call to FormValue |
|
||||||
| stdlib.go:212:23:212:23 | implicit-deref u | semmle.label | implicit-deref u |
|
| stdlib.go:212:23:212:23 | implicit dereference | semmle.label | implicit dereference |
|
||||||
| stdlib.go:212:23:212:23 | u | semmle.label | u |
|
| stdlib.go:212:23:212:23 | u | semmle.label | u |
|
||||||
| stdlib.go:212:23:212:23 | u [pointer] | semmle.label | u [pointer] |
|
| stdlib.go:212:23:212:23 | u [pointer] | semmle.label | u [pointer] |
|
||||||
| stdlib.go:212:23:212:23 | u [postupdate] | semmle.label | u [postupdate] |
|
| stdlib.go:212:23:212:23 | u [postupdate] | semmle.label | u [postupdate] |
|
||||||
| stdlib.go:212:23:212:28 | selection of Path | semmle.label | selection of Path |
|
| stdlib.go:212:23:212:28 | selection of Path | semmle.label | selection of Path |
|
||||||
| stdlib.go:214:23:214:23 | u | semmle.label | u |
|
| stdlib.go:214:23:214:23 | u | semmle.label | u |
|
||||||
| stdlib.go:214:23:214:32 | call to String | semmle.label | call to String |
|
| stdlib.go:214:23:214:32 | call to String | semmle.label | call to String |
|
||||||
| stdlib.go:257:3:257:3 | implicit-deref u [postupdate] | semmle.label | implicit-deref u [postupdate] |
|
| stdlib.go:257:3:257:3 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
|
||||||
| stdlib.go:257:3:257:3 | u [postupdate] | semmle.label | u [postupdate] |
|
| stdlib.go:257:3:257:3 | u [postupdate] | semmle.label | u [postupdate] |
|
||||||
| stdlib.go:257:3:257:3 | u [postupdate] [pointer] | semmle.label | u [postupdate] [pointer] |
|
| stdlib.go:257:3:257:3 | u [postupdate] [pointer] | semmle.label | u [postupdate] [pointer] |
|
||||||
| stdlib.go:257:12:257:30 | call to FormValue | semmle.label | call to FormValue |
|
| stdlib.go:257:12:257:30 | call to FormValue | semmle.label | call to FormValue |
|
||||||
| stdlib.go:260:3:260:3 | implicit-deref u | semmle.label | implicit-deref u |
|
| stdlib.go:260:3:260:3 | implicit dereference | semmle.label | implicit dereference |
|
||||||
| stdlib.go:260:3:260:3 | u | semmle.label | u |
|
| stdlib.go:260:3:260:3 | u | semmle.label | u |
|
||||||
| stdlib.go:260:3:260:3 | u [pointer] | semmle.label | u [pointer] |
|
| stdlib.go:260:3:260:3 | u [pointer] | semmle.label | u [pointer] |
|
||||||
| stdlib.go:260:3:260:3 | u [postupdate] | semmle.label | u [postupdate] |
|
| stdlib.go:260:3:260:3 | u [postupdate] | semmle.label | u [postupdate] |
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ edges
|
|||||||
| UncontrolledAllocationSizeBad.go:11:12:11:24 | call to Query | UncontrolledAllocationSizeBad.go:13:15:13:20 | source | provenance | |
|
| UncontrolledAllocationSizeBad.go:11:12:11:24 | call to Query | UncontrolledAllocationSizeBad.go:13:15:13:20 | source | provenance | |
|
||||||
| UncontrolledAllocationSizeBad.go:13:15:13:20 | source | UncontrolledAllocationSizeBad.go:13:15:13:29 | call to Get | provenance | MaD:3 |
|
| UncontrolledAllocationSizeBad.go:13:15:13:20 | source | UncontrolledAllocationSizeBad.go:13:15:13:29 | call to Get | provenance | MaD:3 |
|
||||||
| UncontrolledAllocationSizeBad.go:13:15:13:29 | call to Get | UncontrolledAllocationSizeBad.go:14:28:14:36 | sourceStr | provenance | |
|
| UncontrolledAllocationSizeBad.go:13:15:13:29 | call to Get | UncontrolledAllocationSizeBad.go:14:28:14:36 | sourceStr | provenance | |
|
||||||
| UncontrolledAllocationSizeBad.go:14:2:14:37 | extract:0 ... := ... | UncontrolledAllocationSizeBad.go:20:27:20:30 | sink | provenance | |
|
| UncontrolledAllocationSizeBad.go:14:2:14:37 | ... := ...[0] | UncontrolledAllocationSizeBad.go:20:27:20:30 | sink | provenance | |
|
||||||
| UncontrolledAllocationSizeBad.go:14:28:14:36 | sourceStr | UncontrolledAllocationSizeBad.go:14:2:14:37 | extract:0 ... := ... | provenance | Config |
|
| UncontrolledAllocationSizeBad.go:14:28:14:36 | sourceStr | UncontrolledAllocationSizeBad.go:14:2:14:37 | ... := ...[0] | provenance | Config |
|
||||||
models
|
models
|
||||||
| 1 | Source: net/http; Request; true; URL; ; ; ; remote; manual |
|
| 1 | Source: net/http; Request; true; URL; ; ; ; remote; manual |
|
||||||
| 2 | Summary: net/url; URL; true; Query; ; ; Argument[receiver]; ReturnValue; taint; manual |
|
| 2 | Summary: net/url; URL; true; Query; ; ; Argument[receiver]; ReturnValue; taint; manual |
|
||||||
@@ -16,7 +16,7 @@ nodes
|
|||||||
| UncontrolledAllocationSizeBad.go:11:12:11:24 | call to Query | semmle.label | call to Query |
|
| UncontrolledAllocationSizeBad.go:11:12:11:24 | call to Query | semmle.label | call to Query |
|
||||||
| UncontrolledAllocationSizeBad.go:13:15:13:20 | source | semmle.label | source |
|
| UncontrolledAllocationSizeBad.go:13:15:13:20 | source | semmle.label | source |
|
||||||
| UncontrolledAllocationSizeBad.go:13:15:13:29 | call to Get | semmle.label | call to Get |
|
| UncontrolledAllocationSizeBad.go:13:15:13:29 | call to Get | semmle.label | call to Get |
|
||||||
| UncontrolledAllocationSizeBad.go:14:2:14:37 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
|
| UncontrolledAllocationSizeBad.go:14:2:14:37 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||||
| UncontrolledAllocationSizeBad.go:14:28:14:36 | sourceStr | semmle.label | sourceStr |
|
| UncontrolledAllocationSizeBad.go:14:28:14:36 | sourceStr | semmle.label | sourceStr |
|
||||||
| UncontrolledAllocationSizeBad.go:20:27:20:30 | sink | semmle.label | sink |
|
| UncontrolledAllocationSizeBad.go:20:27:20:30 | sink | semmle.label | sink |
|
||||||
subpaths
|
subpaths
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ edges
|
|||||||
| tst.go:11:13:11:35 | call to FormValue | tst.go:39:11:39:29 | ...+... | provenance | Src:MaD:1 |
|
| tst.go:11:13:11:35 | call to FormValue | tst.go:39:11:39:29 | ...+... | provenance | Src:MaD:1 |
|
||||||
| tst.go:11:13:11:35 | call to FormValue | tst.go:41:11:41:40 | ...+... | provenance | Src:MaD:1 |
|
| tst.go:11:13:11:35 | call to FormValue | tst.go:41:11:41:40 | ...+... | provenance | Src:MaD:1 |
|
||||||
| tst.go:11:13:11:35 | call to FormValue | tst.go:48:11:48:18 | tainted2 | provenance | Src:MaD:1 |
|
| tst.go:11:13:11:35 | call to FormValue | tst.go:48:11:48:18 | tainted2 | provenance | Src:MaD:1 |
|
||||||
| tst.go:48:2:48:2 | implicit-deref u [postupdate] | tst.go:48:2:48:2 | u [postupdate] | provenance | |
|
| tst.go:48:2:48:2 | implicit dereference [postupdate] | tst.go:48:2:48:2 | u [postupdate] | provenance | |
|
||||||
| tst.go:48:2:48:2 | u [postupdate] | tst.go:49:11:49:11 | u | provenance | |
|
| tst.go:48:2:48:2 | u [postupdate] | tst.go:49:11:49:11 | u | provenance | |
|
||||||
| tst.go:48:11:48:18 | tainted2 | tst.go:48:2:48:2 | implicit-deref u [postupdate] | provenance | Config |
|
| tst.go:48:11:48:18 | tainted2 | tst.go:48:2:48:2 | implicit dereference [postupdate] | provenance | Config |
|
||||||
| tst.go:48:11:48:18 | tainted2 | tst.go:48:2:48:2 | u [postupdate] | provenance | Config |
|
| tst.go:48:11:48:18 | tainted2 | tst.go:48:2:48:2 | u [postupdate] | provenance | Config |
|
||||||
| tst.go:49:11:49:11 | u | tst.go:49:11:49:20 | call to String | provenance | MaD:3 |
|
| tst.go:49:11:49:11 | u | tst.go:49:11:49:20 | call to String | provenance | MaD:3 |
|
||||||
| websocket.go:60:21:60:31 | call to Referer | websocket.go:65:27:65:40 | untrustedInput | provenance | Src:MaD:2 |
|
| websocket.go:60:21:60:31 | call to Referer | websocket.go:65:27:65:40 | untrustedInput | provenance | Src:MaD:2 |
|
||||||
@@ -71,7 +71,7 @@ nodes
|
|||||||
| tst.go:37:18:37:24 | tainted | semmle.label | tainted |
|
| tst.go:37:18:37:24 | tainted | semmle.label | tainted |
|
||||||
| tst.go:39:11:39:29 | ...+... | semmle.label | ...+... |
|
| tst.go:39:11:39:29 | ...+... | semmle.label | ...+... |
|
||||||
| tst.go:41:11:41:40 | ...+... | semmle.label | ...+... |
|
| tst.go:41:11:41:40 | ...+... | semmle.label | ...+... |
|
||||||
| tst.go:48:2:48:2 | implicit-deref u [postupdate] | semmle.label | implicit-deref u [postupdate] |
|
| tst.go:48:2:48:2 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
|
||||||
| tst.go:48:2:48:2 | u [postupdate] | semmle.label | u [postupdate] |
|
| tst.go:48:2:48:2 | u [postupdate] | semmle.label | u [postupdate] |
|
||||||
| tst.go:48:11:48:18 | tainted2 | semmle.label | tainted2 |
|
| tst.go:48:11:48:18 | tainted2 | semmle.label | tainted2 |
|
||||||
| tst.go:49:11:49:11 | u | semmle.label | u |
|
| tst.go:49:11:49:11 | u | semmle.label | u |
|
||||||
|
|||||||
2
python/ql/consistency-queries/CfgConsistency.ql
Normal file
2
python/ql/consistency-queries/CfgConsistency.ql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import semmle.python.controlflow.internal.AstNodeImpl
|
||||||
|
import ControlFlow::Consistency
|
||||||
4
python/ql/lib/change-notes/2026-05-19-add-shared-cfg.md
Normal file
4
python/ql/lib/change-notes/2026-05-19-add-shared-cfg.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* A new Python control flow graph implementation has been added under `semmle.python.controlflow.internal.Cfg` (backed by `AstNodeImpl.qll`), built on the shared `codeql.controlflow.ControlFlowGraph` library. It is not yet used by the dataflow library or any production query; the legacy CFG in `semmle/python/Flow.qll` remains the default. The new library is exposed for tests and for upcoming migrations.
|
||||||
4
python/ql/lib/change-notes/2026-05-19-add-shared-ssa.md
Normal file
4
python/ql/lib/change-notes/2026-05-19-add-shared-ssa.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* A new SSA adapter has been added under `semmle.python.dataflow.new.internal.SsaImpl`, built on the shared `codeql.ssa.Ssa` library and the new shared CFG (`semmle.python.controlflow.internal.Cfg`). It is not yet used by the dataflow library or any production query; the legacy ESSA SSA in `semmle/python/essa/*` remains the default. The new SSA adapter is exposed for tests and for the upcoming dataflow migration.
|
||||||
45
python/ql/lib/printCfgNew.ql
Normal file
45
python/ql/lib/printCfgNew.ql
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* @name Print CFG (New)
|
||||||
|
* @description Produces a representation of a file's Control Flow Graph
|
||||||
|
* using the new shared control flow library.
|
||||||
|
* This query is used by the VS Code extension.
|
||||||
|
* @id python/print-cfg
|
||||||
|
* @kind graph
|
||||||
|
* @tags ide-contextual-queries/print-cfg
|
||||||
|
*/
|
||||||
|
|
||||||
|
private import python as Py
|
||||||
|
import semmle.python.controlflow.internal.AstNodeImpl
|
||||||
|
|
||||||
|
external string selectedSourceFile();
|
||||||
|
|
||||||
|
private predicate selectedSourceFileAlias = selectedSourceFile/0;
|
||||||
|
|
||||||
|
external int selectedSourceLine();
|
||||||
|
|
||||||
|
private predicate selectedSourceLineAlias = selectedSourceLine/0;
|
||||||
|
|
||||||
|
external int selectedSourceColumn();
|
||||||
|
|
||||||
|
private predicate selectedSourceColumnAlias = selectedSourceColumn/0;
|
||||||
|
|
||||||
|
module ViewCfgQueryInput implements ControlFlow::ViewCfgQueryInputSig<Py::File> {
|
||||||
|
predicate selectedSourceFile = selectedSourceFileAlias/0;
|
||||||
|
|
||||||
|
predicate selectedSourceLine = selectedSourceLineAlias/0;
|
||||||
|
|
||||||
|
predicate selectedSourceColumn = selectedSourceColumnAlias/0;
|
||||||
|
|
||||||
|
predicate cfgScopeSpan(
|
||||||
|
Ast::Callable callable, Py::File file, int startLine, int startColumn, int endLine,
|
||||||
|
int endColumn
|
||||||
|
) {
|
||||||
|
exists(Py::Scope scope |
|
||||||
|
scope = callable.asScope() and
|
||||||
|
file = scope.getLocation().getFile() and
|
||||||
|
scope.getLocation().hasLocationInfo(_, startLine, startColumn, endLine, endColumn)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
import ControlFlow::ViewCfgQuery<Py::File, ViewCfgQueryInput>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
overlay[local]
|
overlay[local]
|
||||||
module;
|
module;
|
||||||
|
|
||||||
import python
|
import python as Py
|
||||||
private import semmle.python.internal.CachedStages
|
private import semmle.python.internal.CachedStages
|
||||||
private import codeql.controlflow.BasicBlock as BB
|
private import codeql.controlflow.BasicBlock as BB
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ private import codeql.controlflow.BasicBlock as BB
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
private predicate augstore(ControlFlowNode load, ControlFlowNode store) {
|
private predicate augstore(ControlFlowNode load, ControlFlowNode store) {
|
||||||
exists(Expr load_store | exists(AugAssign aa | aa.getTarget() = load_store) |
|
exists(Py::Expr load_store | exists(Py::AugAssign aa | aa.getTarget() = load_store) |
|
||||||
toAst(load) = load_store and
|
toAst(load) = load_store and
|
||||||
toAst(store) = load_store and
|
toAst(store) = load_store and
|
||||||
load.strictlyDominates(store)
|
load.strictlyDominates(store)
|
||||||
@@ -25,7 +25,7 @@ private predicate augstore(ControlFlowNode load, ControlFlowNode store) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** A non-dispatched getNode() to avoid negative recursion issues */
|
/** A non-dispatched getNode() to avoid negative recursion issues */
|
||||||
private AstNode toAst(ControlFlowNode n) { py_flow_bb_node(n, result, _, _) }
|
private Py::AstNode toAst(ControlFlowNode n) { py_flow_bb_node(n, result, _, _) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A control flow node. Control flow nodes have a many-to-one relation with syntactic nodes,
|
* A control flow node. Control flow nodes have a many-to-one relation with syntactic nodes,
|
||||||
@@ -35,19 +35,19 @@ private AstNode toAst(ControlFlowNode n) { py_flow_bb_node(n, result, _, _) }
|
|||||||
class ControlFlowNode extends @py_flow_node {
|
class ControlFlowNode extends @py_flow_node {
|
||||||
/** Whether this control flow node is a load (including those in augmented assignments) */
|
/** Whether this control flow node is a load (including those in augmented assignments) */
|
||||||
predicate isLoad() {
|
predicate isLoad() {
|
||||||
exists(Expr e | e = toAst(this) | py_expr_contexts(_, 3, e) and not augstore(_, this))
|
exists(Py::Expr e | e = toAst(this) | py_expr_contexts(_, 3, e) and not augstore(_, this))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this control flow node is a store (including those in augmented assignments) */
|
/** Whether this control flow node is a store (including those in augmented assignments) */
|
||||||
predicate isStore() {
|
predicate isStore() {
|
||||||
exists(Expr e | e = toAst(this) | py_expr_contexts(_, 5, e) or augstore(_, this))
|
exists(Py::Expr e | e = toAst(this) | py_expr_contexts(_, 5, e) or augstore(_, this))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this control flow node is a delete */
|
/** Whether this control flow node is a delete */
|
||||||
predicate isDelete() { exists(Expr e | e = toAst(this) | py_expr_contexts(_, 2, e)) }
|
predicate isDelete() { exists(Py::Expr e | e = toAst(this) | py_expr_contexts(_, 2, e)) }
|
||||||
|
|
||||||
/** Whether this control flow node is a parameter */
|
/** Whether this control flow node is a parameter */
|
||||||
predicate isParameter() { exists(Expr e | e = toAst(this) | py_expr_contexts(_, 4, e)) }
|
predicate isParameter() { exists(Py::Expr e | e = toAst(this) | py_expr_contexts(_, 4, e)) }
|
||||||
|
|
||||||
/** Whether this control flow node is a store in an augmented assignment */
|
/** Whether this control flow node is a store in an augmented assignment */
|
||||||
predicate isAugStore() { augstore(_, this) }
|
predicate isAugStore() { augstore(_, this) }
|
||||||
@@ -57,61 +57,61 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
|
|
||||||
/** Whether this flow node corresponds to a literal */
|
/** Whether this flow node corresponds to a literal */
|
||||||
predicate isLiteral() {
|
predicate isLiteral() {
|
||||||
toAst(this) instanceof Bytes
|
toAst(this) instanceof Py::Bytes
|
||||||
or
|
or
|
||||||
toAst(this) instanceof Dict
|
toAst(this) instanceof Py::Dict
|
||||||
or
|
or
|
||||||
toAst(this) instanceof DictComp
|
toAst(this) instanceof Py::DictComp
|
||||||
or
|
or
|
||||||
toAst(this) instanceof Set
|
toAst(this) instanceof Py::Set
|
||||||
or
|
or
|
||||||
toAst(this) instanceof SetComp
|
toAst(this) instanceof Py::SetComp
|
||||||
or
|
or
|
||||||
toAst(this) instanceof Ellipsis
|
toAst(this) instanceof Py::Ellipsis
|
||||||
or
|
or
|
||||||
toAst(this) instanceof GeneratorExp
|
toAst(this) instanceof Py::GeneratorExp
|
||||||
or
|
or
|
||||||
toAst(this) instanceof Lambda
|
toAst(this) instanceof Py::Lambda
|
||||||
or
|
or
|
||||||
toAst(this) instanceof ListComp
|
toAst(this) instanceof Py::ListComp
|
||||||
or
|
or
|
||||||
toAst(this) instanceof List
|
toAst(this) instanceof Py::List
|
||||||
or
|
or
|
||||||
toAst(this) instanceof Num
|
toAst(this) instanceof Py::Num
|
||||||
or
|
or
|
||||||
toAst(this) instanceof Tuple
|
toAst(this) instanceof Py::Tuple
|
||||||
or
|
or
|
||||||
toAst(this) instanceof Unicode
|
toAst(this) instanceof Py::Unicode
|
||||||
or
|
or
|
||||||
toAst(this) instanceof NameConstant
|
toAst(this) instanceof Py::NameConstant
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this flow node corresponds to an attribute expression */
|
/** Whether this flow node corresponds to an attribute expression */
|
||||||
predicate isAttribute() { toAst(this) instanceof Attribute }
|
predicate isAttribute() { toAst(this) instanceof Py::Attribute }
|
||||||
|
|
||||||
/** Whether this flow node corresponds to an subscript expression */
|
/** Whether this flow node corresponds to an subscript expression */
|
||||||
predicate isSubscript() { toAst(this) instanceof Subscript }
|
predicate isSubscript() { toAst(this) instanceof Py::Subscript }
|
||||||
|
|
||||||
/** Whether this flow node corresponds to an import member */
|
/** Whether this flow node corresponds to an import member */
|
||||||
predicate isImportMember() { toAst(this) instanceof ImportMember }
|
predicate isImportMember() { toAst(this) instanceof Py::ImportMember }
|
||||||
|
|
||||||
/** Whether this flow node corresponds to a call */
|
/** Whether this flow node corresponds to a call */
|
||||||
predicate isCall() { toAst(this) instanceof Call }
|
predicate isCall() { toAst(this) instanceof Py::Call }
|
||||||
|
|
||||||
/** Whether this flow node is the first in a module */
|
/** Whether this flow node is the first in a module */
|
||||||
predicate isModuleEntry() { this.isEntryNode() and toAst(this) instanceof Module }
|
predicate isModuleEntry() { this.isEntryNode() and toAst(this) instanceof Py::Module }
|
||||||
|
|
||||||
/** Whether this flow node corresponds to an import */
|
/** Whether this flow node corresponds to an import */
|
||||||
predicate isImport() { toAst(this) instanceof ImportExpr }
|
predicate isImport() { toAst(this) instanceof Py::ImportExpr }
|
||||||
|
|
||||||
/** Whether this flow node corresponds to a conditional expression */
|
/** Whether this flow node corresponds to a conditional expression */
|
||||||
predicate isIfExp() { toAst(this) instanceof IfExp }
|
predicate isIfExp() { toAst(this) instanceof Py::IfExp }
|
||||||
|
|
||||||
/** Whether this flow node corresponds to a function definition expression */
|
/** Whether this flow node corresponds to a function definition expression */
|
||||||
predicate isFunction() { toAst(this) instanceof FunctionExpr }
|
predicate isFunction() { toAst(this) instanceof Py::FunctionExpr }
|
||||||
|
|
||||||
/** Whether this flow node corresponds to a class definition expression */
|
/** Whether this flow node corresponds to a class definition expression */
|
||||||
predicate isClass() { toAst(this) instanceof ClassExpr }
|
predicate isClass() { toAst(this) instanceof Py::ClassExpr }
|
||||||
|
|
||||||
/** Gets a predecessor of this flow node */
|
/** Gets a predecessor of this flow node */
|
||||||
ControlFlowNode getAPredecessor() { this = result.getASuccessor() }
|
ControlFlowNode getAPredecessor() { this = result.getASuccessor() }
|
||||||
@@ -123,25 +123,25 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
ControlFlowNode getImmediateDominator() { py_idoms(this, result) }
|
ControlFlowNode getImmediateDominator() { py_idoms(this, result) }
|
||||||
|
|
||||||
/** Gets the syntactic element corresponding to this flow node */
|
/** Gets the syntactic element corresponding to this flow node */
|
||||||
AstNode getNode() { py_flow_bb_node(this, result, _, _) }
|
Py::AstNode getNode() { py_flow_bb_node(this, result, _, _) }
|
||||||
|
|
||||||
/** Gets a textual representation of this element. */
|
/** Gets a textual representation of this element. */
|
||||||
cached
|
cached
|
||||||
string toString() {
|
string toString() {
|
||||||
Stages::AST::ref() and
|
Stages::AST::ref() and
|
||||||
// Since modules can have ambigous names, entry nodes can too, if we do not collate them.
|
// Since modules can have ambigous names, entry nodes can too, if we do not collate them.
|
||||||
exists(Scope s | s.getEntryNode() = this |
|
exists(Py::Scope s | s.getEntryNode() = this |
|
||||||
result = "Entry node for " + concat( | | s.toString(), ",")
|
result = "Entry node for " + concat( | | s.toString(), ",")
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(Scope s | s.getANormalExit() = this | result = "Exit node for " + s.toString())
|
exists(Py::Scope s | s.getANormalExit() = this | result = "Exit node for " + s.toString())
|
||||||
or
|
or
|
||||||
not exists(Scope s | s.getEntryNode() = this or s.getANormalExit() = this) and
|
not exists(Py::Scope s | s.getEntryNode() = this or s.getANormalExit() = this) and
|
||||||
result = "ControlFlowNode for " + this.getNode().toString()
|
result = "ControlFlowNode for " + this.getNode().toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the location of this ControlFlowNode */
|
/** Gets the location of this ControlFlowNode */
|
||||||
Location getLocation() { result = this.getNode().getLocation() }
|
Py::Location getLocation() { result = this.getNode().getLocation() }
|
||||||
|
|
||||||
/** Whether this flow node is the first in its scope */
|
/** Whether this flow node is the first in its scope */
|
||||||
predicate isEntryNode() { py_scope_flow(this, _, -1) }
|
predicate isEntryNode() { py_scope_flow(this, _, -1) }
|
||||||
@@ -151,9 +151,9 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
|
|
||||||
/** Gets the scope containing this flow node */
|
/** Gets the scope containing this flow node */
|
||||||
cached
|
cached
|
||||||
Scope getScope() {
|
Py::Scope getScope() {
|
||||||
Stages::AST::ref() and
|
Stages::AST::ref() and
|
||||||
if this.getNode() instanceof Scope
|
if this.getNode() instanceof Py::Scope
|
||||||
then
|
then
|
||||||
/* Entry or exit node */
|
/* Entry or exit node */
|
||||||
result = this.getNode()
|
result = this.getNode()
|
||||||
@@ -161,7 +161,7 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the enclosing module */
|
/** Gets the enclosing module */
|
||||||
Module getEnclosingModule() { result = this.getScope().getEnclosingModule() }
|
Py::Module getEnclosingModule() { result = this.getScope().getEnclosingModule() }
|
||||||
|
|
||||||
/** Gets a successor for this node if the relevant condition is True. */
|
/** Gets a successor for this node if the relevant condition is True. */
|
||||||
ControlFlowNode getATrueSuccessor() {
|
ControlFlowNode getATrueSuccessor() {
|
||||||
@@ -188,7 +188,7 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Whether the scope may be exited as a result of this node raising an exception */
|
/** Whether the scope may be exited as a result of this node raising an exception */
|
||||||
predicate isExceptionalExit(Scope s) { py_scope_flow(this, s, 1) }
|
predicate isExceptionalExit(Py::Scope s) { py_scope_flow(this, s, 1) }
|
||||||
|
|
||||||
/** Whether this node is a normal (non-exceptional) exit */
|
/** Whether this node is a normal (non-exceptional) exit */
|
||||||
predicate isNormalExit() { py_scope_flow(this, _, 0) or py_scope_flow(this, _, 2) }
|
predicate isNormalExit() { py_scope_flow(this, _, 0) or py_scope_flow(this, _, 2) }
|
||||||
@@ -236,7 +236,7 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
/* join-ordering helper for `getAChild() */
|
/* join-ordering helper for `getAChild() */
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
private ControlFlowNode getExprChild(BasicBlock dom) {
|
private ControlFlowNode getExprChild(BasicBlock dom) {
|
||||||
this.getNode().(Expr).getAChildNode() = result.getNode() and
|
this.getNode().(Py::Expr).getAChildNode() = result.getNode() and
|
||||||
result.getBasicBlock().dominates(dom) and
|
result.getBasicBlock().dominates(dom) and
|
||||||
not this instanceof UnaryExprNode
|
not this instanceof UnaryExprNode
|
||||||
}
|
}
|
||||||
@@ -249,16 +249,16 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
private class AnyNode extends ControlFlowNode {
|
private class AnyNode extends ControlFlowNode {
|
||||||
override AstNode getNode() { result = super.getNode() }
|
override Py::AstNode getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a call expression, such as `func(...)` */
|
/** A control flow node corresponding to a call expression, such as `func(...)` */
|
||||||
class CallNode extends ControlFlowNode {
|
class CallNode extends ControlFlowNode {
|
||||||
CallNode() { toAst(this) instanceof Call }
|
CallNode() { toAst(this) instanceof Py::Call }
|
||||||
|
|
||||||
/** Gets the flow node corresponding to the function expression for the call corresponding to this flow node */
|
/** Gets the flow node corresponding to the function expression for the call corresponding to this flow node */
|
||||||
ControlFlowNode getFunction() {
|
ControlFlowNode getFunction() {
|
||||||
exists(Call c |
|
exists(Py::Call c |
|
||||||
this.getNode() = c and
|
this.getNode() = c and
|
||||||
c.getFunc() = result.getNode() and
|
c.getFunc() = result.getNode() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -267,7 +267,7 @@ class CallNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** Gets the flow node corresponding to the n'th positional argument of the call corresponding to this flow node */
|
/** Gets the flow node corresponding to the n'th positional argument of the call corresponding to this flow node */
|
||||||
ControlFlowNode getArg(int n) {
|
ControlFlowNode getArg(int n) {
|
||||||
exists(Call c |
|
exists(Py::Call c |
|
||||||
this.getNode() = c and
|
this.getNode() = c and
|
||||||
c.getArg(n) = result.getNode() and
|
c.getArg(n) = result.getNode() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -276,7 +276,7 @@ class CallNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** Gets the flow node corresponding to the named argument of the call corresponding to this flow node */
|
/** Gets the flow node corresponding to the named argument of the call corresponding to this flow node */
|
||||||
ControlFlowNode getArgByName(string name) {
|
ControlFlowNode getArgByName(string name) {
|
||||||
exists(Call c, Keyword k |
|
exists(Py::Call c, Py::Keyword k |
|
||||||
this.getNode() = c and
|
this.getNode() = c and
|
||||||
k = c.getANamedArg() and
|
k = c.getANamedArg() and
|
||||||
k.getValue() = result.getNode() and
|
k.getValue() = result.getNode() and
|
||||||
@@ -292,7 +292,7 @@ class CallNode extends ControlFlowNode {
|
|||||||
result = this.getArgByName(_)
|
result = this.getArgByName(_)
|
||||||
}
|
}
|
||||||
|
|
||||||
override Call getNode() { result = super.getNode() }
|
override Py::Call getNode() { result = super.getNode() }
|
||||||
|
|
||||||
predicate isDecoratorCall() {
|
predicate isDecoratorCall() {
|
||||||
this.isClassDecoratorCall()
|
this.isClassDecoratorCall()
|
||||||
@@ -301,11 +301,11 @@ class CallNode extends ControlFlowNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
predicate isClassDecoratorCall() {
|
predicate isClassDecoratorCall() {
|
||||||
exists(ClassExpr cls | this.getNode() = cls.getADecoratorCall())
|
exists(Py::ClassExpr cls | this.getNode() = cls.getADecoratorCall())
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate isFunctionDecoratorCall() {
|
predicate isFunctionDecoratorCall() {
|
||||||
exists(FunctionExpr func | this.getNode() = func.getADecoratorCall())
|
exists(Py::FunctionExpr func | this.getNode() = func.getADecoratorCall())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the first tuple (*) argument of this call, if any. */
|
/** Gets the first tuple (*) argument of this call, if any. */
|
||||||
@@ -323,11 +323,11 @@ class CallNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** A control flow corresponding to an attribute expression, such as `value.attr` */
|
/** A control flow corresponding to an attribute expression, such as `value.attr` */
|
||||||
class AttrNode extends ControlFlowNode {
|
class AttrNode extends ControlFlowNode {
|
||||||
AttrNode() { toAst(this) instanceof Attribute }
|
AttrNode() { toAst(this) instanceof Py::Attribute }
|
||||||
|
|
||||||
/** Gets the flow node corresponding to the object of the attribute expression corresponding to this flow node */
|
/** Gets the flow node corresponding to the object of the attribute expression corresponding to this flow node */
|
||||||
ControlFlowNode getObject() {
|
ControlFlowNode getObject() {
|
||||||
exists(Attribute a |
|
exists(Py::Attribute a |
|
||||||
this.getNode() = a and
|
this.getNode() = a and
|
||||||
a.getObject() = result.getNode() and
|
a.getObject() = result.getNode() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -339,7 +339,7 @@ class AttrNode extends ControlFlowNode {
|
|||||||
* with the matching name
|
* with the matching name
|
||||||
*/
|
*/
|
||||||
ControlFlowNode getObject(string name) {
|
ControlFlowNode getObject(string name) {
|
||||||
exists(Attribute a |
|
exists(Py::Attribute a |
|
||||||
this.getNode() = a and
|
this.getNode() = a and
|
||||||
a.getObject() = result.getNode() and
|
a.getObject() = result.getNode() and
|
||||||
a.getName() = name and
|
a.getName() = name and
|
||||||
@@ -348,57 +348,57 @@ class AttrNode extends ControlFlowNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the attribute name of the attribute expression corresponding to this flow node */
|
/** Gets the attribute name of the attribute expression corresponding to this flow node */
|
||||||
string getName() { exists(Attribute a | this.getNode() = a and a.getName() = result) }
|
string getName() { exists(Py::Attribute a | this.getNode() = a and a.getName() = result) }
|
||||||
|
|
||||||
override Attribute getNode() { result = super.getNode() }
|
override Py::Attribute getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a `from ... import ...` expression */
|
/** A control flow node corresponding to a `from ... import ...` expression */
|
||||||
class ImportMemberNode extends ControlFlowNode {
|
class ImportMemberNode extends ControlFlowNode {
|
||||||
ImportMemberNode() { toAst(this) instanceof ImportMember }
|
ImportMemberNode() { toAst(this) instanceof Py::ImportMember }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the flow node corresponding to the module in the import-member expression corresponding to this flow node,
|
* Gets the flow node corresponding to the module in the import-member expression corresponding to this flow node,
|
||||||
* with the matching name
|
* with the matching name
|
||||||
*/
|
*/
|
||||||
ControlFlowNode getModule(string name) {
|
ControlFlowNode getModule(string name) {
|
||||||
exists(ImportMember i | this.getNode() = i and i.getModule() = result.getNode() |
|
exists(Py::ImportMember i | this.getNode() = i and i.getModule() = result.getNode() |
|
||||||
i.getName() = name and
|
i.getName() = name and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override ImportMember getNode() { result = super.getNode() }
|
override Py::ImportMember getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to an artificial expression representing an import */
|
/** A control flow node corresponding to an artificial expression representing an import */
|
||||||
class ImportExprNode extends ControlFlowNode {
|
class ImportExprNode extends ControlFlowNode {
|
||||||
ImportExprNode() { toAst(this) instanceof ImportExpr }
|
ImportExprNode() { toAst(this) instanceof Py::ImportExpr }
|
||||||
|
|
||||||
override ImportExpr getNode() { result = super.getNode() }
|
override Py::ImportExpr getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a `from ... import *` statement */
|
/** A control flow node corresponding to a `from ... import *` statement */
|
||||||
class ImportStarNode extends ControlFlowNode {
|
class ImportStarNode extends ControlFlowNode {
|
||||||
ImportStarNode() { toAst(this) instanceof ImportStar }
|
ImportStarNode() { toAst(this) instanceof Py::ImportStar }
|
||||||
|
|
||||||
/** Gets the flow node corresponding to the module in the import-star corresponding to this flow node */
|
/** Gets the flow node corresponding to the module in the import-star corresponding to this flow node */
|
||||||
ControlFlowNode getModule() {
|
ControlFlowNode getModule() {
|
||||||
exists(ImportStar i | this.getNode() = i and i.getModuleExpr() = result.getNode() |
|
exists(Py::ImportStar i | this.getNode() = i and i.getModuleExpr() = result.getNode() |
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override ImportStar getNode() { result = super.getNode() }
|
override Py::ImportStar getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a subscript expression, such as `value[slice]` */
|
/** A control flow node corresponding to a subscript expression, such as `value[slice]` */
|
||||||
class SubscriptNode extends ControlFlowNode {
|
class SubscriptNode extends ControlFlowNode {
|
||||||
SubscriptNode() { toAst(this) instanceof Subscript }
|
SubscriptNode() { toAst(this) instanceof Py::Subscript }
|
||||||
|
|
||||||
/** flow node corresponding to the value of the sequence in a subscript operation */
|
/** flow node corresponding to the value of the sequence in a subscript operation */
|
||||||
ControlFlowNode getObject() {
|
ControlFlowNode getObject() {
|
||||||
exists(Subscript s |
|
exists(Py::Subscript s |
|
||||||
this.getNode() = s and
|
this.getNode() = s and
|
||||||
s.getObject() = result.getNode() and
|
s.getObject() = result.getNode() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -407,23 +407,23 @@ class SubscriptNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** flow node corresponding to the index in a subscript operation */
|
/** flow node corresponding to the index in a subscript operation */
|
||||||
ControlFlowNode getIndex() {
|
ControlFlowNode getIndex() {
|
||||||
exists(Subscript s |
|
exists(Py::Subscript s |
|
||||||
this.getNode() = s and
|
this.getNode() = s and
|
||||||
s.getIndex() = result.getNode() and
|
s.getIndex() = result.getNode() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override Subscript getNode() { result = super.getNode() }
|
override Py::Subscript getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a comparison operation, such as `x<y` */
|
/** A control flow node corresponding to a comparison operation, such as `x<y` */
|
||||||
class CompareNode extends ControlFlowNode {
|
class CompareNode extends ControlFlowNode {
|
||||||
CompareNode() { toAst(this) instanceof Compare }
|
CompareNode() { toAst(this) instanceof Py::Compare }
|
||||||
|
|
||||||
/** Whether left and right are a pair of operands for this comparison */
|
/** Whether left and right are a pair of operands for this comparison */
|
||||||
predicate operands(ControlFlowNode left, Cmpop op, ControlFlowNode right) {
|
predicate operands(ControlFlowNode left, Py::Cmpop op, ControlFlowNode right) {
|
||||||
exists(Compare c, Expr eleft, Expr eright |
|
exists(Py::Compare c, Py::Expr eleft, Py::Expr eright |
|
||||||
this.getNode() = c and left.getNode() = eleft and right.getNode() = eright
|
this.getNode() = c and left.getNode() = eleft and right.getNode() = eright
|
||||||
|
|
|
|
||||||
eleft = c.getLeft() and eright = c.getComparator(0) and op = c.getOp(0)
|
eleft = c.getLeft() and eright = c.getComparator(0) and op = c.getOp(0)
|
||||||
@@ -436,26 +436,26 @@ class CompareNode extends ControlFlowNode {
|
|||||||
right.getBasicBlock().dominates(this.getBasicBlock())
|
right.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
}
|
}
|
||||||
|
|
||||||
override Compare getNode() { result = super.getNode() }
|
override Py::Compare getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a conditional expression such as, `body if test else orelse` */
|
/** A control flow node corresponding to a conditional expression such as, `body if test else orelse` */
|
||||||
class IfExprNode extends ControlFlowNode {
|
class IfExprNode extends ControlFlowNode {
|
||||||
IfExprNode() { toAst(this) instanceof IfExp }
|
IfExprNode() { toAst(this) instanceof Py::IfExp }
|
||||||
|
|
||||||
/** flow node corresponding to one of the operands of an if-expression */
|
/** flow node corresponding to one of the operands of an if-expression */
|
||||||
ControlFlowNode getAnOperand() { result = this.getAPredecessor() }
|
ControlFlowNode getAnOperand() { result = this.getAPredecessor() }
|
||||||
|
|
||||||
override IfExp getNode() { result = super.getNode() }
|
override Py::IfExp getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to an assignment expression such as `lhs := rhs`. */
|
/** A control flow node corresponding to an assignment expression such as `lhs := rhs`. */
|
||||||
class AssignmentExprNode extends ControlFlowNode {
|
class AssignmentExprNode extends ControlFlowNode {
|
||||||
AssignmentExprNode() { toAst(this) instanceof AssignExpr }
|
AssignmentExprNode() { toAst(this) instanceof Py::AssignExpr }
|
||||||
|
|
||||||
/** Gets the flow node corresponding to the left-hand side of the assignment expression */
|
/** Gets the flow node corresponding to the left-hand side of the assignment expression */
|
||||||
ControlFlowNode getTarget() {
|
ControlFlowNode getTarget() {
|
||||||
exists(AssignExpr a |
|
exists(Py::AssignExpr a |
|
||||||
this.getNode() = a and
|
this.getNode() = a and
|
||||||
a.getTarget() = result.getNode() and
|
a.getTarget() = result.getNode() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -464,27 +464,27 @@ class AssignmentExprNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** Gets the flow node corresponding to the right-hand side of the assignment expression */
|
/** Gets the flow node corresponding to the right-hand side of the assignment expression */
|
||||||
ControlFlowNode getValue() {
|
ControlFlowNode getValue() {
|
||||||
exists(AssignExpr a |
|
exists(Py::AssignExpr a |
|
||||||
this.getNode() = a and
|
this.getNode() = a and
|
||||||
a.getValue() = result.getNode() and
|
a.getValue() = result.getNode() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override AssignExpr getNode() { result = super.getNode() }
|
override Py::AssignExpr getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a binary expression, such as `x + y` */
|
/** A control flow node corresponding to a binary expression, such as `x + y` */
|
||||||
class BinaryExprNode extends ControlFlowNode {
|
class BinaryExprNode extends ControlFlowNode {
|
||||||
BinaryExprNode() { toAst(this) instanceof BinaryExpr }
|
BinaryExprNode() { toAst(this) instanceof Py::BinaryExpr }
|
||||||
|
|
||||||
/** flow node corresponding to one of the operands of a binary expression */
|
/** flow node corresponding to one of the operands of a binary expression */
|
||||||
ControlFlowNode getAnOperand() { result = this.getLeft() or result = this.getRight() }
|
ControlFlowNode getAnOperand() { result = this.getLeft() or result = this.getRight() }
|
||||||
|
|
||||||
override BinaryExpr getNode() { result = super.getNode() }
|
override Py::BinaryExpr getNode() { result = super.getNode() }
|
||||||
|
|
||||||
ControlFlowNode getLeft() {
|
ControlFlowNode getLeft() {
|
||||||
exists(BinaryExpr b |
|
exists(Py::BinaryExpr b |
|
||||||
this.getNode() = b and
|
this.getNode() = b and
|
||||||
result.getNode() = b.getLeft() and
|
result.getNode() = b.getLeft() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -492,7 +492,7 @@ class BinaryExprNode extends ControlFlowNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ControlFlowNode getRight() {
|
ControlFlowNode getRight() {
|
||||||
exists(BinaryExpr b |
|
exists(Py::BinaryExpr b |
|
||||||
this.getNode() = b and
|
this.getNode() = b and
|
||||||
result.getNode() = b.getRight() and
|
result.getNode() = b.getRight() and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -500,11 +500,11 @@ class BinaryExprNode extends ControlFlowNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the operator of this binary expression node. */
|
/** Gets the operator of this binary expression node. */
|
||||||
Operator getOp() { result = this.getNode().getOp() }
|
Py::Operator getOp() { result = this.getNode().getOp() }
|
||||||
|
|
||||||
/** Whether left and right are a pair of operands for this binary expression */
|
/** Whether left and right are a pair of operands for this binary expression */
|
||||||
predicate operands(ControlFlowNode left, Operator op, ControlFlowNode right) {
|
predicate operands(ControlFlowNode left, Py::Operator op, ControlFlowNode right) {
|
||||||
exists(BinaryExpr b, Expr eleft, Expr eright |
|
exists(Py::BinaryExpr b, Py::Expr eleft, Py::Expr eright |
|
||||||
this.getNode() = b and left.getNode() = eleft and right.getNode() = eright
|
this.getNode() = b and left.getNode() = eleft and right.getNode() = eright
|
||||||
|
|
|
|
||||||
eleft = b.getLeft() and eright = b.getRight() and op = b.getOp()
|
eleft = b.getLeft() and eright = b.getRight() and op = b.getOp()
|
||||||
@@ -516,20 +516,20 @@ class BinaryExprNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** A control flow node corresponding to a boolean shortcut (and/or) operation */
|
/** A control flow node corresponding to a boolean shortcut (and/or) operation */
|
||||||
class BoolExprNode extends ControlFlowNode {
|
class BoolExprNode extends ControlFlowNode {
|
||||||
BoolExprNode() { toAst(this) instanceof BoolExpr }
|
BoolExprNode() { toAst(this) instanceof Py::BoolExpr }
|
||||||
|
|
||||||
/** flow node corresponding to one of the operands of a boolean expression */
|
/** flow node corresponding to one of the operands of a boolean expression */
|
||||||
ControlFlowNode getAnOperand() {
|
ControlFlowNode getAnOperand() {
|
||||||
exists(BoolExpr b | this.getNode() = b and result.getNode() = b.getAValue()) and
|
exists(Py::BoolExpr b | this.getNode() = b and result.getNode() = b.getAValue()) and
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock())
|
this.getBasicBlock().dominates(result.getBasicBlock())
|
||||||
}
|
}
|
||||||
|
|
||||||
override BoolExpr getNode() { result = super.getNode() }
|
override Py::BoolExpr getNode() { result = super.getNode() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a unary expression: (`+x`), (`-x`) or (`~x`) */
|
/** A control flow node corresponding to a unary expression: (`+x`), (`-x`) or (`~x`) */
|
||||||
class UnaryExprNode extends ControlFlowNode {
|
class UnaryExprNode extends ControlFlowNode {
|
||||||
UnaryExprNode() { toAst(this) instanceof UnaryExpr }
|
UnaryExprNode() { toAst(this) instanceof Py::UnaryExpr }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets flow node corresponding to the operand of a unary expression.
|
* Gets flow node corresponding to the operand of a unary expression.
|
||||||
@@ -540,7 +540,7 @@ class UnaryExprNode extends ControlFlowNode {
|
|||||||
*/
|
*/
|
||||||
ControlFlowNode getOperand() { result = this.getAPredecessor() }
|
ControlFlowNode getOperand() { result = this.getAPredecessor() }
|
||||||
|
|
||||||
override UnaryExpr getNode() { result = super.getNode() }
|
override Py::UnaryExpr getNode() { result = super.getNode() }
|
||||||
|
|
||||||
override ControlFlowNode getAChild() { result = this.getAPredecessor() }
|
override ControlFlowNode getAChild() { result = this.getAPredecessor() }
|
||||||
}
|
}
|
||||||
@@ -555,22 +555,22 @@ class DefinitionNode extends ControlFlowNode {
|
|||||||
cached
|
cached
|
||||||
DefinitionNode() {
|
DefinitionNode() {
|
||||||
Stages::AST::ref() and
|
Stages::AST::ref() and
|
||||||
exists(Assign a | this.getNode() = a.getATarget())
|
exists(Py::Assign a | this.getNode() = a.getATarget())
|
||||||
or
|
or
|
||||||
exists(AssignExpr a | this.getNode() = a.getTarget())
|
exists(Py::AssignExpr a | this.getNode() = a.getTarget())
|
||||||
or
|
or
|
||||||
exists(AnnAssign a | this.getNode() = a.getTarget() and exists(a.getValue()))
|
exists(Py::AnnAssign a | this.getNode() = a.getTarget() and exists(a.getValue()))
|
||||||
or
|
or
|
||||||
exists(Alias a | this.getNode() = a.getAsname())
|
exists(Py::Alias a | this.getNode() = a.getAsname())
|
||||||
or
|
or
|
||||||
augstore(_, this)
|
augstore(_, this)
|
||||||
or
|
or
|
||||||
// `x, y = 1, 2` where LHS is a combination of list or tuples
|
// `x, y = 1, 2` where LHS is a combination of list or tuples
|
||||||
exists(Assign a | this.getNode() = list_or_tuple_nested_element(a.getATarget()))
|
exists(Py::Assign a | this.getNode() = list_or_tuple_nested_element(a.getATarget()))
|
||||||
or
|
or
|
||||||
exists(For for | this.getNode() = for.getTarget())
|
exists(Py::For for | this.getNode() = for.getTarget())
|
||||||
or
|
or
|
||||||
exists(Parameter param | this.getNode() = param.asName() and exists(param.getDefault()))
|
exists(Py::Parameter param | this.getNode() = param.asName() and exists(param.getDefault()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** flow node corresponding to the value assigned for the definition corresponding to this flow node */
|
/** flow node corresponding to the value assigned for the definition corresponding to this flow node */
|
||||||
@@ -584,16 +584,16 @@ class DefinitionNode extends ControlFlowNode {
|
|||||||
// since the default value for a parameter is evaluated in the same basic block as
|
// since the default value for a parameter is evaluated in the same basic block as
|
||||||
// the function definition, but the parameter belongs to the basic block of the function,
|
// the function definition, but the parameter belongs to the basic block of the function,
|
||||||
// there is no dominance relationship between the two.
|
// there is no dominance relationship between the two.
|
||||||
exists(Parameter param | this.getNode() = param.asName())
|
exists(Py::Parameter param | this.getNode() = param.asName())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expr list_or_tuple_nested_element(Expr list_or_tuple) {
|
private Py::Expr list_or_tuple_nested_element(Py::Expr list_or_tuple) {
|
||||||
exists(Expr elt |
|
exists(Py::Expr elt |
|
||||||
elt = list_or_tuple.(Tuple).getAnElt()
|
elt = list_or_tuple.(Py::Tuple).getAnElt()
|
||||||
or
|
or
|
||||||
elt = list_or_tuple.(List).getAnElt()
|
elt = list_or_tuple.(Py::List).getAnElt()
|
||||||
|
|
|
|
||||||
result = elt
|
result = elt
|
||||||
or
|
or
|
||||||
@@ -603,12 +603,12 @@ private Expr list_or_tuple_nested_element(Expr list_or_tuple) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A control flow node corresponding to a deletion statement, such as `del x`.
|
* A control flow node corresponding to a deletion statement, such as `del x`.
|
||||||
* There can be multiple `DeletionNode`s for each `Delete` such that each
|
* There can be multiple `DeletionNode`s for each `Py::Delete` such that each
|
||||||
* target has own `DeletionNode`. The CFG for `del a, x.y` looks like:
|
* target has own `DeletionNode`. The CFG for `del a, x.y` looks like:
|
||||||
* `NameNode('a') -> DeletionNode -> NameNode('b') -> AttrNode('y') -> DeletionNode`.
|
* `NameNode('a') -> DeletionNode -> NameNode('b') -> AttrNode('y') -> DeletionNode`.
|
||||||
*/
|
*/
|
||||||
class DeletionNode extends ControlFlowNode {
|
class DeletionNode extends ControlFlowNode {
|
||||||
DeletionNode() { toAst(this) instanceof Delete }
|
DeletionNode() { toAst(this) instanceof Py::Delete }
|
||||||
|
|
||||||
/** Gets the unique target of this deletion node. */
|
/** Gets the unique target of this deletion node. */
|
||||||
ControlFlowNode getTarget() { result.getASuccessor() = this }
|
ControlFlowNode getTarget() { result.getASuccessor() = this }
|
||||||
@@ -617,9 +617,9 @@ class DeletionNode extends ControlFlowNode {
|
|||||||
/** A control flow node corresponding to a sequence (tuple or list) literal */
|
/** A control flow node corresponding to a sequence (tuple or list) literal */
|
||||||
abstract class SequenceNode extends ControlFlowNode {
|
abstract class SequenceNode extends ControlFlowNode {
|
||||||
SequenceNode() {
|
SequenceNode() {
|
||||||
toAst(this) instanceof Tuple
|
toAst(this) instanceof Py::Tuple
|
||||||
or
|
or
|
||||||
toAst(this) instanceof List
|
toAst(this) instanceof Py::List
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the control flow node for an element of this sequence */
|
/** Gets the control flow node for an element of this sequence */
|
||||||
@@ -632,11 +632,11 @@ abstract class SequenceNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** A control flow node corresponding to a tuple expression such as `( 1, 3, 5, 7, 9 )` */
|
/** A control flow node corresponding to a tuple expression such as `( 1, 3, 5, 7, 9 )` */
|
||||||
class TupleNode extends SequenceNode {
|
class TupleNode extends SequenceNode {
|
||||||
TupleNode() { toAst(this) instanceof Tuple }
|
TupleNode() { toAst(this) instanceof Py::Tuple }
|
||||||
|
|
||||||
override ControlFlowNode getElement(int n) {
|
override ControlFlowNode getElement(int n) {
|
||||||
Stages::AST::ref() and
|
Stages::AST::ref() and
|
||||||
exists(Tuple t | this.getNode() = t and result.getNode() = t.getElt(n)) and
|
exists(Py::Tuple t | this.getNode() = t and result.getNode() = t.getElt(n)) and
|
||||||
(
|
(
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
or
|
or
|
||||||
@@ -647,10 +647,10 @@ class TupleNode extends SequenceNode {
|
|||||||
|
|
||||||
/** A control flow node corresponding to a list expression, such as `[ 1, 3, 5, 7, 9 ]` */
|
/** A control flow node corresponding to a list expression, such as `[ 1, 3, 5, 7, 9 ]` */
|
||||||
class ListNode extends SequenceNode {
|
class ListNode extends SequenceNode {
|
||||||
ListNode() { toAst(this) instanceof List }
|
ListNode() { toAst(this) instanceof Py::List }
|
||||||
|
|
||||||
override ControlFlowNode getElement(int n) {
|
override ControlFlowNode getElement(int n) {
|
||||||
exists(List l | this.getNode() = l and result.getNode() = l.getElt(n)) and
|
exists(Py::List l | this.getNode() = l and result.getNode() = l.getElt(n)) and
|
||||||
(
|
(
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
or
|
or
|
||||||
@@ -661,10 +661,10 @@ class ListNode extends SequenceNode {
|
|||||||
|
|
||||||
/** A control flow node corresponding to a set expression, such as `{ 1, 3, 5, 7, 9 }` */
|
/** A control flow node corresponding to a set expression, such as `{ 1, 3, 5, 7, 9 }` */
|
||||||
class SetNode extends ControlFlowNode {
|
class SetNode extends ControlFlowNode {
|
||||||
SetNode() { toAst(this) instanceof Set }
|
SetNode() { toAst(this) instanceof Py::Set }
|
||||||
|
|
||||||
ControlFlowNode getAnElement() {
|
ControlFlowNode getAnElement() {
|
||||||
exists(Set s | this.getNode() = s and result.getNode() = s.getElt(_)) and
|
exists(Py::Set s | this.getNode() = s and result.getNode() = s.getElt(_)) and
|
||||||
(
|
(
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
or
|
or
|
||||||
@@ -675,20 +675,20 @@ class SetNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** A control flow node corresponding to a dictionary literal, such as `{ 'a': 1, 'b': 2 }` */
|
/** A control flow node corresponding to a dictionary literal, such as `{ 'a': 1, 'b': 2 }` */
|
||||||
class DictNode extends ControlFlowNode {
|
class DictNode extends ControlFlowNode {
|
||||||
DictNode() { toAst(this) instanceof Dict }
|
DictNode() { toAst(this) instanceof Py::Dict }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a key of this dictionary literal node, for those items that have keys
|
* Gets a key of this dictionary literal node, for those items that have keys
|
||||||
* E.g, in {'a':1, **b} this returns only 'a'
|
* E.g, in {'a':1, **b} this returns only 'a'
|
||||||
*/
|
*/
|
||||||
ControlFlowNode getAKey() {
|
ControlFlowNode getAKey() {
|
||||||
exists(Dict d | this.getNode() = d and result.getNode() = d.getAKey()) and
|
exists(Py::Dict d | this.getNode() = d and result.getNode() = d.getAKey()) and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets a value of this dictionary literal node */
|
/** Gets a value of this dictionary literal node */
|
||||||
ControlFlowNode getAValue() {
|
ControlFlowNode getAValue() {
|
||||||
exists(Dict d | this.getNode() = d and result.getNode() = d.getAValue()) and
|
exists(Py::Dict d | this.getNode() = d and result.getNode() = d.getAValue()) and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -712,21 +712,23 @@ class IterableNode extends ControlFlowNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private AstNode assigned_value(Expr lhs) {
|
private Py::AstNode assigned_value(Py::Expr lhs) {
|
||||||
/* lhs = result */
|
/* lhs = result */
|
||||||
exists(Assign a | a.getATarget() = lhs and result = a.getValue())
|
exists(Py::Assign a | a.getATarget() = lhs and result = a.getValue())
|
||||||
or
|
or
|
||||||
/* lhs := result */
|
/* lhs := result */
|
||||||
exists(AssignExpr a | a.getTarget() = lhs and result = a.getValue())
|
exists(Py::AssignExpr a | a.getTarget() = lhs and result = a.getValue())
|
||||||
or
|
or
|
||||||
/* lhs : annotation = result */
|
/* lhs : annotation = result */
|
||||||
exists(AnnAssign a | a.getTarget() = lhs and result = a.getValue())
|
exists(Py::AnnAssign a | a.getTarget() = lhs and result = a.getValue())
|
||||||
or
|
or
|
||||||
/* import result as lhs */
|
/* import result as lhs */
|
||||||
exists(Alias a | a.getAsname() = lhs and result = a.getValue())
|
exists(Py::Alias a | a.getAsname() = lhs and result = a.getValue())
|
||||||
or
|
or
|
||||||
/* lhs += x => result = (lhs + x) */
|
/* lhs += x => result = (lhs + x) */
|
||||||
exists(AugAssign a, BinaryExpr b | b = a.getOperation() and result = b and lhs = b.getLeft())
|
exists(Py::AugAssign a, Py::BinaryExpr b |
|
||||||
|
b = a.getOperation() and result = b and lhs = b.getLeft()
|
||||||
|
)
|
||||||
or
|
or
|
||||||
/*
|
/*
|
||||||
* ..., lhs, ... = ..., result, ...
|
* ..., lhs, ... = ..., result, ...
|
||||||
@@ -734,31 +736,31 @@ private AstNode assigned_value(Expr lhs) {
|
|||||||
* ..., (..., lhs, ...), ... = ..., (..., result, ...), ...
|
* ..., (..., lhs, ...), ... = ..., (..., result, ...), ...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
exists(Assign a | nested_sequence_assign(a.getATarget(), a.getValue(), lhs, result))
|
exists(Py::Assign a | nested_sequence_assign(a.getATarget(), a.getValue(), lhs, result))
|
||||||
or
|
or
|
||||||
/* for lhs in seq: => `result` is the `for` node, representing the `iter(next(seq))` operation. */
|
/* for lhs in seq: => `result` is the `for` node, representing the `iter(next(seq))` operation. */
|
||||||
result.(For).getTarget() = lhs
|
result.(Py::For).getTarget() = lhs
|
||||||
or
|
or
|
||||||
exists(Parameter param | lhs = param.asName() and result = param.getDefault())
|
exists(Py::Parameter param | lhs = param.asName() and result = param.getDefault())
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate nested_sequence_assign(
|
predicate nested_sequence_assign(
|
||||||
Expr left_parent, Expr right_parent, Expr left_result, Expr right_result
|
Py::Expr left_parent, Py::Expr right_parent, Py::Expr left_result, Py::Expr right_result
|
||||||
) {
|
) {
|
||||||
exists(Assign a |
|
exists(Py::Assign a |
|
||||||
a.getATarget().getASubExpression*() = left_parent and
|
a.getATarget().getASubExpression*() = left_parent and
|
||||||
a.getValue().getASubExpression*() = right_parent
|
a.getValue().getASubExpression*() = right_parent
|
||||||
) and
|
) and
|
||||||
exists(int i, Expr left_elem, Expr right_elem |
|
exists(int i, Py::Expr left_elem, Py::Expr right_elem |
|
||||||
(
|
(
|
||||||
left_elem = left_parent.(Tuple).getElt(i)
|
left_elem = left_parent.(Py::Tuple).getElt(i)
|
||||||
or
|
or
|
||||||
left_elem = left_parent.(List).getElt(i)
|
left_elem = left_parent.(Py::List).getElt(i)
|
||||||
) and
|
) and
|
||||||
(
|
(
|
||||||
right_elem = right_parent.(Tuple).getElt(i)
|
right_elem = right_parent.(Py::Tuple).getElt(i)
|
||||||
or
|
or
|
||||||
right_elem = right_parent.(List).getElt(i)
|
right_elem = right_parent.(Py::List).getElt(i)
|
||||||
)
|
)
|
||||||
|
|
|
|
||||||
left_result = left_elem and right_result = right_elem
|
left_result = left_elem and right_result = right_elem
|
||||||
@@ -769,9 +771,9 @@ predicate nested_sequence_assign(
|
|||||||
|
|
||||||
/** A flow node for a `for` statement. */
|
/** A flow node for a `for` statement. */
|
||||||
class ForNode extends ControlFlowNode {
|
class ForNode extends ControlFlowNode {
|
||||||
ForNode() { toAst(this) instanceof For }
|
ForNode() { toAst(this) instanceof Py::For }
|
||||||
|
|
||||||
override For getNode() { result = super.getNode() }
|
override Py::For getNode() { result = super.getNode() }
|
||||||
|
|
||||||
/** Holds if this `for` statement causes iteration over `sequence` storing each step of the iteration in `target` */
|
/** Holds if this `for` statement causes iteration over `sequence` storing each step of the iteration in `target` */
|
||||||
predicate iterates(ControlFlowNode target, ControlFlowNode sequence) {
|
predicate iterates(ControlFlowNode target, ControlFlowNode sequence) {
|
||||||
@@ -782,7 +784,7 @@ class ForNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** Gets the sequence node for this `for` statement. */
|
/** Gets the sequence node for this `for` statement. */
|
||||||
ControlFlowNode getSequence() {
|
ControlFlowNode getSequence() {
|
||||||
exists(For for |
|
exists(Py::For for |
|
||||||
toAst(this) = for and
|
toAst(this) = for and
|
||||||
for.getIter() = result.getNode()
|
for.getIter() = result.getNode()
|
||||||
|
|
|
|
||||||
@@ -792,7 +794,7 @@ class ForNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** A possible `target` for this `for` statement, not accounting for loop unrolling */
|
/** A possible `target` for this `for` statement, not accounting for loop unrolling */
|
||||||
private ControlFlowNode possibleTarget() {
|
private ControlFlowNode possibleTarget() {
|
||||||
exists(For for |
|
exists(Py::For for |
|
||||||
toAst(this) = for and
|
toAst(this) = for and
|
||||||
for.getTarget() = result.getNode() and
|
for.getTarget() = result.getNode() and
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock())
|
this.getBasicBlock().dominates(result.getBasicBlock())
|
||||||
@@ -809,11 +811,11 @@ class ForNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** A flow node for a `raise` statement */
|
/** A flow node for a `raise` statement */
|
||||||
class RaiseStmtNode extends ControlFlowNode {
|
class RaiseStmtNode extends ControlFlowNode {
|
||||||
RaiseStmtNode() { toAst(this) instanceof Raise }
|
RaiseStmtNode() { toAst(this) instanceof Py::Raise }
|
||||||
|
|
||||||
/** Gets the control flow node for the exception raised by this raise statement */
|
/** Gets the control flow node for the exception raised by this raise statement */
|
||||||
ControlFlowNode getException() {
|
ControlFlowNode getException() {
|
||||||
exists(Raise r |
|
exists(Py::Raise r |
|
||||||
r = toAst(this) and
|
r = toAst(this) and
|
||||||
r.getException() = toAst(result) and
|
r.getException() = toAst(result) and
|
||||||
result.getBasicBlock().dominates(this.getBasicBlock())
|
result.getBasicBlock().dominates(this.getBasicBlock())
|
||||||
@@ -827,36 +829,36 @@ class RaiseStmtNode extends ControlFlowNode {
|
|||||||
*/
|
*/
|
||||||
class NameNode extends ControlFlowNode {
|
class NameNode extends ControlFlowNode {
|
||||||
NameNode() {
|
NameNode() {
|
||||||
exists(Name n | py_flow_bb_node(this, n, _, _))
|
exists(Py::Name n | py_flow_bb_node(this, n, _, _))
|
||||||
or
|
or
|
||||||
exists(PlaceHolder p | py_flow_bb_node(this, p, _, _))
|
exists(Py::PlaceHolder p | py_flow_bb_node(this, p, _, _))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this flow node defines the variable `v`. */
|
/** Whether this flow node defines the variable `v`. */
|
||||||
predicate defines(Variable v) {
|
predicate defines(Py::Variable v) {
|
||||||
exists(Name d | this.getNode() = d and d.defines(v)) and
|
exists(Py::Name d | this.getNode() = d and d.defines(v)) and
|
||||||
not this.isLoad()
|
not this.isLoad()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this flow node deletes the variable `v`. */
|
/** Whether this flow node deletes the variable `v`. */
|
||||||
predicate deletes(Variable v) { exists(Name d | this.getNode() = d and d.deletes(v)) }
|
predicate deletes(Py::Variable v) { exists(Py::Name d | this.getNode() = d and d.deletes(v)) }
|
||||||
|
|
||||||
/** Whether this flow node uses the variable `v`. */
|
/** Whether this flow node uses the variable `v`. */
|
||||||
predicate uses(Variable v) {
|
predicate uses(Py::Variable v) {
|
||||||
this.isLoad() and
|
this.isLoad() and
|
||||||
exists(Name u | this.getNode() = u and u.uses(v))
|
exists(Py::Name u | this.getNode() = u and u.uses(v))
|
||||||
or
|
or
|
||||||
exists(PlaceHolder u |
|
exists(Py::PlaceHolder u |
|
||||||
this.getNode() = u and u.getVariable() = v and u.getCtx() instanceof Load
|
this.getNode() = u and u.getVariable() = v and u.getCtx() instanceof Py::Load
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
Scopes::use_of_global_variable(this, v.getScope(), v.getId())
|
Scopes::use_of_global_variable(this, v.getScope(), v.getId())
|
||||||
}
|
}
|
||||||
|
|
||||||
string getId() {
|
string getId() {
|
||||||
result = this.getNode().(Name).getId()
|
result = this.getNode().(Py::Name).getId()
|
||||||
or
|
or
|
||||||
result = this.getNode().(PlaceHolder).getId()
|
result = this.getNode().(Py::PlaceHolder).getId()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this is a use of a local variable. */
|
/** Whether this is a use of a local variable. */
|
||||||
@@ -868,37 +870,39 @@ class NameNode extends ControlFlowNode {
|
|||||||
/** Whether this is a use of a global (including builtin) variable. */
|
/** Whether this is a use of a global (including builtin) variable. */
|
||||||
predicate isGlobal() { Scopes::use_of_global_variable(this, _, _) }
|
predicate isGlobal() { Scopes::use_of_global_variable(this, _, _) }
|
||||||
|
|
||||||
predicate isSelf() { exists(SsaVariable selfvar | selfvar.isSelf() and selfvar.getAUse() = this) }
|
predicate isSelf() {
|
||||||
|
exists(Py::SsaVariable selfvar | selfvar.isSelf() and selfvar.getAUse() = this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a named constant, one of `None`, `True` or `False`. */
|
/** A control flow node corresponding to a named constant, one of `None`, `True` or `False`. */
|
||||||
class NameConstantNode extends NameNode {
|
class NameConstantNode extends NameNode {
|
||||||
NameConstantNode() { exists(NameConstant n | py_flow_bb_node(this, n, _, _)) }
|
NameConstantNode() { exists(Py::NameConstant n | py_flow_bb_node(this, n, _, _)) }
|
||||||
/*
|
/*
|
||||||
* We ought to override uses as well, but that has
|
* We ought to override uses as well, but that has
|
||||||
* a serious performance impact.
|
* a serious performance impact.
|
||||||
* deprecated predicate uses(Variable v) { none() }
|
* deprecated predicate uses(Py::Variable v) { none() }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A control flow node corresponding to a starred expression, `*a`. */
|
/** A control flow node corresponding to a starred expression, `*a`. */
|
||||||
class StarredNode extends ControlFlowNode {
|
class StarredNode extends ControlFlowNode {
|
||||||
StarredNode() { toAst(this) instanceof Starred }
|
StarredNode() { toAst(this) instanceof Py::Starred }
|
||||||
|
|
||||||
ControlFlowNode getValue() { toAst(result) = toAst(this).(Starred).getValue() }
|
ControlFlowNode getValue() { toAst(result) = toAst(this).(Py::Starred).getValue() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The ControlFlowNode for an 'except' statement. */
|
/** The ControlFlowNode for an 'except' statement. */
|
||||||
class ExceptFlowNode extends ControlFlowNode {
|
class ExceptFlowNode extends ControlFlowNode {
|
||||||
ExceptFlowNode() { this.getNode() instanceof ExceptStmt }
|
ExceptFlowNode() { this.getNode() instanceof Py::ExceptStmt }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the type handled by this exception handler.
|
* Gets the type handled by this exception handler.
|
||||||
* `ExceptionType` in `except ExceptionType as e:`
|
* `Py::ExceptionType` in `except Py::ExceptionType as e:`
|
||||||
*/
|
*/
|
||||||
ControlFlowNode getType() {
|
ControlFlowNode getType() {
|
||||||
exists(ExceptStmt ex |
|
exists(Py::ExceptStmt ex |
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
||||||
ex = this.getNode() and
|
ex = this.getNode() and
|
||||||
result.getNode() = ex.getType()
|
result.getNode() = ex.getType()
|
||||||
@@ -907,10 +911,10 @@ class ExceptFlowNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the name assigned to the handled exception, if any.
|
* Gets the name assigned to the handled exception, if any.
|
||||||
* `e` in `except ExceptionType as e:`
|
* `e` in `except Py::ExceptionType as e:`
|
||||||
*/
|
*/
|
||||||
ControlFlowNode getName() {
|
ControlFlowNode getName() {
|
||||||
exists(ExceptStmt ex |
|
exists(Py::ExceptStmt ex |
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
||||||
ex = this.getNode() and
|
ex = this.getNode() and
|
||||||
result.getNode() = ex.getName()
|
result.getNode() = ex.getName()
|
||||||
@@ -920,30 +924,30 @@ class ExceptFlowNode extends ControlFlowNode {
|
|||||||
|
|
||||||
/** The ControlFlowNode for an 'except*' statement. */
|
/** The ControlFlowNode for an 'except*' statement. */
|
||||||
class ExceptGroupFlowNode extends ControlFlowNode {
|
class ExceptGroupFlowNode extends ControlFlowNode {
|
||||||
ExceptGroupFlowNode() { this.getNode() instanceof ExceptGroupStmt }
|
ExceptGroupFlowNode() { this.getNode() instanceof Py::ExceptGroupStmt }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the type handled by this exception handler.
|
* Gets the type handled by this exception handler.
|
||||||
* `ExceptionType` in `except* ExceptionType as e:`
|
* `Py::ExceptionType` in `except* Py::ExceptionType as e:`
|
||||||
*/
|
*/
|
||||||
ControlFlowNode getType() {
|
ControlFlowNode getType() {
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
||||||
result.getNode() = this.getNode().(ExceptGroupStmt).getType()
|
result.getNode() = this.getNode().(Py::ExceptGroupStmt).getType()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the name assigned to the handled exception, if any.
|
* Gets the name assigned to the handled exception, if any.
|
||||||
* `e` in `except* ExceptionType as e:`
|
* `e` in `except* Py::ExceptionType as e:`
|
||||||
*/
|
*/
|
||||||
ControlFlowNode getName() {
|
ControlFlowNode getName() {
|
||||||
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
this.getBasicBlock().dominates(result.getBasicBlock()) and
|
||||||
result.getNode() = this.getNode().(ExceptGroupStmt).getName()
|
result.getNode() = this.getNode().(Py::ExceptGroupStmt).getName()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private module Scopes {
|
private module Scopes {
|
||||||
private predicate fast_local(NameNode n) {
|
private predicate fast_local(NameNode n) {
|
||||||
exists(FastLocalVariable v |
|
exists(Py::FastLocalVariable v |
|
||||||
n.uses(v) and
|
n.uses(v) and
|
||||||
v.getScope() = n.getScope()
|
v.getScope() = n.getScope()
|
||||||
)
|
)
|
||||||
@@ -952,15 +956,15 @@ private module Scopes {
|
|||||||
predicate local(NameNode n) {
|
predicate local(NameNode n) {
|
||||||
fast_local(n)
|
fast_local(n)
|
||||||
or
|
or
|
||||||
exists(SsaVariable var |
|
exists(Py::SsaVariable var |
|
||||||
var.getAUse() = n and
|
var.getAUse() = n and
|
||||||
n.getScope() instanceof Class and
|
n.getScope() instanceof Py::Class and
|
||||||
exists(var.getDefinition())
|
exists(var.getDefinition())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate non_local(NameNode n) {
|
predicate non_local(NameNode n) {
|
||||||
exists(FastLocalVariable flv |
|
exists(Py::FastLocalVariable flv |
|
||||||
flv.getALoad() = n.getNode() and
|
flv.getALoad() = n.getNode() and
|
||||||
not flv.getScope() = n.getScope()
|
not flv.getScope() = n.getScope()
|
||||||
)
|
)
|
||||||
@@ -968,20 +972,20 @@ private module Scopes {
|
|||||||
|
|
||||||
// magic is fine, but we get questionable join-ordering of it
|
// magic is fine, but we get questionable join-ordering of it
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
predicate use_of_global_variable(NameNode n, Module scope, string name) {
|
predicate use_of_global_variable(NameNode n, Py::Module scope, string name) {
|
||||||
n.isLoad() and
|
n.isLoad() and
|
||||||
not non_local(n) and
|
not non_local(n) and
|
||||||
not exists(SsaVariable var | var.getAUse() = n |
|
not exists(Py::SsaVariable var | var.getAUse() = n |
|
||||||
var.getVariable() instanceof FastLocalVariable
|
var.getVariable() instanceof Py::FastLocalVariable
|
||||||
or
|
or
|
||||||
n.getScope() instanceof Class and
|
n.getScope() instanceof Py::Class and
|
||||||
not maybe_undefined(var)
|
not maybe_undefined(var)
|
||||||
) and
|
) and
|
||||||
name = n.getId() and
|
name = n.getId() and
|
||||||
scope = n.getEnclosingModule()
|
scope = n.getEnclosingModule()
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate maybe_undefined(SsaVariable var) {
|
private predicate maybe_undefined(Py::SsaVariable var) {
|
||||||
not exists(var.getDefinition()) and not py_ssa_phi(var, _)
|
not exists(var.getDefinition()) and not py_ssa_phi(var, _)
|
||||||
or
|
or
|
||||||
var.getDefinition().isDelete()
|
var.getDefinition().isDelete()
|
||||||
@@ -1058,13 +1062,13 @@ class BasicBlock extends @py_flow_node {
|
|||||||
private predicate oneNodeBlock() { this.firstNode() = this.getLastNode() }
|
private predicate oneNodeBlock() { this.firstNode() = this.getLastNode() }
|
||||||
|
|
||||||
private predicate startLocationInfo(string file, int line, int col) {
|
private predicate startLocationInfo(string file, int line, int col) {
|
||||||
if this.firstNode().getNode() instanceof Scope
|
if this.firstNode().getNode() instanceof Py::Scope
|
||||||
then this.firstNode().getASuccessor().getLocation().hasLocationInfo(file, line, col, _, _)
|
then this.firstNode().getASuccessor().getLocation().hasLocationInfo(file, line, col, _, _)
|
||||||
else this.firstNode().getLocation().hasLocationInfo(file, line, col, _, _)
|
else this.firstNode().getLocation().hasLocationInfo(file, line, col, _, _)
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate endLocationInfo(int endl, int endc) {
|
private predicate endLocationInfo(int endl, int endc) {
|
||||||
if this.getLastNode().getNode() instanceof Scope and not this.oneNodeBlock()
|
if this.getLastNode().getNode() instanceof Py::Scope and not this.oneNodeBlock()
|
||||||
then this.getLastNode().getAPredecessor().getLocation().hasLocationInfo(_, _, _, endl, endc)
|
then this.getLastNode().getAPredecessor().getLocation().hasLocationInfo(_, _, _, endl, endc)
|
||||||
else this.getLastNode().getLocation().hasLocationInfo(_, _, _, endl, endc)
|
else this.getLastNode().getLocation().hasLocationInfo(_, _, _, endl, endc)
|
||||||
}
|
}
|
||||||
@@ -1081,7 +1085,7 @@ class BasicBlock extends @py_flow_node {
|
|||||||
|
|
||||||
/** Whether flow from this basic block reaches a normal exit from its scope */
|
/** Whether flow from this basic block reaches a normal exit from its scope */
|
||||||
predicate reachesExit() {
|
predicate reachesExit() {
|
||||||
exists(Scope s | s.getANormalExit().getBasicBlock() = this)
|
exists(Py::Scope s | s.getANormalExit().getBasicBlock() = this)
|
||||||
or
|
or
|
||||||
this.getASuccessor().reachesExit()
|
this.getASuccessor().reachesExit()
|
||||||
}
|
}
|
||||||
@@ -1122,7 +1126,7 @@ class BasicBlock extends @py_flow_node {
|
|||||||
|
|
||||||
/** Gets the scope of this block */
|
/** Gets the scope of this block */
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
Scope getScope() {
|
Py::Scope getScope() {
|
||||||
exists(ControlFlowNode n | n.getBasicBlock() = this |
|
exists(ControlFlowNode n | n.getBasicBlock() = this |
|
||||||
/* Take care not to use an entry or exit node as that node's scope will be the outer scope */
|
/* Take care not to use an entry or exit node as that node's scope will be the outer scope */
|
||||||
not py_scope_flow(n, _, -1) and
|
not py_scope_flow(n, _, -1) and
|
||||||
@@ -1145,17 +1149,17 @@ class BasicBlock extends @py_flow_node {
|
|||||||
predicate reaches(BasicBlock other) { this = other or this.strictlyReaches(other) }
|
predicate reaches(BasicBlock other) { this = other or this.strictlyReaches(other) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the `ConditionBlock`, if any, that controls this block and
|
* Gets the `Py::ConditionBlock`, if any, that controls this block and
|
||||||
* does not control any other `ConditionBlock`s that control this block.
|
* does not control any other `Py::ConditionBlock`s that control this block.
|
||||||
* That is the `ConditionBlock` that is closest dominator.
|
* That is the `Py::ConditionBlock` that is closest dominator.
|
||||||
*/
|
*/
|
||||||
ConditionBlock getImmediatelyControllingBlock() {
|
Py::ConditionBlock getImmediatelyControllingBlock() {
|
||||||
result = this.nonControllingImmediateDominator*().getImmediateDominator()
|
result = this.nonControllingImmediateDominator*().getImmediateDominator()
|
||||||
}
|
}
|
||||||
|
|
||||||
private BasicBlock nonControllingImmediateDominator() {
|
private BasicBlock nonControllingImmediateDominator() {
|
||||||
result = this.getImmediateDominator() and
|
result = this.getImmediateDominator() and
|
||||||
not result.(ConditionBlock).controls(this, _)
|
not result.(Py::ConditionBlock).controls(this, _)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1175,7 +1179,7 @@ private class ControlFlowNodeAlias = ControlFlowNode;
|
|||||||
|
|
||||||
final private class FinalBasicBlock = BasicBlock;
|
final private class FinalBasicBlock = BasicBlock;
|
||||||
|
|
||||||
module Cfg implements BB::CfgSig<Location> {
|
module Cfg implements BB::CfgSig<Py::Location> {
|
||||||
private import codeql.controlflow.SuccessorType
|
private import codeql.controlflow.SuccessorType
|
||||||
|
|
||||||
class ControlFlowNode = ControlFlowNodeAlias;
|
class ControlFlowNode = ControlFlowNodeAlias;
|
||||||
@@ -1186,7 +1190,7 @@ module Cfg implements BB::CfgSig<Location> {
|
|||||||
// Using the location of the first node is simple
|
// Using the location of the first node is simple
|
||||||
// and we just need a way to identify the basic block
|
// and we just need a way to identify the basic block
|
||||||
// during debugging, so this will be serviceable.
|
// during debugging, so this will be serviceable.
|
||||||
Location getLocation() { result = super.getNode(0).getLocation() }
|
Py::Location getLocation() { result = super.getNode(0).getLocation() }
|
||||||
|
|
||||||
int length() { result = count(int i | exists(this.getNode(i))) }
|
int length() { result = count(int i | exists(this.getNode(i))) }
|
||||||
|
|
||||||
|
|||||||
1600
python/ql/lib/semmle/python/controlflow/internal/AstNodeImpl.qll
Normal file
1600
python/ql/lib/semmle/python/controlflow/internal/AstNodeImpl.qll
Normal file
File diff suppressed because it is too large
Load Diff
1163
python/ql/lib/semmle/python/controlflow/internal/Cfg.qll
Normal file
1163
python/ql/lib/semmle/python/controlflow/internal/Cfg.qll
Normal file
File diff suppressed because it is too large
Load Diff
547
python/ql/lib/semmle/python/dataflow/new/internal/SsaImpl.qll
Normal file
547
python/ql/lib/semmle/python/dataflow/new/internal/SsaImpl.qll
Normal file
@@ -0,0 +1,547 @@
|
|||||||
|
/**
|
||||||
|
* Provides the Python SSA implementation built on the new (shared) CFG.
|
||||||
|
*
|
||||||
|
* Mirrors the Java SSA adapter at
|
||||||
|
* `java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll`:
|
||||||
|
* an `InputSig` is defined in terms of positional `(BasicBlock, int)`
|
||||||
|
* variable references, and the shared
|
||||||
|
* `codeql.ssa.Ssa::Make<Location, Cfg, Input>` module is then
|
||||||
|
* instantiated.
|
||||||
|
*
|
||||||
|
* `SourceVariable` is the AST-level `Py::Variable`. Variable references
|
||||||
|
* are looked up via the CFG facade's `NameNode.defines`/`uses`/`deletes`
|
||||||
|
* predicates, which themselves are one-line bridges to AST-level
|
||||||
|
* `Name.defines`/`uses`/`deletes`.
|
||||||
|
*
|
||||||
|
* Implicit-entry definitions are inserted for:
|
||||||
|
* - non-local / global / builtin variables that are read in the scope
|
||||||
|
* but never assigned (no enclosing CFG node defines them),
|
||||||
|
* - captured variables (variables defined in an enclosing scope that
|
||||||
|
* are read inside the scope), and
|
||||||
|
* - parameters, but only if the corresponding parameter name is *not*
|
||||||
|
* itself a CFG node. With the C#-style parameter wiring already
|
||||||
|
* installed in `AstNodeImpl.qll`, parameter names *are* CFG nodes,
|
||||||
|
* so the regular `variableWrite` path handles them — no `i = -1`
|
||||||
|
* entry is needed for ordinary parameters.
|
||||||
|
*/
|
||||||
|
overlay[local?]
|
||||||
|
module;
|
||||||
|
|
||||||
|
private import python as Py
|
||||||
|
private import semmle.python.controlflow.internal.AstNodeImpl as CfgImpl
|
||||||
|
private import semmle.python.controlflow.internal.Cfg as Cfg
|
||||||
|
private import codeql.ssa.Ssa as SsaImplCommon
|
||||||
|
private import codeql.controlflow.BasicBlock as BB
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapts the Python `Cfg` facade to the shared SSA library's `CfgSig`.
|
||||||
|
* All members are inherited from `Cfg::ControlFlowNode` and
|
||||||
|
* `Cfg::BasicBlock`.
|
||||||
|
*/
|
||||||
|
private module CfgForSsa implements BB::CfgSig<Py::Location> {
|
||||||
|
class ControlFlowNode = CfgImpl::ControlFlowNode;
|
||||||
|
|
||||||
|
class BasicBlock = CfgImpl::BasicBlock;
|
||||||
|
|
||||||
|
class EntryBasicBlock = CfgImpl::Cfg::EntryBasicBlock;
|
||||||
|
|
||||||
|
predicate dominatingEdge = CfgImpl::Cfg::dominatingEdge/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A source variable for SSA, wrapping a Python AST `Variable`.
|
||||||
|
*
|
||||||
|
* We only track variables that are read at least once in their scope —
|
||||||
|
* tracking write-only variables would be unnecessary work — *except*
|
||||||
|
* for module-scope globals, where the "read" can be external (e.g.
|
||||||
|
* `import mymodule; mymodule.x`). Such globals are tracked
|
||||||
|
* unconditionally so that import-resolution can find their defining
|
||||||
|
* write.
|
||||||
|
*/
|
||||||
|
private newtype TSsaSourceVariable =
|
||||||
|
TPyVar(Py::Variable v) {
|
||||||
|
// Has a use somewhere — read-relevant for SSA.
|
||||||
|
exists(Cfg::NameNode n | n.uses(v))
|
||||||
|
or
|
||||||
|
// Or has a deletion (treated as a write that destroys the value).
|
||||||
|
exists(Cfg::NameNode n | n.deletes(v))
|
||||||
|
or
|
||||||
|
// Or is a module-scope global written in this module — must be
|
||||||
|
// tracked even if never read locally, because importers may read
|
||||||
|
// it as an attribute on the module object.
|
||||||
|
v.getScope() instanceof Py::Module and
|
||||||
|
exists(Cfg::NameNode n | n.defines(v))
|
||||||
|
or
|
||||||
|
// Or is a parameter — parameters must always have a
|
||||||
|
// `ParameterDefinition` for dataflow argument-routing to work,
|
||||||
|
// even if the parameter is never read in its scope. Mirrors
|
||||||
|
// legacy ESSA's `ParameterDefinition` (which fired for every
|
||||||
|
// parameter binding regardless of liveness).
|
||||||
|
exists(Py::Parameter p | p.asName() = v.getAStore())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A source variable for SSA, wrapping a Python AST `Variable`.
|
||||||
|
*/
|
||||||
|
class SsaSourceVariable extends TSsaSourceVariable {
|
||||||
|
/** Gets the underlying Python AST variable. */
|
||||||
|
Py::Variable getVariable() { this = TPyVar(result) }
|
||||||
|
|
||||||
|
/** Gets the (textual) name of this variable. */
|
||||||
|
string getName() { result = this.getVariable().getId() }
|
||||||
|
|
||||||
|
/** Gets a textual representation of this source variable. */
|
||||||
|
string toString() { result = this.getVariable().toString() }
|
||||||
|
|
||||||
|
/** Gets the location of this source variable. */
|
||||||
|
Py::Location getLocation() { result = this.getVariable().getScope().getLocation() }
|
||||||
|
|
||||||
|
/** Gets the scope in which this variable lives. */
|
||||||
|
Py::Scope getScope() { result = this.getVariable().getScope() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a use of this variable as it appears in the source — a `NameNode`
|
||||||
|
* that loads or deletes the variable. Mirrors legacy
|
||||||
|
* `SsaSourceVariable.getASourceUse()`.
|
||||||
|
*/
|
||||||
|
Cfg::ControlFlowNode getASourceUse() {
|
||||||
|
exists(Cfg::NameNode n | result = n |
|
||||||
|
n.uses(this.getVariable()) or n.deletes(this.getVariable())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an implicit use of this variable. The new SSA does not have
|
||||||
|
* implicit-use refinements, but we keep this for API parity — every
|
||||||
|
* normal-exit of the variable's scope counts as a sink, ensuring
|
||||||
|
* variables stay live to scope exit for taint-tracking.
|
||||||
|
*/
|
||||||
|
Cfg::ControlFlowNode getAnImplicitUse() {
|
||||||
|
result.isNormalExit() and result.getScope() = this.getScope()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a use of this variable — either an explicit source use or an
|
||||||
|
* implicit use at scope exit. Mirrors legacy `SsaSourceVariable.getAUse()`.
|
||||||
|
*/
|
||||||
|
Cfg::ControlFlowNode getAUse() {
|
||||||
|
result = this.getASourceUse() or result = this.getAnImplicitUse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `v` is a non-local read in scope `s`, in the sense that `s`
|
||||||
|
* uses `v` but does not write it within `s`. This includes globals,
|
||||||
|
* builtins, and variables captured from an enclosing function scope.
|
||||||
|
*
|
||||||
|
* The `Py::Variable` `v` lives in some defining scope (the module for
|
||||||
|
* globals, an outer function for closures, etc.); the reading scope
|
||||||
|
* `s` is the scope where the use of `v` occurs.
|
||||||
|
*/
|
||||||
|
private predicate nonLocalReadIn(Py::Variable v, Py::Scope s) {
|
||||||
|
exists(Cfg::NameNode n |
|
||||||
|
n.uses(v) and
|
||||||
|
n.getScope() = s and
|
||||||
|
not exists(Cfg::NameNode def | def.defines(v) and def.getScope() = s)
|
||||||
|
) and
|
||||||
|
// Match legacy ESSA: only create entry defs for variables that have
|
||||||
|
// at least one defining store somewhere — otherwise the entry def
|
||||||
|
// represents "nothing reaches here", which is the default anyway and
|
||||||
|
// introduces no useful flow. (Legacy's `ModuleVariable` required a
|
||||||
|
// store; this is the closure-aware generalisation.)
|
||||||
|
exists(Cfg::NameNode store | store.defines(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `bb` is the entry basic block of a scope where `v` should
|
||||||
|
* have an implicit entry definition. This covers:
|
||||||
|
* - non-local / global / builtin variables read in `s`, and
|
||||||
|
* - captured variables (defined in an enclosing scope but read in `s`).
|
||||||
|
*
|
||||||
|
* Each reading scope gets its own entry def, so a closure variable can
|
||||||
|
* have multiple entry defs across all functions/methods that read it.
|
||||||
|
*
|
||||||
|
* Parameters are *not* included: their bound `Name` is itself a CFG
|
||||||
|
* node (per the C#-style parameter wiring), so `variableWrite` fires at
|
||||||
|
* the parameter's natural CFG index.
|
||||||
|
*/
|
||||||
|
private predicate hasEntryDefIn(SsaSourceVariable v, CfgImpl::BasicBlock bb) {
|
||||||
|
exists(Py::Scope s |
|
||||||
|
nonLocalReadIn(v.getVariable(), s) and
|
||||||
|
bb = entryBlock(s)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entry basic block of scope `s`, where implicit entry
|
||||||
|
* definitions are placed (at synthetic index `-1`).
|
||||||
|
*/
|
||||||
|
private CfgImpl::BasicBlock entryBlock(Py::Scope s) {
|
||||||
|
exists(CfgImpl::ControlFlowNode entry |
|
||||||
|
entry instanceof CfgImpl::ControlFlow::EntryNode and
|
||||||
|
entry.getEnclosingCallable().asScope() = s and
|
||||||
|
result = entry.getBasicBlock()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The SSA `InputSig` for Python. References are positional
|
||||||
|
* `(BasicBlock, int)` pairs into the new CFG.
|
||||||
|
*/
|
||||||
|
private module SsaImplInput implements SsaImplCommon::InputSig<Py::Location, CfgImpl::BasicBlock> {
|
||||||
|
class SourceVariable = SsaSourceVariable;
|
||||||
|
|
||||||
|
predicate variableWrite(CfgImpl::BasicBlock bb, int i, SourceVariable v, boolean certain) {
|
||||||
|
// Explicit binding at a CFG node — includes assignments,
|
||||||
|
// parameter Names (wired in via the C# pattern), exception-handler
|
||||||
|
// `as`-bindings, import aliases, and match-pattern captures.
|
||||||
|
exists(Cfg::NameNode n |
|
||||||
|
bb.getNode(i) = n and
|
||||||
|
n.defines(v.getVariable()) and
|
||||||
|
certain = true
|
||||||
|
)
|
||||||
|
or
|
||||||
|
// `del x` — removes the binding. Modelled as a certain write that
|
||||||
|
// makes any subsequent read invalid.
|
||||||
|
exists(Cfg::NameNode n |
|
||||||
|
bb.getNode(i) = n and
|
||||||
|
n.deletes(v.getVariable()) and
|
||||||
|
certain = true
|
||||||
|
)
|
||||||
|
or
|
||||||
|
// Implicit entry definition for non-local / captured / global /
|
||||||
|
// builtin variables read in some scope. Each reading scope's entry
|
||||||
|
// block gets one such write, allowing closures: e.g. when `x` is a
|
||||||
|
// parameter of an outer function and read inside a nested
|
||||||
|
// function, both scopes get entry defs for `x`.
|
||||||
|
hasEntryDefIn(v, bb) and
|
||||||
|
i = -1 and
|
||||||
|
certain = true
|
||||||
|
or
|
||||||
|
// `from X import *` — possibly rebinds every name in the importing
|
||||||
|
// scope. Modelled as an uncertain write at the import-star's CFG
|
||||||
|
// position for every variable that lives in (or is referenced
|
||||||
|
// from) the same scope as the import-star. Mirrors legacy ESSA's
|
||||||
|
// `ImportStarRefinement` (see `essa/SsaDefinitions.qll`'s
|
||||||
|
// `import_star_refinement` predicate). The write is uncertain so
|
||||||
|
// that prior definitions of the variable remain available — the
|
||||||
|
// shared-SSA `SsaUncertainWrite` merges the new value with the
|
||||||
|
// immediately preceding definition.
|
||||||
|
exists(Cfg::ImportStarNode imp |
|
||||||
|
bb.getNode(i) = imp and
|
||||||
|
certain = false and
|
||||||
|
(
|
||||||
|
v.getVariable().getScope() = imp.getScope()
|
||||||
|
or
|
||||||
|
// Variable is defined in some other scope but referenced in
|
||||||
|
// the same scope as the import-star (matches legacy clause 2:
|
||||||
|
// `other.uses(v) and def.getScope() = other.getScope()`).
|
||||||
|
exists(Cfg::NameNode other |
|
||||||
|
other.uses(v.getVariable()) and
|
||||||
|
imp.getScope() = other.getScope()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
predicate variableRead(CfgImpl::BasicBlock bb, int i, SourceVariable v, boolean certain) {
|
||||||
|
// Explicit source use — a `Name` load or a `del x` of the variable.
|
||||||
|
exists(Cfg::NameNode n |
|
||||||
|
bb.getNode(i) = n and
|
||||||
|
n.uses(v.getVariable()) and
|
||||||
|
certain = true
|
||||||
|
)
|
||||||
|
or
|
||||||
|
// Synthetic use at the normal exit of the variable's defining scope.
|
||||||
|
// This keeps every variable live to scope exit so that callers (e.g.
|
||||||
|
// `module_export` in ImportResolution.qll, or taint-tracking pass-through
|
||||||
|
// through unread locals) can ask "which definition reaches end of
|
||||||
|
// scope?". Mirrors legacy ESSA's `SsaSourceVariable.getAUse()` which
|
||||||
|
// included `getScope().getANormalExit()`.
|
||||||
|
exists(Cfg::ControlFlowNode exit |
|
||||||
|
exit.isNormalExit() and
|
||||||
|
exit.getScope() = v.getVariable().getScope() and
|
||||||
|
bb.getNode(i) = exit and
|
||||||
|
certain = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The shared SSA instantiation for Python.
|
||||||
|
*
|
||||||
|
* Members:
|
||||||
|
* - `Definition` — the union of explicit, uncertain, and phi definitions
|
||||||
|
* - `WriteDefinition`, `UncertainWriteDefinition`, `PhiNode`
|
||||||
|
* - the standard SSA predicates (`getAUse`, `getAnUltimateDefinition`, ...).
|
||||||
|
*/
|
||||||
|
module Ssa = SsaImplCommon::Make<Py::Location, CfgForSsa, SsaImplInput>;
|
||||||
|
|
||||||
|
final class Definition = Ssa::Definition;
|
||||||
|
|
||||||
|
final class WriteDefinition = Ssa::WriteDefinition;
|
||||||
|
|
||||||
|
final class UncertainWriteDefinition = Ssa::UncertainWriteDefinition;
|
||||||
|
|
||||||
|
final class PhiNode = Ssa::PhiNode;
|
||||||
|
|
||||||
|
// ===========================================================================
|
||||||
|
// ESSA-shaped adapter layer
|
||||||
|
//
|
||||||
|
// The dataflow library (`python/ql/lib/semmle/python/dataflow/new/`) and
|
||||||
|
// related modules (`ApiGraphs.qll`, etc.) consume the legacy ESSA API
|
||||||
|
// (`EssaVariable`, `EssaDefinition`, `AssignmentDefinition`,
|
||||||
|
// `ScopeEntryDefinition`, `ParameterDefinition`, `WithDefinition`,
|
||||||
|
// `PhiFunction`, plus the `AdjacentUses` module). To migrate them off
|
||||||
|
// the legacy CFG, we expose the same API surface on top of the
|
||||||
|
// shared SSA built above.
|
||||||
|
//
|
||||||
|
// This adapter is intentionally narrow: it covers only the predicates
|
||||||
|
// that new dataflow consumes. The richer legacy ESSA — refinement
|
||||||
|
// nodes, attribute refinements, edge refinements — stays available
|
||||||
|
// via `semmle.python.essa.Essa` for points-to / legacy code.
|
||||||
|
// ===========================================================================
|
||||||
|
/**
|
||||||
|
* Gets the CFG node at which a write definition's binding takes place.
|
||||||
|
*
|
||||||
|
* For ordinary writes (assignment, deletion, parameter) this is the
|
||||||
|
* canonical CFG node of the bound Name. For implicit entry definitions
|
||||||
|
* (synthesised at position `-1` of a scope's entry BB) this is the
|
||||||
|
* scope's entry node.
|
||||||
|
*/
|
||||||
|
private Cfg::ControlFlowNode writeDefNode(Ssa::WriteDefinition def) {
|
||||||
|
exists(CfgImpl::BasicBlock bb, int i | def.definesAt(_, bb, i) |
|
||||||
|
i >= 0 and result = bb.getNode(i)
|
||||||
|
or
|
||||||
|
i = -1 and result = bb.getNode(0)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A write definition whose binding has a corresponding CFG node — i.e.
|
||||||
|
* everything that's not a phi node. Mirrors legacy ESSA's
|
||||||
|
* `EssaNodeDefinition`.
|
||||||
|
*/
|
||||||
|
class EssaNodeDefinition extends Ssa::WriteDefinition {
|
||||||
|
/** Gets the CFG node where this definition's binding takes place. */
|
||||||
|
Cfg::ControlFlowNode getDefiningNode() { result = writeDefNode(this) }
|
||||||
|
|
||||||
|
/** Gets the variable defined here (legacy name). */
|
||||||
|
SsaSourceVariable getVariable() { result = this.getSourceVariable() }
|
||||||
|
|
||||||
|
/** Gets the enclosing scope. */
|
||||||
|
Py::Scope getScope() {
|
||||||
|
exists(Cfg::ControlFlowNode n | n = this.getDefiningNode() | result = n.getScope())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if this definition defines source variable `v` at CFG node
|
||||||
|
* `defNode`. Flatter form of `getSourceVariable()` +
|
||||||
|
* `getDefiningNode()`, matching legacy ESSA's `definedBy`.
|
||||||
|
*/
|
||||||
|
predicate definedBy(SsaSourceVariable v, Cfg::ControlFlowNode defNode) {
|
||||||
|
v = this.getSourceVariable() and defNode = this.getDefiningNode()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An assignment definition: any binding where the value being assigned
|
||||||
|
* is statically known via `Cfg::DefinitionNode.getValue()`. Includes
|
||||||
|
* plain assignments, walrus, annotated assignments, augmented
|
||||||
|
* assignments, import aliases (`import x` / `from m import x [as y]`),
|
||||||
|
* `with ... as x`, and for-target bindings (where `getValue()` returns
|
||||||
|
* the iter expression's CFG node). Excludes parameter bindings —
|
||||||
|
* those are modelled by `ParameterDefinition`.
|
||||||
|
*/
|
||||||
|
class AssignmentDefinition extends EssaNodeDefinition {
|
||||||
|
AssignmentDefinition() {
|
||||||
|
exists(Cfg::NameNode n | n = this.getDefiningNode() |
|
||||||
|
exists(n.(Cfg::DefinitionNode).getValue()) and
|
||||||
|
not n.(Cfg::ControlFlowNode).isParameter()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the CFG node for the value being assigned, if statically known. */
|
||||||
|
Cfg::ControlFlowNode getValue() {
|
||||||
|
result = this.getDefiningNode().(Cfg::DefinitionNode).getValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A parameter definition — the binding of a parameter name in a
|
||||||
|
* function's scope.
|
||||||
|
*/
|
||||||
|
class ParameterDefinition extends EssaNodeDefinition {
|
||||||
|
ParameterDefinition() { this.getDefiningNode().isParameter() }
|
||||||
|
|
||||||
|
/** Gets the AST `Parameter` (a `Py::Name` in param context). */
|
||||||
|
Py::Name getParameter() { result = this.getDefiningNode().getNode() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A definition introduced by a `with ... as x:` clause.
|
||||||
|
*/
|
||||||
|
class WithDefinition extends EssaNodeDefinition {
|
||||||
|
WithDefinition() {
|
||||||
|
exists(Cfg::NameNode n, Py::With w |
|
||||||
|
n = this.getDefiningNode() and
|
||||||
|
w.getOptionalVars() = n.getNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An assignment where the LHS is a tuple/list and the RHS is unpacked:
|
||||||
|
* `a, b = (1, 2)` or `a, *rest = xs`. The SSA def lives at the inner
|
||||||
|
* `Name` CFG node, but for IterableUnpacking integration we expose
|
||||||
|
* the enclosing `StarredNode` as the `getDefiningNode()` for `*rest`
|
||||||
|
* patterns — mirroring legacy ESSA's `multi_assignment_definition`,
|
||||||
|
* which placed the def at the StarredNode CFG node.
|
||||||
|
*/
|
||||||
|
class MultiAssignmentDefinition extends EssaNodeDefinition {
|
||||||
|
MultiAssignmentDefinition() {
|
||||||
|
exists(Cfg::NameNode n | n = super.getDefiningNode() |
|
||||||
|
exists(Py::Assign a, Py::Expr lhs |
|
||||||
|
a.getATarget() = lhs and
|
||||||
|
(lhs instanceof Py::Tuple or lhs instanceof Py::List) and
|
||||||
|
lhs.getASubExpression+() = n.getNode()
|
||||||
|
)
|
||||||
|
or
|
||||||
|
// For-loop with tuple/list target: `for a, b in xs:` —
|
||||||
|
// tuple-unpacking semantics applies to the for-target.
|
||||||
|
exists(Py::For f, Py::Expr lhs |
|
||||||
|
f.getTarget() = lhs and
|
||||||
|
(lhs instanceof Py::Tuple or lhs instanceof Py::List) and
|
||||||
|
lhs.getASubExpression+() = n.getNode()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override Cfg::ControlFlowNode getDefiningNode() {
|
||||||
|
// Default: the underlying `Name` CFG node (where the SSA def lives).
|
||||||
|
not exists(Cfg::StarredNode s |
|
||||||
|
s.getNode().(Py::Starred).getValue() = super.getDefiningNode().getNode()
|
||||||
|
) and
|
||||||
|
result = super.getDefiningNode()
|
||||||
|
or
|
||||||
|
// Exception: for `*rest`, expose the enclosing `Starred` CFG node
|
||||||
|
// so that `IterableUnpacking::iterableUnpackingStarredElementStoreStep`
|
||||||
|
// can attach the rest-list to it.
|
||||||
|
exists(Cfg::StarredNode s |
|
||||||
|
s.getNode().(Py::Starred).getValue() = super.getDefiningNode().getNode()
|
||||||
|
|
|
||||||
|
result = s
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implicit entry definition for a non-local / captured / global /
|
||||||
|
* builtin variable read in a scope but not defined there.
|
||||||
|
*
|
||||||
|
* Inherits from `EssaNodeDefinition` and exposes the scope's entry node
|
||||||
|
* as its defining node (matching legacy ESSA semantics).
|
||||||
|
*/
|
||||||
|
class ScopeEntryDefinition extends EssaNodeDefinition {
|
||||||
|
ScopeEntryDefinition() {
|
||||||
|
exists(CfgImpl::BasicBlock bb |
|
||||||
|
this.definesAt(_, bb, -1) and
|
||||||
|
bb instanceof CfgImpl::Cfg::EntryBasicBlock
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the enclosing scope (the scope whose entry block this def is in). */
|
||||||
|
override Py::Scope getScope() {
|
||||||
|
exists(CfgImpl::BasicBlock bb |
|
||||||
|
this.definesAt(_, bb, -1) and
|
||||||
|
result = bb.getNode(0).(Cfg::ControlFlowNode).getScope()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A phi node (alias matching legacy naming). */
|
||||||
|
class PhiFunction extends PhiNode {
|
||||||
|
/**
|
||||||
|
* Gets an input to this phi function (a definition that flows into
|
||||||
|
* the phi from one of its predecessor blocks). Mirrors legacy
|
||||||
|
* ESSA's `PhiFunction.getAnInput()`.
|
||||||
|
*/
|
||||||
|
Ssa::Definition getAnInput() { Ssa::phiHasInputFromBlock(this, result, _) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Base class for all ESSA definitions (legacy-shaped). */
|
||||||
|
class EssaDefinition = Ssa::Definition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An adapter representing a single SSA-defined "variable" — wrapping
|
||||||
|
* one `Ssa::Definition`. Mirrors legacy `EssaVariable` API.
|
||||||
|
*/
|
||||||
|
class EssaVariable extends Ssa::Definition {
|
||||||
|
/** Gets the underlying SSA definition (legacy name). */
|
||||||
|
Ssa::Definition getDefinition() { result = this }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a CFG node where this definition is used. Includes regular
|
||||||
|
* `Name` reads as well as the synthetic scope-exit "use" registered
|
||||||
|
* via `SsaImplInput::variableRead` — mirrors legacy ESSA's
|
||||||
|
* `EssaVariable.getAUse()` which inherited the synthetic exit-use
|
||||||
|
* from `SsaSourceVariable`.
|
||||||
|
*/
|
||||||
|
Cfg::ControlFlowNode getAUse() {
|
||||||
|
exists(CfgImpl::BasicBlock bb, int i |
|
||||||
|
Ssa::ssaDefReachesRead(this.getSourceVariable(), this, bb, i) and
|
||||||
|
bb.getNode(i) = result
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the (textual) name of the underlying variable. */
|
||||||
|
string getName() { result = this.getSourceVariable().getVariable().getId() }
|
||||||
|
|
||||||
|
/** Gets the scope in which this variable lives. */
|
||||||
|
Py::Scope getScope() { result = this.getSourceVariable().getVariable().getScope() }
|
||||||
|
|
||||||
|
/** Gets an ultimate non-phi ancestor of this definition. */
|
||||||
|
EssaVariable getAnUltimateDefinition() {
|
||||||
|
if this instanceof PhiNode
|
||||||
|
then
|
||||||
|
exists(Ssa::Definition input |
|
||||||
|
Ssa::phiHasInputFromBlock(this, input, _) and
|
||||||
|
result = input.(EssaVariable).getAnUltimateDefinition()
|
||||||
|
)
|
||||||
|
else result = this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjacent use-use and def-use relations exposed by the shared SSA
|
||||||
|
* library. Provides the same interface as legacy
|
||||||
|
* `semmle.python.essa.SsaCompute::AdjacentUses`.
|
||||||
|
*/
|
||||||
|
module AdjacentUses {
|
||||||
|
/** Holds if `nodeFrom` and `nodeTo` are adjacent uses of the same SSA variable. */
|
||||||
|
predicate adjacentUseUse(Cfg::NameNode nodeFrom, Cfg::NameNode nodeTo) {
|
||||||
|
exists(SsaSourceVariable v, CfgImpl::BasicBlock bb1, int i1, CfgImpl::BasicBlock bb2, int i2 |
|
||||||
|
Ssa::adjacentUseUse(bb1, i1, bb2, i2, v, _) and
|
||||||
|
nodeFrom = bb1.getNode(i1) and
|
||||||
|
nodeTo = bb2.getNode(i2)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds if `use` is a first use of definition `def`. */
|
||||||
|
predicate firstUse(Ssa::Definition def, Cfg::NameNode use) {
|
||||||
|
exists(CfgImpl::BasicBlock bb, int i |
|
||||||
|
Ssa::firstUse(def, bb, i, _) and
|
||||||
|
use = bb.getNode(i)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `use` is any reachable use of definition `def`. Combines
|
||||||
|
* `firstUse` with transitive use-use adjacency.
|
||||||
|
*/
|
||||||
|
predicate useOfDef(Ssa::Definition def, Cfg::NameNode use) {
|
||||||
|
firstUse(def, use)
|
||||||
|
or
|
||||||
|
exists(Cfg::NameNode mid | useOfDef(def, mid) and adjacentUseUse(mid, use))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
consistencyOverview
|
||||||
|
| deadEnd | 1 |
|
||||||
|
deadEnd
|
||||||
|
| without_loop.py:7:5:7:9 | Break |
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* Phase -1 of the dataflow CFG migration: verifies that every variable
|
||||||
|
* binding visible to the AST (`Name.defines(v)`) corresponds to a CFG node
|
||||||
|
* in the new CFG (`semmle.python.controlflow.internal.AstNodeImpl`).
|
||||||
|
*
|
||||||
|
* The expected tag is `cfgdefines=<name>`. Each binding annotation in the
|
||||||
|
* test sources looks like `# $ cfgdefines=x` for a binding currently
|
||||||
|
* covered by the new CFG, or `# $ MISSING: cfgdefines=x` for a binding
|
||||||
|
* that is known to be uncovered (a "red" test case that should be
|
||||||
|
* green-flipped once the corresponding `cfg-ext-*` extension lands).
|
||||||
|
*/
|
||||||
|
|
||||||
|
import python
|
||||||
|
import semmle.python.controlflow.internal.AstNodeImpl as CfgImpl
|
||||||
|
import utils.test.InlineExpectationsTest
|
||||||
|
|
||||||
|
module CfgBindingsTest implements TestSig {
|
||||||
|
string getARelevantTag() { result = "cfgdefines" }
|
||||||
|
|
||||||
|
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||||
|
exists(Name n, Variable v, CfgImpl::ControlFlowNode cfg |
|
||||||
|
n.defines(v) and
|
||||||
|
cfg.getAstNode().asExpr() = n and
|
||||||
|
location = n.getLocation() and
|
||||||
|
element = n.toString() and
|
||||||
|
tag = "cfgdefines" and
|
||||||
|
value = v.getId()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
import MakeTest<CfgBindingsTest>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Annotated assignment (PEP 526). Both with and without an initializer.
|
||||||
|
|
||||||
|
a: int = 1 # $ cfgdefines=a
|
||||||
|
b: str = "hi" # $ cfgdefines=b
|
||||||
|
|
||||||
|
# Annotation without value: the AST records `c` as defined,
|
||||||
|
# and the new CFG now visits it via the AnnAssignStmt wrapper.
|
||||||
|
c: int # $ cfgdefines=c
|
||||||
|
|
||||||
|
class K: # $ cfgdefines=K
|
||||||
|
field: int = 0 # $ cfgdefines=field
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Compound (tuple/list) assignment targets — actually wired in the new CFG.
|
||||||
|
|
||||||
|
a, b = (1, 2) # $ cfgdefines=a cfgdefines=b
|
||||||
|
[c, d] = [3, 4] # $ cfgdefines=c cfgdefines=d
|
||||||
|
|
||||||
|
# Nested unpacking.
|
||||||
|
(e, (f, g)) = (1, (2, 3)) # $ cfgdefines=e cfgdefines=f cfgdefines=g
|
||||||
|
|
||||||
|
# Star unpacking.
|
||||||
|
h, *i = [1, 2, 3] # $ cfgdefines=h cfgdefines=i
|
||||||
|
|
||||||
|
# Chained assignment with compound target.
|
||||||
|
j = k, l = (5, 6) # $ cfgdefines=j cfgdefines=k cfgdefines=l
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# Comprehension and `for` loop targets — wired in the new CFG.
|
||||||
|
# Comprehensions are nested function scopes with a synthetic `.0` parameter
|
||||||
|
# bound to the iterable.
|
||||||
|
|
||||||
|
# Bare-name `for` target.
|
||||||
|
for i in range(3): # $ cfgdefines=i
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Compound `for` target.
|
||||||
|
for k, v in [(1, 2)]: # $ cfgdefines=k cfgdefines=v
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Comprehension targets.
|
||||||
|
_ = [x for x in range(3)] # $ cfgdefines=_ cfgdefines=x cfgdefines=.0
|
||||||
|
_ = {y: z for y, z in []} # $ cfgdefines=_ cfgdefines=y cfgdefines=z cfgdefines=.0
|
||||||
|
_ = (a for a in []) # $ cfgdefines=_ cfgdefines=a cfgdefines=.0
|
||||||
|
|
||||||
|
# Nested comprehensions.
|
||||||
|
_ = [b for c in [] for b in c] # $ cfgdefines=_ cfgdefines=c cfgdefines=b cfgdefines=.0
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
# Dead bindings under the "no expressions raise" CFG abstraction.
|
||||||
|
#
|
||||||
|
# The new CFG does not currently model raise edges from arbitrary
|
||||||
|
# expressions. As a consequence, code that is only reachable through
|
||||||
|
# exception flow is (correctly) classified as dead and has no CFG node.
|
||||||
|
# Variable bindings in dead code do not need CFG nodes - SSA / dataflow
|
||||||
|
# over dead code is moot.
|
||||||
|
#
|
||||||
|
# These tests act as a regression guard: the bindings below intentionally
|
||||||
|
# have no `cfgdefines=` annotations. If raise modelling is later added,
|
||||||
|
# the BindingsTest infrastructure will surface the new CFG nodes as
|
||||||
|
# unexpected results, and this file will need to be revisited.
|
||||||
|
|
||||||
|
|
||||||
|
def f(obj): # $ cfgdefines=f cfgdefines=obj
|
||||||
|
try:
|
||||||
|
return len(obj)
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# The first try's body always returns; its except handler does not
|
||||||
|
# raise or otherwise transfer control, so under "no expressions
|
||||||
|
# raise" the only paths out of the try-statement are dead. Everything
|
||||||
|
# below is unreachable.
|
||||||
|
try:
|
||||||
|
hint = type(obj).__length_hint__
|
||||||
|
except AttributeError:
|
||||||
|
return None
|
||||||
|
return hint
|
||||||
|
|
||||||
|
|
||||||
|
def g(): # $ cfgdefines=g
|
||||||
|
try:
|
||||||
|
raise Exception("inner")
|
||||||
|
except:
|
||||||
|
raise Exception("outer")
|
||||||
|
else:
|
||||||
|
# Unreachable: the inner try body always raises, so the `else:`
|
||||||
|
# clause never runs.
|
||||||
|
hit_inner_else = True
|
||||||
|
|
||||||
|
|
||||||
|
def h(cache, key): # $ cfgdefines=h cfgdefines=cache cfgdefines=key
|
||||||
|
try:
|
||||||
|
return cache[key]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Same pattern as `f`: dead under "no expressions raise".
|
||||||
|
value = compute(key)
|
||||||
|
cache[key] = value
|
||||||
|
return value
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Decorated `def`/`class` — wired in the new CFG.
|
||||||
|
|
||||||
|
|
||||||
|
def deco(f): # $ cfgdefines=deco cfgdefines=f
|
||||||
|
return f
|
||||||
|
|
||||||
|
|
||||||
|
@deco
|
||||||
|
def decorated_func(): # $ cfgdefines=decorated_func
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@deco
|
||||||
|
class DecoratedClass: # $ cfgdefines=DecoratedClass
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Stacked decorators.
|
||||||
|
@deco
|
||||||
|
@deco
|
||||||
|
def doubly(): # $ cfgdefines=doubly
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Inside a class body.
|
||||||
|
class Outer: # $ cfgdefines=Outer
|
||||||
|
@staticmethod
|
||||||
|
def inner(): # $ cfgdefines=inner
|
||||||
|
pass
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Exception-handler name bindings. These are already wired in the new
|
||||||
|
# CFG provided the try body can raise; `raise` statements are reliably
|
||||||
|
# treated as exception sources.
|
||||||
|
|
||||||
|
try:
|
||||||
|
raise ValueError("oops")
|
||||||
|
except ValueError as e: # $ cfgdefines=e
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
raise TypeError("oops")
|
||||||
|
except (TypeError, KeyError) as err: # $ cfgdefines=err
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Exception groups (Python 3.11+).
|
||||||
|
try:
|
||||||
|
raise ValueError("oops")
|
||||||
|
except* ValueError as eg: # $ cfgdefines=eg
|
||||||
|
pass
|
||||||
14
python/ql/test/library-tests/ControlFlow/bindings/imports.py
Normal file
14
python/ql/test/library-tests/ControlFlow/bindings/imports.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Import aliases — all bound names below are now reachable via the new
|
||||||
|
# CFG's `ImportStmt` wrapper.
|
||||||
|
|
||||||
|
import os # $ cfgdefines=os
|
||||||
|
import os.path # $ cfgdefines=os
|
||||||
|
import os as o # $ cfgdefines=o
|
||||||
|
from os import path # $ cfgdefines=path
|
||||||
|
from os import path as p # $ cfgdefines=p
|
||||||
|
from os import sep, linesep # $ cfgdefines=sep cfgdefines=linesep
|
||||||
|
from os import (
|
||||||
|
getcwd, # $ cfgdefines=getcwd
|
||||||
|
getcwdb, # $ cfgdefines=getcwdb
|
||||||
|
)
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Match-statement pattern bindings — wired in the new CFG.
|
||||||
|
|
||||||
|
def f(subject): # $ cfgdefines=f cfgdefines=subject
|
||||||
|
match subject:
|
||||||
|
case x: # $ cfgdefines=x
|
||||||
|
pass
|
||||||
|
case [a, b]: # $ cfgdefines=a cfgdefines=b
|
||||||
|
pass
|
||||||
|
case {"k": v}: # $ cfgdefines=v
|
||||||
|
pass
|
||||||
|
case Point(p, q): # $ cfgdefines=p cfgdefines=q
|
||||||
|
pass
|
||||||
|
case [_, *rest]: # $ cfgdefines=rest
|
||||||
|
pass
|
||||||
|
case (1 | 2) as n: # $ cfgdefines=n
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Point: # $ cfgdefines=Point
|
||||||
|
__match_args__ = ("x", "y") # $ cfgdefines=__match_args__
|
||||||
|
x: int # $ cfgdefines=x
|
||||||
|
y: int # $ cfgdefines=y
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Function parameters.
|
||||||
|
|
||||||
|
def positional(a, b): # $ cfgdefines=positional cfgdefines=a cfgdefines=b
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def with_default(x=1, y=2): # $ cfgdefines=with_default cfgdefines=x cfgdefines=y
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def with_vararg(*args): # $ cfgdefines=with_vararg cfgdefines=args
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def with_kwarg(**kwargs): # $ cfgdefines=with_kwarg cfgdefines=kwargs
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def with_kwonly(*, k1, k2=5): # $ cfgdefines=with_kwonly cfgdefines=k1 cfgdefines=k2
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def kitchen_sink(a, b=2, *args, k1, k2=5, **kw): # $ cfgdefines=kitchen_sink cfgdefines=a cfgdefines=b cfgdefines=args cfgdefines=k1 cfgdefines=k2 cfgdefines=kw
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Methods get `self` / `cls`.
|
||||||
|
class C: # $ cfgdefines=C
|
||||||
|
def method(self, x): # $ cfgdefines=method cfgdefines=self cfgdefines=x
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def cmethod(cls, x): # $ cfgdefines=cmethod cfgdefines=cls cfgdefines=x
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Lambda parameter.
|
||||||
|
_ = lambda p: p + 1 # $ cfgdefines=_ cfgdefines=p
|
||||||
|
|
||||||
|
# PEP 570 positional-only.
|
||||||
|
def pos_only(a, b, /, c): # $ cfgdefines=pos_only cfgdefines=a cfgdefines=b cfgdefines=c
|
||||||
|
pass
|
||||||
14
python/ql/test/library-tests/ControlFlow/bindings/simple.py
Normal file
14
python/ql/test/library-tests/ControlFlow/bindings/simple.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Simple bindings that should already work in the new CFG.
|
||||||
|
# No MISSING annotations expected.
|
||||||
|
|
||||||
|
x = 1 # $ cfgdefines=x
|
||||||
|
y = x + 1 # $ cfgdefines=y
|
||||||
|
|
||||||
|
def f(): # $ cfgdefines=f
|
||||||
|
pass
|
||||||
|
|
||||||
|
class C: # $ cfgdefines=C
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Re-assignment.
|
||||||
|
x = 2 # $ cfgdefines=x
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# PEP 695 type parameters (Python 3.12+).
|
||||||
|
|
||||||
|
# PEP 695 type-param names on `def`/`class` bind in an annotation scope
|
||||||
|
# that nests the function/class body — they have no CFG node in the
|
||||||
|
# enclosing scope (matching the legacy CFG).
|
||||||
|
def func[T](x: T) -> T: # $ cfgdefines=func cfgdefines=x
|
||||||
|
return x
|
||||||
|
|
||||||
|
|
||||||
|
class Box[T]: # $ cfgdefines=Box
|
||||||
|
item: T # $ cfgdefines=item
|
||||||
|
|
||||||
|
|
||||||
|
# Multi-parameter, with bound and variadics.
|
||||||
|
def multi[T: int, *Ts, **P](x: T, *args: *Ts, **kwargs: P.kwargs) -> T: # $ cfgdefines=multi cfgdefines=x cfgdefines=args cfgdefines=kwargs
|
||||||
|
return x
|
||||||
|
|
||||||
|
|
||||||
|
# `type` statement (PEP 695).
|
||||||
|
type Alias[T] = list[T] # $ cfgdefines=Alias cfgdefines=T
|
||||||
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Walrus and starred-target edge cases — wired in the new CFG.
|
||||||
|
|
||||||
|
# Walrus in expression context.
|
||||||
|
if (y := 5) > 0: # $ cfgdefines=y
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Walrus in a comprehension. The comprehension introduces a synthetic
|
||||||
|
# `.0` parameter bound to the iterable.
|
||||||
|
_ = [w for _ in range(3) if (w := 1)] # $ cfgdefines=_ cfgdefines=w cfgdefines=.0
|
||||||
|
|
||||||
|
# Starred target in a Tuple LHS.
|
||||||
|
*head, tail = [1, 2, 3] # $ cfgdefines=head cfgdefines=tail
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# `with cm() as x:` bindings — wired in the new CFG.
|
||||||
|
|
||||||
|
class CM: # $ cfgdefines=CM
|
||||||
|
def __enter__(self): return self # $ cfgdefines=__enter__ cfgdefines=self
|
||||||
|
def __exit__(self, *a): pass # $ cfgdefines=__exit__ cfgdefines=self cfgdefines=a
|
||||||
|
|
||||||
|
with CM() as x: # $ cfgdefines=x
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Multiple items.
|
||||||
|
with CM() as a, CM() as b: # $ cfgdefines=a cfgdefines=b
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Parenthesised form (Python 3.10+).
|
||||||
|
with (CM() as p, CM() as q): # $ cfgdefines=p cfgdefines=q
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Compound target in `with`.
|
||||||
|
with CM() as (m, n): # $ cfgdefines=m cfgdefines=n
|
||||||
|
pass
|
||||||
|
|
||||||
@@ -5,6 +5,8 @@
|
|||||||
* have separate CFGs and are excluded from this check.
|
* have separate CFGs and are excluded from this check.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import python
|
||||||
|
import TimerUtils
|
||||||
import OldCfgImpl
|
import OldCfgImpl
|
||||||
|
|
||||||
private module Utils = EvalOrderCfgUtils<OldCfg>;
|
private module Utils = EvalOrderCfgUtils<OldCfg>;
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
* Checks that every timer annotation has a corresponding CFG node.
|
* Checks that every timer annotation has a corresponding CFG node.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import python
|
||||||
|
import TimerUtils
|
||||||
import OldCfgImpl
|
import OldCfgImpl
|
||||||
|
|
||||||
private module Utils = EvalOrderCfgUtils<OldCfg>;
|
private module Utils = EvalOrderCfgUtils<OldCfg>;
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
* edge leaves the basic block and the normal successor may be dead.
|
* edge leaves the basic block and the normal successor may be dead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import python
|
||||||
|
import TimerUtils
|
||||||
import OldCfgImpl
|
import OldCfgImpl
|
||||||
|
|
||||||
private module Utils = EvalOrderCfgUtils<OldCfg>;
|
private module Utils = EvalOrderCfgUtils<OldCfg>;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
| test_boolean.py:9:10:9:43 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:9:59:9:59 | IntegerLiteral | timestamp 2 | test_boolean.py:9:19:9:19 | IntegerLiteral | timestamp 0 |
|
| test_boolean.py:9:10:9:43 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:9:59:9:59 | IntegerLiteral | timestamp 2 | test_boolean.py:9:19:9:19 | IntegerLiteral | timestamp 0 |
|
||||||
| test_boolean.py:15:10:15:43 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:15:50:15:50 | IntegerLiteral | timestamp 1 | test_boolean.py:15:20:15:20 | IntegerLiteral | timestamp 0 |
|
| test_boolean.py:15:10:15:43 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:15:50:15:50 | IntegerLiteral | timestamp 1 | test_boolean.py:15:20:15:20 | IntegerLiteral | timestamp 0 |
|
||||||
| test_boolean.py:21:10:21:42 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:21:49:21:49 | IntegerLiteral | timestamp 1 | test_boolean.py:21:19:21:19 | IntegerLiteral | timestamp 0 |
|
| test_boolean.py:21:10:21:42 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:21:49:21:49 | IntegerLiteral | timestamp 1 | test_boolean.py:21:19:21:19 | IntegerLiteral | timestamp 0 |
|
||||||
| test_boolean.py:27:10:27:34 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:27:50:27:50 | IntegerLiteral | timestamp 2 | test_boolean.py:27:20:27:20 | IntegerLiteral | timestamp 0 |
|
| test_boolean.py:27:10:27:43 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:27:59:27:59 | IntegerLiteral | timestamp 2 | test_boolean.py:27:20:27:20 | IntegerLiteral | timestamp 0 |
|
||||||
| test_boolean.py:40:10:40:61 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:40:86:40:86 | IntegerLiteral | timestamp 3 | test_boolean.py:40:16:40:16 | IntegerLiteral | timestamp 0 |
|
| test_boolean.py:40:10:40:61 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:40:86:40:86 | IntegerLiteral | timestamp 3 | test_boolean.py:40:16:40:16 | IntegerLiteral | timestamp 0 |
|
||||||
| test_boolean.py:46:10:46:61 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:46:86:46:86 | IntegerLiteral | timestamp 3 | test_boolean.py:46:16:46:16 | IntegerLiteral | timestamp 0 |
|
| test_boolean.py:46:10:46:61 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:46:86:46:86 | IntegerLiteral | timestamp 3 | test_boolean.py:46:16:46:16 | IntegerLiteral | timestamp 0 |
|
||||||
| test_boolean.py:52:10:52:95 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:52:120:52:120 | IntegerLiteral | timestamp 4 | test_boolean.py:52:20:52:20 | IntegerLiteral | timestamp 0 |
|
| test_boolean.py:52:10:52:95 | ControlFlowNode for BoolExpr | Basic block ordering: $@ appears before $@ | test_boolean.py:52:120:52:120 | IntegerLiteral | timestamp 4 | test_boolean.py:52:20:52:20 | IntegerLiteral | timestamp 0 |
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
* increasing minimum-timestamp order.
|
* increasing minimum-timestamp order.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import python
|
||||||
|
import TimerUtils
|
||||||
import OldCfgImpl
|
import OldCfgImpl
|
||||||
|
|
||||||
private module Utils = EvalOrderCfgUtils<OldCfg>;
|
private module Utils = EvalOrderCfgUtils<OldCfg>;
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
* lambdas that have annotations in nested scopes).
|
* lambdas that have annotations in nested scopes).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import python
|
||||||
|
import TimerUtils
|
||||||
import OldCfgImpl
|
import OldCfgImpl
|
||||||
|
|
||||||
private module Utils = EvalOrderCfgUtils<OldCfg>;
|
private module Utils = EvalOrderCfgUtils<OldCfg>;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user