Compare commits

..

41 Commits

Author SHA1 Message Date
Owen Mansel-Chan
cae623d669 Test changes to be checked 2026-06-22 23:09:27 +01:00
Owen Mansel-Chan
326fa74b21 Update query for unreachable statements 2026-06-22 23:09:25 +01:00
Owen Mansel-Chan
138a1c3c99 Fix calls for defer statements 2026-06-22 23:09:23 +01:00
Owen Mansel-Chan
13bf978f64 Go CFG: run deferred calls at function exit in LIFO order
Model `defer`ed calls so the call runs at function exit rather than inline
at the `defer` statement, reproducing the previous control-flow semantics:

- Add a per-defer "defer-invoke" node for the deferred call.
- deferExitStep wires normal-exit predecessors (return nodes and body
  fall-through) through the active deferred-call invocations in
  last-in-first-out order, then on to the normal exit target (the
  result-read epilogue for named results, or the normal exit node).
- The chain is reachability-gated using the defer-free successor relation
  (succIgnoringDeferExit / isInOrderNode), so only deferred calls that were
  actually registered on a path are run on that path.
- overridesCallableBodyExit / overridesCallableEndAbruptCompletion suppress
  the default body-exit and return routing for functions containing
  `defer`, so the epilogue is interposed instead.
2026-06-22 23:09:21 +01:00
Owen Mansel-Chan
449732a5fe Shared CFG: add hooks for reachability-gated exit epilogue
Add opt-in InputSig2 predicates to support a function-exit epilogue whose
placement depends on reachability (such as Go's deferred calls, run at
exit in last-in-first-out order):

- deferExitStep: language-provided exit-epilogue edges, wired into
  explicitStep but excluded from the defer-free reachability.
- overridesCallableBodyExit: suppresses the default fall-through edge from
  a body's "after" node to the normal exit, so the epilogue can be
  interposed on fall-through paths.

To let a language compute the reachability gate for those edges without
observing them (and without a non-monotonic cycle through reachable):

- explicitStep is split into explicitStepCommon (defer-free) plus
  deferExitStep, and defaultCfg now negates explicitStepCommon so default
  evaluation does not depend on deferExitStep.
- succIgnoringDeferExit exposes the defer-free successor relation, typed
  over PreControlFlowNode so it does not depend on reachable.
- getASuccessorIgnoringDeferredExit exposes the same relation as a
  ControlFlowNode member for general use.
- isInOrderNode exposes a structural, reachability-free node-identity test
  for use inside the negations a language needs when computing its gate.
- EntryNodeImpl is no longer private, so a language can identify the entry
  node over PreControlFlowNode.

All InputSig2 additions default to none(), leaving other languages
unchanged.
2026-06-22 23:09:19 +01:00
Owen Mansel-Chan
f5eef7d3d7 Go CFG: anchor result-read epilogue on Normal Exit via new hooks 2026-06-22 23:09:17 +01:00
Owen Mansel-Chan
28afda1726 Shared CFG: add callableExitStep hook for routing epilogue tails to exit nodes 2026-06-22 23:09:15 +01:00
Owen Mansel-Chan
db8b2cff07 Allow overriding endAbruptCompletion for callables 2026-06-22 23:09:13 +01:00
Owen Mansel-Chan
3cd6a279d0 Include implicit type switch var in CFG 2026-06-22 23:09:11 +01:00
Owen Mansel-Chan
0f6bccf208 accept test changes 2026-06-22 23:09:10 +01:00
Owen Mansel-Chan
7039942a66 Fix CFG for expressionless switch statements 2026-06-22 23:09:08 +01:00
Owen Mansel-Chan
2453482003 Accept changes 2026-06-22 23:09:06 +01:00
Owen Mansel-Chan
de96f6ceac Fix ConditionGuardNode 2026-06-22 23:09:04 +01:00
Owen Mansel-Chan
c37f235031 Accept test output change names 2026-06-22 23:09:02 +01:00
Owen Mansel-Chan
8908dc4a6e Restore ConditionGuardNode 2026-06-22 23:09:00 +01:00
Owen Mansel-Chan
53a6afa218 Fix treatment of ParenExpr 2026-06-22 23:08:58 +01:00
Owen Mansel-Chan
0dfa9d72b1 Add Go CFG consistency query 2026-06-22 23:08:56 +01:00
Owen Mansel-Chan
6997936a83 Go: update expected node names 2026-06-22 23:08:54 +01:00
Owen Mansel-Chan
8debf965ac Use shared CFG getIfInit 2026-06-22 23:08:52 +01:00
Owen Mansel-Chan
8099b255af Fix lit-init nodes
There was a loop in the definitions which meant nothing ever got made
2026-06-22 23:08:51 +01:00
Owen Mansel-Chan
68a4131523 Fix range loop CFG 2026-06-22 23:08:49 +01:00
Owen Mansel-Chan
b56342533e update function-entry additional nodes 2026-06-22 23:08:47 +01:00
Owen Mansel-Chan
134cc48c75 Restore ExprNode for FuncLit 2026-06-22 23:08:45 +01:00
Owen Mansel-Chan
016c53ccbd Accept change in test output
To determine that test9 can't return normally, you have to use the fact
that test5 can't return normally. This would make CFG construction
recursive, which would be bad for performance. Therefore we accept the
limitation that we cannot detect that test9 can't return normally, and
we change the test output.
2026-06-22 23:08:43 +01:00
Owen Mansel-Chan
9b63398874 Fix empty switch statements 2026-06-22 23:08:41 +01:00
Owen Mansel-Chan
0244d809d1 Control flow shouldn't enter another callable 2026-06-22 23:08:39 +01:00
Owen Mansel-Chan
d582d68afd Fix CFG for return instructions 2026-06-22 23:08:37 +01:00
Owen Mansel-Chan
9b35117475 Produce CFG nodes for more reference expressions, like selector bases 2026-06-22 23:08:35 +01:00
Owen Mansel-Chan
642e567e48 Fix global value numbering calculation 2026-06-22 23:08:33 +01:00
Owen Mansel-Chan
8a62e874ca Include receivers in parameter init 2026-06-22 23:08:31 +01:00
Owen Mansel-Chan
13d4eb6933 Fix CFG for range loop 2026-06-22 23:08:29 +01:00
Owen Mansel-Chan
22ca59d190 Fix CFG for select statements 2026-06-22 23:08:27 +01:00
Owen Mansel-Chan
32a6187434 Use shared CFG implementation of for loops 2026-06-22 23:08:26 +01:00
Owen Mansel-Chan
f9953630a7 Do not include comments in the CFG 2026-06-22 23:08:24 +01:00
Owen Mansel-Chan
0deb94ac2d Fix edges to function exit with result variables 2026-06-22 23:08:22 +01:00
Owen Mansel-Chan
f8c2f2cbd9 Tweak getEnclosingCallable 2026-06-22 23:08:20 +01:00
Owen Mansel-Chan
984a880089 Model non-returning functions in CFG 2026-06-22 23:08:18 +01:00
Owen Mansel-Chan
1c62580835 Create cfg node for child of ParenExpr 2026-06-22 23:08:16 +01:00
Owen Mansel-Chan
99330a65a7 Add go/print-cfg 2026-06-22 23:08:14 +01:00
Owen Mansel-Chan
fc055a8699 Initial shared CFG library instantiation for Go 2026-06-22 23:08:12 +01:00
Owen Mansel-Chan
65513b8cd2 Incidental fix to CaseClause.getAnExpr() 2026-06-22 23:08:09 +01:00
139 changed files with 11820 additions and 13217 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
import go
private import semmle.go.controlflow.ControlFlowGraphShared
import GoCfg::ControlFlow::Consistency

View File

@@ -0,0 +1,4 @@
---
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.

53
go/ql/lib/printCfg.ql Normal file
View File

@@ -0,0 +1,53 @@
/**
* @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>

View File

@@ -431,7 +431,7 @@ private class HeuristicLoggerFunction extends Method {
)
}
override predicate mayReturnNormally() { logFunctionPrefix != "Fatal" }
override predicate mustNotReturnNormally() { logFunctionPrefix = "Fatal" }
override predicate mustPanic() { logFunctionPrefix = "Panic" }
}

View File

@@ -1,7 +1,7 @@
/**
* Provides queries to pretty-print a Go AST as a graph.
*/
overlay[local]
overlay[local?]
module;
import go

View File

@@ -437,11 +437,12 @@ class Function extends ValueEntity, @functionobject {
* 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.
*
* Note this is declared here and not in `DeclaredFunction` so that library models can override this
* by extending `Function` rather than having to remember to extend `DeclaredFunction`.
* Library models should not override this predicate; override `mustNotReturnNormally`
* instead, so that the control-flow graph construction can take the model into account.
*/
predicate mayReturnNormally() {
not this.mustPanic() and
not this.mustNotReturnNormally() and
(ControlFlow::mayReturnNormally(this.getFuncDecl()) or not exists(this.getBody()))
}
@@ -461,6 +462,16 @@ class Function extends ValueEntity, @functionobject {
*/
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. */
int getNumParameter() { result = this.getType().(SignatureType).getNumParameter() }

View File

@@ -761,7 +761,7 @@ class CaseClause extends @caseclause, Stmt, ScopeNode {
*
* Note that the default clause does not have any expressions.
*/
Expr getAnExpr() { result = this.getAChildExpr() }
Expr getAnExpr() { result = this.getExpr(_) }
/**
* Gets the number of expressions of this `case` clause.

View File

@@ -5,66 +5,27 @@ overlay[local]
module;
import go
private import ControlFlowGraphImpl
private import codeql.controlflow.BasicBlock as BB
private import codeql.controlflow.SuccessorType
private import ControlFlowGraphShared
private module Input implements BB::InputSig<Location> {
/** A delineated part of the AST with its own CFG. */
class CfgScope = ControlFlow::Root;
/** A basic block in the control-flow graph. */
class BasicBlock = GoCfg::Cfg::BasicBlock;
/** The class of control flow nodes. */
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))
}
/** An entry basic block. */
class EntryBasicBlock = GoCfg::Cfg::EntryBasicBlock;
/**
* 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 {
ReachableBasicBlock() { reachableBB(this) }
ReachableBasicBlock() { any() }
}
/**
* A reachable basic block with more than one predecessor.
*/
class ReachableJoinBlock extends ReachableBasicBlock {
ReachableJoinBlock() { this.getFirstNode().isJoin() }
ReachableJoinBlock() { this.getFirstNode().(ControlFlow::Node).isJoin() }
}

View File

@@ -5,13 +5,17 @@ overlay[local]
module;
import go
private import ControlFlowGraphImpl
private import ControlFlowGraphShared
/** Provides helper predicates for mapping btween CFG nodes and the AST. */
/** Provides helper predicates for mapping between CFG nodes and the AST. */
module ControlFlow {
/** A file or function with which a CFG is associated. */
class Root extends AstNode {
Root() { exists(this.(File).getADecl()) or exists(this.(FuncDef).getBody()) }
Root() {
exists(this.(FuncDef).getBody())
or
exists(this.(File).getADecl())
}
/** Holds if `nd` belongs to this file or function. */
predicate isRootOf(AstNode nd) {
@@ -29,22 +33,16 @@ module ControlFlow {
}
/**
* A node in the intra-procedural control-flow graph of a Go function or file.
* A node in the intra-procedural control-flow graph of a Go function.
*
* Nodes correspond to expressions and statements that compute a value or perform
* an operation (as opposed to providing syntactic structure or type information).
*
* There are also synthetic entry and exit nodes for each Go function and file
* There are also synthetic entry and exit nodes for each Go function
* that mark the beginning and the end, respectively, of the execution of the
* function and the loading of the file.
* function.
*/
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() }
class Node extends GoCfg::ControlFlowNode {
/** Holds if this is a node with more than one successor. */
predicate isBranch() { strictcount(this.getASuccessor()) > 1 }
@@ -52,22 +50,23 @@ module ControlFlow {
predicate isJoin() { strictcount(this.getAPredecessor()) > 1 }
/** Holds if this is the first control-flow node in `subtree`. */
predicate isFirstNodeOf(AstNode subtree) { CFG::firstNode(subtree, this) }
predicate isFirstNodeOf(AstNode subtree) {
this.isBefore(subtree)
or
this.injects(subtree)
}
/** Holds if this node is the (unique) entry node of a function or file. */
predicate isEntryNode() { this instanceof MkEntryNode }
/** Holds if this node is the (unique) entry node of a function. */
predicate isEntryNode() { this instanceof GoCfg::ControlFlow::EntryNode }
/** Holds if this node is the (unique) exit node of a function or file. */
predicate isExitNode() { this instanceof MkExitNode }
/** Gets the basic block to which this node belongs. */
BasicBlock getBasicBlock() { result.getANode() = this }
/** Holds if this node is the (unique) exit node of a function. */
predicate isExitNode() { this instanceof GoCfg::ControlFlow::ExitNode }
/** Holds if this node dominates `dominee` in the control-flow graph. */
overlay[caller?]
pragma[inline]
predicate dominatesNode(ControlFlow::Node dominee) {
exists(ReachableBasicBlock thisbb, ReachableBasicBlock dbb, int i, int j |
exists(GoCfg::Cfg::BasicBlock thisbb, GoCfg::Cfg::BasicBlock dbb, int i, int j |
this = thisbb.getNode(i) and dominee = dbb.getNode(j)
|
thisbb.strictlyDominates(dbb)
@@ -76,20 +75,12 @@ module ControlFlow {
)
}
/** Gets the innermost function or file to which this node belongs. */
Root getRoot() { none() }
/** Gets the innermost function to which this node belongs. */
Root getRoot() { result = this.getEnclosingCallable() }
/** Gets the file to which this node belongs. */
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.
*
@@ -113,6 +104,22 @@ 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 field, or an (array, slice, or map) element.
@@ -172,7 +179,7 @@ module ControlFlow {
exists(IR::FieldTarget trg | trg = super.getLhs() |
(
trg.getBase() = base or
trg.getBase() = MkImplicitDeref(base.(IR::EvalInstruction).getExpr())
trg.getBase() = IR::implicitDerefInstruction(base.(IR::EvalInstruction).getExpr())
) and
trg.getField() = f and
super.getRhs() = rhs
@@ -220,7 +227,7 @@ module ControlFlow {
exists(IR::ElementTarget trg | trg = super.getLhs() |
(
trg.getBase() = base or
trg.getBase() = MkImplicitDeref(base.(IR::EvalInstruction).getExpr())
trg.getBase() = IR::implicitDerefInstruction(base.(IR::EvalInstruction).getExpr())
) and
trg.getIndex() = index and
super.getRhs() = rhs
@@ -250,11 +257,19 @@ module ControlFlow {
* A control-flow node recording the fact that a certain expression has a known
* Boolean value at this point in the program.
*/
class ConditionGuardNode extends IR::Instruction, MkConditionGuardNode {
class ConditionGuardNode extends IR::Instruction {
Expr cond;
boolean outcome;
ConditionGuardNode() { this = MkConditionGuardNode(cond, outcome) }
ConditionGuardNode() {
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) {
expr = cond and b = outcome
@@ -320,21 +335,17 @@ module ControlFlow {
boolean getOutcome() { result = outcome }
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 or file `root`.
* Gets the entry node of function `root`.
*/
Node entryNode(Root root) { result = MkEntryNode(root) }
EntryNode entryNode(Root root) { result.getEnclosingCallable() = root }
/**
* Gets the exit node of function or file `root`.
* Gets the exit node of function `root`.
*/
Node exitNode(Root root) { result = MkExitNode(root) }
ExitNode exitNode(Root root) { result.getEnclosingCallable() = root }
/**
* Holds if the function `f` may return without panicking, exiting the process, or looping forever.
@@ -342,7 +353,12 @@ module ControlFlow {
* 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.
*/
predicate mayReturnNormally(FuncDecl f) { CFG::mayReturnNormally(f.getBody()) }
predicate mayReturnNormally(FuncDecl f) {
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
@@ -352,10 +368,18 @@ module ControlFlow {
predicate isSwitchCaseTestPassingEdge(
ControlFlow::Node pred, ControlFlow::Node succ, Expr switchExpr, Expr testExpr
) {
CFG::isSwitchCaseTestPassingEdge(pred, succ, switchExpr, testExpr)
exists(ExpressionSwitchStmt ess, CaseClause cc, int i |
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 CfgScope = GoCfg::CfgScope;
class Write = ControlFlow::WriteNode;

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

View File

@@ -200,7 +200,7 @@ private ControlFlow::Node mostRecentSideEffect(ControlFlow::Node entry, ControlF
cached
private ControlFlow::Node mostRecentSideEffectUnique(ControlFlow::Node node) {
result = unique( | | mostRecentSideEffect(_, node))
result = unique( | | mostRecentSideEffect(getControlFlowEntry(node), node))
}
/** Used to represent the "global value number" of an expression. */

View File

@@ -9,6 +9,7 @@ module;
import go
private import codeql.ssa.Ssa as SsaImplCommon
private import semmle.go.controlflow.BasicBlocks as BasicBlocks
private import semmle.go.controlflow.ControlFlowGraphShared
private class BasicBlock = BasicBlocks::BasicBlock;
@@ -38,7 +39,7 @@ private module Internal {
/** Holds if the `i`th node of `bb` in function `f` is an entry node. */
private predicate entryNode(FuncDef f, BasicBlock bb, int i) {
f = bb.getScope() and
bb.getNode(i).isEntryNode()
bb.getNode(i).(ControlFlow::Node).isEntryNode()
}
/**
@@ -110,7 +111,7 @@ private module Internal {
v.isCaptured() and
exists(FuncDef f |
f = bb.getScope() and
bb.getLastNode().isExitNode() and
bb.getLastNode().(ControlFlow::Node).isExitNode() and
i = bb.length() - 1 and
certain = false
|
@@ -126,7 +127,7 @@ private module Internal {
}
import Internal
import SsaImplCommon::Make<Location, BasicBlocks::Cfg, SsaInput> as Impl
import SsaImplCommon::Make<Location, GoCfg::Cfg, SsaInput> as Impl
final class Definition = Impl::Definition;

View File

@@ -59,7 +59,7 @@ module Glog {
/** Holds if this function takes a format string. */
predicate formatter() { format = "f" }
override predicate mayReturnNormally() { level != "Fatal" and level != "Exit" }
override predicate mustNotReturnNormally() { level = "Fatal" or level = "Exit" }
}
private class StringFormatter extends StringOps::Formatting::Range instanceof GlogFunction {

View File

@@ -29,8 +29,8 @@ module Logrus {
)
}
override predicate mayReturnNormally() {
not exists(string level, string suffix | level = ["Fatal", "Panic"] |
override predicate mustNotReturnNormally() {
exists(string level, string suffix | level = ["Fatal", "Panic"] |
this.getName() = level + suffix
)
}

View File

@@ -154,7 +154,7 @@ module Revel {
private IR::EvalInstruction skipImplicitFieldReads(IR::Instruction insn) {
result = insn or
result = skipImplicitFieldReads(insn.(IR::ImplicitFieldReadInstruction).getBase())
result = skipImplicitFieldReads(insn.(IR::ImplicitFieldReadInstruction).getBaseInstruction())
}
/** A call to `Controller.Render`. */

View File

@@ -54,7 +54,7 @@ module Zap {
this.hasQualifiedName(packagePath(), "SugaredLogger", "Fatal" + getSuffix())
}
override predicate mayReturnNormally() { none() }
override predicate mustNotReturnNormally() { any() }
}
/** A Zap logging function which always panics. */

View File

@@ -44,7 +44,7 @@ module Log {
)
}
override predicate mayReturnNormally() { none() }
override predicate mustNotReturnNormally() { any() }
}
/** A log function which must panic. */

View File

@@ -12,7 +12,7 @@ module Os {
private class Exit extends Function {
Exit() { this.hasQualifiedName("os", "Exit") }
override predicate mayReturnNormally() { none() }
override predicate mustNotReturnNormally() { any() }
}
// These models are not implemented using Models-as-Data because they represent reverse flow.

View File

@@ -14,11 +14,36 @@
import go
ControlFlow::Node nonGuardPredecessor(ControlFlow::Node nd) {
exists(ControlFlow::Node pred | pred = nd.getAPredecessor() |
if pred instanceof ControlFlow::ConditionGuardNode
then result = nonGuardPredecessor(pred)
else result = pred
/**
* Holds if `s` is reachable, that is, the control-flow graph contains a node for it.
*
* The shared control-flow library does not create control-flow nodes for dead code, so an
* unreachable statement has no first control-flow node.
*/
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()))
)
}
@@ -63,18 +88,13 @@ predicate allowlist(Stmt s) {
forall(Expr retval | retval = ret.getAnExpr() | isAllowedReturnValue(retval))
)
or
// statements in an `if false { ... }` and similar
exists(IfStmt is, ControlFlow::ConditionGuardNode iffalse, Expr cond, boolean b |
iffalse.getCondition() = is.getCond() and
iffalse = s.getFirstControlFlowNode().getAPredecessor() and
cond.getBoolValue() = b and
iffalse.ensures(DataFlow::exprNode(cond), b.booleanNot())
)
// statements deliberately made unreachable by a constant condition, such as the code
// following `if true { return }`
exists(getPreviousStmt(s).(IfStmt).getCond().getBoolValue())
}
from Stmt s, ControlFlow::Node fst
from Stmt s
where
fst = s.getFirstControlFlowNode() and
not exists(nonGuardPredecessor(fst)) and
firstUnreachableStmt(s) and
not allowlist(s)
select s, "This statement is unreachable."

View File

@@ -1 +1 @@
| main.go:23:3:23:13 | assignment to field Status | main.go:23:17:23:21 | "200" |
| main.go:23:3:23:21 | assign:0 ... = ... | main.go:23:17:23:21 | "200" |

View File

@@ -2,7 +2,7 @@
| 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 WriteProxy |
| main.go:18:12:18:14 | SSA def(req) |
| main.go:18:12:18:14 | argument corresponding to req |
| main.go:18:103:26:1 | SSA def(req) |
| main.go:18:103:26:1 | arg:0 block statement |
| main.go:20:5:20:7 | req |
| main.go:20:5:20:7 | req [postupdate] |

View File

@@ -1 +1 @@
| main.go:29:2:29:4 | assignment to err | main.go:29:9:29:31 | call to test1 |
| main.go:29:2:29:31 | assign:0 ... := ... | main.go:29:9:29:31 | call to test1 |

View File

@@ -1 +1 @@
| main.go:10:2:12:3 | ... := ...[0] | This Pam transaction may not be secure. |
| main.go:10:2:12:3 | extract:0 ... := ... | This Pam transaction may not be secure. |

View File

@@ -8,23 +8,23 @@
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:24 | call to Query | DivideByZero.go:11:27:11:32 | param1 | 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 | ... := ...[0] | provenance | Config |
| DivideByZero.go:11:2:11:33 | extract: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: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: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:24 | call to Query | DivideByZero.go:25:31:25:36 | param1 | 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 | ... := ...[0] | provenance | Config |
| DivideByZero.go:25:2:25:45 | extract: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: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: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 | ... := ...[0] | provenance | Config |
| DivideByZero.go:32:2:32:43 | extract: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: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: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 | ... := ...[0] | provenance | Config |
| DivideByZero.go:39:2:39:46 | extract: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: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:55:11:55:24 | type conversion | DivideByZero.go:57:17:57:21 | value | provenance | |
@@ -34,7 +34,7 @@ models
nodes
| 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:11:2:11:33 | ... := ...[0] | semmle.label | ... := ...[0] |
| DivideByZero.go:11:2:11:33 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| DivideByZero.go:11:27:11:32 | param1 | semmle.label | param1 |
| DivideByZero.go:12:16:12:20 | value | semmle.label | value |
| 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: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:25:2:25:45 | ... := ...[0] | semmle.label | ... := ...[0] |
| DivideByZero.go:25:2:25:45 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| DivideByZero.go:25:31:25:36 | param1 | semmle.label | param1 |
| 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:24 | call to Query | semmle.label | call to Query |
| DivideByZero.go:32:2:32:43 | ... := ...[0] | semmle.label | ... := ...[0] |
| DivideByZero.go:32:2:32:43 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| DivideByZero.go:32:33:32:38 | param1 | semmle.label | param1 |
| 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:24 | call to Query | semmle.label | call to Query |
| DivideByZero.go:39:2:39:46 | ... := ...[0] | semmle.label | ... := ...[0] |
| DivideByZero.go:39:2:39:46 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| DivideByZero.go:39:32:39:37 | param1 | semmle.label | param1 |
| DivideByZero.go:40:16:40:20 | value | semmle.label | value |
| DivideByZero.go:54:12:54:16 | selection of URL | semmle.label | selection of URL |

View File

@@ -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 | 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 | implicit dereference [postupdate] | Dsn.go:63:9:63:11 | cfg [postupdate] [pointer] | provenance | |
| Dsn.go:63:9:63:11 | implicit dereference [postupdate] | Dsn.go:67:102:67:108 | selection of dsn | 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-deref cfg [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:29 | slice expression | Dsn.go:63:9:63:11 | implicit dereference [postupdate] | provenance | FunctionModel |
| Dsn.go:63:19:63:29 | slice expression | Dsn.go:63:9:63:11 | implicit-deref cfg [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 | 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 dereference | provenance | |
| Dsn.go:67:102:67:104 | implicit dereference | Dsn.go:67:102:67:108 | selection of dsn | 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 | implicit-deref cfg | 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 | call to Sprintf | provenance | FunctionModel |
models
@@ -28,13 +28,13 @@ nodes
| Dsn.go:28:102:28:109 | index expression | semmle.label | index expression |
| 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 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
| Dsn.go:63:9:63:11 | implicit-deref cfg [postupdate] | semmle.label | implicit-deref cfg [postupdate] |
| 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: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:102:67:104 | cfg [pointer] | semmle.label | cfg [pointer] |
| Dsn.go:67:102:67:104 | implicit dereference | semmle.label | implicit dereference |
| Dsn.go:67:102:67:104 | implicit-deref cfg | semmle.label | implicit-deref cfg |
| Dsn.go:67:102:67:108 | selection of dsn | semmle.label | selection of dsn |
| Dsn.go:68:29:68:33 | dbDSN | semmle.label | dbDSN |
subpaths

View File

@@ -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: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:154:2:154:4 | implicit dereference [postupdate] | builtin.go:154:2:154:4 | url [postupdate] | provenance | |
| 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 | url [postupdate] | builtin.go:156:21:156:23 | url | provenance | |
| 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 | implicit-deref 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 |
| 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: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: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 | ... := ...[0] | provenance | Src:MaD:6 MaD:13 |
| new-tests.go:62:2:62:39 | extract: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: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: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:133:38:133:51 | untrustedInput | semmle.label | untrustedInput |
| builtin.go:151:16:151:36 | call to FormValue | semmle.label | call to FormValue |
| builtin.go:154:2:154:4 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
| builtin.go:154:2:154:4 | implicit-deref url [postupdate] | semmle.label | implicit-deref 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: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:49:18:49:30 | call to Query | semmle.label | call to Query |
| new-tests.go:50:11:50:46 | ...+... | semmle.label | ...+... |
| new-tests.go:62:2:62:39 | ... := ...[0] | semmle.label | ... := ...[0] |
| new-tests.go:62:2:62:39 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| 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:26:63:30 | &... [postupdate] | semmle.label | &... [postupdate] |

View File

@@ -22,8 +22,8 @@ edges
| 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: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:21:236:23 | SSA def(req) | provenance | |
| WrongUsageOfUnsafe.go:236:21:236:23 | SSA def(req) | WrongUsageOfUnsafe.go:243:9:243:27 | type conversion | provenance | |
| WrongUsageOfUnsafe.go:227:31:227:55 | type conversion | WrongUsageOfUnsafe.go:236:53:245:1 | SSA def(req) | provenance | |
| WrongUsageOfUnsafe.go:236:53:245:1 | 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: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 | |
@@ -51,7 +51,7 @@ nodes
| 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:227:31:227:55 | type conversion | semmle.label | type conversion |
| WrongUsageOfUnsafe.go:236:21:236:23 | SSA def(req) | semmle.label | SSA def(req) |
| WrongUsageOfUnsafe.go:236:53:245:1 | SSA def(req) | semmle.label | SSA def(req) |
| 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:28:256:52 | type conversion | semmle.label | type conversion |

View File

@@ -1,64 +1,156 @@
nodes
edges
| conversions.go:0:0:0:0 | entry | conversions.go:3:1:3:15 | skip |
| conversions.go:3:1:3:15 | skip | conversions.go:5:6:5:8 | skip |
| conversions.go:5:1:5:29 | entry | conversions.go:5:10:5:10 | argument corresponding to _ |
| conversions.go:5:1:5:29 | function declaration | conversions.go:7:6:7:9 | skip |
| conversions.go:5:6:5:8 | skip | conversions.go:5:1:5:29 | function declaration |
| conversions.go:5:10:5:10 | argument corresponding to _ | conversions.go:5:10:5:10 | initialization of _ |
| conversions.go:5:10:5:10 | initialization of _ | conversions.go:5:28:5:29 | skip |
| conversions.go:5:28:5:29 | skip | conversions.go:5:1:5:29 | exit |
| conversions.go:7:1:26:1 | entry | conversions.go:8:6:8:6 | skip |
| conversions.go:7:1:26:1 | function declaration | conversions.go:0:0:0:0 | exit |
| conversions.go:7:6:7:9 | skip | conversions.go:7:1:26:1 | function declaration |
| conversions.go:8:6:8:6 | assignment to a | conversions.go:10:2:10:2 | skip |
| conversions.go:8:6:8:6 | skip | conversions.go:8:6:8:6 | zero value for a |
| conversions.go:8:6:8:6 | zero value for a | conversions.go:8:6:8:6 | assignment to a |
| conversions.go:10:2:10:2 | assignment to b | conversions.go:11:2:11:4 | use |
| conversions.go:10:2:10:2 | skip | conversions.go:10:7:10:16 | selection of Add |
| conversions.go:10:7:10:16 | selection of Add | conversions.go:10:18:10:18 | a |
| conversions.go:10:7:10:23 | call to Add | conversions.go:10:2:10:2 | assignment to b |
| conversions.go:10:18:10:18 | a | conversions.go:10:21:10:22 | 10 |
| conversions.go:10:21:10:22 | 10 | conversions.go:10:7:10:23 | call to Add |
| conversions.go:11:2:11:4 | use | conversions.go:11:6:11:6 | b |
| conversions.go:11:2:11:7 | call to use | conversions.go:7:1:26:1 | exit |
| conversions.go:11:2:11:7 | call to use | conversions.go:13:6:13:8 | skip |
| conversions.go:11:6:11:6 | b | conversions.go:11:2:11:7 | call to use |
| conversions.go:13:6:13:8 | assignment to arr | conversions.go:14:2:14:6 | skip |
| conversions.go:13:6:13:8 | skip | conversions.go:13:6:13:8 | zero value for arr |
| conversions.go:13:6:13:8 | zero value for arr | conversions.go:13:6:13:8 | assignment to arr |
| conversions.go:14:2:14:6 | assignment to slice | conversions.go:17:2:17:4 | skip |
| conversions.go:14:2:14:6 | skip | conversions.go:14:11:14:22 | selection of Slice |
| conversions.go:14:11:14:22 | selection of Slice | conversions.go:14:24:14:26 | arr |
| conversions.go:14:11:14:31 | call to Slice | conversions.go:14:2:14:6 | assignment to slice |
| conversions.go:14:24:14:26 | arr | conversions.go:14:29:14:30 | 20 |
| conversions.go:14:29:14:30 | 20 | conversions.go:14:11:14:31 | call to Slice |
| conversions.go:17:2:17:4 | assignment to ptr | conversions.go:18:2:18:4 | use |
| conversions.go:17:2:17:4 | skip | conversions.go:17:20:17:24 | slice |
| conversions.go:17:9:17:25 | type conversion | conversions.go:7:1:26:1 | exit |
| conversions.go:17:9:17:25 | type conversion | conversions.go:17:2:17:4 | assignment to ptr |
| conversions.go:17:20:17:24 | slice | conversions.go:17:9:17:25 | type conversion |
| conversions.go:18:2:18:4 | use | conversions.go:18:6:18:8 | ptr |
| conversions.go:18:2:18:9 | call to use | conversions.go:7:1:26:1 | exit |
| conversions.go:18:2:18:9 | call to use | conversions.go:21:2:21:4 | skip |
| conversions.go:18:6:18:8 | ptr | conversions.go:18:2:18:9 | call to use |
| conversions.go:21:2:21:4 | assignment to str | conversions.go:22:2:22:6 | skip |
| conversions.go:21:2:21:4 | skip | conversions.go:21:9:21:18 | "a string" |
| conversions.go:21:9:21:18 | "a string" | conversions.go:21:2:21:4 | assignment to str |
| conversions.go:22:2:22:6 | assignment to bytes | conversions.go:23:2:23:4 | use |
| conversions.go:22:2:22:6 | skip | conversions.go:22:18:22:20 | str |
| conversions.go:22:11:22:21 | type conversion | conversions.go:22:2:22:6 | assignment to bytes |
| conversions.go:22:18:22:20 | str | conversions.go:22:11:22:21 | type conversion |
| conversions.go:23:2:23:4 | use | conversions.go:23:6:23:10 | bytes |
| conversions.go:23:2:23:11 | call to use | conversions.go:7:1:26:1 | exit |
| conversions.go:23:2:23:11 | call to use | conversions.go:24:2:24:6 | skip |
| conversions.go:23:6:23:10 | bytes | conversions.go:23:2:23:11 | call to use |
| conversions.go:24:2:24:6 | assignment to runes | conversions.go:25:2:25:4 | use |
| conversions.go:24:2:24:6 | skip | conversions.go:24:18:24:20 | str |
| conversions.go:24:11:24:21 | type conversion | conversions.go:24:2:24:6 | assignment to runes |
| conversions.go:24:18:24:20 | str | conversions.go:24:11:24:21 | type conversion |
| conversions.go:25:2:25:4 | use | conversions.go:25:6:25:10 | runes |
| conversions.go:25:2:25:11 | call to use | conversions.go:7:1:26:1 | exit |
| conversions.go:25:6:25:10 | runes | conversions.go:25:2:25:11 | call to use |
| 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:0:0:0:0 | conversions.go |
| conversions.go:0:0:0:0 | Normal Exit | conversions.go:0:0:0:0 | Exit |
| conversions.go:0:0:0:0 | conversions.go | conversions.go:3:1:3:15 | import declaration |
| conversions.go:3:1:3:15 | After import declaration | conversions.go:5:1:5:29 | Before function declaration |
| conversions.go:3:1:3:15 | import declaration | conversions.go:3:8:3:15 | import specifier |
| conversions.go:3:8:3:15 | import specifier | conversions.go:3:1:3:15 | After import declaration |
| conversions.go:5:1:5:29 | After function declaration | conversions.go:7:1:26:1 | Before function declaration |
| conversions.go:5:1:5:29 | Before function declaration | conversions.go:5:1:5:29 | function declaration |
| conversions.go:5:1:5:29 | Entry | conversions.go:5:28:5:29 | block statement |
| conversions.go:5:1:5:29 | Normal Exit | conversions.go:5:1:5:29 | Exit |
| conversions.go:5:1:5:29 | function declaration | conversions.go:5:1:5:29 | After function declaration |
| conversions.go:5:28:5:29 | After block statement | conversions.go:5:1:5:29 | Normal Exit |
| conversions.go:5:28:5:29 | arg:0 block statement | conversions.go:5:28:5:29 | param-init:0 block statement |
| conversions.go:5:28:5:29 | block statement | conversions.go:5:28:5:29 | arg:0 block statement |
| conversions.go:5:28:5:29 | param-init:0 block statement | conversions.go:5:28:5:29 | After block statement |
| conversions.go:7:1:26:1 | After function declaration | conversions.go:0:0:0:0 | After conversions.go |
| conversions.go:7:1:26:1 | Before function declaration | conversions.go:7:1:26:1 | function declaration |
| conversions.go:7:1:26:1 | Entry | conversions.go:7:13:26:1 | block statement |
| conversions.go:7:1:26:1 | Exceptional Exit | conversions.go:7:1:26:1 | Exit |
| conversions.go:7:1:26:1 | Normal Exit | conversions.go:7:1:26:1 | Exit |
| conversions.go:7:1:26:1 | function declaration | conversions.go:7:1:26:1 | After function declaration |
| conversions.go:7:13:26:1 | After block statement | conversions.go:7:1:26:1 | Normal Exit |
| conversions.go:7:13:26:1 | block statement | conversions.go:8:2:8:21 | declaration statement |
| conversions.go:8:2:8:21 | After declaration statement | conversions.go:10:2:10:23 | ... := ... |
| conversions.go:8:2:8:21 | After variable declaration | conversions.go:8:2:8:21 | After declaration statement |
| conversions.go:8:2:8:21 | declaration statement | conversions.go:8:2:8:21 | variable declaration |
| conversions.go:8:2:8:21 | variable declaration | conversions.go:8:6:8:21 | value declaration specifier |
| conversions.go:8:6:8:21 | After value declaration specifier | conversions.go:8:2:8:21 | After variable declaration |
| conversions.go:8:6:8:21 | assign:0 value declaration specifier | conversions.go:8:6:8:21 | After value declaration specifier |
| conversions.go:8:6:8:21 | value declaration specifier | conversions.go:8:6:8:21 | zero-init:0 value declaration specifier |
| 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:10:2:10:23 | ... := ... | conversions.go:10:7:10:23 | Before call to Add |
| conversions.go:10:2:10:23 | After ... := ... | conversions.go:11:2:11:7 | expression statement |
| conversions.go:10:2:10:23 | assign:0 ... := ... | conversions.go:10:2:10:23 | After ... := ... |
| conversions.go:10:7:10:16 | After selection of Add | conversions.go:10:18:10:18 | Before a |
| conversions.go:10:7:10:16 | Before selection of Add | conversions.go:10:7:10:16 | selection of Add |
| conversions.go:10:7:10:16 | selection of Add | conversions.go:10:7:10:16 | After selection of Add |
| conversions.go:10:7:10:23 | After call to Add | conversions.go:10:2:10:23 | assign:0 ... := ... |
| conversions.go:10:7:10:23 | Before call to Add | conversions.go:10:7:10:16 | Before selection of Add |
| conversions.go:10:7:10:23 | call to Add | conversions.go:10:7:10:23 | After call to Add |
| conversions.go:10:18:10:18 | After a | conversions.go:10:21:10:22 | Before 10 |
| conversions.go:10:18:10:18 | Before a | conversions.go:10:18:10:18 | a |
| conversions.go:10:18:10:18 | a | conversions.go:10:18:10:18 | After a |
| conversions.go:10:21:10:22 | 10 | conversions.go:10:21:10:22 | After 10 |
| conversions.go:10:21:10:22 | After 10 | conversions.go:10:7:10:23 | call to Add |
| conversions.go:10:21:10:22 | Before 10 | conversions.go:10:21:10:22 | 10 |
| conversions.go:11:2:11:4 | After use | conversions.go:11:6:11:6 | Before b |
| conversions.go:11:2:11:4 | Before use | conversions.go:11:2:11:4 | use |
| conversions.go:11:2:11:4 | use | conversions.go:11:2:11:4 | After use |
| conversions.go:11:2:11:7 | After call to use | conversions.go:11:2:11:7 | After expression statement |
| conversions.go:11:2:11:7 | After expression statement | conversions.go:13:2:13:13 | declaration statement |
| conversions.go:11:2:11:7 | Before call to use | conversions.go:11:2:11:4 | Before use |
| conversions.go:11:2:11:7 | call to use | conversions.go:7:1:26:1 | Exceptional Exit |
| conversions.go:11:2:11:7 | call to use | conversions.go:11:2:11:7 | After call to use |
| conversions.go:11:2:11:7 | expression statement | conversions.go:11:2:11:7 | Before call to use |
| conversions.go:11:6:11:6 | After b | conversions.go:11:2:11:7 | call to use |
| conversions.go:11:6:11:6 | Before b | conversions.go:11:6:11:6 | b |
| conversions.go:11:6:11:6 | b | conversions.go:11:6:11:6 | After b |
| conversions.go:13:2:13:13 | After declaration statement | conversions.go:14:2:14:31 | ... := ... |
| 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
| |

View File

@@ -1,10 +1,6 @@
| 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 | ... := ...[1] | test.go:9:13:9:16 | <-... | 1 | file://:0:0:0:0 | bool |
| 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 | ... := ...[1] | test.go:15:13:15:20 | index expression | 1 | file://:0:0:0:0 | bool |
| 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 | ... := ...[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 |
| 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 | extract: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 | extract: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 | extract:1 ... := ... | test.go:21:13:21:22 | type assertion | 1 | file://:0:0:0:0 | bool |

View File

@@ -1,6 +1,6 @@
| 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:7:13:10 | initialization of recv |
| 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:26:17:26 | initialization of y |
| 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:22:33:22 | initialization of a |
| main.go:13:7:13:10 | recv | main.go:13:27:15:1 | param-init:-1 block statement |
| main.go:17:10:17:10 | x | main.go:17:32:21:1 | param-init:0 block statement |
| main.go:17:26:17:26 | y | main.go:17:32:21:1 | param-init:1 block statement |
| main.go:23:7:23:10 | recv | main.go:23:23:25:1 | param-init:-1 block statement |
| types.go:33:22:33:22 | a | types.go:33:34:35:1 | param-init:0 block statement |

View File

@@ -19,4 +19,3 @@
| 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: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 |

View File

@@ -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-w-subtypes |
| test.go:41:8:41:16 | call to Src2 | qltest-w-subtypes |
| test.go:42:2:42:21 | ... = ...[0] | qltest |
| test.go:42:2:42:21 | ... = ...[1] | qltest-w-subtypes |
| test.go:43:2:43:22 | ... = ...[1] | qltest-w-subtypes |
| test.go:42:2:42:21 | extract:0 ... = ... | qltest |
| test.go:42:2:42:21 | extract:1 ... = ... | qltest-w-subtypes |
| test.go:43:2:43:22 | extract:1 ... = ... | qltest-w-subtypes |
| test.go:44:11:44:13 | arg [postupdate] | qltest-arg |
| test.go:59:9:59:16 | 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:191:24:191:31 | call to Src1 | qltest |
| test.go:209:10:209:28 | selection of SourceVariable | qltest |
| test.go:216:15:216:17 | SSA def(src) | qltest |
| test.go:216:37:218:1 | SSA def(src) | qltest |

View File

@@ -1,14 +1,14 @@
invalidModelRow
#select
| 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 | ... = ...[1] |
| test.go:18:27:18:29 | arg | test.go:18:2:18:30 | extract:1 ... = ... |
| 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: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: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:64:29:64:31 | src | test.go:64:2:64:32 | ... := ...[1] |
| test.go:64:29:64:31 | src | test.go:64:2:64:32 | extract:1 ... := ... |
| 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:79:13:79:25 | type assertion | test.go:79:12:79:40 | call to StepQualRes |

View File

@@ -1,42 +1,40 @@
| main.go:6:2:6:5 | 1 | main.go:14:7:14:7 | 1 |
| main.go:10:2:10:2 | SSA def(x) | main.go:10:7:10:7 | 0 |
| main.go:6:2:6:5 | implicit-one increment statement | 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:7:10:7 | 0 | 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:6 | zero value for y | 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:10 | zero-init:0 value declaration specifier | 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: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:14:2:14:2 | SSA def(z) | main.go:14:7:14:7 | 1 |
| main.go:14:2:14:7 | 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: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: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:18:2:18:3 | SSA def(ss) | main.go:18:8:18:24 | call to make |
| main.go:18:2:18:24 | 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: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: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:23:14:23:16 | implicit read of 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:23:23:26:1 | result-read:0 block statement | 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:24:8:24:8 | 4 | main.go:24:8:24:8 | 4 |
| main.go:28:15:28:17 | implicit read of res | main.go:30:9:30:9 | 6 |
| main.go:28:15:28:17 | zero value for res | main.go:10:7:10:7 | 0 |
| main.go:28:24:31:1 | result-read:0 block statement | main.go:29:8:29:8 | 5 |
| main.go:29:2:29:8 | SSA def(res) | 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 | 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:2:34:8 | SSA def(res) | 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:36:3:36:5 | SSA def(res) | main.go:36:9:36:9 | 8 |
| main.go:36:3:36:9 | 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: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: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:9:11:9:12 | !... | regressions.go:11:11:11:14 | true |
| regressions.go:9:12:9:12 | d | regressions.go:7:11:7:15 | false |
| 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:26:30:39 | call to getPayload | regressions.go:30:26:30:39 | call to getPayload |

View File

@@ -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: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 | implicit-deref 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 |

View File

@@ -1,4 +1,4 @@
| 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 | 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 | 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 |

View File

@@ -1,3 +1,3 @@
| 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 | 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 | 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 |

View File

@@ -1,3 +1,3 @@
| 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: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: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 |
| 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: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: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 |

View File

@@ -1,3 +1,3 @@
| 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: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: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 | ...+... |
| 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: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: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 | ...+... |

View File

@@ -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: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: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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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: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: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: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: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: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: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: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: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:51:2:51:30 | ... := ...[0] | test.go:52:16:52:37 | index expression | provenance | Src:MaD:5 |
| test.go:57:2:57:46 | ... := ...[0] | test.go:58:13:58:22 | fileHeader | provenance | Src:MaD:4 |
| 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 | ... := ...[0] | provenance | MaD:17 |
| test.go:51:2:51:30 | extract: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:58:2:58:29 | extract: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: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:18 |
| test.go:60:12:60:17 | buffer [postupdate] | test.go:61:20:61:25 | buffer | provenance | |
| 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 | ... := ...[0] | test.go:74:13:74:22 | fileHeader | provenance | Src:MaD:7 |
| 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 | ... := ...[0] | provenance | MaD:17 |
| test.go:66:2:66:31 | extract: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:74:2:74:29 | extract: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: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:18 |
| test.go:76:12:76:17 | buffer [postupdate] | test.go:77:20:77:25 | buffer | provenance | |
| test.go:82:2:82:32 | ... := ...[0] | test.go:83:16:83:24 | selection of Value | provenance | Src:MaD:2 |
| test.go:82:2:82:32 | extract: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: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 | |
@@ -88,23 +88,23 @@ nodes
| 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:46:16:46:18 | val | semmle.label | val |
| test.go:51:2:51:30 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:51:2:51:30 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| test.go:52:16:52:37 | index expression | semmle.label | index expression |
| test.go:57:2:57:46 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:58:2:58:29 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:57:2:57:46 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| test.go:58:2:58:29 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| test.go:58:13:58:22 | fileHeader | semmle.label | fileHeader |
| test.go:60:2:60:5 | file | semmle.label | file |
| test.go:60:12:60:17 | buffer [postupdate] | semmle.label | buffer [postupdate] |
| test.go:61:20:61:25 | buffer | semmle.label | buffer |
| test.go:66:2:66:31 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:66:2:66:31 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| test.go:67:16:67:41 | index expression | semmle.label | index expression |
| test.go:72:2:72:31 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:74:2:74:29 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:72:2:72:31 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| test.go:74:2:74:29 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| test.go:74:13:74:22 | fileHeader | semmle.label | fileHeader |
| test.go:76:2:76:5 | file | semmle.label | file |
| test.go:76:12:76:17 | buffer [postupdate] | semmle.label | buffer [postupdate] |
| test.go:77:20:77:25 | buffer | semmle.label | buffer |
| test.go:82:2:82:32 | ... := ...[0] | semmle.label | ... := ...[0] |
| test.go:82:2:82:32 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| 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:89:16:89:31 | selection of Value | semmle.label | selection of Value |

View File

@@ -7,18 +7,18 @@
| Gin.go:58:10:58:25 | call to Param |
| Gin.go:62:10:62:34 | call to GetStringSlice |
| Gin.go:66:10:66:29 | call to GetString |
| Gin.go:70:3:70:28 | ... := ...[0] |
| Gin.go:70:3:70:28 | extract:0 ... := ... |
| Gin.go:74:10:74:23 | call to ClientIP |
| Gin.go:78:10:78:26 | call to ContentType |
| Gin.go:82:3:82:29 | ... := ...[0] |
| Gin.go:86:3:86:36 | ... := ...[0] |
| Gin.go:90:3:90:31 | ... := ...[0] |
| Gin.go:94:3:94:39 | ... := ...[0] |
| Gin.go:98:3:98:34 | ... := ...[0] |
| Gin.go:82:3:82:29 | extract:0 ... := ... |
| Gin.go:86:3:86:36 | extract:0 ... := ... |
| Gin.go:90:3:90:31 | extract:0 ... := ... |
| Gin.go:94:3:94:39 | extract:0 ... := ... |
| Gin.go:98:3:98:34 | extract:0 ... := ... |
| Gin.go:102:10:102:52 | call to DefaultPostForm |
| Gin.go:106:10:106:49 | call to DefaultQuery |
| Gin.go:110:3:110:37 | ... := ...[0] |
| Gin.go:114:3:114:34 | ... := ...[0] |
| Gin.go:110:3:110:37 | extract:0 ... := ... |
| Gin.go:114:3:114:34 | extract:0 ... := ... |
| Gin.go:118:10:118:32 | call to GetStringMap |
| Gin.go:122:10:122:38 | call to GetStringMapString |
| Gin.go:126:10:126:43 | call to GetStringMapStringSlice |

View File

@@ -6,18 +6,18 @@ models
| 5 | Source: github.com/emicklei/go-restful; Request; true; ReadEntity; ; ; Argument[0]; remote; manual |
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:17:2:17:39 | ... := ...[0] | gorestful.go:18:15:18:17 | val | provenance | Src:MaD:2 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: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_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 | ... := ...[0] | gorestful_v2.go:18:15:18:17 | val | provenance | Src:MaD:2 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: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 |
nodes
| 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:16:15:16:43 | call to QueryParameter | semmle.label | call to QueryParameter |
| gorestful.go:17:2:17:39 | ... := ...[0] | semmle.label | ... := ...[0] |
| gorestful.go:17:2:17:39 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| 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: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: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:17:2:17:39 | ... := ...[0] | semmle.label | ... := ...[0] |
| gorestful_v2.go:17:2:17:39 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| 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:20:15:20:42 | call to PathParameter | semmle.label | call to PathParameter |
@@ -41,14 +41,14 @@ invalidModelRow
#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: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 | ... := ...[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: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: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: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_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: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: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: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: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 |

View File

@@ -1,17 +1,17 @@
#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 |
edges
| 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 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 dereference | provenance | Src:MaD:2 Config |
| 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-deref selection of Params | 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: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 dereference | provenance | 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:32 | selection of Form | EndToEnd.go:95:20:95:49 | call to Get | provenance | Config Sink:MaD:1 |
models
| 1 | Sink: group:revel; Controller; true; Redirect; ; ; Argument[0]; url-redirection; manual |
| 2 | Source: group:revel; Controller; true; Params; ; ; ; remote; manual |
nodes
| EndToEnd.go:95:20:95:27 | implicit dereference | semmle.label | implicit dereference |
| EndToEnd.go:95:20:95:27 | implicit-deref selection of Params | semmle.label | implicit-deref 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:32 | selection of Form | semmle.label | selection of Form |

View File

@@ -1,12 +1,12 @@
invalidModelRow
#select
| 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 | ... := ...[1] |
| 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 | ... := ...[1] |
| 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 | ... := ...[1] |
| crypto.go:11:42:11:51 | ciphertext | crypto.go:11:2:11:57 | ... := ...[0] |
| 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 | extract: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 | extract: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 | extract:1 ... := ... |
| crypto.go:11:42:11:51 | ciphertext | crypto.go:11:2:11:57 | extract:0 ... := ... |
| 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 | &... [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 [postupdate] | io.go:33:19:33:23 | &... |
| 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 | ... := ...[0] |
| 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 | ... := ...[0] |
| 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 | extract:1 ... := ... |
| io.go:40:14:40:14 | w [postupdate] | io.go:39:3:39:19 | extract:0 ... := ... |
| 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: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: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: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 | ... := ...[1] |
| io.go:109:27:109:32 | reader | io.go:109:2:109:33 | ... := ...[0] |
| 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 | extract:1 ... := ... |
| io.go:109:27:109:32 | reader | io.go:109:2:109:33 | extract:0 ... := ... |
| 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 | ... := ...[0] |
| 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 | ... := ...[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 | ... := ...[1] |
| 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 | ... := ...[0] |
| main.go:13:48:13:51 | " " | main.go:13:2:13:52 | ... := ...[0] |
| 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 | extract:1 ... := ... |
| main.go:11:25:11:25 | v | main.go:11:2:11:26 | extract: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 | extract:1 ... := ... |
| main.go:13:33:13:33 | v | main.go:13:2:13:52 | extract:0 ... := ... |
| main.go:13:36:13:45 | "/*JSON*/" | main.go:13:2:13:52 | extract:0 ... := ... |
| main.go:13:48:13:51 | " " | main.go:13:2:13:52 | extract:0 ... := ... |
| 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: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: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 | ... := ...[1] |
| main.go:19:35:19:41 | encoded | main.go:19:2:19:42 | ... := ...[0] |
| 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 | extract:1 ... := ... |
| main.go:19:35:19:41 | encoded | main.go:19:2:19:42 | extract:0 ... := ... |
| 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:39:23:47 | reEncoded | main.go:23:9:23:48 | slice literal |
| main.go:28:2:28:4 | implicit dereference | 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: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 dereference |
| main.go:28:2:28:4 | implicit-deref req | 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 | req | main.go:28:2:28:4 | implicit-deref req |
| 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:16:28:16 | b [postupdate] |
| main.go:34:2:34:4 | implicit dereference | 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: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 dereference |
| main.go:34:2:34:4 | implicit-deref req | 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 | req | main.go:34:2:34:4 | implicit-deref req |
| 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:16:34:16 | b [postupdate] |

View File

@@ -1,19 +1,19 @@
#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 | 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 |
| 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 |
edges
| 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 | &... | server/main.go:19:109:38:1 | SSA def(params) | 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 | ... := ...[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 | ... := ...[0] | provenance | Src:MaD:1 MaD:3 |
| 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: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: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: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:56:19:61 | SSA def(params) | 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:56:19:61 | 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:56:19:61 | SSA def(params) [Return] | client/main.go:16:35:16:78 | &... [postupdate] | provenance | |
| rpc/notes/service.twirp.go:576:35:576:44 | reqContent | server/main.go:19:109:38:1 | 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:109:38:1 | 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:109:38:1 | SSA def(params) [Return] | client/main.go:16:35:16:78 | &... [postupdate] | provenance | |
models
| 1 | Source: net/http; Request; true; Body; ; ; ; remote; manual |
| 2 | Summary: google.golang.org/protobuf/proto; ; false; Unmarshal; ; ; Argument[0]; Argument[1]; taint; manual |
@@ -21,14 +21,17 @@ models
nodes
| client/main.go:16:35:16:78 | &... | semmle.label | &... |
| client/main.go:16:35:16:78 | &... [postupdate] | semmle.label | &... [postupdate] |
| rpc/notes/service.twirp.go:538:2:538:33 | ... := ...[0] | semmle.label | ... := ...[0] |
| rpc/notes/service.twirp.go:538:2:538:33 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| 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: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:576:35:576:44 | reqContent | semmle.label | reqContent |
| server/main.go:19:56:19:61 | 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:56:19:61 | SSA def(params) [Return] | semmle.label | SSA def(params) [Return] |
| server/main.go:19:109:38:1 | 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:109:38:1 | 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 |
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 |

View File

@@ -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: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:7 | SSA def(result) | result | tests.go:241:10:241:12 | 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:30 | SSA def(result) | result | tests.go:59:2:59:30 | 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 |

View File

@@ -1,52 +1,52 @@
#select
| 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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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: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: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: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: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: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: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: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: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: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 |
edges
| tests.go:9:24:9:24 | SSA def(f) | tests.go:10:8:10:8 | f | provenance | |
| tests.go:13:32:13:32 | SSA def(f) | tests.go:14:13:16:2 | SSA def(f) | provenance | |
| tests.go:9:36:11:1 | 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:14:13:16:2 | SSA def(f) | tests.go:15:3:15:3 | f | provenance | |
| tests.go:32:5:32:78 | ... := ...[0] | tests.go:33:21:33:21 | 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:24:9:24 | 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 | ... := ...[0] | tests.go:47:21:47:21 | 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:24:9:24 | 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 | ... := ...[0] | tests.go:57:3:57: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 | ... := ...[0] | tests.go:126:9:126:9 | 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 | ... := ...[0] | tests.go:166:8:166:8 | f | provenance | Src:MaD:1 |
| 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 | extract: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:34:29:34:29 | f | tests.go:13:44:19:1 | 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 | extract: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:48:29:48:29 | f | tests.go:13:44:19:1 | 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:67:5:67:76 | extract: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:141:5:141:78 | extract: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 |
models
| 1 | Source: os; ; false; OpenFile; ; ; ReturnValue[0]; file; manual |
nodes
| tests.go:9:24:9:24 | SSA def(f) | semmle.label | SSA def(f) |
| tests.go:9:36:11:1 | SSA def(f) | semmle.label | SSA def(f) |
| tests.go:10:8:10:8 | f | semmle.label | f |
| tests.go:13:32:13:32 | SSA def(f) | semmle.label | SSA def(f) |
| tests.go:13:44:19:1 | 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:32:5:32:78 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:32:5:32:78 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| tests.go:33:21:33:21 | f | semmle.label | f |
| tests.go:34:29:34:29 | f | semmle.label | f |
| tests.go:46:5:46:76 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:46:5:46:76 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| tests.go:47:21:47:21 | f | semmle.label | f |
| tests.go:48:29:48:29 | f | semmle.label | f |
| tests.go:55:5:55:78 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:55:5:55:78 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| tests.go:57:3:57:3 | f | semmle.label | f |
| tests.go:67:5:67:76 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:67:5:67:76 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| tests.go:69:3:69:3 | f | semmle.label | f |
| tests.go:124:5:124:78 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:124:5:124:78 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| tests.go:126:9:126:9 | f | semmle.label | f |
| tests.go:141:5:141:78 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:141:5:141:78 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| tests.go:145:3:145:3 | f | semmle.label | f |
| tests.go:162:2:162:74 | ... := ...[0] | semmle.label | ... := ...[0] |
| tests.go:162:2:162:74 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| tests.go:166:8:166:8 | f | semmle.label | f |
subpaths

View File

@@ -1 +1 @@
| DeadStoreOfField.go:8:2:8:6 | assignment to field val | This assignment to val is useless since its value is never read. |
| DeadStoreOfField.go:8:2:8:10 | assign:0 ... = ... | This assignment to val is useless since its value is never read. |

View File

@@ -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: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
| UnsafeUnzipSymlink.go:111:19:111:26 | 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:19:111:26 | SSA def(linkName) | provenance | |
| UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:111:29:111:36 | SSA def(fileName) | provenance | |
| UnsafeUnzipSymlink.go:111:46:113:1 | SSA def(fileName) | UnsafeUnzipSymlink.go:112:23:112:30 | fileName | 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:126:17:126:31 | selection of Linkname | UnsafeUnzipSymlink.go:111:46:113:1 | SSA def(linkName) | provenance | |
| UnsafeUnzipSymlink.go:126:34:126:44 | selection of Name | UnsafeUnzipSymlink.go:111:46:113:1 | SSA def(fileName) | provenance | |
models
| 1 | Sink: os; ; false; Symlink; ; ; Argument[0..1]; path-injection; manual |
nodes
| 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:43:25:43:35 | selection of Name | semmle.label | selection of Name |
| UnsafeUnzipSymlink.go:111:19:111:26 | SSA def(linkName) | semmle.label | SSA def(linkName) |
| UnsafeUnzipSymlink.go:111:29:111:36 | SSA def(fileName) | semmle.label | SSA def(fileName) |
| UnsafeUnzipSymlink.go:111:46:113:1 | SSA def(fileName) | semmle.label | SSA def(fileName) |
| UnsafeUnzipSymlink.go:111:46:113:1 | SSA def(linkName) | semmle.label | SSA def(linkName) |
| UnsafeUnzipSymlink.go:112:13:112:20 | linkName | semmle.label | linkName |
| UnsafeUnzipSymlink.go:112:23:112:30 | fileName | semmle.label | fileName |
| UnsafeUnzipSymlink.go:126:17:126:31 | selection of Linkname | semmle.label | selection of Linkname |

View File

@@ -1,21 +1,21 @@
#select
| 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 | 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 | ... := ...[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 | 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 |
| 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 |
| 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 |
| 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 |
| 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 |
edges
| UnsafeUnzipSymlinkGood.go:52:24:52:32 | SSA def(candidate) | UnsafeUnzipSymlinkGood.go:61:53:61:61 | candidate | provenance | |
| UnsafeUnzipSymlinkGood.go:52:55:67:1 | 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:72:3:72:25 | ... := ...[0] | UnsafeUnzipSymlinkGood.go:76:24:76:38 | selection of Linkname | 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:24:52:32 | 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 | range statement[1] | ZipSlip.go:12:24:12:29 | selection of Name | provenance | |
| 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 | ... := ...[0] | provenance | MaD:4 |
| tarslip.go:15:2:15:30 | ... := ...[0] | tarslip.go:16:23:16:33 | selection of Name | provenance | |
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | extract: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:76:24:76:38 | selection of Linkname | UnsafeUnzipSymlinkGood.go:52:55:67:1 | SSA def(candidate) | provenance | |
| UnsafeUnzipSymlinkGood.go:76:70:76:80 | selection of Name | UnsafeUnzipSymlinkGood.go:52:55:67:1 | 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:12:3:12:30 | extract: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 |
| tarslip.go:15:2:15:30 | extract: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 |
| tst.go:23:2:43:2 | range statement[1] | tst.go:29:20:29:23 | path | provenance | Sink:MaD:1 |
| tst.go:23:2:43:2 | extract:1 range statement | tst.go:29:20:29:23 | path | provenance | Sink:MaD:1 |
models
| 1 | Sink: io/ioutil; ; false; WriteFile; ; ; 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 |
| 5 | Summary: path; ; false; Dir; ; ; Argument[0]; ReturnValue; taint; manual |
nodes
| UnsafeUnzipSymlinkGood.go:52:24:52:32 | SSA def(candidate) | semmle.label | SSA def(candidate) |
| UnsafeUnzipSymlinkGood.go:52:55:67:1 | 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:53:61:61 | candidate | semmle.label | candidate |
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | ... := ...[0] | semmle.label | ... := ...[0] |
| UnsafeUnzipSymlinkGood.go:72:3:72:25 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| 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 |
| ZipSlip.go:11:2:15:2 | range statement[1] | semmle.label | range statement[1] |
| ZipSlip.go:12:3:12:30 | ... := ...[0] | semmle.label | ... := ...[0] |
| ZipSlip.go:11:2:15:2 | extract:1 range statement | semmle.label | extract:1 range statement |
| ZipSlip.go:12:3:12:30 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| ZipSlip.go:12:24:12:29 | selection of Name | semmle.label | selection of Name |
| ZipSlip.go:14:20:14:20 | p | semmle.label | p |
| tarslip.go:15:2:15:30 | ... := ...[0] | semmle.label | ... := ...[0] |
| tarslip.go:15:2:15:30 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| 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 |
| tst.go:23:2:43:2 | range statement[1] | semmle.label | range statement[1] |
| tst.go:23:2:43:2 | extract:1 range statement | semmle.label | extract:1 range statement |
| tst.go:29:20:29:23 | path | semmle.label | path |
subpaths

View File

@@ -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: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 |
| 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 | ... := ...[0] | provenance | Src:MaD:17 MaD:24 |
| issue48.go:17:2:17:33 | extract: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: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: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: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: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 | ... := ...[0] | provenance | Src:MaD:17 MaD:24 |
| issue48.go:27:2:27:34 | extract: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: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: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: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:34:3:34:13 | RequestData [pointer, Category] | main.go:34:3:34:13 | implicit dereference [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:13 | RequestData [pointer, Category] | main.go:34:3:34:13 | implicit-deref RequestData [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: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: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 dereference [postupdate] [Category] | main.go:40:2:40:12 | RequestData [postupdate] [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: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:51 | index expression | main.go:40:2:40:12 | implicit dereference [postupdate] [Category] | provenance | |
| main.go:40:25:40:51 | index expression | main.go:40:2:40:12 | implicit-deref RequestData [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 | 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 dereference [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:13 | RequestData [pointer, Category] | main.go:43:3:43:13 | implicit-deref RequestData [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: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: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: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:52:3:52:13 | RequestData [pointer, Category] | main.go:52:3:52:13 | implicit dereference [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:13 | RequestData [pointer, Category] | main.go:52:3:52:13 | implicit-deref RequestData [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: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: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:29 | index expression | semmle.label | index expression |
| SqlInjection.go:12:11:12:11 | q | semmle.label | q |
| issue48.go:17:2:17:33 | ... := ...[0] | semmle.label | ... := ...[0] |
| issue48.go:17:2:17:33 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| 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: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:21:3:21:33 | index expression | semmle.label | index expression |
| issue48.go:22:11:22:12 | q3 | semmle.label | q3 |
| issue48.go:27:2:27:34 | ... := ...[0] | semmle.label | ... := ...[0] |
| issue48.go:27:2:27:34 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| 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: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 | 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 | implicit dereference [Category] | semmle.label | implicit dereference [Category] |
| main.go:34:3:34:13 | implicit-deref RequestData [Category] | semmle.label | implicit-deref RequestData [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:40:2:40:12 | RequestData [postupdate] [pointer, Category] | semmle.label | RequestData [postupdate] [pointer, Category] |
| main.go:40:2:40:12 | implicit dereference [postupdate] [Category] | semmle.label | implicit dereference [postupdate] [Category] |
| main.go:40:2:40:12 | implicit-deref RequestData [postupdate] [Category] | semmle.label | implicit-deref RequestData [postupdate] [Category] |
| 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: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 | 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 | implicit dereference [Category] | semmle.label | implicit dereference [Category] |
| main.go:43:3:43:13 | implicit-deref RequestData [Category] | semmle.label | implicit-deref RequestData [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: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 | 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 | implicit dereference [Category] | semmle.label | implicit dereference [Category] |
| main.go:52:3:52:13 | implicit-deref RequestData [Category] | semmle.label | implicit-deref RequestData [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:58:3:58:14 | star expression [postupdate] [Category] | semmle.label | star expression [postupdate] [Category] |

View File

@@ -1,25 +1,25 @@
#select
| 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 | ... := ...[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 | ... := ...[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 |
| 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 |
| 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: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 |
edges
| StringBreak.go:11:2:11:40 | ... := ...[0] | StringBreak.go:15:47:15:57 | versionJSON | provenance | |
| StringBreakMismatched.go:13:2:13:40 | ... := ...[0] | StringBreakMismatched.go:14:29:14:47 | type conversion | provenance | |
| StringBreak.go:11:2:11:40 | extract: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: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:25:2:25:40 | ... := ...[0] | StringBreakMismatched.go:26:29:26:47 | type conversion | provenance | |
| StringBreakMismatched.go:25:2:25:40 | extract: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:29:26:47 | type conversion | StringBreakMismatched.go:26:13:26:61 | call to Replace | provenance | MaD:1 |
models
| 1 | Summary: strings; ; false; Replace; ; ; Argument[0]; ReturnValue; taint; manual |
nodes
| StringBreak.go:11:2:11:40 | ... := ...[0] | semmle.label | ... := ...[0] |
| StringBreak.go:11:2:11:40 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| StringBreak.go:15:47:15:57 | versionJSON | semmle.label | versionJSON |
| StringBreakMismatched.go:13:2:13:40 | ... := ...[0] | semmle.label | ... := ...[0] |
| StringBreakMismatched.go:13:2:13:40 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| 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:18:26:18:32 | escaped | semmle.label | escaped |
| StringBreakMismatched.go:25:2:25:40 | ... := ...[0] | semmle.label | ... := ...[0] |
| StringBreakMismatched.go:25:2:25:40 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| 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:30:27:30:33 | escaped | semmle.label | escaped |

View File

@@ -1,22 +1,22 @@
#select
| 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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... = ...[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 | ... = ...[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 | ... = ...[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 | ... = ...[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 |
| 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 |
| 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: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 |
| 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: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: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 |
| 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: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: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: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 |
edges
| AllocationSizeOverflow.go:6:2:6:33 | ... := ...[0] | AllocationSizeOverflow.go:10:14:10:21 | jsonData | provenance | |
| AllocationSizeOverflow.go:6:2:6:33 | extract: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 |
| tst2.go:9:2:9:37 | ... := ...[0] | tst2.go:10:26:10:29 | data | provenance | Src:MaD:1 |
| tst2.go:9:2:9:37 | extract: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:14:2:14:29 | ... := ...[0] | tst2.go:15:26:15:29 | data | provenance | |
| tst2.go:14:2:14:29 | extract: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 |
| tst3.go:6:2:6:31 | ... := ...[0] | tst3.go:7:26:7:33 | jsonData | provenance | |
| tst3.go:6:2:6:31 | extract: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:9:32:9:39 | 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:32:20:32:27 | jsonData | provenance | |
| tst3.go:32:20:32:27 | jsonData | tst3.go:32:16:32:28 | call to len | provenance | Config |
| tst.go:14:2:14:30 | ... = ...[0] | tst.go:15:26:15:33 | jsonData | provenance | |
| tst.go:14:2:14:30 | extract: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:20:2:20:31 | ... = ...[0] | tst.go:21:26:21:33 | jsonData | provenance | |
| tst.go:20:2:20:31 | extract: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:26:2:26:31 | ... = ...[0] | tst.go:27:30:27:37 | jsonData | provenance | |
| tst.go:26:2:26:31 | extract: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:34:2:34:30 | ... = ...[0] | tst.go:35:26:35:33 | jsonData | provenance | |
| tst.go:34:2:34:30 | extract: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 |
models
| 1 | Source: io/ioutil; ; false; ReadFile; ; ; ReturnValue[0]; file; manual |
nodes
| AllocationSizeOverflow.go:6:2:6:33 | ... := ...[0] | semmle.label | ... := ...[0] |
| AllocationSizeOverflow.go:6:2:6:33 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| AllocationSizeOverflow.go:10:10:10:22 | call to len | semmle.label | call to len |
| AllocationSizeOverflow.go:10:14:10:21 | jsonData | semmle.label | jsonData |
| tst2.go:9:2:9:37 | ... := ...[0] | semmle.label | ... := ...[0] |
| tst2.go:9:2:9:37 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| 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:14:2:14:29 | ... := ...[0] | semmle.label | ... := ...[0] |
| tst2.go:14:2:14:29 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| tst2.go:15:22:15:30 | call to len | semmle.label | call to len |
| tst2.go:15:26:15:29 | data | semmle.label | data |
| tst3.go:6:2:6:31 | ... := ...[0] | semmle.label | ... := ...[0] |
| tst3.go:6:2:6:31 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| 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: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:32:16:32:28 | call to len | semmle.label | call to len |
| tst3.go:32:20:32:27 | jsonData | semmle.label | jsonData |
| tst.go:14:2:14:30 | ... = ...[0] | semmle.label | ... = ...[0] |
| tst.go:14:2:14:30 | extract:0 ... = ... | semmle.label | extract:0 ... = ... |
| 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:20:2:20:31 | ... = ...[0] | semmle.label | ... = ...[0] |
| tst.go:20:2:20:31 | extract:0 ... = ... | semmle.label | extract:0 ... = ... |
| 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:26:2:26:31 | ... = ...[0] | semmle.label | ... = ...[0] |
| tst.go:26:2:26:31 | extract:0 ... = ... | semmle.label | extract:0 ... = ... |
| 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:34:2:34:30 | ... = ...[0] | semmle.label | ... = ...[0] |
| tst.go:34:2:34:30 | extract:0 ... = ... | semmle.label | extract:0 ... = ... |
| tst.go:35:22:35:34 | call to len | semmle.label | call to len |
| tst.go:35:26:35:33 | jsonData | semmle.label | jsonData |
subpaths

View File

@@ -1,4 +1,4 @@
| DisabledCertificateCheck.go:10:32:10:55 | init of key-value pair | 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 | init of 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. |
| DisabledCertificateCheck.go:10:32:10:55 | lit-init 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:57:21:57:44 | lit-init 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. |

View File

@@ -1,80 +1,85 @@
#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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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 |
| 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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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 |
| 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 |
| 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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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 |
| 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 |
| 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
| 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 | range statement[1] | provenance | Src:MaD:11 Config |
| 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 | range statement[1] | provenance | Config |
| klog.go:21:3:26:3 | extract:1 range statement | 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:22:4:25:4 | extract:1 range statement | 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: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:9 | SSA def(password) | main.go:19:12:19:19 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:20:19:20:26 | password | provenance | |
| 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:9 | SSA def(password) | main.go:22:14:22:21 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:24:13:24:20 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:27:20:27:27 | password | provenance | |
| 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:9 | SSA def(password) | main.go:33:15:33:22 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:36:13:36:20 | password | provenance | |
| main.go:17:2:17:9 | SSA def(password) | main.go:39:20:39:27 | password | provenance | |
| 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:9 | SSA def(password) | main.go:45:15:45:22 | password | provenance | |
| 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:9 | 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: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:23 | 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:23 | 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:23 | 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:23 | 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:23 | 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:23 | 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:23 | 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:52:17:52:24 | password | main.go:53:11:53:18 | password | provenance | |
@@ -97,17 +102,18 @@ edges
| 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:90:35:90:42 | password | provenance | Sink:MaD:1 |
| overrides.go:8:2:8:9 | SSA def(password) | overrides.go:9:9:9:16 | password | provenance | |
| overrides.go:8:2:8:40 | 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 | |
| passwords.go:8:12:8:12 | SSA def(x) | passwords.go:9:14:9:14 | x | provenance | |
| passwords.go:21:2:21:9 | SSA def(password) | passwords.go:25:14:25:21 | password | provenance | |
| passwords.go:21:2:21:9 | SSA def(password) | passwords.go:30:8:30:15 | password | provenance | |
| passwords.go:21:2:21:9 | SSA def(password) | passwords.go:33:13:33:20 | 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:12:8:12 | SSA def(x) | provenance | |
| passwords.go:8:22:10:1 | 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:23 | 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:23 | 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: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: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: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 |
@@ -117,8 +123,10 @@ 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:115:33:115:40 | password | provenance | |
| passwords.go:50:11:50:18 | password | passwords.go:125:13:125:20 | password | provenance | |
| passwords.go:52:2:52:15 | SSA def(fixed_password) | passwords.go:53:14:53:27 | fixed_password | provenance | |
| passwords.go:52:2:52:44 | 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: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: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 | |
@@ -129,12 +137,13 @@ edges
| 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:125:13:125:20 | password | provenance | |
| passwords.go:118:6:118:14 | SSA def(password1) | passwords.go:119:28:119:36 | password1 | provenance | |
| passwords.go:118:6:118:50 | 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: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 [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: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: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 | |
@@ -142,15 +151,17 @@ edges
| 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:131:14:131:19 | config [y] | passwords.go:131:14:131:21 | selection of y | 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 dereference [postupdate] [Description] | protobuf.go:12:2:12:6 | query [postupdate] [pointer, Description] | provenance | |
| protobuf.go:9:2:9:23 | 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 | 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 dereference [postupdate] [Description] | provenance | |
| protobuf.go:12:22:12:29 | password | protobuf.go:12:2:12:6 | implicit-deref query [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] | protos/query/query.pb.go:117:7:117:7 | SSA def(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 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 dereference [Description] | 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 | |
| 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: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 | x [pointer, Description] | protos/query/query.pb.go:119:10:119:10 | implicit-deref x [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
| 1 | Sink: group:logrus; ; false; WithField; ; ; Argument[0..1]; log-injection; manual |
| 2 | Sink: group:logrus; ; false; WithFields; ; ; Argument[0]; log-injection; manual |
@@ -164,14 +175,14 @@ models
| 10 | Sink: log; Logger; true; Printf; ; ; Argument[0..1]; log-injection; manual |
| 11 | Source: net/http; Request; true; Header; ; ; ; remote; manual |
nodes
| klog.go:21:3:26:3 | range statement[1] | semmle.label | range statement[1] |
| klog.go:21:3:26:3 | extract:1 range statement | semmle.label | extract:1 range statement |
| klog.go:21:30:21:37 | selection of Header | semmle.label | selection of Header |
| klog.go:22:4:25:4 | range statement[1] | semmle.label | range statement[1] |
| klog.go:22:4:25:4 | extract:1 range statement | semmle.label | extract:1 range statement |
| klog.go:22:27:22:33 | headers | semmle.label | headers |
| 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:41 | call to Get | semmle.label | call to Get |
| main.go:17:2:17:9 | SSA def(password) | semmle.label | SSA def(password) |
| main.go:17:2:17:23 | SSA def(password) | semmle.label | SSA def(password) |
| main.go:19:12:19:19 | password | semmle.label | password |
| main.go:20:19:20:26 | password | semmle.label | password |
| main.go:21:13:21:20 | password | semmle.label | password |
@@ -209,12 +220,12 @@ nodes
| main.go:86:19:86:26 | password | semmle.label | password |
| main.go:87:29:87:34 | fields | semmle.label | fields |
| main.go:90:35:90:42 | password | semmle.label | password |
| overrides.go:8:2:8:9 | SSA def(password) | semmle.label | SSA def(password) |
| overrides.go:8:2:8:40 | SSA def(password) | semmle.label | SSA def(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 |
| passwords.go:8:12:8:12 | SSA def(x) | semmle.label | SSA def(x) |
| passwords.go:8:22:10:1 | SSA def(x) | semmle.label | SSA def(x) |
| passwords.go:9:14:9:14 | x | semmle.label | x |
| passwords.go:21:2:21:9 | SSA def(password) | semmle.label | SSA def(password) |
| passwords.go:21:2:21:23 | SSA def(password) | semmle.label | SSA def(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:27:14:27:26 | call to getPassword | semmle.label | call to getPassword |
@@ -224,15 +235,19 @@ nodes
| passwords.go:36:14:36:35 | ...+... | semmle.label | ...+... |
| passwords.go:36:28:36:35 | password | semmle.label | password |
| 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:41:14:41:17 | obj1 | semmle.label | obj1 |
| passwords.go:43:10:45:2 | struct literal | semmle.label | struct literal |
| passwords.go:44:6:44:13 | password | semmle.label | password |
| passwords.go:46:14:46:17 | obj2 | semmle.label | obj2 |
| passwords.go:50:11:50:18 | password | semmle.label | password |
| passwords.go:52:2:52:15 | SSA def(fixed_password) | semmle.label | SSA def(fixed_password) |
| passwords.go:52:2:52:44 | SSA def(fixed_password) | semmle.label | SSA def(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: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:91:14:91:26 | utilityObject | semmle.label | utilityObject |
| passwords.go:94:23:94:28 | secret | semmle.label | secret |
@@ -242,13 +257,14 @@ nodes
| passwords.go:110:34:110:41 | password | semmle.label | password |
| passwords.go:115:15:115:40 | ...+... | semmle.label | ...+... |
| passwords.go:115:33:115:40 | password | semmle.label | password |
| passwords.go:118:6:118:14 | SSA def(password1) | semmle.label | SSA def(password1) |
| passwords.go:118:6:118:50 | SSA def(password1) | semmle.label | SSA def(password1) |
| passwords.go:119:14:119:45 | ...+... | semmle.label | ...+... |
| 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: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 [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:125:13:125:20 | password | semmle.label | password |
| passwords.go:126:13:126:25 | call to getPassword | semmle.label | call to getPassword |
@@ -257,15 +273,23 @@ nodes
| 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:21 | selection of y | semmle.label | selection of y |
| protobuf.go:9:2:9:9 | SSA def(password) | semmle.label | SSA def(password) |
| protobuf.go:12:2:12:6 | implicit dereference [postupdate] [Description] | semmle.label | implicit dereference [postupdate] [Description] |
| protobuf.go:9:2:9:23 | 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 | query [postupdate] [pointer, Description] | semmle.label | query [postupdate] [pointer, Description] |
| 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:35 | call to GetDescription | semmle.label | call to GetDescription |
| 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 dereference [Description] | semmle.label | implicit dereference [Description] |
| 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:119:10:119:10 | implicit-deref x [Description] | semmle.label | implicit-deref x [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 |
| 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
| 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 |
| 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 |
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 |

View File

@@ -8,18 +8,18 @@ edges
| 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:45:3:47:3 | function literal | InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | provenance | |
| InsecureHostKeyCallbackExample.go:58:39:58:46 | SSA def(callback) | InsecureHostKeyCallbackExample.go:62:20:62:27 | 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 | ... := ...[0] | InsecureHostKeyCallbackExample.go:95:28:95:35 | callback | provenance | |
| InsecureHostKeyCallbackExample.go:58:69:64:1 | 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:94:3:94:43 | extract: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: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:39:58:46 | SSA def(callback) | provenance | |
| InsecureHostKeyCallbackExample.go:107:35:107:50 | insecureCallback | InsecureHostKeyCallbackExample.go:58:69:64:1 | 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: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: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:39:58:46 | SSA def(callback) | provenance | |
| InsecureHostKeyCallbackExample.go:120:44:120:68 | potentiallySecureCallback | InsecureHostKeyCallbackExample.go:68:48:68:55 | SSA def(callback) | provenance | |
| InsecureHostKeyCallbackExample.go:117:35:117:59 | potentiallySecureCallback | InsecureHostKeyCallbackExample.go:58:69:64:1 | 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:120:44:120:68 | potentiallySecureCallback | InsecureHostKeyCallbackExample.go:68:78:80:1 | SSA def(callback) | provenance | |
nodes
| InsecureHostKeyCallbackExample.go:15:20:18:5 | type conversion | semmle.label | type conversion |
| 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:45:3:47:3 | function literal | semmle.label | function literal |
| InsecureHostKeyCallbackExample.go:52:20:52:48 | type conversion | semmle.label | type conversion |
| InsecureHostKeyCallbackExample.go:58:39:58:46 | SSA def(callback) | semmle.label | SSA def(callback) |
| InsecureHostKeyCallbackExample.go:58:69:64:1 | SSA def(callback) | semmle.label | SSA def(callback) |
| InsecureHostKeyCallbackExample.go:62:20:62:27 | callback | semmle.label | callback |
| InsecureHostKeyCallbackExample.go:68:48:68:55 | SSA def(callback) | semmle.label | SSA def(callback) |
| InsecureHostKeyCallbackExample.go:68:78:80:1 | SSA def(callback) | semmle.label | SSA def(callback) |
| 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:92:28:92:54 | call to InsecureIgnoreHostKey | semmle.label | call to InsecureIgnoreHostKey |
| InsecureHostKeyCallbackExample.go:94:3:94:43 | ... := ...[0] | semmle.label | ... := ...[0] |
| InsecureHostKeyCallbackExample.go:94:3:94:43 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| InsecureHostKeyCallbackExample.go:95:28:95:35 | callback | semmle.label | callback |
| InsecureHostKeyCallbackExample.go:102:22:105:4 | type conversion | semmle.label | type conversion |
| InsecureHostKeyCallbackExample.go:103:3:105:3 | function literal | semmle.label | function literal |

View File

@@ -1,7 +1,14 @@
#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
| 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:11:25:14 | SSA def(size) | provenance | |
| InsufficientKeySize.go:25:11:25:14 | SSA def(size) | InsufficientKeySize.go:26:31:26:34 | size | provenance | |
| InsufficientKeySize.go:18:7:18:10 | 1024 | InsufficientKeySize.go:25:21:27:1 | SSA def(size) | provenance | |
| InsufficientKeySize.go:25:21:27:1 | 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: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 | |
@@ -10,7 +17,7 @@ nodes
| InsufficientKeySize.go:13:10:13:13 | 1024 | semmle.label | 1024 |
| InsufficientKeySize.go:14:31:14:34 | size | semmle.label | size |
| InsufficientKeySize.go:18:7:18:10 | 1024 | semmle.label | 1024 |
| InsufficientKeySize.go:25:11:25:14 | SSA def(size) | semmle.label | SSA def(size) |
| InsufficientKeySize.go:25:21:27:1 | SSA def(size) | semmle.label | SSA def(size) |
| InsufficientKeySize.go:26:31:26:34 | size | semmle.label | size |
| InsufficientKeySize.go:30:13:30:16 | 1024 | semmle.label | 1024 |
| InsufficientKeySize.go:32:32:32:38 | keyBits | semmle.label | keyBits |
@@ -19,10 +26,3 @@ nodes
| InsufficientKeySize.go:61:21:61:24 | 1024 | semmle.label | 1024 |
| InsufficientKeySize.go:67:31:67:37 | keyBits | semmle.label | keyBits |
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. |

View File

@@ -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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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 | ... := ...[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: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: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: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: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: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: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: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: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: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: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 [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 | 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 | 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 | extract: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: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: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: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: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: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: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: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: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: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 [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 | 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 | 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 | extract: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 |

View File

@@ -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: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:26:15:26:25 | signedToken | go-jose.v3.go:29:19:29:29 | SSA def(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 | ... := ...[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 | ... := ...[0] | provenance | MaD:4 |
| 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:29:39:37:1 | 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:37:31:47 | signedToken | go-jose.v3.go:31:2:31:48 | extract: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: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:29:25:29:35 | signedToken | golang-jwt-v5.go:32:29:32:39 | SSA def(signedToken) | provenance | |
| golang-jwt-v5.go:32:29:32:39 | SSA def(signedToken) | golang-jwt-v5.go:34:58:34:68 | signedToken | provenance | Sink:MaD:1 |
| 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:32:49:40:1 | SSA def(signedToken) | golang-jwt-v5.go:34:58:34:68 | signedToken | provenance | Sink:MaD:1 |
models
| 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 |
@@ -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: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:29:19:29:29 | SSA def(signedToken) | semmle.label | SSA def(signedToken) |
| go-jose.v3.go:31:2:31:48 | ... := ...[0] | semmle.label | ... := ...[0] |
| go-jose.v3.go:29:39:37:1 | 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:37:31:47 | signedToken | semmle.label | signedToken |
| 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: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:29:25:29:35 | signedToken | semmle.label | signedToken |
| golang-jwt-v5.go:32:29:32:39 | SSA def(signedToken) | semmle.label | SSA def(signedToken) |
| golang-jwt-v5.go:32:49:40:1 | SSA def(signedToken) | semmle.label | SSA def(signedToken) |
| golang-jwt-v5.go:34:58:34:68 | signedToken | semmle.label | signedToken |
subpaths

View File

@@ -1,63 +1,76 @@
#select
| 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: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: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 |
| 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 | ...==... | 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 |
| 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: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 |
| 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: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: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: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: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: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: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
| BadRedirectCheck.go:3:18:3:22 | SSA def(redir) | 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:3:39:8:1 | 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:5:10:5:14 | redir | main.go:11:25:11:45 | call to sanitizeUrl | 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:14:78:18:1 | arg:0 block statement | 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:41:14:41:34 | call to Get | cves.go:45:25:45:32 | redirect | provenance | Sink:MaD:1 |
| 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:18:3:22 | SSA def(redir) | provenance | |
| main.go:10:78:12:1 | arg:0 block statement | 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 | main.go:11:25:11:45 | call to sanitizeUrl | 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:17:68:24 | SSA def(redirect) | 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:32:79:36:1 | arg:0 block statement | 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:41:74:1 | arg:0 block statement | 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: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: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:17:68:24 | SSA def(redirect) | provenance | |
| main.go:76:74:78:1 | arg:0 block statement | 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: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 |
models
| 1 | Sink: net/http; ; false; Redirect; ; ; Argument[2]; url-redirection[0]; manual |
| 2 | Summary: path; ; false; Clean; ; ; Argument[0]; ReturnValue; taint; manual |
nodes
| BadRedirectCheck.go:3:18:3:22 | SSA def(redir) | semmle.label | SSA def(redir) |
| BadRedirectCheck.go:3:18:3:22 | argument corresponding to redir | semmle.label | argument corresponding to redir |
| BadRedirectCheck.go:3:39:8:1 | 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:5:10:5:14 | redir | semmle.label | redir |
| BadRedirectCheck.go:5:10:5:14 | redir | semmle.label | redir |
| cves.go:14:23:14:25 | argument corresponding to url | semmle.label | argument corresponding to url |
| cves.go:14:78:18:1 | arg:0 block statement | semmle.label | arg:0 block statement |
| 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:37:25:37:32 | redirect | semmle.label | redirect |
| cves.go:41:14:41:34 | call to Get | semmle.label | call to Get |
| cves.go:45:25:45:32 | redirect | semmle.label | redirect |
| main.go:10:18:10:25 | argument corresponding to redirect | semmle.label | argument corresponding to redirect |
| main.go:10:78:12:1 | arg:0 block statement | semmle.label | arg:0 block statement |
| 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:32:24:32:26 | argument corresponding to url | semmle.label | argument corresponding to url |
| main.go:32:79:36:1 | arg:0 block statement | semmle.label | arg:0 block statement |
| main.go:34:26:34:28 | url | semmle.label | url |
| main.go:68:17:68:24 | SSA def(redirect) | semmle.label | SSA def(redirect) |
| main.go:68:17:68:24 | argument corresponding to redirect | semmle.label | argument corresponding to redirect |
| main.go:68:41:74:1 | 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: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:76:19:76:21 | argument corresponding to url | semmle.label | argument corresponding to url |
| main.go:76:74:78:1 | arg:0 block statement | semmle.label | arg:0 block statement |
| 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: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 |
subpaths
| 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:17:68:24 | SSA def(redirect) | main.go:73:9:73:28 | call to Clean | main.go:77:25:77:39 | call to getTarget1 |
| 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: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 |
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 |

View File

@@ -30,16 +30,16 @@ edges
| 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: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 | ... += ... | provenance | Config |
| stdlib.go:94:3:94:25 | ... += ... | stdlib.go:96:23:96:28 | target | provenance | Sink:MaD:1 |
| stdlib.go:116:4:116:4 | implicit dereference [postupdate] [URL] | stdlib.go:116:4:116:4 | r [postupdate] [pointer, URL] | provenance | |
| stdlib.go:94:3:94:8 | target | stdlib.go:94:3:94:25 | compound-rhs ... += ... | provenance | Config |
| stdlib.go:94:3:94:25 | compound-rhs ... += ... | 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 | r [postupdate] [pointer, URL] | stdlib.go:117:24:117:24 | r [pointer, URL] | provenance | |
| 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 dereference | provenance | Src:MaD:4 Config |
| 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 dereference | provenance | Config |
| 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 dereference [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 | 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 [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:8 | implicit-deref selection of URL | 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 | r [pointer, URL] | stdlib.go:117:24:117:24 | implicit-deref r [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: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 |
@@ -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: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: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 | ... := ...[0] | provenance | Src:MaD:3 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 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 dereference | provenance | Config |
| stdlib.go:194:3:194:57 | extract: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:196:23:196:28 | implicit-deref target | 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 | target | stdlib.go:196:23:196:28 | implicit-deref target | 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:198:23:198:28 | target | provenance | |
| 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:196:23:196:28 | implicit-deref target | provenance | Config |
| 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:210:3:210:3 | implicit dereference [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] [pointer] | provenance | |
| 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-deref u [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] [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 dereference [postupdate] | provenance | Src:MaD:3 Config |
| 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 | u [postupdate] | provenance | Src:MaD:3 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 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 dereference | provenance | 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-deref 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:23 | implicit-deref u | 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:214:23:214:23 | 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 dereference | provenance | Config |
| 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 [postupdate] | stdlib.go:212:23:212:23 | implicit-deref u | provenance | Config |
| 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:257:3:257:3 | implicit dereference [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] [pointer] | provenance | |
| 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-deref u [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] [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 dereference [postupdate] | provenance | Src:MaD:3 Config |
| 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 | u [postupdate] | provenance | Src:MaD:3 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 dereference | provenance | 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 | u | stdlib.go:260:3:260:3 | implicit-deref u | provenance | Config |
| 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 dereference | provenance | |
| 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 [pointer] | stdlib.go:260:3:260:3 | implicit-deref u | 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: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 |
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:32 | call to Get | semmle.label | call to Get |
| stdlib.go:94:3:94:8 | target | semmle.label | target |
| stdlib.go:94:3:94:25 | ... += ... | semmle.label | ... += ... |
| stdlib.go:94:3:94:25 | compound-rhs ... += ... | semmle.label | compound-rhs ... += ... |
| stdlib.go:96:23:96:28 | target | semmle.label | target |
| stdlib.go:116:4:116:4 | implicit dereference [postupdate] [URL] | semmle.label | implicit dereference [postupdate] [URL] |
| stdlib.go:116:4:116:4 | implicit-deref r [postupdate] [URL] | semmle.label | implicit-deref r [postupdate] [URL] |
| stdlib.go:116:4:116:4 | r [postupdate] [pointer, URL] | semmle.label | r [postupdate] [pointer, URL] |
| stdlib.go:116:4:116:8 | implicit dereference | semmle.label | implicit dereference |
| stdlib.go:116:4:116:8 | implicit-deref selection of URL | semmle.label | implicit-deref 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:117:24:117:24 | implicit dereference [URL] | semmle.label | implicit dereference [URL] |
| stdlib.go:117:24:117:24 | implicit-deref r [URL] | semmle.label | implicit-deref r [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: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:186:13:186:33 | call to FormValue | semmle.label | call to FormValue |
| stdlib.go:188:23:188:28 | target | semmle.label | target |
| stdlib.go:194:3:194:57 | ... := ...[0] | semmle.label | ... := ...[0] |
| stdlib.go:194:3:194:57 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| stdlib.go:194:36:194:56 | call to FormValue | semmle.label | call to FormValue |
| stdlib.go:196:23:196:28 | implicit dereference | semmle.label | implicit dereference |
| stdlib.go:196:23:196:28 | implicit-deref target | semmle.label | implicit-deref 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:33 | selection of Path | semmle.label | selection of Path |
| 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:210:3:210:3 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
| stdlib.go:210:3:210:3 | implicit-deref u [postupdate] | semmle.label | implicit-deref 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:12:210:30 | call to FormValue | semmle.label | call to FormValue |
| stdlib.go:212:23:212:23 | implicit dereference | semmle.label | implicit dereference |
| stdlib.go:212:23:212:23 | implicit-deref u | semmle.label | implicit-deref 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 [postupdate] | semmle.label | u [postupdate] |
| 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:32 | call to String | semmle.label | call to String |
| stdlib.go:257:3:257:3 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
| stdlib.go:257:3:257:3 | implicit-deref u [postupdate] | semmle.label | implicit-deref 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:12:257:30 | call to FormValue | semmle.label | call to FormValue |
| stdlib.go:260:3:260:3 | implicit dereference | semmle.label | implicit dereference |
| stdlib.go:260:3:260:3 | implicit-deref u | semmle.label | implicit-deref 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 [postupdate] | semmle.label | u [postupdate] |

View File

@@ -5,8 +5,8 @@ edges
| 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:29 | call to Get | UncontrolledAllocationSizeBad.go:14:28:14:36 | sourceStr | 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 | ... := ...[0] | provenance | Config |
| UncontrolledAllocationSizeBad.go:14:2:14:37 | extract: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 |
models
| 1 | Source: net/http; Request; true; URL; ; ; ; remote; 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:13:15:13:20 | source | semmle.label | source |
| UncontrolledAllocationSizeBad.go:13:15:13:29 | call to Get | semmle.label | call to Get |
| UncontrolledAllocationSizeBad.go:14:2:14:37 | ... := ...[0] | semmle.label | ... := ...[0] |
| UncontrolledAllocationSizeBad.go:14:2:14:37 | extract:0 ... := ... | semmle.label | extract:0 ... := ... |
| UncontrolledAllocationSizeBad.go:14:28:14:36 | sourceStr | semmle.label | sourceStr |
| UncontrolledAllocationSizeBad.go:20:27:20:30 | sink | semmle.label | sink |
subpaths

View File

@@ -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: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:48:2:48:2 | implicit dereference [postupdate] | tst.go:48:2:48:2 | u [postupdate] | provenance | |
| 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 | u [postupdate] | tst.go:49:11:49:11 | u | provenance | |
| 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 | implicit-deref 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 |
| 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:39:11:39:29 | ...+... | semmle.label | ...+... |
| tst.go:41:11:41:40 | ...+... | semmle.label | ...+... |
| tst.go:48:2:48:2 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
| tst.go:48:2:48:2 | implicit-deref u [postupdate] | semmle.label | implicit-deref 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:49:11:49:11 | u | semmle.label | u |

View File

@@ -1,2 +0,0 @@
import semmle.python.controlflow.internal.AstNodeImpl
import ControlFlow::Consistency

View File

@@ -1,4 +0,0 @@
---
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.

View File

@@ -1,45 +0,0 @@
/**
* @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>

View File

@@ -1,7 +1,7 @@
overlay[local]
module;
import python as Py
import python
private import semmle.python.internal.CachedStages
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) {
exists(Py::Expr load_store | exists(Py::AugAssign aa | aa.getTarget() = load_store) |
exists(Expr load_store | exists(AugAssign aa | aa.getTarget() = load_store) |
toAst(load) = load_store and
toAst(store) = load_store and
load.strictlyDominates(store)
@@ -25,7 +25,7 @@ private predicate augstore(ControlFlowNode load, ControlFlowNode store) {
}
/** A non-dispatched getNode() to avoid negative recursion issues */
private Py::AstNode toAst(ControlFlowNode n) { py_flow_bb_node(n, result, _, _) }
private 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,
@@ -35,19 +35,19 @@ private Py::AstNode toAst(ControlFlowNode n) { py_flow_bb_node(n, result, _, _)
class ControlFlowNode extends @py_flow_node {
/** Whether this control flow node is a load (including those in augmented assignments) */
predicate isLoad() {
exists(Py::Expr e | e = toAst(this) | py_expr_contexts(_, 3, e) and not augstore(_, this))
exists(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) */
predicate isStore() {
exists(Py::Expr e | e = toAst(this) | py_expr_contexts(_, 5, e) or augstore(_, this))
exists(Expr e | e = toAst(this) | py_expr_contexts(_, 5, e) or augstore(_, this))
}
/** Whether this control flow node is a delete */
predicate isDelete() { exists(Py::Expr e | e = toAst(this) | py_expr_contexts(_, 2, e)) }
predicate isDelete() { exists(Expr e | e = toAst(this) | py_expr_contexts(_, 2, e)) }
/** Whether this control flow node is a parameter */
predicate isParameter() { exists(Py::Expr e | e = toAst(this) | py_expr_contexts(_, 4, e)) }
predicate isParameter() { exists(Expr e | e = toAst(this) | py_expr_contexts(_, 4, e)) }
/** Whether this control flow node is a store in an augmented assignment */
predicate isAugStore() { augstore(_, this) }
@@ -57,61 +57,61 @@ class ControlFlowNode extends @py_flow_node {
/** Whether this flow node corresponds to a literal */
predicate isLiteral() {
toAst(this) instanceof Py::Bytes
toAst(this) instanceof Bytes
or
toAst(this) instanceof Py::Dict
toAst(this) instanceof Dict
or
toAst(this) instanceof Py::DictComp
toAst(this) instanceof DictComp
or
toAst(this) instanceof Py::Set
toAst(this) instanceof Set
or
toAst(this) instanceof Py::SetComp
toAst(this) instanceof SetComp
or
toAst(this) instanceof Py::Ellipsis
toAst(this) instanceof Ellipsis
or
toAst(this) instanceof Py::GeneratorExp
toAst(this) instanceof GeneratorExp
or
toAst(this) instanceof Py::Lambda
toAst(this) instanceof Lambda
or
toAst(this) instanceof Py::ListComp
toAst(this) instanceof ListComp
or
toAst(this) instanceof Py::List
toAst(this) instanceof List
or
toAst(this) instanceof Py::Num
toAst(this) instanceof Num
or
toAst(this) instanceof Py::Tuple
toAst(this) instanceof Tuple
or
toAst(this) instanceof Py::Unicode
toAst(this) instanceof Unicode
or
toAst(this) instanceof Py::NameConstant
toAst(this) instanceof NameConstant
}
/** Whether this flow node corresponds to an attribute expression */
predicate isAttribute() { toAst(this) instanceof Py::Attribute }
predicate isAttribute() { toAst(this) instanceof Attribute }
/** Whether this flow node corresponds to an subscript expression */
predicate isSubscript() { toAst(this) instanceof Py::Subscript }
predicate isSubscript() { toAst(this) instanceof Subscript }
/** Whether this flow node corresponds to an import member */
predicate isImportMember() { toAst(this) instanceof Py::ImportMember }
predicate isImportMember() { toAst(this) instanceof ImportMember }
/** Whether this flow node corresponds to a call */
predicate isCall() { toAst(this) instanceof Py::Call }
predicate isCall() { toAst(this) instanceof Call }
/** Whether this flow node is the first in a module */
predicate isModuleEntry() { this.isEntryNode() and toAst(this) instanceof Py::Module }
predicate isModuleEntry() { this.isEntryNode() and toAst(this) instanceof Module }
/** Whether this flow node corresponds to an import */
predicate isImport() { toAst(this) instanceof Py::ImportExpr }
predicate isImport() { toAst(this) instanceof ImportExpr }
/** Whether this flow node corresponds to a conditional expression */
predicate isIfExp() { toAst(this) instanceof Py::IfExp }
predicate isIfExp() { toAst(this) instanceof IfExp }
/** Whether this flow node corresponds to a function definition expression */
predicate isFunction() { toAst(this) instanceof Py::FunctionExpr }
predicate isFunction() { toAst(this) instanceof FunctionExpr }
/** Whether this flow node corresponds to a class definition expression */
predicate isClass() { toAst(this) instanceof Py::ClassExpr }
predicate isClass() { toAst(this) instanceof ClassExpr }
/** Gets a predecessor of this flow node */
ControlFlowNode getAPredecessor() { this = result.getASuccessor() }
@@ -123,25 +123,25 @@ class ControlFlowNode extends @py_flow_node {
ControlFlowNode getImmediateDominator() { py_idoms(this, result) }
/** Gets the syntactic element corresponding to this flow node */
Py::AstNode getNode() { py_flow_bb_node(this, result, _, _) }
AstNode getNode() { py_flow_bb_node(this, result, _, _) }
/** Gets a textual representation of this element. */
cached
string toString() {
Stages::AST::ref() and
// Since modules can have ambigous names, entry nodes can too, if we do not collate them.
exists(Py::Scope s | s.getEntryNode() = this |
exists(Scope s | s.getEntryNode() = this |
result = "Entry node for " + concat( | | s.toString(), ",")
)
or
exists(Py::Scope s | s.getANormalExit() = this | result = "Exit node for " + s.toString())
exists(Scope s | s.getANormalExit() = this | result = "Exit node for " + s.toString())
or
not exists(Py::Scope s | s.getEntryNode() = this or s.getANormalExit() = this) and
not exists(Scope s | s.getEntryNode() = this or s.getANormalExit() = this) and
result = "ControlFlowNode for " + this.getNode().toString()
}
/** Gets the location of this ControlFlowNode */
Py::Location getLocation() { result = this.getNode().getLocation() }
Location getLocation() { result = this.getNode().getLocation() }
/** Whether this flow node is the first in its scope */
predicate isEntryNode() { py_scope_flow(this, _, -1) }
@@ -151,9 +151,9 @@ class ControlFlowNode extends @py_flow_node {
/** Gets the scope containing this flow node */
cached
Py::Scope getScope() {
Scope getScope() {
Stages::AST::ref() and
if this.getNode() instanceof Py::Scope
if this.getNode() instanceof Scope
then
/* Entry or exit node */
result = this.getNode()
@@ -161,7 +161,7 @@ class ControlFlowNode extends @py_flow_node {
}
/** Gets the enclosing module */
Py::Module getEnclosingModule() { result = this.getScope().getEnclosingModule() }
Module getEnclosingModule() { result = this.getScope().getEnclosingModule() }
/** Gets a successor for this node if the relevant condition is True. */
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 */
predicate isExceptionalExit(Py::Scope s) { py_scope_flow(this, s, 1) }
predicate isExceptionalExit(Scope s) { py_scope_flow(this, s, 1) }
/** Whether this node is a normal (non-exceptional) exit */
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() */
pragma[noinline]
private ControlFlowNode getExprChild(BasicBlock dom) {
this.getNode().(Py::Expr).getAChildNode() = result.getNode() and
this.getNode().(Expr).getAChildNode() = result.getNode() and
result.getBasicBlock().dominates(dom) and
not this instanceof UnaryExprNode
}
@@ -249,16 +249,16 @@ class ControlFlowNode extends @py_flow_node {
*/
private class AnyNode extends ControlFlowNode {
override Py::AstNode getNode() { result = super.getNode() }
override AstNode getNode() { result = super.getNode() }
}
/** A control flow node corresponding to a call expression, such as `func(...)` */
class CallNode extends ControlFlowNode {
CallNode() { toAst(this) instanceof Py::Call }
CallNode() { toAst(this) instanceof Call }
/** Gets the flow node corresponding to the function expression for the call corresponding to this flow node */
ControlFlowNode getFunction() {
exists(Py::Call c |
exists(Call c |
this.getNode() = c and
c.getFunc() = result.getNode() and
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 */
ControlFlowNode getArg(int n) {
exists(Py::Call c |
exists(Call c |
this.getNode() = c and
c.getArg(n) = result.getNode() and
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 */
ControlFlowNode getArgByName(string name) {
exists(Py::Call c, Py::Keyword k |
exists(Call c, Keyword k |
this.getNode() = c and
k = c.getANamedArg() and
k.getValue() = result.getNode() and
@@ -292,7 +292,7 @@ class CallNode extends ControlFlowNode {
result = this.getArgByName(_)
}
override Py::Call getNode() { result = super.getNode() }
override Call getNode() { result = super.getNode() }
predicate isDecoratorCall() {
this.isClassDecoratorCall()
@@ -301,11 +301,11 @@ class CallNode extends ControlFlowNode {
}
predicate isClassDecoratorCall() {
exists(Py::ClassExpr cls | this.getNode() = cls.getADecoratorCall())
exists(ClassExpr cls | this.getNode() = cls.getADecoratorCall())
}
predicate isFunctionDecoratorCall() {
exists(Py::FunctionExpr func | this.getNode() = func.getADecoratorCall())
exists(FunctionExpr func | this.getNode() = func.getADecoratorCall())
}
/** 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` */
class AttrNode extends ControlFlowNode {
AttrNode() { toAst(this) instanceof Py::Attribute }
AttrNode() { toAst(this) instanceof Attribute }
/** Gets the flow node corresponding to the object of the attribute expression corresponding to this flow node */
ControlFlowNode getObject() {
exists(Py::Attribute a |
exists(Attribute a |
this.getNode() = a and
a.getObject() = result.getNode() and
result.getBasicBlock().dominates(this.getBasicBlock())
@@ -339,7 +339,7 @@ class AttrNode extends ControlFlowNode {
* with the matching name
*/
ControlFlowNode getObject(string name) {
exists(Py::Attribute a |
exists(Attribute a |
this.getNode() = a and
a.getObject() = result.getNode() 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 */
string getName() { exists(Py::Attribute a | this.getNode() = a and a.getName() = result) }
string getName() { exists(Attribute a | this.getNode() = a and a.getName() = result) }
override Py::Attribute getNode() { result = super.getNode() }
override Attribute getNode() { result = super.getNode() }
}
/** A control flow node corresponding to a `from ... import ...` expression */
class ImportMemberNode extends ControlFlowNode {
ImportMemberNode() { toAst(this) instanceof Py::ImportMember }
ImportMemberNode() { toAst(this) instanceof ImportMember }
/**
* Gets the flow node corresponding to the module in the import-member expression corresponding to this flow node,
* with the matching name
*/
ControlFlowNode getModule(string name) {
exists(Py::ImportMember i | this.getNode() = i and i.getModule() = result.getNode() |
exists(ImportMember i | this.getNode() = i and i.getModule() = result.getNode() |
i.getName() = name and
result.getBasicBlock().dominates(this.getBasicBlock())
)
}
override Py::ImportMember getNode() { result = super.getNode() }
override ImportMember getNode() { result = super.getNode() }
}
/** A control flow node corresponding to an artificial expression representing an import */
class ImportExprNode extends ControlFlowNode {
ImportExprNode() { toAst(this) instanceof Py::ImportExpr }
ImportExprNode() { toAst(this) instanceof ImportExpr }
override Py::ImportExpr getNode() { result = super.getNode() }
override ImportExpr getNode() { result = super.getNode() }
}
/** A control flow node corresponding to a `from ... import *` statement */
class ImportStarNode extends ControlFlowNode {
ImportStarNode() { toAst(this) instanceof Py::ImportStar }
ImportStarNode() { toAst(this) instanceof ImportStar }
/** Gets the flow node corresponding to the module in the import-star corresponding to this flow node */
ControlFlowNode getModule() {
exists(Py::ImportStar i | this.getNode() = i and i.getModuleExpr() = result.getNode() |
exists(ImportStar i | this.getNode() = i and i.getModuleExpr() = result.getNode() |
result.getBasicBlock().dominates(this.getBasicBlock())
)
}
override Py::ImportStar getNode() { result = super.getNode() }
override ImportStar getNode() { result = super.getNode() }
}
/** A control flow node corresponding to a subscript expression, such as `value[slice]` */
class SubscriptNode extends ControlFlowNode {
SubscriptNode() { toAst(this) instanceof Py::Subscript }
SubscriptNode() { toAst(this) instanceof Subscript }
/** flow node corresponding to the value of the sequence in a subscript operation */
ControlFlowNode getObject() {
exists(Py::Subscript s |
exists(Subscript s |
this.getNode() = s and
s.getObject() = result.getNode() and
result.getBasicBlock().dominates(this.getBasicBlock())
@@ -407,23 +407,23 @@ class SubscriptNode extends ControlFlowNode {
/** flow node corresponding to the index in a subscript operation */
ControlFlowNode getIndex() {
exists(Py::Subscript s |
exists(Subscript s |
this.getNode() = s and
s.getIndex() = result.getNode() and
result.getBasicBlock().dominates(this.getBasicBlock())
)
}
override Py::Subscript getNode() { result = super.getNode() }
override Subscript getNode() { result = super.getNode() }
}
/** A control flow node corresponding to a comparison operation, such as `x<y` */
class CompareNode extends ControlFlowNode {
CompareNode() { toAst(this) instanceof Py::Compare }
CompareNode() { toAst(this) instanceof Compare }
/** Whether left and right are a pair of operands for this comparison */
predicate operands(ControlFlowNode left, Py::Cmpop op, ControlFlowNode right) {
exists(Py::Compare c, Py::Expr eleft, Py::Expr eright |
predicate operands(ControlFlowNode left, Cmpop op, ControlFlowNode right) {
exists(Compare c, Expr eleft, Expr 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)
@@ -436,26 +436,26 @@ class CompareNode extends ControlFlowNode {
right.getBasicBlock().dominates(this.getBasicBlock())
}
override Py::Compare getNode() { result = super.getNode() }
override Compare getNode() { result = super.getNode() }
}
/** A control flow node corresponding to a conditional expression such as, `body if test else orelse` */
class IfExprNode extends ControlFlowNode {
IfExprNode() { toAst(this) instanceof Py::IfExp }
IfExprNode() { toAst(this) instanceof IfExp }
/** flow node corresponding to one of the operands of an if-expression */
ControlFlowNode getAnOperand() { result = this.getAPredecessor() }
override Py::IfExp getNode() { result = super.getNode() }
override IfExp getNode() { result = super.getNode() }
}
/** A control flow node corresponding to an assignment expression such as `lhs := rhs`. */
class AssignmentExprNode extends ControlFlowNode {
AssignmentExprNode() { toAst(this) instanceof Py::AssignExpr }
AssignmentExprNode() { toAst(this) instanceof AssignExpr }
/** Gets the flow node corresponding to the left-hand side of the assignment expression */
ControlFlowNode getTarget() {
exists(Py::AssignExpr a |
exists(AssignExpr a |
this.getNode() = a and
a.getTarget() = result.getNode() and
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 */
ControlFlowNode getValue() {
exists(Py::AssignExpr a |
exists(AssignExpr a |
this.getNode() = a and
a.getValue() = result.getNode() and
result.getBasicBlock().dominates(this.getBasicBlock())
)
}
override Py::AssignExpr getNode() { result = super.getNode() }
override AssignExpr getNode() { result = super.getNode() }
}
/** A control flow node corresponding to a binary expression, such as `x + y` */
class BinaryExprNode extends ControlFlowNode {
BinaryExprNode() { toAst(this) instanceof Py::BinaryExpr }
BinaryExprNode() { toAst(this) instanceof BinaryExpr }
/** flow node corresponding to one of the operands of a binary expression */
ControlFlowNode getAnOperand() { result = this.getLeft() or result = this.getRight() }
override Py::BinaryExpr getNode() { result = super.getNode() }
override BinaryExpr getNode() { result = super.getNode() }
ControlFlowNode getLeft() {
exists(Py::BinaryExpr b |
exists(BinaryExpr b |
this.getNode() = b and
result.getNode() = b.getLeft() and
result.getBasicBlock().dominates(this.getBasicBlock())
@@ -492,7 +492,7 @@ class BinaryExprNode extends ControlFlowNode {
}
ControlFlowNode getRight() {
exists(Py::BinaryExpr b |
exists(BinaryExpr b |
this.getNode() = b and
result.getNode() = b.getRight() and
result.getBasicBlock().dominates(this.getBasicBlock())
@@ -500,11 +500,11 @@ class BinaryExprNode extends ControlFlowNode {
}
/** Gets the operator of this binary expression node. */
Py::Operator getOp() { result = this.getNode().getOp() }
Operator getOp() { result = this.getNode().getOp() }
/** Whether left and right are a pair of operands for this binary expression */
predicate operands(ControlFlowNode left, Py::Operator op, ControlFlowNode right) {
exists(Py::BinaryExpr b, Py::Expr eleft, Py::Expr eright |
predicate operands(ControlFlowNode left, Operator op, ControlFlowNode right) {
exists(BinaryExpr b, Expr eleft, Expr eright |
this.getNode() = b and left.getNode() = eleft and right.getNode() = eright
|
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 */
class BoolExprNode extends ControlFlowNode {
BoolExprNode() { toAst(this) instanceof Py::BoolExpr }
BoolExprNode() { toAst(this) instanceof BoolExpr }
/** flow node corresponding to one of the operands of a boolean expression */
ControlFlowNode getAnOperand() {
exists(Py::BoolExpr b | this.getNode() = b and result.getNode() = b.getAValue()) and
exists(BoolExpr b | this.getNode() = b and result.getNode() = b.getAValue()) and
this.getBasicBlock().dominates(result.getBasicBlock())
}
override Py::BoolExpr getNode() { result = super.getNode() }
override BoolExpr getNode() { result = super.getNode() }
}
/** A control flow node corresponding to a unary expression: (`+x`), (`-x`) or (`~x`) */
class UnaryExprNode extends ControlFlowNode {
UnaryExprNode() { toAst(this) instanceof Py::UnaryExpr }
UnaryExprNode() { toAst(this) instanceof UnaryExpr }
/**
* Gets flow node corresponding to the operand of a unary expression.
@@ -540,7 +540,7 @@ class UnaryExprNode extends ControlFlowNode {
*/
ControlFlowNode getOperand() { result = this.getAPredecessor() }
override Py::UnaryExpr getNode() { result = super.getNode() }
override UnaryExpr getNode() { result = super.getNode() }
override ControlFlowNode getAChild() { result = this.getAPredecessor() }
}
@@ -555,22 +555,22 @@ class DefinitionNode extends ControlFlowNode {
cached
DefinitionNode() {
Stages::AST::ref() and
exists(Py::Assign a | this.getNode() = a.getATarget())
exists(Assign a | this.getNode() = a.getATarget())
or
exists(Py::AssignExpr a | this.getNode() = a.getTarget())
exists(AssignExpr a | this.getNode() = a.getTarget())
or
exists(Py::AnnAssign a | this.getNode() = a.getTarget() and exists(a.getValue()))
exists(AnnAssign a | this.getNode() = a.getTarget() and exists(a.getValue()))
or
exists(Py::Alias a | this.getNode() = a.getAsname())
exists(Alias a | this.getNode() = a.getAsname())
or
augstore(_, this)
or
// `x, y = 1, 2` where LHS is a combination of list or tuples
exists(Py::Assign a | this.getNode() = list_or_tuple_nested_element(a.getATarget()))
exists(Assign a | this.getNode() = list_or_tuple_nested_element(a.getATarget()))
or
exists(Py::For for | this.getNode() = for.getTarget())
exists(For for | this.getNode() = for.getTarget())
or
exists(Py::Parameter param | this.getNode() = param.asName() and exists(param.getDefault()))
exists(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 */
@@ -584,16 +584,16 @@ class DefinitionNode extends ControlFlowNode {
// 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,
// there is no dominance relationship between the two.
exists(Py::Parameter param | this.getNode() = param.asName())
exists(Parameter param | this.getNode() = param.asName())
)
}
}
private Py::Expr list_or_tuple_nested_element(Py::Expr list_or_tuple) {
exists(Py::Expr elt |
elt = list_or_tuple.(Py::Tuple).getAnElt()
private Expr list_or_tuple_nested_element(Expr list_or_tuple) {
exists(Expr elt |
elt = list_or_tuple.(Tuple).getAnElt()
or
elt = list_or_tuple.(Py::List).getAnElt()
elt = list_or_tuple.(List).getAnElt()
|
result = elt
or
@@ -603,12 +603,12 @@ private Py::Expr list_or_tuple_nested_element(Py::Expr list_or_tuple) {
/**
* A control flow node corresponding to a deletion statement, such as `del x`.
* There can be multiple `DeletionNode`s for each `Py::Delete` such that each
* There can be multiple `DeletionNode`s for each `Delete` such that each
* target has own `DeletionNode`. The CFG for `del a, x.y` looks like:
* `NameNode('a') -> DeletionNode -> NameNode('b') -> AttrNode('y') -> DeletionNode`.
*/
class DeletionNode extends ControlFlowNode {
DeletionNode() { toAst(this) instanceof Py::Delete }
DeletionNode() { toAst(this) instanceof Delete }
/** Gets the unique target of this deletion node. */
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 */
abstract class SequenceNode extends ControlFlowNode {
SequenceNode() {
toAst(this) instanceof Py::Tuple
toAst(this) instanceof Tuple
or
toAst(this) instanceof Py::List
toAst(this) instanceof List
}
/** 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 )` */
class TupleNode extends SequenceNode {
TupleNode() { toAst(this) instanceof Py::Tuple }
TupleNode() { toAst(this) instanceof Tuple }
override ControlFlowNode getElement(int n) {
Stages::AST::ref() and
exists(Py::Tuple t | this.getNode() = t and result.getNode() = t.getElt(n)) and
exists(Tuple t | this.getNode() = t and result.getNode() = t.getElt(n)) and
(
result.getBasicBlock().dominates(this.getBasicBlock())
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 ]` */
class ListNode extends SequenceNode {
ListNode() { toAst(this) instanceof Py::List }
ListNode() { toAst(this) instanceof List }
override ControlFlowNode getElement(int n) {
exists(Py::List l | this.getNode() = l and result.getNode() = l.getElt(n)) and
exists(List l | this.getNode() = l and result.getNode() = l.getElt(n)) and
(
result.getBasicBlock().dominates(this.getBasicBlock())
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 }` */
class SetNode extends ControlFlowNode {
SetNode() { toAst(this) instanceof Py::Set }
SetNode() { toAst(this) instanceof Set }
ControlFlowNode getAnElement() {
exists(Py::Set s | this.getNode() = s and result.getNode() = s.getElt(_)) and
exists(Set s | this.getNode() = s and result.getNode() = s.getElt(_)) and
(
result.getBasicBlock().dominates(this.getBasicBlock())
or
@@ -675,20 +675,20 @@ class SetNode extends ControlFlowNode {
/** A control flow node corresponding to a dictionary literal, such as `{ 'a': 1, 'b': 2 }` */
class DictNode extends ControlFlowNode {
DictNode() { toAst(this) instanceof Py::Dict }
DictNode() { toAst(this) instanceof Dict }
/**
* Gets a key of this dictionary literal node, for those items that have keys
* E.g, in {'a':1, **b} this returns only 'a'
*/
ControlFlowNode getAKey() {
exists(Py::Dict d | this.getNode() = d and result.getNode() = d.getAKey()) and
exists(Dict d | this.getNode() = d and result.getNode() = d.getAKey()) and
result.getBasicBlock().dominates(this.getBasicBlock())
}
/** Gets a value of this dictionary literal node */
ControlFlowNode getAValue() {
exists(Py::Dict d | this.getNode() = d and result.getNode() = d.getAValue()) and
exists(Dict d | this.getNode() = d and result.getNode() = d.getAValue()) and
result.getBasicBlock().dominates(this.getBasicBlock())
}
}
@@ -712,23 +712,21 @@ class IterableNode extends ControlFlowNode {
}
}
private Py::AstNode assigned_value(Py::Expr lhs) {
private AstNode assigned_value(Expr lhs) {
/* lhs = result */
exists(Py::Assign a | a.getATarget() = lhs and result = a.getValue())
exists(Assign a | a.getATarget() = lhs and result = a.getValue())
or
/* lhs := result */
exists(Py::AssignExpr a | a.getTarget() = lhs and result = a.getValue())
exists(AssignExpr a | a.getTarget() = lhs and result = a.getValue())
or
/* lhs : annotation = result */
exists(Py::AnnAssign a | a.getTarget() = lhs and result = a.getValue())
exists(AnnAssign a | a.getTarget() = lhs and result = a.getValue())
or
/* import result as lhs */
exists(Py::Alias a | a.getAsname() = lhs and result = a.getValue())
exists(Alias a | a.getAsname() = lhs and result = a.getValue())
or
/* lhs += x => result = (lhs + x) */
exists(Py::AugAssign a, Py::BinaryExpr b |
b = a.getOperation() and result = b and lhs = b.getLeft()
)
exists(AugAssign a, BinaryExpr b | b = a.getOperation() and result = b and lhs = b.getLeft())
or
/*
* ..., lhs, ... = ..., result, ...
@@ -736,31 +734,31 @@ private Py::AstNode assigned_value(Py::Expr lhs) {
* ..., (..., lhs, ...), ... = ..., (..., result, ...), ...
*/
exists(Py::Assign a | nested_sequence_assign(a.getATarget(), a.getValue(), lhs, result))
exists(Assign a | nested_sequence_assign(a.getATarget(), a.getValue(), lhs, result))
or
/* for lhs in seq: => `result` is the `for` node, representing the `iter(next(seq))` operation. */
result.(Py::For).getTarget() = lhs
result.(For).getTarget() = lhs
or
exists(Py::Parameter param | lhs = param.asName() and result = param.getDefault())
exists(Parameter param | lhs = param.asName() and result = param.getDefault())
}
predicate nested_sequence_assign(
Py::Expr left_parent, Py::Expr right_parent, Py::Expr left_result, Py::Expr right_result
Expr left_parent, Expr right_parent, Expr left_result, Expr right_result
) {
exists(Py::Assign a |
exists(Assign a |
a.getATarget().getASubExpression*() = left_parent and
a.getValue().getASubExpression*() = right_parent
) and
exists(int i, Py::Expr left_elem, Py::Expr right_elem |
exists(int i, Expr left_elem, Expr right_elem |
(
left_elem = left_parent.(Py::Tuple).getElt(i)
left_elem = left_parent.(Tuple).getElt(i)
or
left_elem = left_parent.(Py::List).getElt(i)
left_elem = left_parent.(List).getElt(i)
) and
(
right_elem = right_parent.(Py::Tuple).getElt(i)
right_elem = right_parent.(Tuple).getElt(i)
or
right_elem = right_parent.(Py::List).getElt(i)
right_elem = right_parent.(List).getElt(i)
)
|
left_result = left_elem and right_result = right_elem
@@ -771,9 +769,9 @@ predicate nested_sequence_assign(
/** A flow node for a `for` statement. */
class ForNode extends ControlFlowNode {
ForNode() { toAst(this) instanceof Py::For }
ForNode() { toAst(this) instanceof For }
override Py::For getNode() { result = super.getNode() }
override For getNode() { result = super.getNode() }
/** Holds if this `for` statement causes iteration over `sequence` storing each step of the iteration in `target` */
predicate iterates(ControlFlowNode target, ControlFlowNode sequence) {
@@ -784,7 +782,7 @@ class ForNode extends ControlFlowNode {
/** Gets the sequence node for this `for` statement. */
ControlFlowNode getSequence() {
exists(Py::For for |
exists(For for |
toAst(this) = for and
for.getIter() = result.getNode()
|
@@ -794,7 +792,7 @@ class ForNode extends ControlFlowNode {
/** A possible `target` for this `for` statement, not accounting for loop unrolling */
private ControlFlowNode possibleTarget() {
exists(Py::For for |
exists(For for |
toAst(this) = for and
for.getTarget() = result.getNode() and
this.getBasicBlock().dominates(result.getBasicBlock())
@@ -811,11 +809,11 @@ class ForNode extends ControlFlowNode {
/** A flow node for a `raise` statement */
class RaiseStmtNode extends ControlFlowNode {
RaiseStmtNode() { toAst(this) instanceof Py::Raise }
RaiseStmtNode() { toAst(this) instanceof Raise }
/** Gets the control flow node for the exception raised by this raise statement */
ControlFlowNode getException() {
exists(Py::Raise r |
exists(Raise r |
r = toAst(this) and
r.getException() = toAst(result) and
result.getBasicBlock().dominates(this.getBasicBlock())
@@ -829,36 +827,36 @@ class RaiseStmtNode extends ControlFlowNode {
*/
class NameNode extends ControlFlowNode {
NameNode() {
exists(Py::Name n | py_flow_bb_node(this, n, _, _))
exists(Name n | py_flow_bb_node(this, n, _, _))
or
exists(Py::PlaceHolder p | py_flow_bb_node(this, p, _, _))
exists(PlaceHolder p | py_flow_bb_node(this, p, _, _))
}
/** Whether this flow node defines the variable `v`. */
predicate defines(Py::Variable v) {
exists(Py::Name d | this.getNode() = d and d.defines(v)) and
predicate defines(Variable v) {
exists(Name d | this.getNode() = d and d.defines(v)) and
not this.isLoad()
}
/** Whether this flow node deletes the variable `v`. */
predicate deletes(Py::Variable v) { exists(Py::Name d | this.getNode() = d and d.deletes(v)) }
predicate deletes(Variable v) { exists(Name d | this.getNode() = d and d.deletes(v)) }
/** Whether this flow node uses the variable `v`. */
predicate uses(Py::Variable v) {
predicate uses(Variable v) {
this.isLoad() and
exists(Py::Name u | this.getNode() = u and u.uses(v))
exists(Name u | this.getNode() = u and u.uses(v))
or
exists(Py::PlaceHolder u |
this.getNode() = u and u.getVariable() = v and u.getCtx() instanceof Py::Load
exists(PlaceHolder u |
this.getNode() = u and u.getVariable() = v and u.getCtx() instanceof Load
)
or
Scopes::use_of_global_variable(this, v.getScope(), v.getId())
}
string getId() {
result = this.getNode().(Py::Name).getId()
result = this.getNode().(Name).getId()
or
result = this.getNode().(Py::PlaceHolder).getId()
result = this.getNode().(PlaceHolder).getId()
}
/** Whether this is a use of a local variable. */
@@ -870,39 +868,37 @@ class NameNode extends ControlFlowNode {
/** Whether this is a use of a global (including builtin) variable. */
predicate isGlobal() { Scopes::use_of_global_variable(this, _, _) }
predicate isSelf() {
exists(Py::SsaVariable selfvar | selfvar.isSelf() and selfvar.getAUse() = this)
}
predicate isSelf() { exists(SsaVariable selfvar | selfvar.isSelf() and selfvar.getAUse() = this) }
}
/** A control flow node corresponding to a named constant, one of `None`, `True` or `False`. */
class NameConstantNode extends NameNode {
NameConstantNode() { exists(Py::NameConstant n | py_flow_bb_node(this, n, _, _)) }
NameConstantNode() { exists(NameConstant n | py_flow_bb_node(this, n, _, _)) }
/*
* We ought to override uses as well, but that has
* a serious performance impact.
* deprecated predicate uses(Py::Variable v) { none() }
* deprecated predicate uses(Variable v) { none() }
*/
}
/** A control flow node corresponding to a starred expression, `*a`. */
class StarredNode extends ControlFlowNode {
StarredNode() { toAst(this) instanceof Py::Starred }
StarredNode() { toAst(this) instanceof Starred }
ControlFlowNode getValue() { toAst(result) = toAst(this).(Py::Starred).getValue() }
ControlFlowNode getValue() { toAst(result) = toAst(this).(Starred).getValue() }
}
/** The ControlFlowNode for an 'except' statement. */
class ExceptFlowNode extends ControlFlowNode {
ExceptFlowNode() { this.getNode() instanceof Py::ExceptStmt }
ExceptFlowNode() { this.getNode() instanceof ExceptStmt }
/**
* Gets the type handled by this exception handler.
* `Py::ExceptionType` in `except Py::ExceptionType as e:`
* `ExceptionType` in `except ExceptionType as e:`
*/
ControlFlowNode getType() {
exists(Py::ExceptStmt ex |
exists(ExceptStmt ex |
this.getBasicBlock().dominates(result.getBasicBlock()) and
ex = this.getNode() and
result.getNode() = ex.getType()
@@ -911,10 +907,10 @@ class ExceptFlowNode extends ControlFlowNode {
/**
* Gets the name assigned to the handled exception, if any.
* `e` in `except Py::ExceptionType as e:`
* `e` in `except ExceptionType as e:`
*/
ControlFlowNode getName() {
exists(Py::ExceptStmt ex |
exists(ExceptStmt ex |
this.getBasicBlock().dominates(result.getBasicBlock()) and
ex = this.getNode() and
result.getNode() = ex.getName()
@@ -924,30 +920,30 @@ class ExceptFlowNode extends ControlFlowNode {
/** The ControlFlowNode for an 'except*' statement. */
class ExceptGroupFlowNode extends ControlFlowNode {
ExceptGroupFlowNode() { this.getNode() instanceof Py::ExceptGroupStmt }
ExceptGroupFlowNode() { this.getNode() instanceof ExceptGroupStmt }
/**
* Gets the type handled by this exception handler.
* `Py::ExceptionType` in `except* Py::ExceptionType as e:`
* `ExceptionType` in `except* ExceptionType as e:`
*/
ControlFlowNode getType() {
this.getBasicBlock().dominates(result.getBasicBlock()) and
result.getNode() = this.getNode().(Py::ExceptGroupStmt).getType()
result.getNode() = this.getNode().(ExceptGroupStmt).getType()
}
/**
* Gets the name assigned to the handled exception, if any.
* `e` in `except* Py::ExceptionType as e:`
* `e` in `except* ExceptionType as e:`
*/
ControlFlowNode getName() {
this.getBasicBlock().dominates(result.getBasicBlock()) and
result.getNode() = this.getNode().(Py::ExceptGroupStmt).getName()
result.getNode() = this.getNode().(ExceptGroupStmt).getName()
}
}
private module Scopes {
private predicate fast_local(NameNode n) {
exists(Py::FastLocalVariable v |
exists(FastLocalVariable v |
n.uses(v) and
v.getScope() = n.getScope()
)
@@ -956,15 +952,15 @@ private module Scopes {
predicate local(NameNode n) {
fast_local(n)
or
exists(Py::SsaVariable var |
exists(SsaVariable var |
var.getAUse() = n and
n.getScope() instanceof Py::Class and
n.getScope() instanceof Class and
exists(var.getDefinition())
)
}
predicate non_local(NameNode n) {
exists(Py::FastLocalVariable flv |
exists(FastLocalVariable flv |
flv.getALoad() = n.getNode() and
not flv.getScope() = n.getScope()
)
@@ -972,20 +968,20 @@ private module Scopes {
// magic is fine, but we get questionable join-ordering of it
pragma[nomagic]
predicate use_of_global_variable(NameNode n, Py::Module scope, string name) {
predicate use_of_global_variable(NameNode n, Module scope, string name) {
n.isLoad() and
not non_local(n) and
not exists(Py::SsaVariable var | var.getAUse() = n |
var.getVariable() instanceof Py::FastLocalVariable
not exists(SsaVariable var | var.getAUse() = n |
var.getVariable() instanceof FastLocalVariable
or
n.getScope() instanceof Py::Class and
n.getScope() instanceof Class and
not maybe_undefined(var)
) and
name = n.getId() and
scope = n.getEnclosingModule()
}
private predicate maybe_undefined(Py::SsaVariable var) {
private predicate maybe_undefined(SsaVariable var) {
not exists(var.getDefinition()) and not py_ssa_phi(var, _)
or
var.getDefinition().isDelete()
@@ -1062,13 +1058,13 @@ class BasicBlock extends @py_flow_node {
private predicate oneNodeBlock() { this.firstNode() = this.getLastNode() }
private predicate startLocationInfo(string file, int line, int col) {
if this.firstNode().getNode() instanceof Py::Scope
if this.firstNode().getNode() instanceof Scope
then this.firstNode().getASuccessor().getLocation().hasLocationInfo(file, line, col, _, _)
else this.firstNode().getLocation().hasLocationInfo(file, line, col, _, _)
}
private predicate endLocationInfo(int endl, int endc) {
if this.getLastNode().getNode() instanceof Py::Scope and not this.oneNodeBlock()
if this.getLastNode().getNode() instanceof Scope and not this.oneNodeBlock()
then this.getLastNode().getAPredecessor().getLocation().hasLocationInfo(_, _, _, endl, endc)
else this.getLastNode().getLocation().hasLocationInfo(_, _, _, endl, endc)
}
@@ -1085,7 +1081,7 @@ class BasicBlock extends @py_flow_node {
/** Whether flow from this basic block reaches a normal exit from its scope */
predicate reachesExit() {
exists(Py::Scope s | s.getANormalExit().getBasicBlock() = this)
exists(Scope s | s.getANormalExit().getBasicBlock() = this)
or
this.getASuccessor().reachesExit()
}
@@ -1126,7 +1122,7 @@ class BasicBlock extends @py_flow_node {
/** Gets the scope of this block */
pragma[nomagic]
Py::Scope getScope() {
Scope getScope() {
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 */
not py_scope_flow(n, _, -1) and
@@ -1149,17 +1145,17 @@ class BasicBlock extends @py_flow_node {
predicate reaches(BasicBlock other) { this = other or this.strictlyReaches(other) }
/**
* Gets the `Py::ConditionBlock`, if any, that controls this block and
* does not control any other `Py::ConditionBlock`s that control this block.
* That is the `Py::ConditionBlock` that is closest dominator.
* Gets the `ConditionBlock`, if any, that controls this block and
* does not control any other `ConditionBlock`s that control this block.
* That is the `ConditionBlock` that is closest dominator.
*/
Py::ConditionBlock getImmediatelyControllingBlock() {
ConditionBlock getImmediatelyControllingBlock() {
result = this.nonControllingImmediateDominator*().getImmediateDominator()
}
private BasicBlock nonControllingImmediateDominator() {
result = this.getImmediateDominator() and
not result.(Py::ConditionBlock).controls(this, _)
not result.(ConditionBlock).controls(this, _)
}
/**
@@ -1179,7 +1175,7 @@ private class ControlFlowNodeAlias = ControlFlowNode;
final private class FinalBasicBlock = BasicBlock;
module Cfg implements BB::CfgSig<Py::Location> {
module Cfg implements BB::CfgSig<Location> {
private import codeql.controlflow.SuccessorType
class ControlFlowNode = ControlFlowNodeAlias;
@@ -1190,7 +1186,7 @@ module Cfg implements BB::CfgSig<Py::Location> {
// Using the location of the first node is simple
// and we just need a way to identify the basic block
// during debugging, so this will be serviceable.
Py::Location getLocation() { result = super.getNode(0).getLocation() }
Location getLocation() { result = super.getNode(0).getLocation() }
int length() { result = count(int i | exists(this.getNode(i))) }

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +0,0 @@
consistencyOverview
| deadEnd | 1 |
deadEnd
| without_loop.py:7:5:7:9 | Break |

View File

@@ -1,32 +0,0 @@
/**
* 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>

View File

@@ -1,13 +0,0 @@
# 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

View File

@@ -1,14 +0,0 @@
# 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

View File

@@ -1,21 +0,0 @@
# 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

View File

@@ -1,52 +0,0 @@
# 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

View File

@@ -1,30 +0,0 @@
# 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

View File

@@ -1,19 +0,0 @@
# 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

View File

@@ -1,14 +0,0 @@
# 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
)

View File

@@ -1,24 +0,0 @@
# 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

View File

@@ -1,42 +0,0 @@
# 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

View File

@@ -1,14 +0,0 @@
# 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

View File

@@ -1,21 +0,0 @@
# 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

View File

@@ -1,14 +0,0 @@
# 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

View File

@@ -1,21 +0,0 @@
# `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

View File

@@ -5,8 +5,6 @@
* have separate CFGs and are excluded from this check.
*/
import python
import TimerUtils
import OldCfgImpl
private module Utils = EvalOrderCfgUtils<OldCfg>;

View File

@@ -2,8 +2,6 @@
* Checks that every timer annotation has a corresponding CFG node.
*/
import python
import TimerUtils
import OldCfgImpl
private module Utils = EvalOrderCfgUtils<OldCfg>;

View File

@@ -8,8 +8,6 @@
* edge leaves the basic block and the normal successor may be dead.
*/
import python
import TimerUtils
import OldCfgImpl
private module Utils = EvalOrderCfgUtils<OldCfg>;

View File

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

View File

@@ -3,8 +3,6 @@
* increasing minimum-timestamp order.
*/
import python
import TimerUtils
import OldCfgImpl
private module Utils = EvalOrderCfgUtils<OldCfg>;

View File

@@ -11,8 +11,6 @@
* lambdas that have annotations in nested scopes).
*/
import python
import TimerUtils
import OldCfgImpl
private module Utils = EvalOrderCfgUtils<OldCfg>;

View File

@@ -4,7 +4,6 @@
* in at least one annotation (live or dead).
*/
import python
import TimerUtils
from TestFunction f, int missing, int maxTs, TimerAnnotation maxAnn

View File

@@ -4,8 +4,6 @@
* entry (including within the same basic block).
*/
import python
import TimerUtils
import OldCfgImpl
private module Utils = EvalOrderCfgUtils<OldCfg>;

View File

@@ -1,14 +0,0 @@
/** New-CFG version of AllLiveReachable. */
import python
import TimerUtils
import NewCfgImpl
private module Utils = EvalOrderCfgUtils<NewCfg>;
private import Utils
private import Utils::CfgTests
from TimerCfgNode a, TestFunction f
where allLiveReachable(a, f)
select a, "Unreachable live annotation; entry of $@ does not reach this node", f, f.getName()

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