Compare commits

..

4 Commits

Author SHA1 Message Date
yoff
47d2b05bc5 Python: visit function parameter and return annotations in new CFG
The new (shared-CFG-based) Python control flow graph in
`semmle.python.controlflow.internal.Cfg` previously did not emit CFG
nodes for parameter type annotations (`def f(x: T): ...`) or for the
return type annotation (`-> T`). The legacy CFG emitted both, and a
small number of framework models rely on this: `LocalSources.qll`'s
`annotatedInstance` walks the parameter annotation expression by way
of its CFG node to track that a parameter receives an instance of the
annotated class.

After the dataflow flip to the new CFG/SSA this regression manifested
as lost flows in any test exercising annotation-based parameter
tracking: FastAPI `Depends()` receivers, Pydantic request bodies,
Starlette `WebSocket`, the call-graph type-annotation test, and so on.
Extend `FunctionDefExpr` to visit each annotation as a child of the
function-def expression, in CPython evaluation order: positional
parameter annotations, `*args` annotation, keyword-only parameter
annotations, `**kwargs` annotation, then the return annotation. (Lambda
expressions have no annotations in Python syntax, so `LambdaExpr` is
unchanged.) PEP 695 type parameters remain out of scope; they belong
to the inner annotation scope, not the enclosing CFG.

Restored test results across `framework/aiohttp`, `framework/fastapi`,
`framework/lxml`, the `CallGraph-type-annotations` test, and
`CWE-022-PathInjection`. Two FastAPI list-comprehension MISSING markers
become positive (`taint_test.py:41,55`). CPython CFG consistency
remains clean.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-30 15:22:36 +00:00
yoff
41c9d8b80a Python: model exception edges for raise-prone expressions inside try/with
The new CFG previously only emitted exception edges for explicit `raise`
and `assert` statements. As a result, code that became reachable only
via the exception path of an arbitrary expression (e.g., the body of an
`except` handler following a try-body whose `call()` could raise) was
classified as dead, breaking analyses like StackTraceExposure,
FileNotAlwaysClosed, ExceptionInfo, UseOfExit, and CatchingBaseException.

This commit adds a `mayThrow` predicate over expressions that are known
sources of implicit exceptions in Python (calls, attribute access,
subscripts, arithmetic/comparison operators, imports, await/yield/yield
from) plus `from m import *` at the statement level, and routes them
through the shared CFG's `beginAbruptCompletion(_, _, ExceptionSuccessor,
always=false)` hook.

The set of exception sources is restricted to nodes that are
syntactically inside a `try`/`with` statement in the same scope.
This mirrors Java's `ControlFlowGraph::mayThrow`, which only emits
exception edges where local handling can observe them — outside such
contexts, the edges add CFG complexity (weakening BarrierGuard
precision and breaking SSA continuity around augmented assignments and
subscript stores) without analysis benefit, since exceptions just
propagate to the function exit anyway.

Net effect on the test suite: ~100 alerts restored across the exception-
related query tests (StackTraceExposure +29, ExceptionInfo +17,
FileNotAlwaysClosed +52, UseOfExit +1, CatchingBaseException restored)
with no precision regressions. Affected `.expected` files and the
regression-guard `dead_under_no_raise.py` are updated accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-30 15:22:36 +00:00
yoff
fbfbbd342a Python: add new shared-CFG-backed control flow graph facade (Cfg)
Adds the public facade on top of the AstNodeImpl adapter from the
previous commit. Re-exposes the same API surface as
semmle/python/Flow.qll (ControlFlowNode, CallNode, BasicBlock,
NameNode, DefinitionNode, CompareNode, ...), backed by the shared
codeql.controlflow.ControlFlowGraph library.

- semmle.python.controlflow.internal.Cfg — public facade.
- ControlFlow/store-load/* — basic store/load coverage via the facade.

The new CFG library is added additively: it has zero callers in lib/
and src/, and the legacy CFG in semmle/python/Flow.qll remains the
default. Dataflow, SSA, and production query migration land in
follow-up PRs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-30 15:22:35 +00:00
yoff
872c08148e Python: add shared-CFG AstSig adapter (AstNodeImpl)
Preparatory refactor for the shared-CFG dataflow migration. Adds the
adapter that mediates between the Python AST and the shared
codeql.controlflow.ControlFlowGraph signature, plus the test suites
that validate the new CFG directly against this adapter. The public
facade is added in the following commit.

Library additions:

- semmle.python.controlflow.internal.AstNodeImpl — wraps Python's
  Stmt/Expr/Scope/Pattern and adds two synthetic kinds of node
  (BlockStmt for body slots, intermediate nodes for multi-operand
  boolean expressions) to satisfy the shared CFG signature.

- lib/ide-contextual-queries/printCfg.ql — the IDE "Print CFG" query, retargeted to the new CFG.

- consistency-queries/CfgConsistency.ql — consistency query running
  the shared CFG's standard checks against Python.

Test additions (all driven directly off AstNodeImpl):

- ControlFlow/bindings/* — annotation-driven SSA-binding tests
  (annassign, compound, comprehension, decorated, except_handler,
  imports, match_pattern, parameters, simple, type_params,
  walrus_starred, with_stmt, dead_under_no_raise).

- ControlFlow/evaluation-order/NewCfg*.ql — mirrors of the existing
  OldCfg evaluation-order self-validation suite, run against the
  new CFG via NewCfgImpl.qll.

- Minor extensions to existing test_if.py / test_boolean.py +
  cosmetic .expected churn on a handful of OldCfg tests.

No dataflow, SSA, or production query is migrated yet.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-29 18:49:41 +00:00
384 changed files with 11386 additions and 7523 deletions

View File

@@ -1,4 +0,0 @@
---
category: deprecated
---
* Models-as-data flow summaries now use fully qualified field names (for example, `MyNamespace::MyStruct::myField`) instead of unqualified field names such as `myField`. We recommend updating existing flow summaries to use fully qualified field names. Unqualified field names are still supported, but that support will be removed in a future release.

View File

@@ -1,4 +0,0 @@
---
category: breaking
---
* Removed support for using variables as sources and sinks in models-as-data. Users of this feature should convert such sources and sinks to models defined using the QL language.

View File

@@ -931,6 +931,31 @@ private Element interpretElement0(
signature = "" and
elementSpec(namespace, type, subtypes, name, signature, _)
)
or
// Member variables
elementSpec(namespace, type, subtypes, name, signature, _) and
signature = "" and
exists(Class namedClass, Class classWithMember, MemberVariable member |
member.getName() = name and
member = classWithMember.getAMember() and
namedClass.hasQualifiedName(namespace, type) and
result = member
|
// field declared in the named type or a subtype of it (or an extension of any)
subtypes = true and
classWithMember = namedClass.getADerivedClass*()
or
// field declared directly in the named type (or an extension of it)
subtypes = false and
classWithMember = namedClass
)
or
// Global or namespace variables
elementSpec(namespace, type, subtypes, name, signature, _) and
signature = "" and
type = "" and
subtypes = false and
result = any(GlobalOrNamespaceVariable v | v.hasQualifiedName(namespace, name))
}
cached

View File

@@ -40,24 +40,12 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
arg = repeatStars(rk.(NormalReturnKind).getIndirectionIndex())
}
bindingset[namespace, type, base]
private string formatQualifiedName(string namespace, string type, string base) {
if namespace = ""
then result = type + "::" + base
else result = namespace + "::" + type + "::" + base
}
string encodeContent(ContentSet cs, string arg) {
exists(FieldContent c, string namespace, string type, string base |
exists(FieldContent c |
cs.isSingleton(c) and
// FieldContent indices have 0 for the address, 1 for content, so we need to subtract one.
result = "Field" and
c.getField().hasQualifiedName(namespace, type, base)
|
arg = repeatStars(c.getIndirectionIndex() - 1) + formatQualifiedName(namespace, type, base)
or
// TODO: This disjunct can be removed once we stop supporting unqualified field names.
arg = repeatStars(c.getIndirectionIndex() - 1) + base
arg = repeatStars(c.getIndirectionIndex() - 1) + c.getField().getName()
)
or
exists(ElementContent ec |
@@ -230,11 +218,40 @@ module SourceSinkInterpretationInput implements
/** Provides additional sink specification logic. */
bindingset[c]
predicate interpretOutput(string c, InterpretNode mid, InterpretNode node) { none() }
predicate interpretOutput(string c, InterpretNode mid, InterpretNode node) {
// Allow variables to be picked as output nodes.
exists(Node n, Element ast |
n = node.asNode() and
ast = mid.asElement()
|
c = "" and
n.asExpr().(VariableAccess).getTarget() = ast
)
}
/** Provides additional source specification logic. */
bindingset[c]
predicate interpretInput(string c, InterpretNode mid, InterpretNode node) { none() }
predicate interpretInput(string c, InterpretNode mid, InterpretNode node) {
exists(Node n, Element ast, VariableAccess e |
n = node.asNode() and
ast = mid.asElement() and
e.getTarget() = ast
|
// Allow variables to be picked as input nodes.
// We could simply do this as `e = n.asExpr()`, but that would not allow
// us to pick `x` as a sink in an example such as `x = source()` (but
// only subsequent uses of `x`) since the variable access on `x` doesn't
// actually load the value of `x`. So instead, we pick the instruction
// node corresponding to the generated `StoreInstruction` and use the
// expression associated with the destination instruction. This means
// that the `x` in `x = source()` can be marked as an input.
c = "" and
exists(StoreInstruction store |
store.getDestinationAddress().getUnconvertedResultExpression() = e and
n.asInstruction() = store
)
)
}
}
module Private {

View File

@@ -1378,8 +1378,6 @@ predicate nodeIsHidden(Node n) {
n instanceof InitialGlobalValue
or
n instanceof SsaSynthNode
or
n.(FlowSummaryNode).getSummaryNode().isHidden()
}
predicate neverSkipInPathGraph(Node n) {

View File

@@ -48,20 +48,19 @@ models
| 47 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
| 48 | Summary: ; ; false; callWithNonTypeTemplate<T>; (const T &); ; Argument[*0]; ReturnValue; value; manual |
| 49 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
| 50 | Summary: ; ; false; read_field_from_struct; ; ; Argument[*0].Field[MyNamespace::MyStructInNamespace::myField]; ReturnValue; value; manual |
| 51 | Summary: ; ; false; read_field_from_struct_2; ; ; Argument[*0].Field[MyGlobalStruct::myField]; ReturnValue; value; manual |
| 52 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
| 53 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
| 54 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
| 55 | Summary: ; TemplateClass1; true; templateFunction2<U,V>; (U,V); ; Argument[1]; ReturnValue; value; manual |
| 56 | Summary: ; TemplateClass1<T>; false; templateFunction<U>; (T,U); ; Argument[0]; ReturnValue; value; manual |
| 57 | Summary: ; TemplateClass2<T,U>; true; function; (U,T); ; Argument[1]; ReturnValue; value; manual |
| 58 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
| 59 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
| 60 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
| 61 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
| 62 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
| 50 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
| 51 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
| 52 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
| 53 | Summary: ; TemplateClass1; true; templateFunction2<U,V>; (U,V); ; Argument[1]; ReturnValue; value; manual |
| 54 | Summary: ; TemplateClass1<T>; false; templateFunction<U>; (T,U); ; Argument[0]; ReturnValue; value; manual |
| 55 | Summary: ; TemplateClass2<T,U>; true; function; (U,T); ; Argument[1]; ReturnValue; value; manual |
| 56 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
| 57 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
| 58 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
| 59 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
| 60 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
edges
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:60 |
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:32 |
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:32 Sink:MaD:2 |
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction |
@@ -69,16 +68,25 @@ edges
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | |
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 |
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:62 |
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | |
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:60 |
| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:59 |
| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:56 |
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:57 |
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:58 |
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | provenance | |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:29 |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:257:5:257:8 | *resp | provenance | |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:262:5:262:8 | *resp | provenance | |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:266:38:266:41 | *resp | provenance | |
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:58 |
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | provenance | |
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:56 |
| azure.cpp:257:16:257:21 | Read output argument | azure.cpp:258:10:258:16 | * ... | provenance | |
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:59 |
| azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | provenance | |
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:57 |
| azure.cpp:262:23:262:28 | ReadToCount output argument | azure.cpp:263:10:263:16 | * ... | provenance | |
| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:60 |
| azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:58 |
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | |
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:267:10:267:12 | vec [element] | provenance | |
| azure.cpp:267:10:267:12 | vec [element] | azure.cpp:267:10:267:12 | vec | provenance | |
@@ -94,10 +102,12 @@ edges
| azure.cpp:278:10:278:13 | body | azure.cpp:278:10:278:13 | body | provenance | |
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:26 |
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | |
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:60 |
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:58 |
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:10:282:38 | call to ReadToEnd | provenance | |
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | |
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:61 |
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | provenance | |
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:59 |
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:24:289:56 | call to GetHeader | provenance | |
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:32:289:40 | call to GetHeader | provenance | Src:MaD:30 |
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:289:63:289:65 | call to Value | provenance | |
@@ -109,6 +119,9 @@ edges
| azure.cpp:294:38:294:53 | call to operator[] | azure.cpp:295:10:295:20 | contentType | provenance | |
| azure.cpp:294:38:294:53 | call to operator[] | azure.cpp:295:10:295:20 | contentType | provenance | |
| azure.cpp:295:10:295:20 | contentType | azure.cpp:295:10:295:20 | contentType | provenance | |
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:51 |
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:50 |
| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:52 |
| test.cpp:7:47:7:52 | value2 | test.cpp:7:64:7:69 | value2 | provenance | |
| test.cpp:7:64:7:69 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | provenance | |
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:25 |
@@ -119,13 +132,16 @@ edges
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:32:41:32:41 | x | provenance | |
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | |
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:1 |
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:53 |
| test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | provenance | |
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:51 |
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | |
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:1 |
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:52 |
| test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | provenance | |
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:50 |
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | |
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:1 |
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:54 |
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | provenance | |
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:52 |
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | |
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:1 |
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | provenance | |
@@ -133,10 +149,20 @@ edges
| test.cpp:46:30:46:32 | *arg [x] | test.cpp:47:12:47:19 | *arg [x] | provenance | |
| test.cpp:47:12:47:19 | *arg [x] | test.cpp:48:13:48:13 | *s [x] | provenance | |
| test.cpp:48:13:48:13 | *s [x] | test.cpp:48:16:48:16 | x | provenance | Sink:MaD:1 |
| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:49 |
| test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | test.cpp:46:30:46:32 | *arg [x] | provenance | |
| test.cpp:56:2:56:2 | *s [post update] [x] | test.cpp:59:55:59:64 | *& ... [x] | provenance | |
| test.cpp:56:2:56:18 | ... = ... | test.cpp:56:2:56:2 | *s [post update] [x] | provenance | |
| test.cpp:56:8:56:16 | call to ymlSource | test.cpp:56:2:56:18 | ... = ... | provenance | Src:MaD:25 |
| test.cpp:59:55:59:64 | *& ... [x] | test.cpp:46:30:46:32 | *arg [x] | provenance | MaD:49 |
| test.cpp:59:55:59:64 | *& ... [x] | test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | provenance | |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:47 |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:47 |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:47 |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:47 |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:68:22:68:22 | y | provenance | |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:74:22:74:22 | y | provenance | |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:82:22:82:22 | y | provenance | |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:88:22:88:22 | y | provenance | |
| test.cpp:68:22:68:22 | y | test.cpp:69:11:69:11 | y | provenance | Sink:MaD:1 |
| test.cpp:74:22:74:22 | y | test.cpp:75:11:75:11 | y | provenance | Sink:MaD:1 |
| test.cpp:82:22:82:22 | y | test.cpp:83:11:83:11 | y | provenance | Sink:MaD:1 |
@@ -146,61 +172,69 @@ edges
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:101:26:101:26 | x | provenance | |
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:103:63:103:63 | x | provenance | |
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:104:62:104:62 | x | provenance | |
| test.cpp:97:26:97:26 | x | test.cpp:68:22:68:22 | y | provenance | MaD:47 |
| test.cpp:101:26:101:26 | x | test.cpp:74:22:74:22 | y | provenance | MaD:47 |
| test.cpp:103:63:103:63 | x | test.cpp:82:22:82:22 | y | provenance | MaD:47 |
| test.cpp:104:62:104:62 | x | test.cpp:88:22:88:22 | y | provenance | MaD:47 |
| test.cpp:97:26:97:26 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
| test.cpp:101:26:101:26 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
| test.cpp:103:63:103:63 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
| test.cpp:104:62:104:62 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
| test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | provenance | MaD:48 |
| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:114:10:114:18 | call to ymlSource | provenance | Src:MaD:25 |
| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:118:44:118:44 | *x | provenance | |
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | |
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:119:10:119:11 | y2 | provenance | Sink:MaD:1 |
| test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | provenance | |
| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:48 |
| test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | provenance | MaD:54 |
| test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | test.cpp:128:5:128:21 | [summary] to write: ReturnValue in templateFunction2 | provenance | MaD:53 |
| test.cpp:133:10:133:18 | call to ymlSource | test.cpp:133:10:133:18 | call to ymlSource | provenance | Src:MaD:25 |
| test.cpp:133:10:133:18 | call to ymlSource | test.cpp:134:45:134:45 | x | provenance | |
| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:134:13:134:43 | call to templateFunction | provenance | |
| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:135:10:135:10 | y | provenance | Sink:MaD:1 |
| test.cpp:134:45:134:45 | x | test.cpp:134:13:134:43 | call to templateFunction | provenance | MaD:56 |
| test.cpp:134:45:134:45 | x | test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | provenance | |
| test.cpp:134:45:134:45 | x | test.cpp:134:13:134:43 | call to templateFunction | provenance | MaD:54 |
| test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | provenance | MaD:55 |
| test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | provenance | MaD:55 |
| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:146:10:146:18 | call to ymlSource | provenance | Src:MaD:25 |
| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:148:26:148:26 | x | provenance | |
| test.cpp:148:10:148:27 | call to function | test.cpp:148:10:148:27 | call to function | provenance | |
| test.cpp:148:10:148:27 | call to function | test.cpp:149:10:149:10 | z | provenance | Sink:MaD:1 |
| test.cpp:148:26:148:26 | x | test.cpp:148:10:148:27 | call to function | provenance | MaD:57 |
| test.cpp:148:26:148:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | provenance | |
| test.cpp:148:26:148:26 | x | test.cpp:148:10:148:27 | call to function | provenance | MaD:55 |
| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:155:10:155:18 | call to ymlSource | provenance | Src:MaD:25 |
| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:157:26:157:26 | x | provenance | |
| test.cpp:157:13:157:20 | call to function | test.cpp:157:13:157:20 | call to function | provenance | |
| test.cpp:157:13:157:20 | call to function | test.cpp:158:10:158:10 | z | provenance | Sink:MaD:1 |
| test.cpp:157:26:157:26 | x | test.cpp:157:13:157:20 | call to function | provenance | MaD:57 |
| test.cpp:157:26:157:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | provenance | |
| test.cpp:157:26:157:26 | x | test.cpp:157:13:157:20 | call to function | provenance | MaD:55 |
| test.cpp:164:34:164:34 | x | test.cpp:165:69:165:69 | x | provenance | |
| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:164:7:164:7 | *templateFunction3 | provenance | |
| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | |
| test.cpp:165:69:165:69 | x | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | MaD:55 |
| test.cpp:165:69:165:69 | x | test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | provenance | |
| test.cpp:165:69:165:69 | x | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | MaD:53 |
| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:170:10:170:18 | call to ymlSource | provenance | Src:MaD:25 |
| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:172:51:172:51 | x | provenance | |
| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | |
| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:173:10:173:10 | y | provenance | Sink:MaD:1 |
| test.cpp:172:51:172:51 | x | test.cpp:164:34:164:34 | x | provenance | |
| test.cpp:172:51:172:51 | x | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | MaD:55 |
| test.cpp:186:2:186:2 | *s [post update] [myField] | test.cpp:187:33:187:34 | *& ... [myField] | provenance | |
| test.cpp:186:2:186:24 | ... = ... | test.cpp:186:2:186:2 | *s [post update] [myField] | provenance | |
| test.cpp:186:14:186:22 | call to ymlSource | test.cpp:186:2:186:24 | ... = ... | provenance | Src:MaD:25 |
| test.cpp:187:10:187:31 | call to read_field_from_struct | test.cpp:187:10:187:31 | call to read_field_from_struct | provenance | |
| test.cpp:187:10:187:31 | call to read_field_from_struct | test.cpp:188:10:188:10 | x | provenance | Sink:MaD:1 |
| test.cpp:187:33:187:34 | *& ... [myField] | test.cpp:187:10:187:31 | call to read_field_from_struct | provenance | MaD:50 |
| test.cpp:199:2:199:2 | *s [post update] [myField] | test.cpp:200:35:200:36 | *& ... [myField] | provenance | |
| test.cpp:199:2:199:24 | ... = ... | test.cpp:199:2:199:2 | *s [post update] [myField] | provenance | |
| test.cpp:199:14:199:22 | call to ymlSource | test.cpp:199:2:199:24 | ... = ... | provenance | Src:MaD:25 |
| test.cpp:200:10:200:33 | call to read_field_from_struct_2 | test.cpp:200:10:200:33 | call to read_field_from_struct_2 | provenance | |
| test.cpp:200:10:200:33 | call to read_field_from_struct_2 | test.cpp:201:10:201:10 | x | provenance | Sink:MaD:1 |
| test.cpp:200:35:200:36 | *& ... [myField] | test.cpp:200:10:200:33 | call to read_field_from_struct_2 | provenance | MaD:51 |
| test.cpp:172:51:172:51 | x | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | MaD:53 |
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:33 |
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | |
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:27:36:27:38 | *cmd | provenance | |
| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | |
| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | windows.cpp:30:8:30:15 | * ... | provenance | |
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | provenance | |
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | MaD:33 |
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | provenance | Src:MaD:4 |
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | windows.cpp:36:10:36:13 | * ... | provenance | |
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | windows.cpp:41:10:41:13 | * ... | provenance | Src:MaD:5 |
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [*hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | provenance | |
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | provenance | |
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:37 |
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:37 |
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | windows.cpp:147:16:147:27 | *lpOverlapped [*hEvent] | provenance | |
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | windows.cpp:157:16:157:27 | *lpOverlapped [hEvent] | provenance | |
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | provenance | |
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | provenance | |
| windows.cpp:147:16:147:27 | *lpOverlapped [*hEvent] | windows.cpp:149:42:149:53 | *lpOverlapped [*hEvent] | provenance | |
| windows.cpp:149:18:149:62 | *hEvent | windows.cpp:149:18:149:62 | *hEvent | provenance | |
| windows.cpp:149:18:149:62 | *hEvent | windows.cpp:151:8:151:14 | * ... | provenance | |
@@ -217,11 +251,11 @@ edges
| windows.cpp:189:21:189:26 | ReadFile output argument | windows.cpp:190:5:190:56 | *... = ... | provenance | Src:MaD:17 |
| windows.cpp:190:5:190:14 | *overlapped [post update] [*hEvent] | windows.cpp:192:53:192:63 | *& ... [*hEvent] | provenance | |
| windows.cpp:190:5:190:56 | *... = ... | windows.cpp:190:5:190:14 | *overlapped [post update] [*hEvent] | provenance | |
| windows.cpp:192:53:192:63 | *& ... [*hEvent] | windows.cpp:147:16:147:27 | *lpOverlapped [*hEvent] | provenance | MaD:37 |
| windows.cpp:192:53:192:63 | *& ... [*hEvent] | windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [*hEvent] | provenance | |
| windows.cpp:198:21:198:26 | ReadFile output argument | windows.cpp:199:5:199:57 | ... = ... | provenance | Src:MaD:17 |
| windows.cpp:199:5:199:14 | *overlapped [post update] [hEvent] | windows.cpp:201:53:201:63 | *& ... [hEvent] | provenance | |
| windows.cpp:199:5:199:57 | ... = ... | windows.cpp:199:5:199:14 | *overlapped [post update] [hEvent] | provenance | |
| windows.cpp:201:53:201:63 | *& ... [hEvent] | windows.cpp:157:16:157:27 | *lpOverlapped [hEvent] | provenance | MaD:37 |
| windows.cpp:201:53:201:63 | *& ... [hEvent] | windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [hEvent] | provenance | |
| windows.cpp:209:84:209:89 | NtReadFile output argument | windows.cpp:211:10:211:16 | * ... | provenance | Src:MaD:16 |
| windows.cpp:286:23:286:35 | *call to MapViewOfFile | windows.cpp:286:23:286:35 | *call to MapViewOfFile | provenance | Src:MaD:12 |
| windows.cpp:286:23:286:35 | *call to MapViewOfFile | windows.cpp:287:20:287:52 | *pMapView | provenance | |
@@ -244,6 +278,12 @@ edges
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | provenance | Src:MaD:15 |
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:333:20:333:52 | *pMapView | provenance | |
| windows.cpp:333:20:333:52 | *pMapView | windows.cpp:335:10:335:16 | * ... | provenance | |
| windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | provenance | MaD:36 |
| windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | windows.cpp:403:26:403:36 | *lpParameter [x] | provenance | |
| windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | provenance | MaD:34 |
| windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | windows.cpp:410:26:410:36 | *lpParameter [x] | provenance | |
| windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | provenance | MaD:35 |
| windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | windows.cpp:417:26:417:36 | *lpParameter [x] | provenance | |
| windows.cpp:403:26:403:36 | *lpParameter [x] | windows.cpp:405:10:405:25 | *lpParameter [x] | provenance | |
| windows.cpp:405:10:405:25 | *lpParameter [x] | windows.cpp:406:8:406:8 | *s [x] | provenance | |
| windows.cpp:406:8:406:8 | *s [x] | windows.cpp:406:8:406:11 | x | provenance | |
@@ -258,9 +298,22 @@ edges
| windows.cpp:431:3:431:3 | *s [post update] [x] | windows.cpp:464:7:464:8 | *& ... [x] | provenance | |
| windows.cpp:431:3:431:16 | ... = ... | windows.cpp:431:3:431:3 | *s [post update] [x] | provenance | |
| windows.cpp:431:9:431:14 | call to source | windows.cpp:431:3:431:16 | ... = ... | provenance | |
| windows.cpp:439:7:439:8 | *& ... [x] | windows.cpp:403:26:403:36 | *lpParameter [x] | provenance | MaD:36 |
| windows.cpp:451:7:451:8 | *& ... [x] | windows.cpp:410:26:410:36 | *lpParameter [x] | provenance | MaD:34 |
| windows.cpp:464:7:464:8 | *& ... [x] | windows.cpp:417:26:417:36 | *lpParameter [x] | provenance | MaD:35 |
| windows.cpp:439:7:439:8 | *& ... [x] | windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | provenance | |
| windows.cpp:451:7:451:8 | *& ... [x] | windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | provenance | |
| windows.cpp:464:7:464:8 | *& ... [x] | windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | provenance | |
| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | provenance | MaD:42 |
| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | provenance | MaD:38 |
| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | provenance | MaD:39 |
| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | provenance | MaD:40 |
| windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | provenance | |
| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | provenance | MaD:41 |
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | provenance | |
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | provenance | |
| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | provenance | MaD:44 |
| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | provenance | MaD:45 |
| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | provenance | MaD:43 |
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | provenance | |
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | provenance | |
| windows.cpp:533:11:533:16 | call to source | windows.cpp:533:11:533:16 | call to source | provenance | |
| windows.cpp:533:11:533:16 | call to source | windows.cpp:537:40:537:41 | *& ... | provenance | |
| windows.cpp:533:11:533:16 | call to source | windows.cpp:542:38:542:39 | *& ... | provenance | |
@@ -269,29 +322,37 @@ edges
| windows.cpp:533:11:533:16 | call to source | windows.cpp:568:32:568:33 | *& ... | provenance | |
| windows.cpp:533:11:533:16 | call to source | windows.cpp:573:40:573:41 | *& ... | provenance | |
| windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | windows.cpp:538:10:538:23 | access to array | provenance | |
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | provenance | |
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | provenance | MaD:42 |
| windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | windows.cpp:543:10:543:23 | access to array | provenance | |
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | provenance | |
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | provenance | MaD:38 |
| windows.cpp:547:19:547:29 | RtlCopyMemory output argument | windows.cpp:548:10:548:23 | access to array | provenance | |
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | provenance | |
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:547:19:547:29 | RtlCopyMemory output argument | provenance | MaD:39 |
| windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | windows.cpp:553:10:553:23 | access to array | provenance | |
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | provenance | |
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | provenance | MaD:40 |
| windows.cpp:559:5:559:24 | ... = ... | windows.cpp:561:39:561:44 | *buffer | provenance | |
| windows.cpp:559:17:559:24 | call to source | windows.cpp:559:5:559:24 | ... = ... | provenance | |
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:562:10:562:19 | *src_string [*Buffer] | provenance | |
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:563:40:563:50 | *& ... [*Buffer] | provenance | |
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | provenance | |
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | provenance | MaD:43 |
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:10:562:29 | access to array | provenance | |
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:21:562:26 | *Buffer | provenance | |
| windows.cpp:562:21:562:26 | *Buffer | windows.cpp:562:10:562:29 | access to array | provenance | |
| windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | windows.cpp:564:10:564:20 | *dest_string [*Buffer] | provenance | |
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | provenance | |
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | provenance | MaD:41 |
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:10:564:30 | access to array | provenance | |
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:22:564:27 | *Buffer | provenance | |
| windows.cpp:564:22:564:27 | *Buffer | windows.cpp:564:10:564:30 | access to array | provenance | |
| windows.cpp:568:19:568:29 | RtlMoveMemory output argument | windows.cpp:569:10:569:23 | access to array | provenance | |
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | provenance | |
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:568:19:568:29 | RtlMoveMemory output argument | provenance | MaD:44 |
| windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | windows.cpp:574:10:574:23 | access to array | provenance | |
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | provenance | |
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | provenance | MaD:45 |
| windows.cpp:645:45:645:50 | WinHttpReadData output argument | windows.cpp:647:10:647:16 | * ... | provenance | Src:MaD:23 |
| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | windows.cpp:654:10:654:16 | * ... | provenance | Src:MaD:24 |
@@ -299,8 +360,10 @@ edges
| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | windows.cpp:673:10:673:29 | * ... | provenance | Src:MaD:21 |
| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | windows.cpp:671:10:671:16 | * ... | provenance | Src:MaD:22 |
| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | windows.cpp:675:10:675:27 | * ... | provenance | Src:MaD:20 |
| windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | provenance | MaD:46 |
| windows.cpp:728:5:728:28 | ... = ... | windows.cpp:729:35:729:35 | *x | provenance | |
| windows.cpp:728:12:728:28 | call to source | windows.cpp:728:5:728:28 | ... = ... | provenance | |
| windows.cpp:729:35:729:35 | *x | windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | provenance | |
| windows.cpp:729:35:729:35 | *x | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | provenance | MaD:46 |
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:731:10:731:36 | * ... | provenance | |
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:733:10:733:35 | * ... | provenance | |
@@ -323,6 +386,8 @@ edges
| windows.cpp:936:70:936:78 | HttpReceiveClientCertificate output argument | windows.cpp:941:10:941:31 | * ... | provenance | Src:MaD:6 |
| windows.cpp:937:15:937:48 | *& ... | windows.cpp:939:10:939:11 | * ... | provenance | |
nodes
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer |
| asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer |
| asio_streams.cpp:87:34:87:44 | read_until output argument | semmle.label | read_until output argument |
| asio_streams.cpp:91:7:91:17 | recv_buffer | semmle.label | recv_buffer |
| asio_streams.cpp:93:29:93:39 | *recv_buffer | semmle.label | *recv_buffer |
@@ -333,6 +398,15 @@ nodes
| asio_streams.cpp:100:64:100:71 | *send_str | semmle.label | *send_str |
| asio_streams.cpp:101:7:101:17 | send_buffer | semmle.label | send_buffer |
| asio_streams.cpp:103:29:103:39 | *send_buffer | semmle.label | *send_buffer |
| azure.cpp:62:10:62:14 | [summary param] this in Value | semmle.label | [summary param] this in Value |
| azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | semmle.label | [summary] to write: ReturnValue[*] in Value |
| azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | semmle.label | [summary param] *0 in Read [Return] |
| azure.cpp:113:16:113:19 | [summary param] this in Read | semmle.label | [summary param] this in Read |
| azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | semmle.label | [summary param] *0 in ReadToCount [Return] |
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | semmle.label | [summary param] this in ReadToCount |
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | semmle.label | [summary param] this in ReadToEnd |
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | semmle.label | [summary] to write: ReturnValue in ReadToEnd [element] |
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | semmle.label | [summary] to write: ReturnValue.Element in ReadToEnd |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | semmle.label | *call to GetBodyStream |
| azure.cpp:253:48:253:60 | *call to GetBodyStream | semmle.label | *call to GetBodyStream |
| azure.cpp:257:5:257:8 | *resp | semmle.label | *resp |
@@ -377,6 +451,12 @@ nodes
| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | semmle.label | [summary param] 0 in ymlStepManual |
| test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | semmle.label | [summary] to write: ReturnValue in ymlStepManual |
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | semmle.label | [summary param] 0 in ymlStepGenerated |
| test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | semmle.label | [summary] to write: ReturnValue in ymlStepGenerated |
| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | semmle.label | [summary param] 0 in ymlStepManual_with_body |
| test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | semmle.label | [summary] to write: ReturnValue in ymlStepManual_with_body |
| test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | semmle.label | *ymlStepGenerated_with_body |
| test.cpp:7:47:7:52 | value2 | semmle.label | value2 |
| test.cpp:7:64:7:69 | value2 | semmle.label | value2 |
@@ -403,10 +483,20 @@ nodes
| test.cpp:47:12:47:19 | *arg [x] | semmle.label | *arg [x] |
| test.cpp:48:13:48:13 | *s [x] | semmle.label | *s [x] |
| test.cpp:48:16:48:16 | x | semmle.label | x |
| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | semmle.label | [summary param] *3 in pthread_create [x] |
| test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | semmle.label | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] |
| test.cpp:56:2:56:2 | *s [post update] [x] | semmle.label | *s [post update] [x] |
| test.cpp:56:2:56:18 | ... = ... | semmle.label | ... = ... |
| test.cpp:56:8:56:16 | call to ymlSource | semmle.label | call to ymlSource |
| test.cpp:59:55:59:64 | *& ... [x] | semmle.label | *& ... [x] |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | semmle.label | [summary param] 1 in callWithArgument |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | semmle.label | [summary param] 1 in callWithArgument |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | semmle.label | [summary param] 1 in callWithArgument |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | semmle.label | [summary param] 1 in callWithArgument |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | semmle.label | [summary] to write: Argument[0].Parameter[0] in callWithArgument |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | semmle.label | [summary] to write: Argument[0].Parameter[0] in callWithArgument |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | semmle.label | [summary] to write: Argument[0].Parameter[0] in callWithArgument |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | semmle.label | [summary] to write: Argument[0].Parameter[0] in callWithArgument |
| test.cpp:68:22:68:22 | y | semmle.label | y |
| test.cpp:69:11:69:11 | y | semmle.label | y |
| test.cpp:74:22:74:22 | y | semmle.label | y |
@@ -421,18 +511,28 @@ nodes
| test.cpp:101:26:101:26 | x | semmle.label | x |
| test.cpp:103:63:103:63 | x | semmle.label | x |
| test.cpp:104:62:104:62 | x | semmle.label | x |
| test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | semmle.label | [summary param] *0 in callWithNonTypeTemplate |
| test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | semmle.label | [summary] to write: ReturnValue in callWithNonTypeTemplate |
| test.cpp:114:10:114:18 | call to ymlSource | semmle.label | call to ymlSource |
| test.cpp:114:10:114:18 | call to ymlSource | semmle.label | call to ymlSource |
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | semmle.label | call to callWithNonTypeTemplate |
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | semmle.label | call to callWithNonTypeTemplate |
| test.cpp:118:44:118:44 | *x | semmle.label | *x |
| test.cpp:119:10:119:11 | y2 | semmle.label | y2 |
| test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | semmle.label | [summary param] 0 in templateFunction |
| test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | semmle.label | [summary] to write: ReturnValue in templateFunction |
| test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | semmle.label | [summary param] 1 in templateFunction2 |
| test.cpp:128:5:128:21 | [summary] to write: ReturnValue in templateFunction2 | semmle.label | [summary] to write: ReturnValue in templateFunction2 |
| test.cpp:133:10:133:18 | call to ymlSource | semmle.label | call to ymlSource |
| test.cpp:133:10:133:18 | call to ymlSource | semmle.label | call to ymlSource |
| test.cpp:134:13:134:43 | call to templateFunction | semmle.label | call to templateFunction |
| test.cpp:134:13:134:43 | call to templateFunction | semmle.label | call to templateFunction |
| test.cpp:134:45:134:45 | x | semmle.label | x |
| test.cpp:135:10:135:10 | y | semmle.label | y |
| test.cpp:140:4:140:11 | [summary param] 1 in function | semmle.label | [summary param] 1 in function |
| test.cpp:140:4:140:11 | [summary param] 1 in function | semmle.label | [summary param] 1 in function |
| test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | semmle.label | [summary] to write: ReturnValue in function |
| test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | semmle.label | [summary] to write: ReturnValue in function |
| test.cpp:146:10:146:18 | call to ymlSource | semmle.label | call to ymlSource |
| test.cpp:146:10:146:18 | call to ymlSource | semmle.label | call to ymlSource |
| test.cpp:148:10:148:27 | call to function | semmle.label | call to function |
@@ -456,20 +556,8 @@ nodes
| test.cpp:172:13:172:44 | call to templateFunction3 | semmle.label | call to templateFunction3 |
| test.cpp:172:51:172:51 | x | semmle.label | x |
| test.cpp:173:10:173:10 | y | semmle.label | y |
| test.cpp:186:2:186:2 | *s [post update] [myField] | semmle.label | *s [post update] [myField] |
| test.cpp:186:2:186:24 | ... = ... | semmle.label | ... = ... |
| test.cpp:186:14:186:22 | call to ymlSource | semmle.label | call to ymlSource |
| test.cpp:187:10:187:31 | call to read_field_from_struct | semmle.label | call to read_field_from_struct |
| test.cpp:187:10:187:31 | call to read_field_from_struct | semmle.label | call to read_field_from_struct |
| test.cpp:187:33:187:34 | *& ... [myField] | semmle.label | *& ... [myField] |
| test.cpp:188:10:188:10 | x | semmle.label | x |
| test.cpp:199:2:199:2 | *s [post update] [myField] | semmle.label | *s [post update] [myField] |
| test.cpp:199:2:199:24 | ... = ... | semmle.label | ... = ... |
| test.cpp:199:14:199:22 | call to ymlSource | semmle.label | call to ymlSource |
| test.cpp:200:10:200:33 | call to read_field_from_struct_2 | semmle.label | call to read_field_from_struct_2 |
| test.cpp:200:10:200:33 | call to read_field_from_struct_2 | semmle.label | call to read_field_from_struct_2 |
| test.cpp:200:35:200:36 | *& ... [myField] | semmle.label | *& ... [myField] |
| test.cpp:201:10:201:10 | x | semmle.label | x |
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | semmle.label | [summary param] *0 in CommandLineToArgvA |
| windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | semmle.label | [summary] to write: ReturnValue[**] in CommandLineToArgvA |
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA |
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA |
| windows.cpp:24:8:24:11 | * ... | semmle.label | * ... |
@@ -482,6 +570,14 @@ nodes
| windows.cpp:36:10:36:13 | * ... | semmle.label | * ... |
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | semmle.label | GetEnvironmentVariableA output argument |
| windows.cpp:41:10:41:13 | * ... | semmle.label | * ... |
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [*hEvent] | semmle.label | [summary param] *3 in ReadFileEx [*hEvent] |
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [hEvent] | semmle.label | [summary param] *3 in ReadFileEx [hEvent] |
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | semmle.label | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx |
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | semmle.label | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx |
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | semmle.label | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] |
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | semmle.label | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] |
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | semmle.label | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx |
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | semmle.label | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx |
| windows.cpp:147:16:147:27 | *lpOverlapped [*hEvent] | semmle.label | *lpOverlapped [*hEvent] |
| windows.cpp:149:18:149:62 | *hEvent | semmle.label | *hEvent |
| windows.cpp:149:18:149:62 | *hEvent | semmle.label | *hEvent |
@@ -535,6 +631,12 @@ nodes
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | semmle.label | *call to MapViewOfFileNuma2 |
| windows.cpp:333:20:333:52 | *pMapView | semmle.label | *pMapView |
| windows.cpp:335:10:335:16 | * ... | semmle.label | * ... |
| windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | semmle.label | [summary param] *3 in CreateThread [x] |
| windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | semmle.label | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] |
| windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | semmle.label | [summary param] *4 in CreateRemoteThread [x] |
| windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | semmle.label | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] |
| windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | semmle.label | [summary param] *4 in CreateRemoteThreadEx [x] |
| windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | semmle.label | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] |
| windows.cpp:403:26:403:36 | *lpParameter [x] | semmle.label | *lpParameter [x] |
| windows.cpp:405:10:405:25 | *lpParameter [x] | semmle.label | *lpParameter [x] |
| windows.cpp:406:8:406:8 | *s [x] | semmle.label | *s [x] |
@@ -553,6 +655,27 @@ nodes
| windows.cpp:439:7:439:8 | *& ... [x] | semmle.label | *& ... [x] |
| windows.cpp:451:7:451:8 | *& ... [x] | semmle.label | *& ... [x] |
| windows.cpp:464:7:464:8 | *& ... [x] | semmle.label | *& ... [x] |
| windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | semmle.label | [summary param] *0 in RtlCopyVolatileMemory [Return] |
| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | semmle.label | [summary param] *1 in RtlCopyVolatileMemory |
| windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | semmle.label | [summary param] *0 in RtlCopyDeviceMemory [Return] |
| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | semmle.label | [summary param] *1 in RtlCopyDeviceMemory |
| windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | semmle.label | [summary param] *0 in RtlCopyMemory [Return] |
| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | semmle.label | [summary param] *1 in RtlCopyMemory |
| windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | semmle.label | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] |
| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | semmle.label | [summary param] *1 in RtlCopyMemoryNonTemporal |
| windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | semmle.label | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] |
| windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | semmle.label | [summary param] *1 in RtlCopyUnicodeString [*Buffer] |
| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | semmle.label | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString |
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | semmle.label | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] |
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | semmle.label | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString |
| windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | semmle.label | [summary param] *0 in RtlMoveMemory [Return] |
| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | semmle.label | [summary param] *1 in RtlMoveMemory |
| windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | semmle.label | [summary param] *0 in RtlMoveVolatileMemory [Return] |
| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | semmle.label | [summary param] *1 in RtlMoveVolatileMemory |
| windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | semmle.label | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] |
| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | semmle.label | [summary param] *1 in RtlInitUnicodeString |
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | semmle.label | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] |
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | semmle.label | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString |
| windows.cpp:533:11:533:16 | call to source | semmle.label | call to source |
| windows.cpp:533:11:533:16 | call to source | semmle.label | call to source |
| windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | semmle.label | RtlCopyVolatileMemory output argument |
@@ -597,6 +720,8 @@ nodes
| windows.cpp:671:10:671:16 | * ... | semmle.label | * ... |
| windows.cpp:673:10:673:29 | * ... | semmle.label | * ... |
| windows.cpp:675:10:675:27 | * ... | semmle.label | * ... |
| windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | semmle.label | [summary param] *0 in WinHttpCrackUrl |
| windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | semmle.label | [summary param] *3 in WinHttpCrackUrl [Return] |
| windows.cpp:728:5:728:28 | ... = ... | semmle.label | ... = ... |
| windows.cpp:728:12:728:28 | call to source | semmle.label | call to source |
| windows.cpp:729:35:729:35 | *x | semmle.label | *x |
@@ -625,6 +750,30 @@ nodes
| windows.cpp:939:10:939:11 | * ... | semmle.label | * ... |
| windows.cpp:941:10:941:31 | * ... | semmle.label | * ... |
subpaths
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | asio_streams.cpp:100:44:100:62 | call to buffer |
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | azure.cpp:257:16:257:21 | Read output argument |
| azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | azure.cpp:262:23:262:28 | ReadToCount output argument |
| azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] |
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] |
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | azure.cpp:289:63:289:65 | call to Value |
| test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual |
| test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated |
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body |
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body |
| test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate |
| test.cpp:134:45:134:45 | x | test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | test.cpp:134:13:134:43 | call to templateFunction |
| test.cpp:148:26:148:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | test.cpp:148:10:148:27 | call to function |
| test.cpp:157:26:157:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | test.cpp:157:13:157:20 | call to function |
| test.cpp:165:69:165:69 | x | test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | test.cpp:128:5:128:21 | [summary] to write: ReturnValue in templateFunction2 | test.cpp:165:12:165:64 | call to templateFunction2 |
| test.cpp:172:51:172:51 | x | test.cpp:164:34:164:34 | x | test.cpp:164:7:164:7 | *templateFunction3 | test.cpp:172:13:172:44 | call to templateFunction3 |
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA |
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument |
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument |
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | windows.cpp:547:19:547:29 | RtlCopyMemory output argument |
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument |
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] |
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] |
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | windows.cpp:568:19:568:29 | RtlMoveMemory output argument |
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument |
| windows.cpp:729:35:729:35 | *x | windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument |
testFailures

View File

@@ -21,6 +21,4 @@ extensions:
- ["", "", False, "callWithNonTypeTemplate<T>", "(const T &)", "", "Argument[*0]", "ReturnValue", "value", "manual"]
- ["", "TemplateClass1<T>", False, "templateFunction<U>", "(T,U)", "", "Argument[0]", "ReturnValue", "value", "manual"]
- ["", "TemplateClass1", True, "templateFunction2<U,V>", "(U,V)", "", "Argument[1]", "ReturnValue", "value", "manual"]
- ["", "TemplateClass2<T,U>", True, "function", "(U,T)", "", "Argument[1]", "ReturnValue", "value", "manual"]
- ["", "", False, "read_field_from_struct", "", "", "Argument[*0].Field[MyNamespace::MyStructInNamespace::myField]", "ReturnValue", "value", "manual"]
- ["", "", False, "read_field_from_struct_2", "", "", "Argument[*0].Field[MyGlobalStruct::myField]", "ReturnValue", "value", "manual"]
- ["", "TemplateClass2<T,U>", True, "function", "(U,T)", "", "Argument[1]", "ReturnValue", "value", "manual"]

View File

@@ -19,5 +19,3 @@
| test.cpp:149:10:149:10 | z | test-sink |
| test.cpp:158:10:158:10 | z | test-sink |
| test.cpp:173:10:173:10 | y | test-sink |
| test.cpp:188:10:188:10 | x | test-sink |
| test.cpp:201:10:201:10 | x | test-sink |

View File

@@ -13,8 +13,6 @@
| test.cpp:146:10:146:18 | call to ymlSource | local |
| test.cpp:155:10:155:18 | call to ymlSource | local |
| test.cpp:170:10:170:18 | call to ymlSource | local |
| test.cpp:186:14:186:22 | call to ymlSource | local |
| test.cpp:199:14:199:22 | call to ymlSource | local |
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | local |
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | local |
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | local |

View File

@@ -171,32 +171,4 @@ void test_class1() {
Class1<int> c;
auto y = c.templateFunction3<unsigned long>(0UL, x);
ymlSink(y); // $ ir
}
namespace MyNamespace {
struct MyStructInNamespace {
int myField;
};
}
int read_field_from_struct(MyNamespace::MyStructInNamespace* s);
void test_fully_qualified_field_test() {
MyNamespace::MyStructInNamespace s;
s.myField = ymlSource();
int x = read_field_from_struct(&s);
ymlSink(x); // $ ir
}
struct MyGlobalStruct {
int myField;
};
int read_field_from_struct_2(MyGlobalStruct* s);
void test_fully_qualified_field_test_2() {
MyGlobalStruct s;
s.myField = ymlSource();
int x = read_field_from_struct_2(&s);
ymlSink(x); // $ ir
}

View File

@@ -33,34 +33,34 @@ summaryCalls
| file://:0:0:0:0 | [summary] call to [summary param] 0 in madCallArg0ReturnToReturnFirst in madCallArg0ReturnToReturnFirst |
| file://:0:0:0:0 | [summary] call to [summary param] 0 in madCallArg0WithValue in madCallArg0WithValue |
summarizedCallables
| tests.cpp:127:5:127:19 | madArg0ToReturn |
| tests.cpp:128:6:128:28 | madArg0ToReturnIndirect |
| tests.cpp:130:5:130:28 | madArg0ToReturnValueFlow |
| tests.cpp:131:5:131:27 | madArg0IndirectToReturn |
| tests.cpp:132:5:132:33 | madArg0DoubleIndirectToReturn |
| tests.cpp:133:5:133:30 | madArg0NotIndirectToReturn |
| tests.cpp:134:6:134:26 | madArg0ToArg1Indirect |
| tests.cpp:135:6:135:34 | madArg0IndirectToArg1Indirect |
| tests.cpp:136:5:136:18 | madArgsComplex |
| tests.cpp:137:5:137:14 | madArgsAny |
| tests.cpp:138:5:138:28 | madAndImplementedComplex |
| tests.cpp:143:5:143:24 | madArg0FieldToReturn |
| tests.cpp:144:5:144:32 | madArg0IndirectFieldToReturn |
| tests.cpp:145:5:145:32 | madArg0FieldIndirectToReturn |
| tests.cpp:146:13:146:32 | madArg0ToReturnField |
| tests.cpp:147:14:147:41 | madArg0ToReturnIndirectField |
| tests.cpp:148:13:148:40 | madArg0ToReturnFieldIndirect |
| tests.cpp:250:7:250:19 | madArg0ToSelf |
| tests.cpp:251:6:251:20 | madSelfToReturn |
| tests.cpp:253:7:253:20 | madArg0ToField |
| tests.cpp:254:6:254:21 | madFieldToReturn |
| tests.cpp:277:7:277:30 | namespaceMadSelfToReturn |
| tests.cpp:392:5:392:29 | madCallArg0ReturnToReturn |
| tests.cpp:393:9:393:38 | madCallArg0ReturnToReturnFirst |
| tests.cpp:394:6:394:25 | madCallArg0WithValue |
| tests.cpp:395:5:395:36 | madCallReturnValueIgnoreFunction |
| tests.cpp:417:5:417:31 | parameter_ref_to_return_ref |
| tests.cpp:429:5:429:17 | receive_array |
| tests.cpp:144:5:144:19 | madArg0ToReturn |
| tests.cpp:145:6:145:28 | madArg0ToReturnIndirect |
| tests.cpp:147:5:147:28 | madArg0ToReturnValueFlow |
| tests.cpp:148:5:148:27 | madArg0IndirectToReturn |
| tests.cpp:149:5:149:33 | madArg0DoubleIndirectToReturn |
| tests.cpp:150:5:150:30 | madArg0NotIndirectToReturn |
| tests.cpp:151:6:151:26 | madArg0ToArg1Indirect |
| tests.cpp:152:6:152:34 | madArg0IndirectToArg1Indirect |
| tests.cpp:153:5:153:18 | madArgsComplex |
| tests.cpp:154:5:154:14 | madArgsAny |
| tests.cpp:155:5:155:28 | madAndImplementedComplex |
| tests.cpp:160:5:160:24 | madArg0FieldToReturn |
| tests.cpp:161:5:161:32 | madArg0IndirectFieldToReturn |
| tests.cpp:162:5:162:32 | madArg0FieldIndirectToReturn |
| tests.cpp:163:13:163:32 | madArg0ToReturnField |
| tests.cpp:164:14:164:41 | madArg0ToReturnIndirectField |
| tests.cpp:165:13:165:40 | madArg0ToReturnFieldIndirect |
| tests.cpp:284:7:284:19 | madArg0ToSelf |
| tests.cpp:285:6:285:20 | madSelfToReturn |
| tests.cpp:287:7:287:20 | madArg0ToField |
| tests.cpp:288:6:288:21 | madFieldToReturn |
| tests.cpp:313:7:313:30 | namespaceMadSelfToReturn |
| tests.cpp:434:5:434:29 | madCallArg0ReturnToReturn |
| tests.cpp:435:9:435:38 | madCallArg0ReturnToReturnFirst |
| tests.cpp:436:6:436:25 | madCallArg0WithValue |
| tests.cpp:437:5:437:36 | madCallReturnValueIgnoreFunction |
| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
| tests.cpp:471:5:471:17 | receive_array |
sourceCallables
| tests.cpp:3:5:3:10 | source |
| tests.cpp:4:6:4:14 | sourcePtr |
@@ -82,284 +82,297 @@ sourceCallables
| tests.cpp:19:6:19:32 | remoteMadSourceIndirectArg1 |
| tests.cpp:19:39:19:39 | x |
| tests.cpp:19:47:19:47 | y |
| tests.cpp:23:7:23:30 | namespace2LocalMadSource |
| tests.cpp:26:6:26:19 | localMadSource |
| tests.cpp:28:5:28:27 | namespaceLocalMadSource |
| tests.cpp:30:6:30:17 | test_sources |
| tests.cpp:45:6:45:6 | v |
| tests.cpp:46:7:46:16 | v_indirect |
| tests.cpp:47:6:47:13 | v_direct |
| tests.cpp:58:6:58:6 | a |
| tests.cpp:58:9:58:9 | b |
| tests.cpp:58:12:58:12 | c |
| tests.cpp:58:15:58:15 | d |
| tests.cpp:67:6:67:6 | e |
| tests.cpp:75:6:75:26 | remoteMadSourceParam0 |
| tests.cpp:75:32:75:32 | x |
| tests.cpp:82:6:82:16 | madSinkArg0 |
| tests.cpp:82:22:82:22 | x |
| tests.cpp:83:6:83:13 | notASink |
| tests.cpp:83:19:83:19 | x |
| tests.cpp:84:6:84:16 | madSinkArg1 |
| tests.cpp:84:22:84:22 | x |
| tests.cpp:84:29:84:29 | y |
| tests.cpp:85:6:85:17 | madSinkArg01 |
| tests.cpp:85:23:85:23 | x |
| tests.cpp:85:30:85:30 | y |
| tests.cpp:85:37:85:37 | z |
| tests.cpp:86:6:86:17 | madSinkArg02 |
| tests.cpp:86:23:86:23 | x |
| tests.cpp:86:30:86:30 | y |
| tests.cpp:86:37:86:37 | z |
| tests.cpp:87:6:87:24 | madSinkIndirectArg0 |
| tests.cpp:87:31:87:31 | x |
| tests.cpp:88:6:88:30 | madSinkDoubleIndirectArg0 |
| tests.cpp:88:38:88:38 | x |
| tests.cpp:92:6:92:15 | test_sinks |
| tests.cpp:106:6:106:6 | a |
| tests.cpp:107:7:107:11 | a_ptr |
| tests.cpp:115:6:115:18 | madSinkParam0 |
| tests.cpp:115:24:115:24 | x |
| tests.cpp:121:8:121:8 | operator= |
| tests.cpp:121:8:121:8 | operator= |
| tests.cpp:121:8:121:18 | MyContainer |
| tests.cpp:122:6:122:10 | value |
| tests.cpp:123:6:123:11 | value2 |
| tests.cpp:124:7:124:9 | ptr |
| tests.cpp:127:5:127:19 | madArg0ToReturn |
| tests.cpp:127:25:127:25 | x |
| tests.cpp:128:6:128:28 | madArg0ToReturnIndirect |
| tests.cpp:128:34:128:34 | x |
| tests.cpp:129:5:129:15 | notASummary |
| tests.cpp:129:21:129:21 | x |
| tests.cpp:130:5:130:28 | madArg0ToReturnValueFlow |
| tests.cpp:130:34:130:34 | x |
| tests.cpp:131:5:131:27 | madArg0IndirectToReturn |
| tests.cpp:131:34:131:34 | x |
| tests.cpp:132:5:132:33 | madArg0DoubleIndirectToReturn |
| tests.cpp:132:41:132:41 | x |
| tests.cpp:133:5:133:30 | madArg0NotIndirectToReturn |
| tests.cpp:133:37:133:37 | x |
| tests.cpp:134:6:134:26 | madArg0ToArg1Indirect |
| tests.cpp:134:32:134:32 | x |
| tests.cpp:134:40:134:40 | y |
| tests.cpp:135:6:135:34 | madArg0IndirectToArg1Indirect |
| tests.cpp:135:47:135:47 | x |
| tests.cpp:135:55:135:55 | y |
| tests.cpp:136:5:136:18 | madArgsComplex |
| tests.cpp:136:25:136:25 | a |
| tests.cpp:136:33:136:33 | b |
| tests.cpp:136:40:136:40 | c |
| tests.cpp:136:47:136:47 | d |
| tests.cpp:137:5:137:14 | madArgsAny |
| tests.cpp:137:20:137:20 | a |
| tests.cpp:137:28:137:28 | b |
| tests.cpp:138:5:138:28 | madAndImplementedComplex |
| tests.cpp:138:34:138:34 | a |
| tests.cpp:138:41:138:41 | b |
| tests.cpp:138:48:138:48 | c |
| tests.cpp:143:5:143:24 | madArg0FieldToReturn |
| tests.cpp:143:38:143:39 | mc |
| tests.cpp:144:5:144:32 | madArg0IndirectFieldToReturn |
| tests.cpp:144:47:144:48 | mc |
| tests.cpp:145:5:145:32 | madArg0FieldIndirectToReturn |
| tests.cpp:145:46:145:47 | mc |
| tests.cpp:146:13:146:32 | madArg0ToReturnField |
| tests.cpp:146:38:146:38 | x |
| tests.cpp:147:14:147:41 | madArg0ToReturnIndirectField |
| tests.cpp:147:47:147:47 | x |
| tests.cpp:148:13:148:40 | madArg0ToReturnFieldIndirect |
| tests.cpp:148:46:148:46 | x |
| tests.cpp:150:6:150:19 | test_summaries |
| tests.cpp:153:6:153:6 | a |
| tests.cpp:153:9:153:9 | b |
| tests.cpp:153:12:153:12 | c |
| tests.cpp:153:15:153:15 | d |
| tests.cpp:153:18:153:18 | e |
| tests.cpp:154:7:154:11 | a_ptr |
| tests.cpp:197:14:197:16 | mc1 |
| tests.cpp:197:19:197:21 | mc2 |
| tests.cpp:216:15:216:18 | rtn1 |
| tests.cpp:219:14:219:17 | rtn2 |
| tests.cpp:220:7:220:14 | rtn2_ptr |
| tests.cpp:233:7:233:7 | operator= |
| tests.cpp:233:7:233:7 | operator= |
| tests.cpp:233:7:233:13 | MyClass |
| tests.cpp:236:6:236:26 | memberRemoteMadSource |
| tests.cpp:237:7:237:39 | memberRemoteMadSourceIndirectArg0 |
| tests.cpp:237:46:237:46 | x |
| tests.cpp:239:7:239:21 | qualifierSource |
| tests.cpp:240:7:240:26 | qualifierFieldSource |
| tests.cpp:243:7:243:23 | memberMadSinkArg0 |
| tests.cpp:243:29:243:29 | x |
| tests.cpp:245:7:245:19 | qualifierSink |
| tests.cpp:246:7:246:23 | qualifierArg0Sink |
| tests.cpp:246:29:246:29 | x |
| tests.cpp:247:7:247:24 | qualifierFieldSink |
| tests.cpp:250:7:250:19 | madArg0ToSelf |
| tests.cpp:250:25:250:25 | x |
| tests.cpp:251:6:251:20 | madSelfToReturn |
| tests.cpp:252:6:252:16 | notASummary |
| tests.cpp:253:7:253:20 | madArg0ToField |
| tests.cpp:253:26:253:26 | x |
| tests.cpp:254:6:254:21 | madFieldToReturn |
| tests.cpp:256:6:256:8 | val |
| tests.cpp:259:7:259:7 | MyDerivedClass |
| tests.cpp:259:7:259:7 | operator= |
| tests.cpp:259:7:259:7 | operator= |
| tests.cpp:259:7:259:20 | MyDerivedClass |
| tests.cpp:261:6:261:28 | subtypeRemoteMadSource1 |
| tests.cpp:262:6:262:21 | subtypeNonSource |
| tests.cpp:263:6:263:28 | subtypeRemoteMadSource2 |
| tests.cpp:266:9:266:15 | source2 |
| tests.cpp:267:6:267:9 | sink |
| tests.cpp:267:19:267:20 | mc |
| tests.cpp:270:8:270:8 | operator= |
| tests.cpp:270:8:270:8 | operator= |
| tests.cpp:270:8:270:14 | MyClass |
| tests.cpp:273:8:273:33 | namespaceMemberMadSinkArg0 |
| tests.cpp:273:39:273:39 | x |
| tests.cpp:274:15:274:46 | namespaceStaticMemberMadSinkArg0 |
| tests.cpp:274:52:274:52 | x |
| tests.cpp:277:7:277:30 | namespaceMadSelfToReturn |
| tests.cpp:281:22:281:28 | source3 |
| tests.cpp:283:6:283:23 | test_class_members |
| tests.cpp:284:10:284:11 | mc |
| tests.cpp:284:14:284:16 | mc2 |
| tests.cpp:284:19:284:21 | mc3 |
| tests.cpp:284:24:284:26 | mc4 |
| tests.cpp:284:29:284:31 | mc5 |
| tests.cpp:284:34:284:36 | mc6 |
| tests.cpp:284:39:284:41 | mc7 |
| tests.cpp:284:44:284:46 | mc8 |
| tests.cpp:284:49:284:51 | mc9 |
| tests.cpp:284:54:284:57 | mc10 |
| tests.cpp:284:60:284:63 | mc11 |
| tests.cpp:285:11:285:13 | ptr |
| tests.cpp:285:17:285:23 | mc4_ptr |
| tests.cpp:286:17:286:19 | mdc |
| tests.cpp:287:23:287:25 | mnc |
| tests.cpp:287:28:287:31 | mnc2 |
| tests.cpp:288:24:288:31 | mnc2_ptr |
| tests.cpp:294:6:294:6 | a |
| tests.cpp:387:8:387:8 | operator= |
| tests.cpp:387:8:387:8 | operator= |
| tests.cpp:387:8:387:14 | intPair |
| tests.cpp:388:6:388:10 | first |
| tests.cpp:389:6:389:11 | second |
| tests.cpp:392:5:392:29 | madCallArg0ReturnToReturn |
| tests.cpp:392:37:392:43 | fun_ptr |
| tests.cpp:393:9:393:38 | madCallArg0ReturnToReturnFirst |
| tests.cpp:393:46:393:52 | fun_ptr |
| tests.cpp:394:6:394:25 | madCallArg0WithValue |
| tests.cpp:394:34:394:40 | fun_ptr |
| tests.cpp:394:53:394:57 | value |
| tests.cpp:395:5:395:36 | madCallReturnValueIgnoreFunction |
| tests.cpp:395:45:395:51 | fun_ptr |
| tests.cpp:395:64:395:68 | value |
| tests.cpp:397:5:397:14 | getTainted |
| tests.cpp:398:6:398:13 | useValue |
| tests.cpp:398:19:398:19 | x |
| tests.cpp:399:6:399:17 | dontUseValue |
| tests.cpp:399:23:399:23 | x |
| tests.cpp:401:6:401:27 | test_function_pointers |
| tests.cpp:414:19:414:19 | X |
| tests.cpp:415:8:415:35 | StructWithTypedefInParameter<X> |
| tests.cpp:415:8:415:35 | StructWithTypedefInParameter<int> |
| tests.cpp:416:12:416:15 | Type |
| tests.cpp:417:5:417:31 | parameter_ref_to_return_ref |
| tests.cpp:417:5:417:31 | parameter_ref_to_return_ref |
| tests.cpp:417:45:417:45 | x |
| tests.cpp:417:45:417:45 | x |
| tests.cpp:420:6:420:37 | test_parameter_ref_to_return_ref |
| tests.cpp:421:6:421:6 | x |
| tests.cpp:422:36:422:36 | s |
| tests.cpp:423:6:423:6 | y |
| tests.cpp:427:7:427:9 | INT |
| tests.cpp:429:5:429:17 | receive_array |
| tests.cpp:429:23:429:23 | a |
| tests.cpp:431:6:431:23 | test_receive_array |
| tests.cpp:432:6:432:6 | x |
| tests.cpp:433:6:433:10 | array |
| tests.cpp:434:6:434:6 | y |
| tests.cpp:20:5:20:22 | remoteMadSourceVar |
| tests.cpp:21:6:21:31 | remoteMadSourceVarIndirect |
| tests.cpp:24:6:24:28 | namespaceLocalMadSource |
| tests.cpp:25:6:25:31 | namespaceLocalMadSourceVar |
| tests.cpp:28:7:28:30 | namespace2LocalMadSource |
| tests.cpp:31:6:31:19 | localMadSource |
| tests.cpp:33:5:33:27 | namespaceLocalMadSource |
| tests.cpp:35:6:35:17 | test_sources |
| tests.cpp:50:6:50:6 | v |
| tests.cpp:51:7:51:16 | v_indirect |
| tests.cpp:52:6:52:13 | v_direct |
| tests.cpp:63:6:63:6 | a |
| tests.cpp:63:9:63:9 | b |
| tests.cpp:63:12:63:12 | c |
| tests.cpp:63:15:63:15 | d |
| tests.cpp:75:6:75:6 | e |
| tests.cpp:85:6:85:26 | remoteMadSourceParam0 |
| tests.cpp:85:32:85:32 | x |
| tests.cpp:92:6:92:16 | madSinkArg0 |
| tests.cpp:92:22:92:22 | x |
| tests.cpp:93:6:93:13 | notASink |
| tests.cpp:93:19:93:19 | x |
| tests.cpp:94:6:94:16 | madSinkArg1 |
| tests.cpp:94:22:94:22 | x |
| tests.cpp:94:29:94:29 | y |
| tests.cpp:95:6:95:17 | madSinkArg01 |
| tests.cpp:95:23:95:23 | x |
| tests.cpp:95:30:95:30 | y |
| tests.cpp:95:37:95:37 | z |
| tests.cpp:96:6:96:17 | madSinkArg02 |
| tests.cpp:96:23:96:23 | x |
| tests.cpp:96:30:96:30 | y |
| tests.cpp:96:37:96:37 | z |
| tests.cpp:97:6:97:24 | madSinkIndirectArg0 |
| tests.cpp:97:31:97:31 | x |
| tests.cpp:98:6:98:30 | madSinkDoubleIndirectArg0 |
| tests.cpp:98:38:98:38 | x |
| tests.cpp:99:5:99:14 | madSinkVar |
| tests.cpp:100:6:100:23 | madSinkVarIndirect |
| tests.cpp:102:6:102:15 | test_sinks |
| tests.cpp:116:6:116:6 | a |
| tests.cpp:117:7:117:11 | a_ptr |
| tests.cpp:132:6:132:18 | madSinkParam0 |
| tests.cpp:132:24:132:24 | x |
| tests.cpp:138:8:138:8 | operator= |
| tests.cpp:138:8:138:8 | operator= |
| tests.cpp:138:8:138:18 | MyContainer |
| tests.cpp:139:6:139:10 | value |
| tests.cpp:140:6:140:11 | value2 |
| tests.cpp:141:7:141:9 | ptr |
| tests.cpp:144:5:144:19 | madArg0ToReturn |
| tests.cpp:144:25:144:25 | x |
| tests.cpp:145:6:145:28 | madArg0ToReturnIndirect |
| tests.cpp:145:34:145:34 | x |
| tests.cpp:146:5:146:15 | notASummary |
| tests.cpp:146:21:146:21 | x |
| tests.cpp:147:5:147:28 | madArg0ToReturnValueFlow |
| tests.cpp:147:34:147:34 | x |
| tests.cpp:148:5:148:27 | madArg0IndirectToReturn |
| tests.cpp:148:34:148:34 | x |
| tests.cpp:149:5:149:33 | madArg0DoubleIndirectToReturn |
| tests.cpp:149:41:149:41 | x |
| tests.cpp:150:5:150:30 | madArg0NotIndirectToReturn |
| tests.cpp:150:37:150:37 | x |
| tests.cpp:151:6:151:26 | madArg0ToArg1Indirect |
| tests.cpp:151:32:151:32 | x |
| tests.cpp:151:40:151:40 | y |
| tests.cpp:152:6:152:34 | madArg0IndirectToArg1Indirect |
| tests.cpp:152:47:152:47 | x |
| tests.cpp:152:55:152:55 | y |
| tests.cpp:153:5:153:18 | madArgsComplex |
| tests.cpp:153:25:153:25 | a |
| tests.cpp:153:33:153:33 | b |
| tests.cpp:153:40:153:40 | c |
| tests.cpp:153:47:153:47 | d |
| tests.cpp:154:5:154:14 | madArgsAny |
| tests.cpp:154:20:154:20 | a |
| tests.cpp:154:28:154:28 | b |
| tests.cpp:155:5:155:28 | madAndImplementedComplex |
| tests.cpp:155:34:155:34 | a |
| tests.cpp:155:41:155:41 | b |
| tests.cpp:155:48:155:48 | c |
| tests.cpp:160:5:160:24 | madArg0FieldToReturn |
| tests.cpp:160:38:160:39 | mc |
| tests.cpp:161:5:161:32 | madArg0IndirectFieldToReturn |
| tests.cpp:161:47:161:48 | mc |
| tests.cpp:162:5:162:32 | madArg0FieldIndirectToReturn |
| tests.cpp:162:46:162:47 | mc |
| tests.cpp:163:13:163:32 | madArg0ToReturnField |
| tests.cpp:163:38:163:38 | x |
| tests.cpp:164:14:164:41 | madArg0ToReturnIndirectField |
| tests.cpp:164:47:164:47 | x |
| tests.cpp:165:13:165:40 | madArg0ToReturnFieldIndirect |
| tests.cpp:165:46:165:46 | x |
| tests.cpp:167:13:167:30 | madFieldToFieldVar |
| tests.cpp:168:13:168:38 | madFieldToIndirectFieldVar |
| tests.cpp:169:14:169:39 | madIndirectFieldToFieldVar |
| tests.cpp:171:6:171:19 | test_summaries |
| tests.cpp:174:6:174:6 | a |
| tests.cpp:174:9:174:9 | b |
| tests.cpp:174:12:174:12 | c |
| tests.cpp:174:15:174:15 | d |
| tests.cpp:174:18:174:18 | e |
| tests.cpp:175:7:175:11 | a_ptr |
| tests.cpp:218:14:218:16 | mc1 |
| tests.cpp:218:19:218:21 | mc2 |
| tests.cpp:237:15:237:18 | rtn1 |
| tests.cpp:240:14:240:17 | rtn2 |
| tests.cpp:241:7:241:14 | rtn2_ptr |
| tests.cpp:267:7:267:7 | operator= |
| tests.cpp:267:7:267:7 | operator= |
| tests.cpp:267:7:267:13 | MyClass |
| tests.cpp:270:6:270:26 | memberRemoteMadSource |
| tests.cpp:271:7:271:39 | memberRemoteMadSourceIndirectArg0 |
| tests.cpp:271:46:271:46 | x |
| tests.cpp:272:6:272:29 | memberRemoteMadSourceVar |
| tests.cpp:273:7:273:21 | qualifierSource |
| tests.cpp:274:7:274:26 | qualifierFieldSource |
| tests.cpp:277:7:277:23 | memberMadSinkArg0 |
| tests.cpp:277:29:277:29 | x |
| tests.cpp:278:6:278:21 | memberMadSinkVar |
| tests.cpp:279:7:279:19 | qualifierSink |
| tests.cpp:280:7:280:23 | qualifierArg0Sink |
| tests.cpp:280:29:280:29 | x |
| tests.cpp:281:7:281:24 | qualifierFieldSink |
| tests.cpp:284:7:284:19 | madArg0ToSelf |
| tests.cpp:284:25:284:25 | x |
| tests.cpp:285:6:285:20 | madSelfToReturn |
| tests.cpp:286:6:286:16 | notASummary |
| tests.cpp:287:7:287:20 | madArg0ToField |
| tests.cpp:287:26:287:26 | x |
| tests.cpp:288:6:288:21 | madFieldToReturn |
| tests.cpp:290:6:290:8 | val |
| tests.cpp:293:7:293:7 | MyDerivedClass |
| tests.cpp:293:7:293:7 | operator= |
| tests.cpp:293:7:293:7 | operator= |
| tests.cpp:293:7:293:20 | MyDerivedClass |
| tests.cpp:295:6:295:28 | subtypeRemoteMadSource1 |
| tests.cpp:296:6:296:21 | subtypeNonSource |
| tests.cpp:297:6:297:28 | subtypeRemoteMadSource2 |
| tests.cpp:300:9:300:15 | source2 |
| tests.cpp:301:6:301:9 | sink |
| tests.cpp:301:19:301:20 | mc |
| tests.cpp:304:8:304:8 | operator= |
| tests.cpp:304:8:304:8 | operator= |
| tests.cpp:304:8:304:14 | MyClass |
| tests.cpp:307:8:307:33 | namespaceMemberMadSinkArg0 |
| tests.cpp:307:39:307:39 | x |
| tests.cpp:308:15:308:46 | namespaceStaticMemberMadSinkArg0 |
| tests.cpp:308:52:308:52 | x |
| tests.cpp:309:7:309:31 | namespaceMemberMadSinkVar |
| tests.cpp:310:14:310:44 | namespaceStaticMemberMadSinkVar |
| tests.cpp:313:7:313:30 | namespaceMadSelfToReturn |
| tests.cpp:317:22:317:28 | source3 |
| tests.cpp:319:6:319:23 | test_class_members |
| tests.cpp:320:10:320:11 | mc |
| tests.cpp:320:14:320:16 | mc2 |
| tests.cpp:320:19:320:21 | mc3 |
| tests.cpp:320:24:320:26 | mc4 |
| tests.cpp:320:29:320:31 | mc5 |
| tests.cpp:320:34:320:36 | mc6 |
| tests.cpp:320:39:320:41 | mc7 |
| tests.cpp:320:44:320:46 | mc8 |
| tests.cpp:320:49:320:51 | mc9 |
| tests.cpp:320:54:320:57 | mc10 |
| tests.cpp:320:60:320:63 | mc11 |
| tests.cpp:321:11:321:13 | ptr |
| tests.cpp:321:17:321:23 | mc4_ptr |
| tests.cpp:322:17:322:19 | mdc |
| tests.cpp:323:23:323:25 | mnc |
| tests.cpp:323:28:323:31 | mnc2 |
| tests.cpp:324:24:324:31 | mnc2_ptr |
| tests.cpp:330:6:330:6 | a |
| tests.cpp:429:8:429:8 | operator= |
| tests.cpp:429:8:429:8 | operator= |
| tests.cpp:429:8:429:14 | intPair |
| tests.cpp:430:6:430:10 | first |
| tests.cpp:431:6:431:11 | second |
| tests.cpp:434:5:434:29 | madCallArg0ReturnToReturn |
| tests.cpp:434:37:434:43 | fun_ptr |
| tests.cpp:435:9:435:38 | madCallArg0ReturnToReturnFirst |
| tests.cpp:435:46:435:52 | fun_ptr |
| tests.cpp:436:6:436:25 | madCallArg0WithValue |
| tests.cpp:436:34:436:40 | fun_ptr |
| tests.cpp:436:53:436:57 | value |
| tests.cpp:437:5:437:36 | madCallReturnValueIgnoreFunction |
| tests.cpp:437:45:437:51 | fun_ptr |
| tests.cpp:437:64:437:68 | value |
| tests.cpp:439:5:439:14 | getTainted |
| tests.cpp:440:6:440:13 | useValue |
| tests.cpp:440:19:440:19 | x |
| tests.cpp:441:6:441:17 | dontUseValue |
| tests.cpp:441:23:441:23 | x |
| tests.cpp:443:6:443:27 | test_function_pointers |
| tests.cpp:456:19:456:19 | X |
| tests.cpp:457:8:457:35 | StructWithTypedefInParameter<X> |
| tests.cpp:457:8:457:35 | StructWithTypedefInParameter<int> |
| tests.cpp:458:12:458:15 | Type |
| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
| tests.cpp:459:5:459:31 | parameter_ref_to_return_ref |
| tests.cpp:459:45:459:45 | x |
| tests.cpp:459:45:459:45 | x |
| tests.cpp:462:6:462:37 | test_parameter_ref_to_return_ref |
| tests.cpp:463:6:463:6 | x |
| tests.cpp:464:36:464:36 | s |
| tests.cpp:465:6:465:6 | y |
| tests.cpp:469:7:469:9 | INT |
| tests.cpp:471:5:471:17 | receive_array |
| tests.cpp:471:23:471:23 | a |
| tests.cpp:473:6:473:23 | test_receive_array |
| tests.cpp:474:6:474:6 | x |
| tests.cpp:475:6:475:10 | array |
| tests.cpp:476:6:476:6 | y |
flowSummaryNode
| tests.cpp:127:5:127:19 | [summary param] 0 in madArg0ToReturn | ParameterNode | madArg0ToReturn | madArg0ToReturn |
| tests.cpp:127:5:127:19 | [summary] to write: ReturnValue in madArg0ToReturn | ReturnNode | madArg0ToReturn | madArg0ToReturn |
| tests.cpp:128:6:128:28 | [summary param] 0 in madArg0ToReturnIndirect | ParameterNode | madArg0ToReturnIndirect | madArg0ToReturnIndirect |
| tests.cpp:128:6:128:28 | [summary] to write: ReturnValue[*] in madArg0ToReturnIndirect | ReturnNode | madArg0ToReturnIndirect | madArg0ToReturnIndirect |
| tests.cpp:130:5:130:28 | [summary param] 0 in madArg0ToReturnValueFlow | ParameterNode | madArg0ToReturnValueFlow | madArg0ToReturnValueFlow |
| tests.cpp:130:5:130:28 | [summary] to write: ReturnValue in madArg0ToReturnValueFlow | ReturnNode | madArg0ToReturnValueFlow | madArg0ToReturnValueFlow |
| tests.cpp:131:5:131:27 | [summary param] *0 in madArg0IndirectToReturn | ParameterNode | madArg0IndirectToReturn | madArg0IndirectToReturn |
| tests.cpp:131:5:131:27 | [summary] to write: ReturnValue in madArg0IndirectToReturn | ReturnNode | madArg0IndirectToReturn | madArg0IndirectToReturn |
| tests.cpp:132:5:132:33 | [summary param] **0 in madArg0DoubleIndirectToReturn | ParameterNode | madArg0DoubleIndirectToReturn | madArg0DoubleIndirectToReturn |
| tests.cpp:132:5:132:33 | [summary] to write: ReturnValue in madArg0DoubleIndirectToReturn | ReturnNode | madArg0DoubleIndirectToReturn | madArg0DoubleIndirectToReturn |
| tests.cpp:133:5:133:30 | [summary param] 0 in madArg0NotIndirectToReturn | ParameterNode | madArg0NotIndirectToReturn | madArg0NotIndirectToReturn |
| tests.cpp:133:5:133:30 | [summary] to write: ReturnValue in madArg0NotIndirectToReturn | ReturnNode | madArg0NotIndirectToReturn | madArg0NotIndirectToReturn |
| tests.cpp:134:6:134:26 | [summary param] 0 in madArg0ToArg1Indirect | ParameterNode | madArg0ToArg1Indirect | madArg0ToArg1Indirect |
| tests.cpp:134:6:134:26 | [summary param] *1 in madArg0ToArg1Indirect | ParameterNode | madArg0ToArg1Indirect | madArg0ToArg1Indirect |
| tests.cpp:134:6:134:26 | [summary] to write: Argument[*1] in madArg0ToArg1Indirect | PostUpdateNode | madArg0ToArg1Indirect | madArg0ToArg1Indirect |
| tests.cpp:135:6:135:34 | [summary param] *0 in madArg0IndirectToArg1Indirect | ParameterNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
| tests.cpp:135:6:135:34 | [summary param] *1 in madArg0IndirectToArg1Indirect | ParameterNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
| tests.cpp:135:6:135:34 | [summary] to write: Argument[*1] in madArg0IndirectToArg1Indirect | PostUpdateNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
| tests.cpp:136:5:136:18 | [summary param] 2 in madArgsComplex | ParameterNode | madArgsComplex | madArgsComplex |
| tests.cpp:136:5:136:18 | [summary param] *0 in madArgsComplex | ParameterNode | madArgsComplex | madArgsComplex |
| tests.cpp:136:5:136:18 | [summary param] *1 in madArgsComplex | ParameterNode | madArgsComplex | madArgsComplex |
| tests.cpp:136:5:136:18 | [summary] to write: ReturnValue in madArgsComplex | ReturnNode | madArgsComplex | madArgsComplex |
| tests.cpp:138:5:138:28 | [summary param] 2 in madAndImplementedComplex | ParameterNode | madAndImplementedComplex | madAndImplementedComplex |
| tests.cpp:138:5:138:28 | [summary] to write: ReturnValue in madAndImplementedComplex | ReturnNode | madAndImplementedComplex | madAndImplementedComplex |
| tests.cpp:143:5:143:24 | [summary param] 0 in madArg0FieldToReturn | ParameterNode | madArg0FieldToReturn | madArg0FieldToReturn |
| tests.cpp:143:5:143:24 | [summary] read: Argument[0].Field[MyContainer::value]/Field[value] in madArg0FieldToReturn | | madArg0FieldToReturn | madArg0FieldToReturn |
| tests.cpp:143:5:143:24 | [summary] to write: ReturnValue in madArg0FieldToReturn | ReturnNode | madArg0FieldToReturn | madArg0FieldToReturn |
| tests.cpp:144:5:144:32 | [summary param] *0 in madArg0IndirectFieldToReturn | ParameterNode | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
| tests.cpp:144:5:144:32 | [summary] read: Argument[*0].Field[MyContainer::value]/Field[value] in madArg0IndirectFieldToReturn | | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
| tests.cpp:144:5:144:32 | [summary] to write: ReturnValue in madArg0IndirectFieldToReturn | ReturnNode | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
| tests.cpp:145:5:145:32 | [summary param] 0 in madArg0FieldIndirectToReturn | ParameterNode | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
| tests.cpp:145:5:145:32 | [summary] read: Argument[0].Field[*MyContainer::ptr]/Field[*ptr] in madArg0FieldIndirectToReturn | | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
| tests.cpp:145:5:145:32 | [summary] to write: ReturnValue in madArg0FieldIndirectToReturn | ReturnNode | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
| tests.cpp:146:13:146:32 | [summary param] 0 in madArg0ToReturnField | ParameterNode | madArg0ToReturnField | madArg0ToReturnField |
| tests.cpp:146:13:146:32 | [summary] to write: ReturnValue in madArg0ToReturnField | ReturnNode | madArg0ToReturnField | madArg0ToReturnField |
| tests.cpp:146:13:146:32 | [summary] to write: ReturnValue.Field[MyContainer::value]/Field[value] in madArg0ToReturnField | | madArg0ToReturnField | madArg0ToReturnField |
| tests.cpp:147:14:147:41 | [summary param] 0 in madArg0ToReturnIndirectField | ParameterNode | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
| tests.cpp:147:14:147:41 | [summary] to write: ReturnValue[*] in madArg0ToReturnIndirectField | ReturnNode | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
| tests.cpp:147:14:147:41 | [summary] to write: ReturnValue[*].Field[MyContainer::value]/Field[value] in madArg0ToReturnIndirectField | | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
| tests.cpp:148:13:148:40 | [summary param] 0 in madArg0ToReturnFieldIndirect | ParameterNode | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
| tests.cpp:148:13:148:40 | [summary] to write: ReturnValue in madArg0ToReturnFieldIndirect | ReturnNode | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
| tests.cpp:148:13:148:40 | [summary] to write: ReturnValue.Field[*MyContainer::ptr]/Field[*ptr] in madArg0ToReturnFieldIndirect | | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
| tests.cpp:250:7:250:19 | [summary param] 0 in madArg0ToSelf | ParameterNode | madArg0ToSelf | madArg0ToSelf |
| tests.cpp:250:7:250:19 | [summary param] this in madArg0ToSelf | ParameterNode | madArg0ToSelf | madArg0ToSelf |
| tests.cpp:250:7:250:19 | [summary] to write: Argument[this] in madArg0ToSelf | PostUpdateNode | madArg0ToSelf | madArg0ToSelf |
| tests.cpp:251:6:251:20 | [summary param] this in madSelfToReturn | ParameterNode | madSelfToReturn | madSelfToReturn |
| tests.cpp:251:6:251:20 | [summary] to write: ReturnValue in madSelfToReturn | ReturnNode | madSelfToReturn | madSelfToReturn |
| tests.cpp:253:7:253:20 | [summary param] 0 in madArg0ToField | ParameterNode | madArg0ToField | madArg0ToField |
| tests.cpp:253:7:253:20 | [summary param] this in madArg0ToField | ParameterNode | madArg0ToField | madArg0ToField |
| tests.cpp:253:7:253:20 | [summary] to write: Argument[this] in madArg0ToField | PostUpdateNode | madArg0ToField | madArg0ToField |
| tests.cpp:253:7:253:20 | [summary] to write: Argument[this].Field[MyClass::val]/Field[val] in madArg0ToField | | madArg0ToField | madArg0ToField |
| tests.cpp:254:6:254:21 | [summary param] this in madFieldToReturn | ParameterNode | madFieldToReturn | madFieldToReturn |
| tests.cpp:254:6:254:21 | [summary] read: Argument[this].Field[MyClass::val]/Field[val] in madFieldToReturn | | madFieldToReturn | madFieldToReturn |
| tests.cpp:254:6:254:21 | [summary] to write: ReturnValue in madFieldToReturn | ReturnNode | madFieldToReturn | madFieldToReturn |
| tests.cpp:277:7:277:30 | [summary param] this in namespaceMadSelfToReturn | ParameterNode | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
| tests.cpp:277:7:277:30 | [summary] to write: ReturnValue in namespaceMadSelfToReturn | ReturnNode | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
| tests.cpp:392:5:392:29 | [summary param] 0 in madCallArg0ReturnToReturn | ParameterNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
| tests.cpp:392:5:392:29 | [summary] read: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturn | PostUpdateNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
| tests.cpp:392:5:392:29 | [summary] read: Argument[0].ReturnValue in madCallArg0ReturnToReturn | OutNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
| tests.cpp:392:5:392:29 | [summary] to write: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturn | ArgumentNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
| tests.cpp:392:5:392:29 | [summary] to write: ReturnValue in madCallArg0ReturnToReturn | ReturnNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
| tests.cpp:393:9:393:38 | [summary param] 0 in madCallArg0ReturnToReturnFirst | ParameterNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:393:9:393:38 | [summary] read: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturnFirst | PostUpdateNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:393:9:393:38 | [summary] read: Argument[0].ReturnValue in madCallArg0ReturnToReturnFirst | OutNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:393:9:393:38 | [summary] to write: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturnFirst | ArgumentNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:393:9:393:38 | [summary] to write: ReturnValue in madCallArg0ReturnToReturnFirst | ReturnNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:393:9:393:38 | [summary] to write: ReturnValue.Field[first]/Field[intPair::first] in madCallArg0ReturnToReturnFirst | | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:394:6:394:25 | [summary param] 0 in madCallArg0WithValue | ParameterNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:394:6:394:25 | [summary param] 1 in madCallArg0WithValue | ParameterNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:394:6:394:25 | [summary] read: Argument[0].Parameter[0] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:394:6:394:25 | [summary] read: Argument[0].Parameter[this pointer] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:394:6:394:25 | [summary] to write: Argument[0].Parameter[0] in madCallArg0WithValue | ArgumentNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:394:6:394:25 | [summary] to write: Argument[0].Parameter[this pointer] in madCallArg0WithValue | ArgumentNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:394:6:394:25 | [summary] to write: Argument[1] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:395:5:395:36 | [summary param] 1 in madCallReturnValueIgnoreFunction | ParameterNode | madCallReturnValueIgnoreFunction | madCallReturnValueIgnoreFunction |
| tests.cpp:395:5:395:36 | [summary] to write: ReturnValue in madCallReturnValueIgnoreFunction | ReturnNode | madCallReturnValueIgnoreFunction | madCallReturnValueIgnoreFunction |
| tests.cpp:417:5:417:31 | [summary param] *0 in parameter_ref_to_return_ref | ParameterNode | parameter_ref_to_return_ref | parameter_ref_to_return_ref |
| tests.cpp:417:5:417:31 | [summary] to write: ReturnValue[*] in parameter_ref_to_return_ref | ReturnNode | parameter_ref_to_return_ref | parameter_ref_to_return_ref |
| tests.cpp:429:5:429:17 | [summary param] *0 in receive_array | ParameterNode | receive_array | receive_array |
| tests.cpp:429:5:429:17 | [summary] to write: ReturnValue in receive_array | ReturnNode | receive_array | receive_array |
| tests.cpp:144:5:144:19 | [summary param] 0 in madArg0ToReturn | ParameterNode | madArg0ToReturn | madArg0ToReturn |
| tests.cpp:144:5:144:19 | [summary] to write: ReturnValue in madArg0ToReturn | ReturnNode | madArg0ToReturn | madArg0ToReturn |
| tests.cpp:145:6:145:28 | [summary param] 0 in madArg0ToReturnIndirect | ParameterNode | madArg0ToReturnIndirect | madArg0ToReturnIndirect |
| tests.cpp:145:6:145:28 | [summary] to write: ReturnValue[*] in madArg0ToReturnIndirect | ReturnNode | madArg0ToReturnIndirect | madArg0ToReturnIndirect |
| tests.cpp:147:5:147:28 | [summary param] 0 in madArg0ToReturnValueFlow | ParameterNode | madArg0ToReturnValueFlow | madArg0ToReturnValueFlow |
| tests.cpp:147:5:147:28 | [summary] to write: ReturnValue in madArg0ToReturnValueFlow | ReturnNode | madArg0ToReturnValueFlow | madArg0ToReturnValueFlow |
| tests.cpp:148:5:148:27 | [summary param] *0 in madArg0IndirectToReturn | ParameterNode | madArg0IndirectToReturn | madArg0IndirectToReturn |
| tests.cpp:148:5:148:27 | [summary] to write: ReturnValue in madArg0IndirectToReturn | ReturnNode | madArg0IndirectToReturn | madArg0IndirectToReturn |
| tests.cpp:149:5:149:33 | [summary param] **0 in madArg0DoubleIndirectToReturn | ParameterNode | madArg0DoubleIndirectToReturn | madArg0DoubleIndirectToReturn |
| tests.cpp:149:5:149:33 | [summary] to write: ReturnValue in madArg0DoubleIndirectToReturn | ReturnNode | madArg0DoubleIndirectToReturn | madArg0DoubleIndirectToReturn |
| tests.cpp:150:5:150:30 | [summary param] 0 in madArg0NotIndirectToReturn | ParameterNode | madArg0NotIndirectToReturn | madArg0NotIndirectToReturn |
| tests.cpp:150:5:150:30 | [summary] to write: ReturnValue in madArg0NotIndirectToReturn | ReturnNode | madArg0NotIndirectToReturn | madArg0NotIndirectToReturn |
| tests.cpp:151:6:151:26 | [summary param] 0 in madArg0ToArg1Indirect | ParameterNode | madArg0ToArg1Indirect | madArg0ToArg1Indirect |
| tests.cpp:151:6:151:26 | [summary param] *1 in madArg0ToArg1Indirect | ParameterNode | madArg0ToArg1Indirect | madArg0ToArg1Indirect |
| tests.cpp:151:6:151:26 | [summary] to write: Argument[*1] in madArg0ToArg1Indirect | PostUpdateNode | madArg0ToArg1Indirect | madArg0ToArg1Indirect |
| tests.cpp:152:6:152:34 | [summary param] *0 in madArg0IndirectToArg1Indirect | ParameterNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
| tests.cpp:152:6:152:34 | [summary param] *1 in madArg0IndirectToArg1Indirect | ParameterNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
| tests.cpp:152:6:152:34 | [summary] to write: Argument[*1] in madArg0IndirectToArg1Indirect | PostUpdateNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
| tests.cpp:153:5:153:18 | [summary param] 2 in madArgsComplex | ParameterNode | madArgsComplex | madArgsComplex |
| tests.cpp:153:5:153:18 | [summary param] *0 in madArgsComplex | ParameterNode | madArgsComplex | madArgsComplex |
| tests.cpp:153:5:153:18 | [summary param] *1 in madArgsComplex | ParameterNode | madArgsComplex | madArgsComplex |
| tests.cpp:153:5:153:18 | [summary] to write: ReturnValue in madArgsComplex | ReturnNode | madArgsComplex | madArgsComplex |
| tests.cpp:155:5:155:28 | [summary param] 2 in madAndImplementedComplex | ParameterNode | madAndImplementedComplex | madAndImplementedComplex |
| tests.cpp:155:5:155:28 | [summary] to write: ReturnValue in madAndImplementedComplex | ReturnNode | madAndImplementedComplex | madAndImplementedComplex |
| tests.cpp:160:5:160:24 | [summary param] 0 in madArg0FieldToReturn | ParameterNode | madArg0FieldToReturn | madArg0FieldToReturn |
| tests.cpp:160:5:160:24 | [summary] read: Argument[0].Field[value] in madArg0FieldToReturn | | madArg0FieldToReturn | madArg0FieldToReturn |
| tests.cpp:160:5:160:24 | [summary] to write: ReturnValue in madArg0FieldToReturn | ReturnNode | madArg0FieldToReturn | madArg0FieldToReturn |
| tests.cpp:161:5:161:32 | [summary param] *0 in madArg0IndirectFieldToReturn | ParameterNode | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
| tests.cpp:161:5:161:32 | [summary] read: Argument[*0].Field[value] in madArg0IndirectFieldToReturn | | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
| tests.cpp:161:5:161:32 | [summary] to write: ReturnValue in madArg0IndirectFieldToReturn | ReturnNode | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
| tests.cpp:162:5:162:32 | [summary param] 0 in madArg0FieldIndirectToReturn | ParameterNode | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
| tests.cpp:162:5:162:32 | [summary] read: Argument[0].Field[*ptr] in madArg0FieldIndirectToReturn | | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
| tests.cpp:162:5:162:32 | [summary] to write: ReturnValue in madArg0FieldIndirectToReturn | ReturnNode | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
| tests.cpp:163:13:163:32 | [summary param] 0 in madArg0ToReturnField | ParameterNode | madArg0ToReturnField | madArg0ToReturnField |
| tests.cpp:163:13:163:32 | [summary] to write: ReturnValue in madArg0ToReturnField | ReturnNode | madArg0ToReturnField | madArg0ToReturnField |
| tests.cpp:163:13:163:32 | [summary] to write: ReturnValue.Field[value] in madArg0ToReturnField | | madArg0ToReturnField | madArg0ToReturnField |
| tests.cpp:164:14:164:41 | [summary param] 0 in madArg0ToReturnIndirectField | ParameterNode | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
| tests.cpp:164:14:164:41 | [summary] to write: ReturnValue[*] in madArg0ToReturnIndirectField | ReturnNode | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
| tests.cpp:164:14:164:41 | [summary] to write: ReturnValue[*].Field[value] in madArg0ToReturnIndirectField | | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
| tests.cpp:165:13:165:40 | [summary param] 0 in madArg0ToReturnFieldIndirect | ParameterNode | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
| tests.cpp:165:13:165:40 | [summary] to write: ReturnValue in madArg0ToReturnFieldIndirect | ReturnNode | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
| tests.cpp:165:13:165:40 | [summary] to write: ReturnValue.Field[*ptr] in madArg0ToReturnFieldIndirect | | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
| tests.cpp:284:7:284:19 | [summary param] 0 in madArg0ToSelf | ParameterNode | madArg0ToSelf | madArg0ToSelf |
| tests.cpp:284:7:284:19 | [summary param] this in madArg0ToSelf | ParameterNode | madArg0ToSelf | madArg0ToSelf |
| tests.cpp:284:7:284:19 | [summary] to write: Argument[this] in madArg0ToSelf | PostUpdateNode | madArg0ToSelf | madArg0ToSelf |
| tests.cpp:285:6:285:20 | [summary param] this in madSelfToReturn | ParameterNode | madSelfToReturn | madSelfToReturn |
| tests.cpp:285:6:285:20 | [summary] to write: ReturnValue in madSelfToReturn | ReturnNode | madSelfToReturn | madSelfToReturn |
| tests.cpp:287:7:287:20 | [summary param] 0 in madArg0ToField | ParameterNode | madArg0ToField | madArg0ToField |
| tests.cpp:287:7:287:20 | [summary param] this in madArg0ToField | ParameterNode | madArg0ToField | madArg0ToField |
| tests.cpp:287:7:287:20 | [summary] to write: Argument[this] in madArg0ToField | PostUpdateNode | madArg0ToField | madArg0ToField |
| tests.cpp:287:7:287:20 | [summary] to write: Argument[this].Field[val] in madArg0ToField | | madArg0ToField | madArg0ToField |
| tests.cpp:288:6:288:21 | [summary param] this in madFieldToReturn | ParameterNode | madFieldToReturn | madFieldToReturn |
| tests.cpp:288:6:288:21 | [summary] read: Argument[this].Field[val] in madFieldToReturn | | madFieldToReturn | madFieldToReturn |
| tests.cpp:288:6:288:21 | [summary] to write: ReturnValue in madFieldToReturn | ReturnNode | madFieldToReturn | madFieldToReturn |
| tests.cpp:313:7:313:30 | [summary param] this in namespaceMadSelfToReturn | ParameterNode | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
| tests.cpp:313:7:313:30 | [summary] to write: ReturnValue in namespaceMadSelfToReturn | ReturnNode | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
| tests.cpp:434:5:434:29 | [summary param] 0 in madCallArg0ReturnToReturn | ParameterNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
| tests.cpp:434:5:434:29 | [summary] read: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturn | PostUpdateNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
| tests.cpp:434:5:434:29 | [summary] read: Argument[0].ReturnValue in madCallArg0ReturnToReturn | OutNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
| tests.cpp:434:5:434:29 | [summary] to write: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturn | ArgumentNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
| tests.cpp:434:5:434:29 | [summary] to write: ReturnValue in madCallArg0ReturnToReturn | ReturnNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
| tests.cpp:435:9:435:38 | [summary param] 0 in madCallArg0ReturnToReturnFirst | ParameterNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:435:9:435:38 | [summary] read: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturnFirst | PostUpdateNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:435:9:435:38 | [summary] read: Argument[0].ReturnValue in madCallArg0ReturnToReturnFirst | OutNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:435:9:435:38 | [summary] to write: Argument[0].Parameter[this pointer] in madCallArg0ReturnToReturnFirst | ArgumentNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:435:9:435:38 | [summary] to write: ReturnValue in madCallArg0ReturnToReturnFirst | ReturnNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:435:9:435:38 | [summary] to write: ReturnValue.Field[first] in madCallArg0ReturnToReturnFirst | | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:436:6:436:25 | [summary param] 0 in madCallArg0WithValue | ParameterNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:436:6:436:25 | [summary param] 1 in madCallArg0WithValue | ParameterNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:436:6:436:25 | [summary] read: Argument[0].Parameter[0] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:436:6:436:25 | [summary] read: Argument[0].Parameter[this pointer] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:436:6:436:25 | [summary] to write: Argument[0].Parameter[0] in madCallArg0WithValue | ArgumentNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:436:6:436:25 | [summary] to write: Argument[0].Parameter[this pointer] in madCallArg0WithValue | ArgumentNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:436:6:436:25 | [summary] to write: Argument[1] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:437:5:437:36 | [summary param] 1 in madCallReturnValueIgnoreFunction | ParameterNode | madCallReturnValueIgnoreFunction | madCallReturnValueIgnoreFunction |
| tests.cpp:437:5:437:36 | [summary] to write: ReturnValue in madCallReturnValueIgnoreFunction | ReturnNode | madCallReturnValueIgnoreFunction | madCallReturnValueIgnoreFunction |
| tests.cpp:459:5:459:31 | [summary param] *0 in parameter_ref_to_return_ref | ParameterNode | parameter_ref_to_return_ref | parameter_ref_to_return_ref |
| tests.cpp:459:5:459:31 | [summary] to write: ReturnValue[*] in parameter_ref_to_return_ref | ReturnNode | parameter_ref_to_return_ref | parameter_ref_to_return_ref |
| tests.cpp:471:5:471:17 | [summary param] *0 in receive_array | ParameterNode | receive_array | receive_array |
| tests.cpp:471:5:471:17 | [summary] to write: ReturnValue in receive_array | ReturnNode | receive_array | receive_array |

View File

@@ -11,12 +11,15 @@ extensions:
- ["", "", False, "remoteMadSourceDoubleIndirect", "", "", "ReturnValue[**]", "remote", "manual"]
- ["", "", False, "remoteMadSourceIndirectArg0", "", "", "Argument[*0]", "remote", "manual"]
- ["", "", False, "remoteMadSourceIndirectArg1", "", "", "Argument[*1]", "remote", "manual"]
- ["", "", False, "remoteMadSourceVar", "", "", "", "remote", "manual"]
- ["", "", False, "remoteMadSourceVarIndirect", "", "", "*", "remote", "manual"] # we can't express this source/sink correctly at present, "*" is not a valid access path
- ["", "", False, "remoteMadSourceParam0", "", "", "Parameter[0]", "remote", "manual"]
- ["MyNamespace", "", False, "namespaceLocalMadSource", "", "", "ReturnValue", "local", "manual"]
- ["MyNamespace", "", False, "namespaceLocalMadSourceVar", "", "", "", "local", "manual"]
- ["MyNamespace::MyNamespace2", "", False, "namespace2LocalMadSource", "", "", "ReturnValue", "local", "manual"]
- ["", "MyClass", True, "memberRemoteMadSource", "", "", "ReturnValue", "remote", "manual"]
- ["", "MyClass", True, "memberRemoteMadSourceIndirectArg0", "", "", "Argument[*0]", "remote", "manual"]
- ["", "MyClass", True, "memberRemoteMadSourceVar", "", "", "", "remote", "manual"]
- ["", "MyClass", True, "subtypeRemoteMadSource1", "", "", "ReturnValue", "remote", "manual"]
- ["", "MyClass", False, "subtypeNonSource", "", "", "ReturnValue", "remote", "manual"] # the tests define this in MyDerivedClass, so it should *not* be recongized as a source
- ["", "MyClass", True, "qualifierSource", "", "", "Argument[-1]", "remote", "manual"]
@@ -32,13 +35,18 @@ extensions:
- ["", "", False, "madSinkArg02", "", "", "Argument[0,2]", "test-sink", "manual"]
- ["", "", False, "madSinkIndirectArg0", "", "", "Argument[*0]", "test-sink", "manual"]
- ["", "", False, "madSinkDoubleIndirectArg0", "", "", "Argument[**0]", "test-sink", "manual"]
- ["", "", False, "madSinkVar", "", "", "", "test-sink", "manual"]
- ["", "", False, "madSinkVarIndirect", "", "", "*", "test-sink", "manual"] # we can't express this source/sink correctly at present, "*" is not a valid access path
- ["", "", False, "madSinkParam0", "", "", "Parameter[0]", "test-sink", "manual"]
- ["", "MyClass", True, "memberMadSinkArg0", "", "", "Argument[0]", "test-sink", "manual"]
- ["", "MyClass", True, "memberMadSinkVar", "", "", "", "test-sink", "manual"]
- ["", "MyClass", True, "qualifierSink", "", "", "Argument[-1]", "test-sink", "manual"]
- ["", "MyClass", True, "qualifierArg0Sink", "", "", "Argument[-1..0]", "test-sink", "manual"]
- ["", "MyClass", True, "qualifierFieldSink", "", "", "Argument[-1].val", "test-sink", "manual"]
- ["MyNamespace", "MyClass", True, "namespaceMemberMadSinkArg0", "", "", "Argument[0]", "test-sink", "manual"]
- ["MyNamespace", "MyClass", True, "namespaceStaticMemberMadSinkArg0", "", "", "Argument[0]", "test-sink", "manual"]
- ["MyNamespace", "MyClass", True, "namespaceMemberMadSinkVar", "", "", "", "test-sink", "manual"]
- ["MyNamespace", "MyClass", True, "namespaceStaticMemberMadSinkVar", "", "", "", "test-sink", "manual"]
- addsTo:
pack: codeql/cpp-all
extensible: summaryModel
@@ -60,6 +68,9 @@ extensions:
- ["", "", False, "madArg0ToReturnField", "", "", "Argument[0]", "ReturnValue.Field[value]", "taint", "manual"]
- ["", "", False, "madArg0ToReturnIndirectField", "", "", "Argument[0]", "ReturnValue[*].Field[value]", "taint", "manual"]
- ["", "", False, "madArg0ToReturnFieldIndirect", "", "", "Argument[0]", "ReturnValue.Field[*ptr]", "taint", "manual"]
- ["", "", False, "madFieldToFieldVar", "", "", "Field[value]", "Field[value2]", "taint", "manual"] # we can't express this source/sink correctly at present, "Field[value]" is not a valid input and "Field[value2]" is not a valid output
- ["", "", False, "madFieldToIndirectFieldVar", "", "", "Field[value]", "Field[*ptr]", "taint", "manual"] # we can't express this source/sink correctly at present, "Field[value]" is not a valid input and "Field[*ptr]" is not a valid output
- ["", "", False, "madIndirectFieldToFieldVar", "", "", "Field[value]", "Field[value2]", "taint", "manual"] # we can't express this source/sink correctly at present, "Field[value]" is not a valid input and "Field[value2]" is not a valid output
- ["", "MyClass", True, "madArg0ToSelf", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
- ["", "MyClass", True, "madSelfToReturn", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
- ["", "MyClass", True, "madArg0ToField", "", "", "Argument[0]", "Argument[-1].Field[val]", "taint", "manual"]

View File

@@ -17,8 +17,13 @@ int *remoteMadSourceIndirect(); // $ interpretElement
int **remoteMadSourceDoubleIndirect(); // $ interpretElement
void remoteMadSourceIndirectArg0(int *x, int *y); // $ interpretElement
void remoteMadSourceIndirectArg1(int &x, int &y); // $ interpretElement
int remoteMadSourceVar; // $ interpretElement
int *remoteMadSourceVarIndirect; // $ interpretElement
namespace MyNamespace {
int namespaceLocalMadSource(); // $ interpretElement
int namespaceLocalMadSourceVar; // $ interpretElement
namespace MyNamespace2 {
int namespace2LocalMadSource(); // $ interpretElement
}
@@ -64,9 +69,14 @@ void test_sources() {
sink(c);
sink(d); // $ ir
sink(remoteMadSourceVar); // $ ir
sink(*remoteMadSourceVarIndirect); // $ MISSING: ir
int e = localMadSource();
sink(e); // $ ir
sink(MyNamespace::namespaceLocalMadSource()); // $ ir
sink(MyNamespace::namespaceLocalMadSourceVar); // $ ir
sink(MyNamespace::MyNamespace2::namespace2LocalMadSource()); // $ ir
sink(MyNamespace::localMadSource()); // $ (the MyNamespace version of this function is not a source)
sink(namespaceLocalMadSource()); // (the global namespace version of this function is not a source)
@@ -86,8 +96,8 @@ void madSinkArg01(int x, int y, int z); // $ interpretElement
void madSinkArg02(int x, int y, int z); // $ interpretElement
void madSinkIndirectArg0(int *x); // $ interpretElement
void madSinkDoubleIndirectArg0(int **x); // $ interpretElement
int madSinkVar; // $ interpretElement
int *madSinkVarIndirect; // $ interpretElement
void test_sinks() {
// test sinks
@@ -108,8 +118,15 @@ void test_sinks() {
madSinkIndirectArg0(&a); // $ ir
madSinkIndirectArg0(a_ptr); // $ ir
madSinkDoubleIndirectArg0(&a_ptr); // $ ir
madSinkVar = source(); // $ ir
// test sources + sinks together
madSinkArg0(localMadSource()); // $ ir
madSinkIndirectArg0(remoteMadSourceIndirect()); // $ ir
madSinkVar = remoteMadSourceVar; // $ ir
*madSinkVarIndirect = remoteMadSourceVar; // $ MISSING: ir
}
void madSinkParam0(int x) { // $ interpretElement
@@ -147,6 +164,10 @@ MyContainer madArg0ToReturnField(int x); // $ interpretElement
MyContainer *madArg0ToReturnIndirectField(int x); // $ interpretElement
MyContainer madArg0ToReturnFieldIndirect(int x); // $ interpretElement
MyContainer madFieldToFieldVar; // $ interpretElement
MyContainer madFieldToIndirectFieldVar; // $ interpretElement
MyContainer *madIndirectFieldToFieldVar; // $ interpretElement
void test_summaries() {
// test summaries
@@ -220,6 +241,19 @@ void test_summaries() {
int *rtn2_ptr = rtn2.ptr;
sink(*rtn2_ptr); // $ ir
// test global variable summaries
madFieldToFieldVar.value = source();
sink(madFieldToFieldVar.value2); // $ MISSING: ir
madFieldToIndirectFieldVar.value = source();
sink(madFieldToIndirectFieldVar.ptr);
sink(*(madFieldToIndirectFieldVar.ptr)); // $ MISSING: ir
madIndirectFieldToFieldVar->value = source();
sink((*madIndirectFieldToFieldVar).value2); // $ MISSING: ir
sink(madIndirectFieldToFieldVar->value2); // $ MISSING: ir
// test source + sinks + summaries together
madSinkArg0(madArg0ToReturn(remoteMadSource())); // $ ir
@@ -235,13 +269,13 @@ public:
// sources
int memberRemoteMadSource(); // $ interpretElement
void memberRemoteMadSourceIndirectArg0(int *x); // $ interpretElement
int memberRemoteMadSourceVar; // $ interpretElement
void qualifierSource(); // $ interpretElement
void qualifierFieldSource(); // $ interpretElement
// sinks
void memberMadSinkArg0(int x); // $ interpretElement
int memberMadSinkVar; // $ interpretElement
void qualifierSink(); // $ interpretElement
void qualifierArg0Sink(int x); // $ interpretElement
void qualifierFieldSink(); // $ interpretElement
@@ -272,6 +306,8 @@ namespace MyNamespace {
// sinks
void namespaceMemberMadSinkArg0(int x); // $ interpretElement
static void namespaceStaticMemberMadSinkArg0(int x); // $ interpretElement
int namespaceMemberMadSinkVar; // $ interpretElement
static int namespaceStaticMemberMadSinkVar; // $ interpretElement
// summaries
int namespaceMadSelfToReturn(); // $ interpretElement
@@ -295,6 +331,8 @@ void test_class_members() {
mc.memberRemoteMadSourceIndirectArg0(&a);
sink(a); // $ ir
sink(mc.memberRemoteMadSourceVar); // $ ir
// test subtype sources
sink(mdc.memberRemoteMadSource()); // $ ir
@@ -306,8 +344,12 @@ void test_class_members() {
mc.memberMadSinkArg0(source()); // $ ir
mc.memberMadSinkVar = source(); // $ ir
mnc.namespaceMemberMadSinkArg0(source()); // $ ir
MyNamespace::MyClass::namespaceStaticMemberMadSinkArg0(source()); // $ ir
mnc.namespaceMemberMadSinkVar = source(); // $ ir
MyNamespace::MyClass::namespaceStaticMemberMadSinkVar = source(); // $ ir
// test class member summaries

View File

@@ -11,10 +11,12 @@ edges
| nested.cpp:86:19:86:46 | *call to __builtin_alloca | nested.cpp:87:18:87:20 | *fmt | provenance | |
| test.cpp:46:27:46:30 | **argv | test.cpp:130:20:130:26 | *access to array | provenance | |
| test.cpp:167:31:167:34 | *data | test.cpp:170:12:170:14 | *res | provenance | DataFlowFunction |
| test.cpp:179:6:179:21 | [summary param] *2 in StringCchPrintfW | test.cpp:179:6:179:21 | [summary param] *0 in StringCchPrintfW [Return] | provenance | MaD:403 |
| test.cpp:193:32:193:34 | *str | test.cpp:195:31:195:33 | *str | provenance | |
| test.cpp:193:32:193:34 | *str | test.cpp:195:31:195:33 | *str | provenance | |
| test.cpp:193:32:193:34 | *str | test.cpp:197:11:197:14 | *wstr | provenance | TaintFunction |
| test.cpp:195:20:195:23 | StringCchPrintfW output argument | test.cpp:197:11:197:14 | *wstr | provenance | |
| test.cpp:195:31:195:33 | *str | test.cpp:179:6:179:21 | [summary param] *2 in StringCchPrintfW | provenance | |
| test.cpp:195:31:195:33 | *str | test.cpp:195:20:195:23 | StringCchPrintfW output argument | provenance | MaD:403 |
| test.cpp:204:25:204:36 | *call to get_string | test.cpp:204:25:204:36 | *call to get_string | provenance | |
| test.cpp:204:25:204:36 | *call to get_string | test.cpp:205:12:205:20 | *... + ... | provenance | |
@@ -58,6 +60,8 @@ nodes
| test.cpp:130:20:130:26 | *access to array | semmle.label | *access to array |
| test.cpp:167:31:167:34 | *data | semmle.label | *data |
| test.cpp:170:12:170:14 | *res | semmle.label | *res |
| test.cpp:179:6:179:21 | [summary param] *0 in StringCchPrintfW [Return] | semmle.label | [summary param] *0 in StringCchPrintfW [Return] |
| test.cpp:179:6:179:21 | [summary param] *2 in StringCchPrintfW | semmle.label | [summary param] *2 in StringCchPrintfW |
| test.cpp:193:32:193:34 | *str | semmle.label | *str |
| test.cpp:195:20:195:23 | StringCchPrintfW output argument | semmle.label | StringCchPrintfW output argument |
| test.cpp:195:31:195:33 | *str | semmle.label | *str |
@@ -93,6 +97,7 @@ nodes
| test.cpp:245:25:245:36 | *call to get_string | semmle.label | *call to get_string |
| test.cpp:247:12:247:16 | *hello | semmle.label | *hello |
subpaths
| test.cpp:195:31:195:33 | *str | test.cpp:179:6:179:21 | [summary param] *2 in StringCchPrintfW | test.cpp:179:6:179:21 | [summary param] *0 in StringCchPrintfW [Return] | test.cpp:195:20:195:23 | StringCchPrintfW output argument |
#select
| NonConstantFormat.c:30:10:30:16 | *access to array | NonConstantFormat.c:28:27:28:30 | **argv | NonConstantFormat.c:30:10:30:16 | *access to array | The format string argument to $@ has a source which cannot be verified to originate from a string literal. | NonConstantFormat.c:30:3:30:8 | call to printf | printf |
| NonConstantFormat.c:41:9:41:45 | *call to any_random_function | NonConstantFormat.c:41:9:41:45 | *call to any_random_function | NonConstantFormat.c:41:9:41:45 | *call to any_random_function | The format string argument to $@ has a source which cannot be verified to originate from a string literal. | NonConstantFormat.c:41:2:41:7 | call to printf | printf |

View File

@@ -33,6 +33,7 @@ edges
| tests2.cpp:111:14:111:15 | *c1 [*ptr] | tests2.cpp:111:14:111:19 | *ptr | provenance | |
| tests2.cpp:111:14:111:15 | *c1 [*ptr] | tests2.cpp:111:17:111:19 | *ptr | provenance | |
| tests2.cpp:111:17:111:19 | *ptr | tests2.cpp:111:14:111:19 | *ptr | provenance | |
| tests2.cpp:120:5:120:21 | [summary param] *1 in zmq_msg_init_data | tests2.cpp:120:5:120:21 | [summary param] *0 in zmq_msg_init_data [Return] | provenance | MaD:4 |
| tests2.cpp:134:2:134:30 | *... = ... | tests2.cpp:138:23:138:34 | *message_data | provenance | Sink:MaD:2 |
| tests2.cpp:134:2:134:30 | *... = ... | tests2.cpp:143:34:143:45 | *message_data | provenance | |
| tests2.cpp:134:17:134:22 | *call to getenv | tests2.cpp:134:2:134:30 | *... = ... | provenance | |
@@ -40,6 +41,7 @@ edges
| tests2.cpp:143:24:143:31 | zmq_msg_init_data output argument | tests2.cpp:147:20:147:27 | *& ... | provenance | Sink:MaD:1 |
| tests2.cpp:143:24:143:31 | zmq_msg_init_data output argument | tests2.cpp:155:32:155:39 | *& ... | provenance | Sink:MaD:3 |
| tests2.cpp:143:24:143:31 | zmq_msg_init_data output argument | tests2.cpp:158:20:158:27 | *& ... | provenance | Sink:MaD:1 |
| tests2.cpp:143:34:143:45 | *message_data | tests2.cpp:120:5:120:21 | [summary param] *1 in zmq_msg_init_data | provenance | |
| tests2.cpp:143:34:143:45 | *message_data | tests2.cpp:143:24:143:31 | zmq_msg_init_data output argument | provenance | MaD:4 |
| tests_sockets.cpp:26:15:26:20 | *call to getenv | tests_sockets.cpp:26:15:26:20 | *call to getenv | provenance | |
| tests_sockets.cpp:26:15:26:20 | *call to getenv | tests_sockets.cpp:39:19:39:22 | *path | provenance | |
@@ -76,6 +78,8 @@ nodes
| tests2.cpp:111:14:111:15 | *c1 [*ptr] | semmle.label | *c1 [*ptr] |
| tests2.cpp:111:14:111:19 | *ptr | semmle.label | *ptr |
| tests2.cpp:111:17:111:19 | *ptr | semmle.label | *ptr |
| tests2.cpp:120:5:120:21 | [summary param] *0 in zmq_msg_init_data [Return] | semmle.label | [summary param] *0 in zmq_msg_init_data [Return] |
| tests2.cpp:120:5:120:21 | [summary param] *1 in zmq_msg_init_data | semmle.label | [summary param] *1 in zmq_msg_init_data |
| tests2.cpp:134:2:134:30 | *... = ... | semmle.label | *... = ... |
| tests2.cpp:134:17:134:22 | *call to getenv | semmle.label | *call to getenv |
| tests2.cpp:138:23:138:34 | *message_data | semmle.label | *message_data |
@@ -96,3 +100,4 @@ nodes
| tests_sysconf.cpp:36:21:36:27 | confstr output argument | semmle.label | confstr output argument |
| tests_sysconf.cpp:39:19:39:25 | *pathbuf | semmle.label | *pathbuf |
subpaths
| tests2.cpp:143:34:143:45 | *message_data | tests2.cpp:120:5:120:21 | [summary param] *1 in zmq_msg_init_data | tests2.cpp:120:5:120:21 | [summary param] *0 in zmq_msg_init_data [Return] | tests2.cpp:143:24:143:31 | zmq_msg_init_data output argument |

View File

@@ -88,12 +88,12 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
private IEnumerable<string> GetFeedsFromNugetConfig(string nugetConfigPath) =>
GetFeeds(() => dotnet.GetNugetFeeds(nugetConfigPath));
public string FeedsToRestoreArgument(IEnumerable<string> feeds, string sourceArgumentPrefix)
private string FeedsToRestoreArgument(IEnumerable<string> feeds)
{
// If there are no feeds, we want to override any default feeds that `restore` would use by passing a dummy source argument.
// If there are no feeds, we want to override any default feeds that `dotnet restore` would use by passing a dummy source argument.
if (!feeds.Any())
{
return $" {sourceArgumentPrefix} \"{emptyPackageDirectory.DirInfo.FullName}\"";
return $" -s \"{emptyPackageDirectory.DirInfo.FullName}\"";
}
// Add package sources. If any are present, they override all sources specified in
@@ -101,7 +101,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var feedArgs = new StringBuilder();
foreach (var feed in feeds)
{
feedArgs.Append($" {sourceArgumentPrefix} \"{feed}\"");
feedArgs.Append($" -s \"{feed}\"");
}
return feedArgs.ToString();
@@ -112,11 +112,17 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// (1) Use the feeds we get from `dotnet nuget list source`
/// (2) Use private registries, if they are configured
/// </summary>
/// <param name="path">Path to project/solution/packages.config</param>
/// <param name="path">Path to project/solution</param>
/// <param name="reachableFeeds">The set of reachable NuGet feeds.</param>
/// <returns>The list of NuGet feeds to use for this restore.</returns>
public IEnumerable<string> FeedsToUse(string path, HashSet<string> reachableFeeds)
/// <returns>A string representing the NuGet sources argument for the restore command.</returns>
public string? MakeRestoreSourcesArgument(string path, HashSet<string> reachableFeeds)
{
// Do not construct a set of explicit NuGet sources to use for restore.
if (!CheckNugetFeedResponsiveness && !HasPrivateRegistryFeeds)
{
return null;
}
// Find the path specific feeds.
var folder = GetDirectoryName(path);
var feedsToConsider = folder is not null ? GetFeedsFromFolder(folder).ToHashSet() : new HashSet<string>();
@@ -130,28 +136,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
? feedsToConsider.Where(reachableFeeds.Contains)
: feedsToConsider;
return feedsToUse;
}
/// <summary>
/// Constructs the list of NuGet sources to use for dotnet restore.
/// (1) Use the feeds we get from `dotnet nuget list source`
/// (2) Use private registries, if they are configured
/// </summary>
/// <param name="path">Path to project/solution</param>
/// <param name="reachableFeeds">The set of reachable NuGet feeds.</param>
/// <returns>A string representing the NuGet sources argument for the restore command.</returns>
public string? MakeDotnetRestoreSourcesArgument(string path, HashSet<string> reachableFeeds)
{
// Do not construct a set of explicit NuGet sources to use for restore.
if (!CheckNugetFeedResponsiveness && !HasPrivateRegistryFeeds)
{
return null;
}
var feedsToUse = FeedsToUse(path, reachableFeeds);
return FeedsToRestoreArgument(feedsToUse, "-s");
return FeedsToRestoreArgument(feedsToUse);
}
private (int initialTimeout, int tryCount) GetFeedRequestSettings(bool isFallback)

View File

@@ -110,55 +110,58 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
logger.LogInfo($"Checking NuGet feed responsiveness: {feedManager.CheckNugetFeedResponsiveness}");
compilationInfoContainer.CompilationInfos.Add(("NuGet feed responsiveness checked", feedManager.CheckNugetFeedResponsiveness ? "1" : "0"));
HashSet<string> explicitFeeds = [];
HashSet<string> reachableFeeds = [];
EmitNugetConfigDiagnostics();
// Find feeds that are configured in NuGet.config files and divide them into ones that
// are explicitly configured for the project or by a private registry, and "all feeds"
// (including inherited ones) from other locations on the host outside of the working directory.
(var explicitFeeds, var allFeeds) = feedManager.GetAllFeeds();
if (feedManager.CheckNugetFeedResponsiveness)
{
var inheritedFeeds = allFeeds.Except(explicitFeeds).ToHashSet();
if (inheritedFeeds.Count > 0)
{
compilationInfoContainer.CompilationInfos.Add(("Inherited NuGet feed count", inheritedFeeds.Count.ToString()));
}
var timeout = feedManager.CheckSpecifiedFeeds(explicitFeeds, out var reachableExplicitFeeds);
reachableFeeds.UnionWith(reachableExplicitFeeds);
var allExplicitReachable = explicitFeeds.Count == reachableExplicitFeeds.Count;
EmitUnreachableFeedsDiagnostics(allExplicitReachable);
if (timeout)
{
// If we experience a timeout, we use this fallback.
// todo: we could also check the reachability of the inherited nuget feeds, but to use those in the fallback we would need to handle authentication too.
var unresponsiveMissingPackageLocation = DownloadMissingPackagesFromSpecificFeeds([], explicitFeeds);
return unresponsiveMissingPackageLocation is null
? []
: [unresponsiveMissingPackageLocation];
}
// Inherited feeds should only be used, if they are indeed reachable (as they may be environment specific).
feedManager.CheckSpecifiedFeeds(inheritedFeeds, out var reachableInheritedFeeds);
reachableFeeds.UnionWith(reachableInheritedFeeds);
}
try
{
var packagesConfigRestore = PackagesConfigRestoreFactory.Create(fileProvider, legacyPackageDirectory, logger, feedManager, reachableFeeds);
var count = packagesConfigRestore.InstallPackages();
if (packagesConfigRestore.PackageCount > 0)
EmitNugetConfigDiagnostics();
// Find feeds that are configured in NuGet.config files and divide them into ones that
// are explicitly configured for the project or by a private registry, and "all feeds"
// (including inherited ones) from other locations on the host outside of the working directory.
(explicitFeeds, var allFeeds) = feedManager.GetAllFeeds();
if (feedManager.CheckNugetFeedResponsiveness)
{
compilationInfoContainer.CompilationInfos.Add(("packages.config files", packagesConfigRestore.PackageCount.ToString()));
compilationInfoContainer.CompilationInfos.Add(("Successfully restored packages.config files", count.ToString()));
var inheritedFeeds = allFeeds.Except(explicitFeeds).ToHashSet();
if (inheritedFeeds.Count > 0)
{
compilationInfoContainer.CompilationInfos.Add(("Inherited NuGet feed count", inheritedFeeds.Count.ToString()));
}
var timeout = feedManager.CheckSpecifiedFeeds(explicitFeeds, out var reachableExplicitFeeds);
reachableFeeds.UnionWith(reachableExplicitFeeds);
var allExplicitReachable = explicitFeeds.Count == reachableExplicitFeeds.Count;
EmitUnreachableFeedsDiagnostics(allExplicitReachable);
if (timeout)
{
// If we experience a timeout, we use this fallback.
// todo: we could also check the reachability of the inherited nuget feeds, but to use those in the fallback we would need to handle authentication too.
var unresponsiveMissingPackageLocation = DownloadMissingPackagesFromSpecificFeeds([], explicitFeeds);
return unresponsiveMissingPackageLocation is null
? []
: [unresponsiveMissingPackageLocation];
}
// Inherited feeds should only be used, if they are indeed reachable (as they may be environment specific).
feedManager.CheckSpecifiedFeeds(inheritedFeeds, out var reachableInheritedFeeds);
reachableFeeds.UnionWith(reachableInheritedFeeds);
}
using (var packagesConfigRestore = PackagesConfigRestoreFactory.Create(fileProvider, legacyPackageDirectory, logger, feedManager.IsDefaultFeedReachable))
{
var count = packagesConfigRestore.InstallPackages();
if (packagesConfigRestore.PackageCount > 0)
{
compilationInfoContainer.CompilationInfos.Add(("packages.config files", packagesConfigRestore.PackageCount.ToString()));
compilationInfoContainer.CompilationInfos.Add(("Successfully restored packages.config files", count.ToString()));
}
}
var nugetPackageDlls = legacyPackageDirectory.DirInfo.GetFiles("*.dll", new EnumerationOptions { RecurseSubdirectories = true });
var nugetPackageDllPaths = nugetPackageDlls.Select(f => f.FullName).ToHashSet();
@@ -236,7 +239,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
var projects = fileProvider.Solutions.SelectMany(solution =>
{
logger.LogInfo($"Restoring solution {solution}...");
var nugetSources = feedManager.MakeDotnetRestoreSourcesArgument(solution, reachableFeeds);
var nugetSources = feedManager.MakeRestoreSourcesArgument(solution, reachableFeeds);
var res = dotnet.Restore(new(solution, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, NugetSources: nugetSources, TargetWindows: isWindows));
if (res.Success)
{
@@ -285,7 +288,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
foreach (var project in projectGroup)
{
logger.LogInfo($"Restoring project {project}...");
var nugetSources = feedManager.MakeDotnetRestoreSourcesArgument(project, reachableFeeds);
var nugetSources = feedManager.MakeRestoreSourcesArgument(project, reachableFeeds);
var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, NugetSources: nugetSources, TargetWindows: isWindows));
assets.AddDependenciesRange(res.AssetsFilePaths);
lock (sync)

View File

@@ -7,7 +7,7 @@ using Semmle.Util;
namespace Semmle.Extraction.CSharp.DependencyFetching
{
internal interface IPackagesConfigRestore
internal interface IPackagesConfigRestore : IDisposable
{
/// <summary>
/// The number of packages.config files found in the source tree.
@@ -33,11 +33,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// </summary>
internal class PackagesConfigRestoreFactory
{
public static IPackagesConfigRestore Create(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, FeedManager feedManager, HashSet<string> reachableFeeds)
public static IPackagesConfigRestore Create(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, Func<bool> useDefaultFeed)
{
if (SystemBuildActions.Instance.IsWindows() || SystemBuildActions.Instance.IsMonoInstalled())
{
return new NugetExeWrapper(fileProvider, packageDirectory, logger, feedManager, reachableFeeds);
return new NugetExeWrapper(fileProvider, packageDirectory, logger, useDefaultFeed);
}
return new NoOpPackagesConfig(fileProvider.PackagesConfigs, logger);
@@ -55,6 +55,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
public int PackageCount => fileProvider.PackagesConfigs.Count;
private readonly string? backupNugetConfig;
private readonly string? nugetConfigPath;
private readonly FileProvider fileProvider;
/// <summary>
@@ -63,30 +65,57 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
/// so as to not trample the source tree.
/// </summary>
private readonly DependencyDirectory packageDirectory;
private readonly FeedManager feedManager;
private readonly HashSet<string> reachableFeeds;
private bool IsWindows => SystemBuildActions.Instance.IsWindows();
private bool? isDefaultFeedReachable;
private bool IsDefaultFeedReachable =>
isDefaultFeedReachable ??= feedManager.IsDefaultFeedReachable();
/// <summary>
/// Create the package manager for a specified source tree.
/// </summary>
public NugetExeWrapper(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, FeedManager feedManager, HashSet<string> reachableFeeds)
public NugetExeWrapper(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, Func<bool> useDefaultFeed)
{
this.fileProvider = fileProvider;
this.packageDirectory = packageDirectory;
this.logger = logger;
this.feedManager = feedManager;
this.reachableFeeds = reachableFeeds;
if (fileProvider.PackagesConfigs.Count > 0)
{
logger.LogInfo($"Found packages.config files, trying to use nuget.exe for package restore");
nugetExe = ResolveNugetExe();
if (!HasPackageSource() && useDefaultFeed())
{
// We only modify or add a top level nuget.config file
nugetConfigPath = Path.Join(fileProvider.SourceDir.FullName, "nuget.config");
try
{
if (File.Exists(nugetConfigPath))
{
var tempFolderPath = FileUtils.GetTemporaryWorkingDirectory(out _);
do
{
backupNugetConfig = Path.Join(tempFolderPath, Path.GetRandomFileName());
}
while (File.Exists(backupNugetConfig));
File.Copy(nugetConfigPath, backupNugetConfig, true);
}
else
{
File.WriteAllText(nugetConfigPath,
"""
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
</packageSources>
</configuration>
""");
}
AddDefaultPackageSource(nugetConfigPath);
}
catch (Exception e)
{
logger.LogError($"Failed to add default package source to {nugetConfigPath}: {e}");
}
}
}
}
@@ -169,21 +198,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
{
logger.LogInfo($"Restoring file \"{packagesConfig}\"...");
var sourcesArgument = "";
var feedsToUse = feedManager.FeedsToUse(packagesConfig, reachableFeeds).ToList();
var useDefaultFeed = feedsToUse.Count == 0 && IsDefaultFeedReachable;
// Explicitly construct the sources to be used for the restore command when checking feed
// responsiveness, using private registries, or falling back to nuget.org.
if (feedManager.CheckNugetFeedResponsiveness || feedManager.HasPrivateRegistryFeeds || useDefaultFeed)
{
if (useDefaultFeed)
{
feedsToUse.Add(FeedManager.PublicNugetOrgFeed);
}
sourcesArgument = feedManager.FeedsToRestoreArgument(feedsToUse, "-Source");
}
/* Use nuget.exe to install a package.
* Note that there is a clutch of NuGet assemblies which could be used to
* invoke this directly, which would arguably be nicer. However they are
@@ -194,12 +208,12 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
if (RunWithMono)
{
exe = "mono";
args = $"\"{nugetExe}\" install -OutputDirectory \"{packageDirectory}\" {sourcesArgument} \"{packagesConfig}\"";
args = $"\"{nugetExe}\" install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
}
else
{
exe = nugetExe!;
args = $"install -OutputDirectory \"{packageDirectory}\" {sourcesArgument} \"{packagesConfig}\"";
args = $"install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
}
var pi = new ProcessStartInfo(exe, args)
@@ -232,6 +246,98 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
{
return fileProvider.PackagesConfigs.Count(TryRestoreNugetPackage);
}
private bool HasPackageSource()
{
if (IsWindows)
{
return true;
}
try
{
logger.LogInfo("Checking if default package source is available...");
RunMonoNugetCommand("sources list -ForceEnglishOutput", out var stdout);
if (stdout.All(line => line != "No sources found."))
{
return true;
}
return false;
}
catch (Exception e)
{
logger.LogWarning($"Failed to check if default package source is added: {e}");
return true;
}
}
private void RunMonoNugetCommand(string command, out IList<string> stdout)
{
string exe, args;
if (RunWithMono)
{
exe = "mono";
args = $"\"{nugetExe}\" {command}";
}
else
{
exe = nugetExe!;
args = command;
}
var pi = new ProcessStartInfo(exe, args)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
var threadId = Environment.CurrentManagedThreadId;
void onOut(string s) => logger.LogDebug(s, threadId);
void onError(string s) => logger.LogError(s, threadId);
pi.ReadOutput(out stdout, onOut, onError);
}
private void AddDefaultPackageSource(string nugetConfig)
{
logger.LogInfo("Adding default package source...");
RunMonoNugetCommand($"sources add -Name DefaultNugetOrg -Source {FeedManager.PublicNugetOrgFeed} -ConfigFile \"{nugetConfig}\"", out _);
}
public void Dispose()
{
if (nugetConfigPath is null)
{
return;
}
try
{
if (backupNugetConfig is null)
{
logger.LogInfo("Removing nuget.config file");
File.Delete(nugetConfigPath);
return;
}
logger.LogInfo("Reverting nuget.config file content");
// The content of the original nuget.config file is reverted without changing the file's attributes or casing:
using (var backup = File.OpenRead(backupNugetConfig))
using (var current = File.OpenWrite(nugetConfigPath))
{
current.SetLength(0); // Truncate file
backup.CopyTo(current); // Restore original content
}
logger.LogInfo("Deleting backup nuget.config file");
File.Delete(backupNugetConfig);
}
catch (Exception exc)
{
logger.LogError($"Failed to restore original nuget.config file: {exc}");
}
}
}
private class NoOpPackagesConfig : IPackagesConfigRestore
@@ -255,6 +361,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
}
return 0;
}
public void Dispose() { }
}
}
}

View File

@@ -1,4 +0,0 @@
class Program
{
static void Main() {}
}

View File

@@ -1,10 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@@ -1,5 +0,0 @@
{
"sdk": {
"version": "9.0.201"
}
}

View File

@@ -1,8 +0,0 @@
| code/Program.cs:0:0:0:0 | code/Program.cs | |
| code/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs:0:0:0:0 | code/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs | |
| code/obj/Debug/net9.0/dotnet_build.AssemblyInfo.cs:0:0:0:0 | code/obj/Debug/net9.0/dotnet_build.AssemblyInfo.cs | |
| code/obj/Debug/net9.0/dotnet_build.GlobalUsings.g.cs:0:0:0:0 | code/obj/Debug/net9.0/dotnet_build.GlobalUsings.g.cs | |
| code/obj/Debug/net9.0/dotnet_build.dll:0:0:0:0 | code/obj/Debug/net9.0/dotnet_build.dll | |
| file://:0:0:0:0 | | |
| file://Z:/dotnet_build.csproj:0:0:0:0 | Z:/dotnet_build.csproj | relative |
| file://Z:/obj/dotnet_build.csproj.nuget.g.props:0:0:0:0 | Z:/obj/dotnet_build.csproj.nuget.g.props | relative |

View File

@@ -1,7 +0,0 @@
import csharp
from File f, string relative
where
not f.getURL().matches("file://C:/Program Files/%") and
if exists(f.getRelativePath()) then relative = "relative" else relative = ""
select f, relative

View File

@@ -1,7 +0,0 @@
import runs_on
@runs_on.windows
def test(codeql, csharp, cwd, subst_drive):
drive = subst_drive(cwd / "code")
codeql.database.create(source_root=drive)

View File

@@ -1,4 +0,0 @@
---
category: majorAnalysis
---
* Simplified and streamlined the use of NuGet sources when downloading dependencies via `[mono] nuget.exe` in `build-mode: none`: NuGet sources are now supplied via the `-Source` flag instead of moving or creating `nuget.config` files in the checked-out repository, private registries are used if configured, and only reachable feeds are used when NuGet feed checking is enabled (the default).

View File

@@ -123,7 +123,7 @@ k8s.io/api/core,,,10,,,,,,,,,,,,,,,,,,,,,,,10,
k8s.io/apimachinery/pkg/runtime,,,47,,,,,,,,,,,,,,,,,,,,,,,47,
k8s.io/klog,90,,,,,,90,,,,,,,,,,,,,,,,,,,,
launchpad.net/xmlpath,2,,,,,,,,,,,,,,,,,,2,,,,,,,,
log,43,,16,,,,43,,,,,,,,,,,,,,,,,,,16,
log,40,,3,,,,40,,,,,,,,,,,,,,,,,,,3,
math/big,,,1,,,,,,,,,,,,,,,,,,,,,,,1,
mime,,,14,,,,,,,,,,,,,,,,,,,,,,,14,
net,2,16,100,,,,,,1,,,,,,,,1,,,,,,,16,,100,
1 package sink source summary sink:command-injection sink:credentials-key sink:jwt sink:log-injection sink:nosql-injection sink:path-injection sink:regex-use[0] sink:regex-use[1] sink:regex-use[c] sink:request-forgery sink:request-forgery[TCP Addr + Port] sink:sql-injection sink:url-redirection sink:url-redirection[0] sink:url-redirection[receiver] sink:xpath-injection source:commandargs source:database source:environment source:file source:remote source:stdin summary:taint summary:value
123 k8s.io/apimachinery/pkg/runtime 47 47
124 k8s.io/klog 90 90
125 launchpad.net/xmlpath 2 2
126 log 43 40 16 3 43 40 16 3
127 math/big 1 1
128 mime 14 14
129 net 2 16 100 1 1 16 100

View File

@@ -32,7 +32,7 @@ Go framework & library support
`Revel <http://revel.github.io/>`_,"``github.com/revel/revel*``, ``github.com/robfig/revel*``",46,20,4
`SendGrid <https://github.com/sendgrid/sendgrid-go>`_,``github.com/sendgrid/sendgrid-go*``,,1,
`Squirrel <https://github.com/Masterminds/squirrel>`_,"``github.com/Masterminds/squirrel*``, ``github.com/lann/squirrel*``, ``gopkg.in/Masterminds/squirrel``",81,,96
`Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``, ``weak``",52,625,127
`Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``, ``weak``",52,612,124
`XORM <https://xorm.io>`_,"``github.com/go-xorm/xorm*``, ``xorm.io/xorm*``",,,68
`XPath <https://github.com/antchfx/xpath>`_,``github.com/antchfx/xpath*``,,,4
`appleboy/gin-jwt <https://github.com/appleboy/gin-jwt>`_,``github.com/appleboy/gin-jwt*``,,,1
@@ -74,5 +74,5 @@ Go framework & library support
`xpathparser <https://github.com/santhosh-tekuri/xpathparser>`_,``github.com/santhosh-tekuri/xpathparser*``,,,2
`yaml <https://gopkg.in/yaml.v3>`_,``gopkg.in/yaml*``,,9,
`zap <https://go.uber.org/zap>`_,``go.uber.org/zap*``,,11,33
Totals,,688,1085,1580
Totals,,688,1072,1577

View File

@@ -19,7 +19,6 @@ go_library(
"//go/extractor/dbscheme",
"//go/extractor/diagnostics",
"//go/extractor/srcarchive",
"//go/extractor/subst",
"//go/extractor/toolchain",
"//go/extractor/trap",
"//go/extractor/util",

View File

@@ -25,7 +25,6 @@ import (
"github.com/github/codeql-go/extractor/dbscheme"
"github.com/github/codeql-go/extractor/diagnostics"
"github.com/github/codeql-go/extractor/srcarchive"
"github.com/github/codeql-go/extractor/subst"
"github.com/github/codeql-go/extractor/toolchain"
"github.com/github/codeql-go/extractor/trap"
"github.com/github/codeql-go/extractor/util"
@@ -765,9 +764,9 @@ func normalizedPath(ast *ast.File, fset *token.FileSet) string {
file := fset.File(ast.Package).Name()
path, err := filepath.EvalSymlinks(file)
if err != nil {
path = file
return file
}
return subst.ResolvePath(path)
return path
}
// extractFile extracts AST information for the given file

View File

@@ -1,12 +0,0 @@
load("@rules_go//go:def.bzl", "go_library")
go_library(
name = "subst",
srcs = [
"subst.go",
"subst_other.go",
"subst_windows.go",
],
importpath = "github.com/github/codeql-go/extractor/subst",
visibility = ["//go:__subpackages__"],
)

View File

@@ -1,30 +0,0 @@
package subst
// ResolvePath resolves subst'd drive letters in a full path.
// If the path starts with a subst'd drive letter, replaces it with the backing path.
// Otherwise returns the path unchanged.
func ResolvePath(path string) string {
return resolvePath(path, ResolveDrive)
}
func resolvePath(path string, resolveDrive func(string) string) string {
if len(path) < 3 {
return path
}
if path[1] != ':' {
return path
}
if path[2] != '\\' && path[2] != '/' {
return path
}
c := path[0]
if !((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
return path
}
resolved := resolveDrive(path[:3])
if resolved == "" {
return path
}
return resolved + path[2:]
}

View File

@@ -1,6 +0,0 @@
//go:build !windows
package subst
// ResolveDrive is a no-op on non-Windows platforms.
func ResolveDrive(driveRoot string) string { return "" }

View File

@@ -1,67 +0,0 @@
//go:build windows
package subst
import (
"os"
"path/filepath"
"syscall"
"unsafe"
)
var (
dll *syscall.DLL
procResolve *syscall.Proc
procFree *syscall.Proc
available bool
)
func init() {
dist := os.Getenv("CODEQL_DIST")
if dist == "" {
return
}
dllPath := filepath.Join(dist, "tools", "win64", "canonicalize.dll")
d, err := syscall.LoadDLL(dllPath)
if err != nil {
return
}
p, err := d.FindProc("resolve_subst_u8")
if err != nil {
return
}
f, _ := d.FindProc("resolve_subst_free_u8")
dll = d
procResolve = p
procFree = f
available = true
}
// ResolveDrive resolves a subst'd drive root (e.g. "X:\") to its backing path.
// Returns "" if the drive is not subst'd or on error.
func ResolveDrive(driveRoot string) string {
if !available {
return ""
}
driveBytes := append([]byte(driveRoot), 0)
ret, _, _ := procResolve.Call(uintptr(unsafe.Pointer(&driveBytes[0])))
if ret == 0 {
return ""
}
result := goString((*byte)(unsafe.Pointer(ret)))
if procFree != nil {
procFree.Call(ret)
}
return result
}
func goString(p *byte) string {
if p == nil {
return ""
}
var n int
for ptr := unsafe.Pointer(p); *(*byte)(ptr) != 0; n++ {
ptr = unsafe.Add(ptr, 1)
}
return string(unsafe.Slice(p, n))
}

View File

@@ -1,3 +0,0 @@
package main
func main() {}

View File

@@ -1 +0,0 @@
| file://Z:/main.go:0:0:0:0 | Z:/main.go | relative |

View File

@@ -1,5 +0,0 @@
import go
from File f, string relative
where if exists(f.getRelativePath()) then relative = "relative" else relative = ""
select f, relative

View File

@@ -1,7 +0,0 @@
import runs_on
@runs_on.windows
def test(codeql, go, cwd, subst_drive):
drive = subst_drive(cwd / "code")
codeql.database.create(command="go build main.go", source_root=drive)

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Improved models for the `log/slog` package (Go 1.21+), including `*slog.Logger` methods, `With`/`WithGroup`, and `Attr`/`Value` helpers, improving coverage for the `go/log-injection` and `go/clear-text-logging` queries.

View File

@@ -27,27 +27,3 @@ extensions:
- ["log/slog", "Logger", True, "ErrorContext", "", "", "Argument[1..2]", "log-injection", "manual"]
- ["log/slog", "Logger", True, "Log", "", "", "Argument[2..3]", "log-injection", "manual"]
- ["log/slog", "Logger", True, "LogAttrs", "", "", "Argument[2..3]", "log-injection", "manual"]
# With/WithGroup add attributes that are included in every subsequent log call.
- ["log/slog", "", False, "With", "", "", "Argument[0]", "log-injection", "manual"]
- ["log/slog", "Logger", True, "With", "", "", "Argument[0]", "log-injection", "manual"]
- ["log/slog", "Logger", True, "WithGroup", "", "", "Argument[0]", "log-injection", "manual"]
- addsTo:
pack: codeql/go-all
extensible: summaryModel
data:
# Constructors for Attr that can carry a tainted string into the result.
- ["log/slog", "", False, "Any", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"]
- ["log/slog", "", False, "Group", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
- ["log/slog", "", False, "Group", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"]
- ["log/slog", "", False, "GroupAttrs", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
- ["log/slog", "", False, "GroupAttrs", "", "", "Argument[1].ArrayElement", "ReturnValue", "taint", "manual"]
- ["log/slog", "", False, "String", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"]
# Constructors for Value that can carry a tainted string into the result.
- ["log/slog", "", False, "AnyValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
- ["log/slog", "", False, "GroupValue", "", "", "Argument[0].ArrayElement", "ReturnValue", "taint", "manual"]
- ["log/slog", "", False, "StringValue", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
# Methods that read a string back out of an Attr or Value.
- ["log/slog", "Attr", True, "String", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["log/slog", "Value", True, "Any", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]
- ["log/slog", "Value", True, "Group", "", "", "Argument[receiver]", "ReturnValue.ArrayElement", "taint", "manual"]
- ["log/slog", "Value", True, "String", "", "", "Argument[receiver]", "ReturnValue", "taint", "manual"]

View File

@@ -37,9 +37,4 @@ func slogTest() {
slog.InfoContext(ctx, text, key, v) // $ logger=text logger=key logger=v
slog.Log(ctx, slog.LevelInfo, text, key, v) // $ logger=text logger=key logger=v
slog.LogAttrs(ctx, slog.LevelInfo, text, attr) // $ logger=text logger=attr
// With/WithGroup add attributes that are included in every subsequent log call.
logger.With(key, v) // $ logger=key logger=v
logger.WithGroup(text) // $ logger=text
slog.With(key, v) // $ logger=key logger=v
}

View File

@@ -1,2 +0,0 @@
reverseRead
| test.go:114:21:114:33 | call to Group | Origin of readStep is missing a PostUpdateNode. |

View File

@@ -1,2 +0,0 @@
invalidModelRow
testFailures

View File

@@ -1,14 +0,0 @@
import go
import semmle.go.dataflow.ExternalFlow
import ModelValidation
import utils.test.InlineFlowTest
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.(DataFlow::CallNode).getTarget().getName() = ["getUntrustedData", "getUntrustedString"]
}
predicate isSink(DataFlow::Node sink) { sink = any(LoggerCall log).getAMessageComponent() }
}
import FlowTest<Config, Config>

View File

@@ -1,3 +0,0 @@
module codeql-go-tests/frameworks/slog
go 1.26

View File

@@ -1,115 +0,0 @@
package main
import (
"context"
"log/slog"
)
func main() {}
func getUntrustedData() interface{} { return nil }
func getUntrustedString() string {
return "tainted string"
}
// Package-level convenience functions.
func testSlogDebug() {
slog.Debug(getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
slog.Debug("msg", "key", getUntrustedData()) // $ hasValueFlow="call to getUntrustedData"
slog.Debug("msg", slog.String("key", getUntrustedString())) // $ hasTaintFlow="call to String"
}
func testSlogInfo() {
slog.Info(getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
slog.Info("msg", slog.Any("key", getUntrustedData())) // $ hasTaintFlow="call to Any"
slog.Info("msg", slog.String("key", getUntrustedString())) // $ hasTaintFlow="call to String"
}
func testSlogWarn() {
slog.Warn(getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
slog.Warn("msg", slog.String("key", getUntrustedString())) // $ hasTaintFlow="call to String"
}
func testSlogError() {
slog.Error(getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
slog.Error("msg", slog.String("key", getUntrustedString())) // $ hasTaintFlow="call to String"
}
func testSlogContextVariants(ctx context.Context) {
slog.DebugContext(ctx, getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
slog.InfoContext(ctx, getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
slog.WarnContext(ctx, getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
slog.ErrorContext(ctx, getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
slog.InfoContext(ctx, "msg", slog.String("key", getUntrustedString())) // $ hasTaintFlow="call to String"
}
func testSlogLog(ctx context.Context) {
slog.Log(ctx, slog.LevelInfo, getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
slog.Log(ctx, slog.LevelInfo, "msg", slog.String("key", getUntrustedString())) // $ hasTaintFlow="call to String"
slog.LogAttrs(ctx, slog.LevelInfo, getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
slog.LogAttrs(ctx, slog.LevelInfo, "msg", slog.String("key", getUntrustedString())) // $ hasTaintFlow="call to String"
}
// Methods on *slog.Logger.
func testLoggerMethods(logger *slog.Logger, ctx context.Context) {
logger.Debug(getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
logger.Info(getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
logger.Warn(getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
logger.Error(getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
logger.Info("msg", slog.Any("key", getUntrustedData())) // $ hasTaintFlow="call to Any"
logger.InfoContext(ctx, getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
logger.Log(ctx, slog.LevelInfo, getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
logger.LogAttrs(ctx, slog.LevelInfo, "msg", slog.String("key", getUntrustedString())) // $ hasTaintFlow="call to String"
}
// With, Logger.With and Logger.WithGroup. Note that for ease of modeling we make these functions
// sinks, although strictly speaking we should consider logging functions called on the returned
// loggers as the sinks.
func testWith(logger *slog.Logger) {
logger1 := logger.With(slog.String("key", getUntrustedString())) // $ hasTaintFlow="call to String"
logger1.Info("hello world")
logger2 := logger.With(slog.Any(getUntrustedString(), nil)) // $ hasTaintFlow="call to Any"
logger2.Info("hello world")
logger.With("key", getUntrustedData()).Info("hello world") // $ hasValueFlow="call to getUntrustedData"
}
func testPackageWith() {
logger := slog.With(slog.String("key", getUntrustedString())) // $ hasTaintFlow="call to String"
logger.Info("hello world")
slog.With("key", getUntrustedData()).Info("hello world") // $ hasValueFlow="call to getUntrustedData"
}
func testWithGroup(logger *slog.Logger) {
grouped := logger.WithGroup(getUntrustedString()) // $ hasValueFlow="call to getUntrustedString"
grouped.Info("hello world")
}
// Summary models: functions relating to Attr/Value that propagate strings.
func testAttrConstructors(logger *slog.Logger) {
logger.Info("msg", slog.Group("group", slog.String("key", getUntrustedString()))) // $ hasTaintFlow="call to Group"
logger.Info("msg", slog.GroupAttrs("group", slog.String("key", getUntrustedString()))) // $ hasTaintFlow="call to GroupAttrs"
}
func testValueConstructors(logger *slog.Logger) {
logger.Info("msg", "key", slog.AnyValue(getUntrustedString())) // $ hasTaintFlow="call to AnyValue"
logger.Info("msg", "key", slog.StringValue(getUntrustedString())) // $ hasTaintFlow="call to StringValue"
attr := slog.String("key", getUntrustedString())
logger.Info("msg", "key", slog.GroupValue(attr)) // $ hasTaintFlow="call to GroupValue"
}
func testAttrAndValueAccessors(logger *slog.Logger) {
attr := slog.String("key", getUntrustedString())
logger.Info("msg", "key", attr.String()) // $ hasTaintFlow="call to String"
v := slog.AnyValue(getUntrustedString())
logger.Info("msg", "key", v.Any()) // $ hasTaintFlow="call to Any"
logger.Info("msg", "key", v.String()) // $ hasTaintFlow="call to String"
group := slog.GroupValue(slog.String("key", getUntrustedString()))
logger.Info("msg", group.Group()[0]) // $ hasTaintFlow="index expression"
}

View File

@@ -1242,13 +1242,12 @@ public class FileUtil
public static File tryMakeCanonical (File f)
{
try {
f = f.getCanonicalFile();
return f.getCanonicalFile();
}
catch (IOException ignored) {
Exceptions.ignore(ignored, "Can't log error: Could be too verbose.");
f = new File(simplifyPath(f));
return new File(simplifyPath(f));
}
return SubstResolver.resolve(f);
}

View File

@@ -1,76 +0,0 @@
package com.semmle.util.files;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Resolves Windows {@code subst}ed drive letters to their underlying paths. On non-Windows
* platforms, or when the native library failed to load, {@link #resolve(File)} is a no-op that
* returns its argument unchanged.
*/
public class SubstResolver {
private static final boolean available;
static {
boolean loaded = false;
if (File.separatorChar == '\\') {
String dist = System.getenv("CODEQL_DIST");
if (dist != null && !dist.isEmpty()) {
try {
Path library = Paths.get(dist).resolve("tools").resolve("win64")
.resolve("canonicalize.dll").toAbsolutePath();
System.load(library.toString());
loaded = true;
} catch (RuntimeException | UnsatisfiedLinkError ignored) {
}
}
}
available = loaded;
}
private SubstResolver() {}
/**
* Given a drive root like {@code "X:\\"}, returns the path that drive is
* {@code subst}ed to, or {@code null} if the letter isn't a subst mapping.
*/
private static native String nativeResolveSubst(String driveRoot);
/**
* If {@code f} is an absolute path starting with a {@code subst}ed drive letter, return an
* equivalent path with the drive letter replaced by its target. Otherwise return {@code f}
* unchanged.
*/
public static File resolve(File f) {
if (!available) {
return f;
}
String path = f.getPath();
if (path.length() < 3 || path.charAt(1) != ':') {
return f;
}
char sep = path.charAt(2);
if (sep != '\\' && sep != '/') {
return f;
}
if (!isDriveLetter(path.charAt(0))) {
return f;
}
String resolved = nativeResolveSubst(path.substring(0, 3));
if (resolved == null) {
return f;
}
return new File(resolved + path.substring(2));
}
private static boolean isDriveLetter(char c) {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
public static boolean isAvailable() {
return available;
}
}

View File

@@ -1,4 +0,0 @@
class Test {
public static void main(String[] args) {
}
}

View File

@@ -1 +0,0 @@
fun main() {}

View File

@@ -1,5 +0,0 @@
| file://:0:0:0:0 | | |
| file://:0:0:0:0 | | |
| file://Z:/Test.class:0:0:0:0 | Test | relative |
| file://Z:/test1.java:0:0:0:0 | test1 | relative |
| file://Z:/test2.kt:0:0:0:0 | test2 | relative |

View File

@@ -1,9 +0,0 @@
import java
from File f, string relative
where
not f.getURL().matches("file:///modules/%") and
not f.getURL().matches("file:///!unknown-binary-location/kotlin/%") and
not f.getURL().matches("%/ql/java/kotlin-extractor/%") and
if exists(f.getRelativePath()) then relative = "relative" else relative = ""
select f, relative

View File

@@ -1,7 +0,0 @@
import runs_on
@runs_on.windows
def test(codeql, java, cwd, subst_drive):
drive = subst_drive(cwd / "code")
codeql.database.create(command=["javac test1.java", "kotlinc test2.kt"], source_root=drive)

View File

@@ -1,10 +1,4 @@
extensions:
- addsTo:
pack: codeql/java-all
extensible: summaryModel
data:
- ["org.apache.hc.client5.http.protocol", "RedirectLocations", True, "add", "(URI)", "", "Argument[0]", "Argument[this].Element", "value", "hq-manual"]
- addsTo:
pack: codeql/java-all
extensible: neutralModel

View File

@@ -0,0 +1,6 @@
extensions:
- addsTo:
pack: codeql/java-all
extensible: summaryModel
data:
- ["org.apache.hc.client5.http.protocol", "RedirectLocations", True, "add", "(URI)", "", "Argument[0]", "Argument[this].Element", "value", "hq-manual"]

View File

@@ -234,3 +234,8 @@ subpaths
| use.kt:9:14:9:25 | taint(...) : Closeable | use.kt:9:31:9:36 | it : Closeable | use.kt:9:33:9:34 | it : Closeable | use.kt:9:14:9:36 | use(...) |
| with.kt:7:19:7:30 | taint(...) : String | with.kt:7:33:7:40 | $this$with : String | with.kt:7:35:7:38 | this : String | with.kt:7:14:7:40 | with(...) |
testFailures
| test.kt:28:14:28:21 | getSecond(...) | Unexpected result: hasTaintFlow=a |
| test.kt:35:14:35:27 | component1(...) | Unexpected result: hasTaintFlow=d |
| test.kt:41:14:41:22 | getSecond(...) | Unexpected result: hasTaintFlow=e |
| test.kt:53:14:53:24 | getDuration(...) | Unexpected result: hasTaintFlow=f |
| test.kt:58:14:58:29 | component2(...) | Unexpected result: hasTaintFlow=g |

View File

@@ -25,20 +25,20 @@ class Test {
val p = Pair(taint("a"), "")
sink(p) // $ hasTaintFlow=a
sink(p.component1()) // $ hasTaintFlow=a
sink(p.second) // $ SPURIOUS: hasTaintFlow=a
sink(p.second)
sink(taint("b").capitalize()) // $ hasTaintFlow=b
sink(taint("c").replaceFirstChar { _ -> 'x' }) // $ hasTaintFlow=c
val t = Triple("", taint("d"), "")
sink(t) // $ hasTaintFlow=d
sink(t.component1()) // $ SPURIOUS: hasTaintFlow=d
sink(t.component1())
sink(t.second) // $ hasTaintFlow=d
val p1 = taint("e") to ""
sink(p1) // $ hasTaintFlow=e
sink(p1.component1()) // $ hasTaintFlow=e
sink(p1.second) // $ SPURIOUS: hasTaintFlow=e
sink(p1.second)
val l = p.toList()
sink(l) // $ hasTaintFlow=a
@@ -50,12 +50,12 @@ class Test {
val tv = TimedValue(taint("f"), Duration.parse(""))
sink(tv) // $ hasTaintFlow=f
sink(tv.component1()) // $ hasTaintFlow=f
sink(tv.duration) // $ SPURIOUS: hasTaintFlow=f
sink(tv.duration)
val mg0 = MatchGroup(taint("g"), IntRange(0, 10))
sink(mg0) // $ hasTaintFlow=g
sink(mg0.value) // $ hasTaintFlow=g
sink(mg0.component2()) // $ SPURIOUS: hasTaintFlow=g
sink(mg0.component2())
val iv = IndexedValue<String>(5, taint("h"))
sink(iv) // $ hasTaintFlow=h
@@ -72,4 +72,4 @@ class Test {
sink(x.index)
}
}
}
}

View File

@@ -234,3 +234,8 @@ subpaths
| use.kt:9:14:9:25 | taint(...) : Closeable | use.kt:9:31:9:36 | it : Closeable | use.kt:9:33:9:34 | it : Closeable | use.kt:9:14:9:36 | use(...) |
| with.kt:7:19:7:30 | taint(...) : String | with.kt:7:33:7:40 | $this$with : String | with.kt:7:35:7:38 | this : String | with.kt:7:14:7:40 | with(...) |
testFailures
| test.kt:28:14:28:21 | getSecond(...) | Unexpected result: hasTaintFlow=a |
| test.kt:35:14:35:27 | component1(...) | Unexpected result: hasTaintFlow=d |
| test.kt:41:14:41:22 | getSecond(...) | Unexpected result: hasTaintFlow=e |
| test.kt:53:14:53:24 | getDuration(...) | Unexpected result: hasTaintFlow=f |
| test.kt:58:14:58:29 | component2(...) | Unexpected result: hasTaintFlow=g |

View File

@@ -25,20 +25,20 @@ class Test {
val p = Pair(taint("a"), "")
sink(p) // $ hasTaintFlow=a
sink(p.component1()) // $ hasTaintFlow=a
sink(p.second) // $ SPURIOUS: hasTaintFlow=a
sink(p.second)
sink(taint("b").capitalize()) // $ hasTaintFlow=b
sink(taint("c").replaceFirstChar { _ -> 'x' }) // $ hasTaintFlow=c
val t = Triple("", taint("d"), "")
sink(t) // $ hasTaintFlow=d
sink(t.component1()) // $ SPURIOUS: hasTaintFlow=d
sink(t.component1())
sink(t.second) // $ hasTaintFlow=d
val p1 = taint("e") to ""
sink(p1) // $ hasTaintFlow=e
sink(p1.component1()) // $ hasTaintFlow=e
sink(p1.second) // $ SPURIOUS: hasTaintFlow=e
sink(p1.second)
val l = p.toList()
sink(l) // $ hasTaintFlow=a
@@ -50,12 +50,12 @@ class Test {
val tv = TimedValue(taint("f"), Duration.parse(""))
sink(tv) // $ hasTaintFlow=f
sink(tv.component1()) // $ hasTaintFlow=f
sink(tv.duration) // $ SPURIOUS: hasTaintFlow=f
sink(tv.duration)
val mg0 = MatchGroup(taint("g"), IntRange(0, 10))
sink(mg0) // $ hasTaintFlow=g
sink(mg0.value) // $ hasTaintFlow=g
sink(mg0.component2()) // $ SPURIOUS: hasTaintFlow=g
sink(mg0.component2())
val iv = IndexedValue<String>(5, taint("h"))
sink(iv) // $ hasTaintFlow=h
@@ -72,4 +72,4 @@ class Test {
sink(x.index)
}
}
}
}

View File

@@ -29,3 +29,8 @@ nodes
| BadMacUse.java:146:48:146:57 | ciphertext : byte[] | semmle.label | ciphertext : byte[] |
| BadMacUse.java:152:42:152:51 | ciphertext | semmle.label | ciphertext |
subpaths
testFailures
| BadMacUse.java:50:56:50:66 | // $ Source | Missing result: Source |
| BadMacUse.java:63:118:63:128 | // $ Source | Missing result: Source |
| BadMacUse.java:92:31:92:35 | bytes : byte[] | Unexpected result: Source |
| BadMacUse.java:146:95:146:105 | // $ Source | Missing result: Source |

View File

@@ -30,3 +30,8 @@ nodes
| BadMacUse.java:118:83:118:84 | iv : byte[] | semmle.label | iv : byte[] |
| BadMacUse.java:124:42:124:51 | ciphertext | semmle.label | ciphertext |
subpaths
testFailures
| BadMacUse.java:63:118:63:128 | // $ Source | Missing result: Source |
| BadMacUse.java:92:16:92:36 | doFinal(...) : byte[] | Unexpected result: Source |
| BadMacUse.java:124:42:124:51 | ciphertext | Unexpected result: Alert |
| BadMacUse.java:146:95:146:105 | // $ Source | Missing result: Source |

View File

@@ -44,3 +44,8 @@ nodes
| BadMacUse.java:146:48:146:57 | ciphertext : byte[] [[]] : Object | semmle.label | ciphertext : byte[] [[]] : Object |
| BadMacUse.java:152:42:152:51 | ciphertext | semmle.label | ciphertext |
subpaths
testFailures
| BadMacUse.java:50:56:50:66 | // $ Source | Missing result: Source |
| BadMacUse.java:139:79:139:90 | input : byte[] | Unexpected result: Source |
| BadMacUse.java:146:95:146:105 | // $ Source | Missing result: Source |
| BadMacUse.java:152:42:152:51 | ciphertext | Unexpected result: Alert |

View File

@@ -47,7 +47,7 @@ class BadMacUse {
SecretKey encryptionKey = new SecretKeySpec(encryptionKeyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, encryptionKey, new SecureRandom());
byte[] plaintext = cipher.doFinal(ciphertext); // $ Source[java/quantum/examples/bad-mac-order-decrypt-to-mac]
byte[] plaintext = cipher.doFinal(ciphertext); // $ Source
// Now verify MAC (too late)
SecretKey macKey = new SecretKeySpec(macKeyBytes, "HmacSHA256");
@@ -60,7 +60,7 @@ class BadMacUse {
}
}
public void BadMacOnPlaintext(byte[] encryptionKeyBytes, byte[] macKeyBytes, byte[] plaintext) throws Exception {// $ Source[java/quantum/examples/bad-mac-order-encrypt-plaintext-also-in-mac]
public void BadMacOnPlaintext(byte[] encryptionKeyBytes, byte[] macKeyBytes, byte[] plaintext) throws Exception {// $ Source
// Create keys directly from provided byte arrays
SecretKey encryptionKey = new SecretKeySpec(encryptionKeyBytes, "AES");
SecretKey macKey = new SecretKeySpec(macKeyBytes, "HmacSHA256");
@@ -89,7 +89,7 @@ class BadMacUse {
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(mode, secretKeySpec, ivParameterSpec);
return cipher.doFinal(bytes); // $ Source[java/quantum/examples/bad-mac-order-decrypt-then-mac] Source[java/quantum/examples/bad-mac-order-decrypt-to-mac]
return cipher.doFinal(bytes);
}
/**
@@ -121,7 +121,7 @@ class BadMacUse {
SecretKey macKey = new SecretKeySpec(macKeyBytes, "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(macKey);
byte[] computedMac = mac.doFinal(ciphertext); // $ SPURIOUS: Alert[java/quantum/examples/bad-mac-order-decrypt-to-mac]
byte[] computedMac = mac.doFinal(ciphertext); // False Positive
// Concatenate ciphertext and MAC
byte[] output = new byte[ciphertext.length + computedMac.length];
@@ -136,20 +136,20 @@ class BadMacUse {
* The function decrypts THEN computes the MAC on the plaintext.
* It should have the MAC computed on the ciphertext first.
*/
public void decryptThenMac(byte[] encryptionKeyBytes, byte[] macKeyBytes, byte[] input) throws Exception { // $ SPURIOUS: Source[java/quantum/examples/bad-mac-order-encrypt-plaintext-also-in-mac]
public void decryptThenMac(byte[] encryptionKeyBytes, byte[] macKeyBytes, byte[] input) throws Exception {
// Split input into ciphertext and MAC
int macLength = 32; // HMAC-SHA256 output length
byte[] ciphertext = Arrays.copyOfRange(input, 0, input.length - macLength);
byte[] receivedMac = Arrays.copyOfRange(input, input.length - macLength, input.length);
// Decrypt first (unsafe)
byte[] plaintext = decryptUsingWrapper(ciphertext, encryptionKeyBytes, new byte[16]);
byte[] plaintext = decryptUsingWrapper(ciphertext, encryptionKeyBytes, new byte[16]); // $ Source
// Now verify MAC (too late)
SecretKey macKey = new SecretKeySpec(macKeyBytes, "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(macKey);
byte[] computedMac = mac.doFinal(ciphertext); // $ Alert[java/quantum/examples/bad-mac-order-decrypt-then-mac] SPURIOUS: Alert[java/quantum/examples/bad-mac-order-encrypt-plaintext-also-in-mac]
byte[] computedMac = mac.doFinal(ciphertext); // $ Alert[java/quantum/examples/bad-mac-order-decrypt-then-mac], False positive for Plaintext reuse
if (!MessageDigest.isEqual(receivedMac, computedMac)) {
throw new SecurityException("MAC verification failed");

View File

@@ -126,3 +126,5 @@ nodes
| InsecureIVorNonceSource.java:202:54:202:55 | iv : byte[] | semmle.label | iv : byte[] |
| InsecureIVorNonceSource.java:206:51:206:56 | ivSpec | semmle.label | ivSpec |
subpaths
testFailures
| InsecureIVorNonceSource.java:42:21:42:21 | 1 : Number | Unexpected result: Source |

View File

@@ -39,7 +39,7 @@ public class InsecureIVorNonceSource {
public byte[] encryptWithStaticIvByteArray(byte[] key, byte[] plaintext) throws Exception {
byte[] iv = new byte[16];
for (byte i = 0; i < iv.length; i++) {
iv[i] = 1; // $ Source[java/quantum/examples/insecure-iv-or-nonce]
iv[i] = 1;
}
IvParameterSpec ivSpec = new IvParameterSpec(iv);

View File

@@ -40,11 +40,11 @@ public class Test {
* SAST/CBOM: - Parent: PBKDF2. - Iteration count is only 10, which is far
* below acceptable security standards. - Flagged as insecure.
*/
public void pbkdf2LowIteration(String password, int iterationCount) throws Exception { // $ Source[java/quantum/examples/unknown-kdf-iteration-count]
public void pbkdf2LowIteration(String password, int iterationCount) throws Exception { // $ Source
byte[] salt = generateSalt(16);
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterationCount, 256);
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterationCount, 256); // $ Alert[java/quantum/examples/unknown-kdf-iteration-count]
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
byte[] key = factory.generateSecret(spec).getEncoded(); // $ Alert[java/quantum/examples/unknown-kdf-iteration-count]
byte[] key = factory.generateSecret(spec).getEncoded();
}
/**

View File

@@ -1 +1,5 @@
#select
| Test.java:47:22:47:49 | KeyDerivation | Key derivation operation with unknown iteration: $@ | Test.java:43:53:43:70 | iterationCount | iterationCount |
testFailures
| Test.java:45:94:45:154 | // $ Alert[java/quantum/examples/unknown-kdf-iteration-count] | Missing result: Alert[java/quantum/examples/unknown-kdf-iteration-count] |
| Test.java:47:22:47:49 | Key derivation operation with unknown iteration: $@ | Unexpected result: Alert |

View File

@@ -12,3 +12,5 @@ nodes
| Test.java:58:30:58:38 | 1_000_000 : Number | semmle.label | 1_000_000 : Number |
| Test.java:59:72:59:85 | iterationCount | semmle.label | iterationCount |
subpaths
testFailures
| Test.java:43:92:43:102 | // $ Source | Missing result: Source |

View File

@@ -1 +0,0 @@
function interesting() { }

View File

@@ -1,2 +0,0 @@
| file://Z:/main.js:0:0:0:0 | Z:/main.js | relative |
| file://Z:/test.ts:0:0:0:0 | Z:/test.ts | relative |

View File

@@ -1,7 +0,0 @@
import javascript
from File f, string relative
where
not f.getURL().matches("%/target/intree/%") and
if exists(f.getRelativePath()) then relative = "relative" else relative = ""
select f, relative

View File

@@ -1,7 +0,0 @@
import runs_on
@runs_on.windows
def test(codeql, javascript, cwd, subst_drive):
drive = subst_drive(cwd / "code")
codeql.database.create(source_root=drive)

View File

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

View File

@@ -1 +0,0 @@
print(0)

View File

@@ -1 +0,0 @@
| code/main.py:0:0:0:0 | code/main.py | |

View File

@@ -1,5 +0,0 @@
import python
from File f, string relative
where if exists(f.getRelativePath()) then relative = "relative" else relative = ""
select f, relative

View File

@@ -1,7 +0,0 @@
import runs_on
@runs_on.windows
def test(codeql, python, cwd, subst_drive):
drive = subst_drive(cwd / "code")
codeql.database.create(source_root=drive)

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* A new Python control flow graph implementation has been added under `semmle.python.controlflow.internal.Cfg` (backed by `AstNodeImpl.qll`), built on the shared `codeql.controlflow.ControlFlowGraph` library. It is not yet used by the dataflow library or any production query; the legacy CFG in `semmle/python/Flow.qll` remains the default. The new library is exposed for tests and for upcoming migrations.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The new (shared-CFG-based) Python control flow graph now visits parameter and return type annotations as CFG nodes for function definitions, matching the legacy CFG. This restores annotation-based type tracking through framework models such as FastAPI's `Depends()`, Pydantic request models, Starlette `WebSocket` handlers, and any other models that flow a class reference through `Parameter.getAnnotation()` to identify instances of the annotated class.

View File

@@ -0,0 +1,42 @@
/**
* @name Print CFG
* @description Produces a representation of a file's Control Flow Graph.
* This query is used by the VS Code extension.
* @id py/print-cfg
* @kind graph
* @tags ide-contextual-queries/print-cfg
*/
import semmle.python.Files as Files
// import semmle.python.Scope
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<Files::File> {
predicate selectedSourceFile = selectedSourceFileAlias/0;
predicate selectedSourceLine = selectedSourceLineAlias/0;
predicate selectedSourceColumn = selectedSourceColumnAlias/0;
predicate cfgScopeSpan(
Ast::Callable scope, Files::File file, int startLine, int startColumn, int endLine,
int endColumn
) {
file = scope.getLocation().getFile() and
scope.getLocation().hasLocationInfo(_, startLine, startColumn, endLine, endColumn)
}
}
import ControlFlow::ViewCfgQuery<Files::File, ViewCfgQueryInput>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1138,9 +1138,7 @@ predicate clearsContent(Node n, ContentSet cs) {
* Holds if the value that is being tracked is expected to be stored inside content `c`
* at node `n`.
*/
predicate expectsContent(Node n, ContentSet c) {
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c)
}
predicate expectsContent(Node n, ContentSet c) { none() }
/**
* Holds if values stored inside attribute `c` are cleared at node `n`.

View File

@@ -91,8 +91,6 @@ module Input implements InputSig<Location, DataFlowImplSpecific::PythonDataFlow>
cs.isAnyTupleOrDictionaryElement() and result = "AnyTupleOrDictionaryElement" and arg = ""
}
string encodeWithContent(ContentSet c, string arg) { result = "With" + encodeContent(c, arg) }
bindingset[token]
ParameterPosition decodeUnknownParameterPosition(AccessPath::AccessPathTokenBase token) {
// needed to support `Argument[x..y]` ranges

View File

@@ -4199,9 +4199,11 @@ module StdlibPrivate {
// The positional argument contains a mapping.
// TODO: these values can be overwritten by keyword arguments
// - dict mapping
input = "Argument[0].WithAnyDictionaryElement" and
output = "ReturnValue" and
preservesValue = true
exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() |
input = "Argument[0].DictionaryElement[" + key + "]" and
output = "ReturnValue.DictionaryElement[" + key + "]" and
preservesValue = true
)
or
// - list-of-pairs mapping
input = "Argument[0].ListElement.TupleElement[1]" and
@@ -4238,7 +4240,9 @@ module StdlibPrivate {
or
input = "Argument[0].SetElement"
or
input = "Argument[0].AnyTupleElement"
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
input = "Argument[0].TupleElement[" + i.toString() + "]"
)
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
) and
// Element content is mutated into list element content
@@ -4262,9 +4266,11 @@ module StdlibPrivate {
}
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
input = "Argument[0].WithAnyTupleElement" and
output = "ReturnValue" and
preservesValue = true
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
input = "Argument[0].TupleElement[" + i.toString() + "]" and
output = "ReturnValue.TupleElement[" + i.toString() + "]" and
preservesValue = true
)
or
input = "Argument[0].ListElement" and
output = "ReturnValue" and
@@ -4288,7 +4294,9 @@ module StdlibPrivate {
or
input = "Argument[0].SetElement"
or
input = "Argument[0].AnyTupleElement"
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
input = "Argument[0].TupleElement[" + i.toString() + "]"
)
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
) and
output = "ReturnValue.SetElement" and
@@ -4334,7 +4342,9 @@ module StdlibPrivate {
or
input = "Argument[0].SetElement"
or
input = "Argument[0].AnyTupleElement"
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
input = "Argument[0].TupleElement[" + i.toString() + "]"
)
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
) and
output = "ReturnValue.ListElement" and
@@ -4362,7 +4372,9 @@ module StdlibPrivate {
or
content = "SetElement"
or
content = "AnyTupleElement"
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
content = "TupleElement[" + i.toString() + "]"
)
|
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
input = "Argument[0]." + content and
@@ -4392,7 +4404,9 @@ module StdlibPrivate {
or
input = "Argument[0].SetElement"
or
input = "Argument[0].AnyTupleElement"
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
input = "Argument[0].TupleElement[" + i.toString() + "]"
)
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
) and
output = "ReturnValue.ListElement" and
@@ -4420,7 +4434,9 @@ module StdlibPrivate {
or
input = "Argument[0].SetElement"
or
input = "Argument[0].AnyTupleElement"
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
input = "Argument[0].TupleElement[" + i.toString() + "]"
)
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
) and
output = "ReturnValue" and
@@ -4452,7 +4468,9 @@ module StdlibPrivate {
// We reduce generality slightly by not tracking tuple contents on list arguments beyond the first, for performance.
// TODO: Once we have TupleElementAny, this generality can be increased.
i = 0 and
input = "Argument[1].AnyTupleElement"
exists(DataFlow::TupleElementContent tc, int j | j = tc.getIndex() |
input = "Argument[1].TupleElement[" + j.toString() + "]"
)
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
) and
output = "Argument[0].Parameter[" + i.toString() + "]" and
@@ -4481,7 +4499,9 @@ module StdlibPrivate {
or
input = "Argument[1].SetElement"
or
input = "Argument[1].AnyTupleElement"
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
input = "Argument[1].TupleElement[" + i.toString() + "]"
)
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
) and
(output = "Argument[0].Parameter[0]" or output = "ReturnValue.ListElement") and
@@ -4505,7 +4525,9 @@ module StdlibPrivate {
or
input = "Argument[0].SetElement"
or
input = "Argument[0].AnyTupleElement"
exists(DataFlow::TupleElementContent tc, int i | i = tc.getIndex() |
input = "Argument[0].TupleElement[" + i.toString() + "]"
)
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
) and
output = "ReturnValue.ListElement.TupleElement[1]" and
@@ -4530,7 +4552,12 @@ module StdlibPrivate {
or
input = "Argument[" + i.toString() + "].SetElement"
or
input = "Argument[" + i.toString() + "].AnyTupleElement"
// We reduce generality slightly by not tracking tuple contents on arguments beyond the first two, for performance.
// TODO: Once we have TupleElementAny, this generality can be increased.
i in [0 .. 1] and
exists(DataFlow::TupleElementContent tc, int j | j = tc.getIndex() |
input = "Argument[" + i.toString() + "].TupleElement[" + j.toString() + "]"
)
// TODO: Once we have DictKeyContent, we need to transform that into ListElementContent
) and
output = "ReturnValue.ListElement.TupleElement[" + i.toString() + "]" and
@@ -4553,6 +4580,12 @@ module StdlibPrivate {
override DataFlow::ArgumentNode getACallback() { none() }
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
exists(DataFlow::Content c |
input = "Argument[self]." + c.getMaDRepresentation() and
output = "ReturnValue." + c.getMaDRepresentation() and
preservesValue = true
)
or
input = "Argument[self]" and
output = "ReturnValue" and
preservesValue = true
@@ -4708,10 +4741,12 @@ module StdlibPrivate {
override DataFlow::ArgumentNode getACallback() { none() }
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
input = "Argument[self].AnyDictionaryElement" and
output = "ReturnValue.TupleElement[1]" and
preservesValue = true
// TODO: put `key` into "ReturnValue.TupleElement[0]"
exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() |
input = "Argument[self].DictionaryElement[" + key + "]" and
output = "ReturnValue.TupleElement[1]" and
preservesValue = true
// TODO: put `key` into "ReturnValue.TupleElement[0]"
)
}
}
@@ -4790,9 +4825,11 @@ module StdlibPrivate {
}
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
input = "Argument[self].AnyDictionaryElement" and
output = "ReturnValue.ListElement" and
preservesValue = true
exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() |
input = "Argument[self].DictionaryElement[" + key + "]" and
output = "ReturnValue.ListElement" and
preservesValue = true
)
or
input = "Argument[self]" and
output = "ReturnValue" and
@@ -4839,9 +4876,11 @@ module StdlibPrivate {
}
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
input = "Argument[self].AnyDictionaryElement" and
output = "ReturnValue.ListElement.TupleElement[1]" and
preservesValue = true
exists(DataFlow::DictionaryElementContent dc, string key | key = dc.getKey() |
input = "Argument[self].DictionaryElement[" + key + "]" and
output = "ReturnValue.ListElement.TupleElement[1]" and
preservesValue = true
)
or
// TODO: Add the keys to output list
input = "Argument[self]" and

View File

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

View File

@@ -0,0 +1,32 @@
/**
* Phase -1 of the dataflow CFG migration: verifies that every variable
* binding visible to the AST (`Name.defines(v)`) corresponds to a CFG node
* in the new CFG (`semmle.python.controlflow.internal.AstNodeImpl`).
*
* The expected tag is `cfgdefines=<name>`. Each binding annotation in the
* test sources looks like `# $ cfgdefines=x` for a binding currently
* covered by the new CFG, or `# $ MISSING: cfgdefines=x` for a binding
* that is known to be uncovered (a "red" test case that should be
* green-flipped once the corresponding `cfg-ext-*` extension lands).
*/
import python
import semmle.python.controlflow.internal.AstNodeImpl as CfgImpl
import utils.test.InlineExpectationsTest
module CfgBindingsTest implements TestSig {
string getARelevantTag() { result = "cfgdefines" }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(Name n, Variable v, CfgImpl::ControlFlowNode cfg |
n.defines(v) and
cfg.getAstNode().asExpr() = n and
location = n.getLocation() and
element = n.toString() and
tag = "cfgdefines" and
value = v.getId()
)
}
}
import MakeTest<CfgBindingsTest>

View File

@@ -0,0 +1,13 @@
# Annotated assignment (PEP 526). Both with and without an initializer.
a: int = 1 # $ cfgdefines=a
b: str = "hi" # $ cfgdefines=b
# Annotation without value: the AST records `c` as defined,
# and the new CFG now visits it via the AnnAssignStmt wrapper.
c: int # $ cfgdefines=c
class K: # $ cfgdefines=K
field: int = 0 # $ cfgdefines=field

View File

@@ -0,0 +1,14 @@
# Compound (tuple/list) assignment targets — actually wired in the new CFG.
a, b = (1, 2) # $ cfgdefines=a cfgdefines=b
[c, d] = [3, 4] # $ cfgdefines=c cfgdefines=d
# Nested unpacking.
(e, (f, g)) = (1, (2, 3)) # $ cfgdefines=e cfgdefines=f cfgdefines=g
# Star unpacking.
h, *i = [1, 2, 3] # $ cfgdefines=h cfgdefines=i
# Chained assignment with compound target.
j = k, l = (5, 6) # $ cfgdefines=j cfgdefines=k cfgdefines=l

View File

@@ -0,0 +1,21 @@
# Comprehension and `for` loop targets — wired in the new CFG.
# Comprehensions are nested function scopes with a synthetic `.0` parameter
# bound to the iterable.
# Bare-name `for` target.
for i in range(3): # $ cfgdefines=i
pass
# Compound `for` target.
for k, v in [(1, 2)]: # $ cfgdefines=k cfgdefines=v
pass
# Comprehension targets.
_ = [x for x in range(3)] # $ cfgdefines=_ cfgdefines=x cfgdefines=.0
_ = {y: z for y, z in []} # $ cfgdefines=_ cfgdefines=y cfgdefines=z cfgdefines=.0
_ = (a for a in []) # $ cfgdefines=_ cfgdefines=a cfgdefines=.0
# Nested comprehensions.
_ = [b for c in [] for b in c] # $ cfgdefines=_ cfgdefines=c cfgdefines=b cfgdefines=.0

View File

@@ -0,0 +1,53 @@
# Reachability of code following a try whose body always returns.
#
# The new CFG models exception edges for raise-prone expressions when
# they appear inside a `try` (or `with`) statement, mirroring Java's
# `mayThrow`. This means the body of a `try` has both a normal
# completion edge and an exception edge to its handlers, so code
# following the try-statement is reachable via the except-handler path
# even when the try-body would otherwise always return.
#
# Code that is not reachable under either normal or exception flow
# (for example, the `else` clause of a try whose body unconditionally
# raises) remains correctly classified as dead.
def f(obj): # $ cfgdefines=f cfgdefines=obj
try:
return len(obj)
except TypeError:
pass
# The try-body always returns, but `len(obj)` can raise (it is
# inside the try, so we model its exception edge). The
# `except TypeError: pass` handler falls through to here, making
# the code below reachable.
try:
hint = type(obj).__length_hint__ # $ cfgdefines=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 (via an explicit
# `raise`, which is modelled unconditionally), 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`: reachable via the except-handler fall-through.
value = compute(key) # $ cfgdefines=value
cache[key] = value
return value

View File

@@ -0,0 +1,30 @@
# Decorated `def`/`class` — wired in the new CFG.
def deco(f): # $ cfgdefines=deco cfgdefines=f
return f
@deco
def decorated_func(): # $ cfgdefines=decorated_func
pass
@deco
class DecoratedClass: # $ cfgdefines=DecoratedClass
pass
# Stacked decorators.
@deco
@deco
def doubly(): # $ cfgdefines=doubly
pass
# Inside a class body.
class Outer: # $ cfgdefines=Outer
@staticmethod
def inner(): # $ cfgdefines=inner
pass

View File

@@ -0,0 +1,19 @@
# Exception-handler name bindings. These are already wired in the new
# CFG provided the try body can raise; `raise` statements are reliably
# treated as exception sources.
try:
raise ValueError("oops")
except ValueError as e: # $ cfgdefines=e
pass
try:
raise TypeError("oops")
except (TypeError, KeyError) as err: # $ cfgdefines=err
pass
# Exception groups (Python 3.11+).
try:
raise ValueError("oops")
except* ValueError as eg: # $ cfgdefines=eg
pass

View File

@@ -0,0 +1,14 @@
# Import aliases — all bound names below are now reachable via the new
# CFG's `ImportStmt` wrapper.
import os # $ cfgdefines=os
import os.path # $ cfgdefines=os
import os as o # $ cfgdefines=o
from os import path # $ cfgdefines=path
from os import path as p # $ cfgdefines=p
from os import sep, linesep # $ cfgdefines=sep cfgdefines=linesep
from os import (
getcwd, # $ cfgdefines=getcwd
getcwdb, # $ cfgdefines=getcwdb
)

View File

@@ -0,0 +1,24 @@
# Match-statement pattern bindings — wired in the new CFG.
def f(subject): # $ cfgdefines=f cfgdefines=subject
match subject:
case x: # $ cfgdefines=x
pass
case [a, b]: # $ cfgdefines=a cfgdefines=b
pass
case {"k": v}: # $ cfgdefines=v
pass
case Point(p, q): # $ cfgdefines=p cfgdefines=q
pass
case [_, *rest]: # $ cfgdefines=rest
pass
case (1 | 2) as n: # $ cfgdefines=n
pass
class Point: # $ cfgdefines=Point
__match_args__ = ("x", "y") # $ cfgdefines=__match_args__
x: int # $ cfgdefines=x
y: int # $ cfgdefines=y

View File

@@ -0,0 +1,42 @@
# Function parameters.
def positional(a, b): # $ cfgdefines=positional cfgdefines=a cfgdefines=b
pass
def with_default(x=1, y=2): # $ cfgdefines=with_default cfgdefines=x cfgdefines=y
pass
def with_vararg(*args): # $ cfgdefines=with_vararg cfgdefines=args
pass
def with_kwarg(**kwargs): # $ cfgdefines=with_kwarg cfgdefines=kwargs
pass
def with_kwonly(*, k1, k2=5): # $ cfgdefines=with_kwonly cfgdefines=k1 cfgdefines=k2
pass
def kitchen_sink(a, b=2, *args, k1, k2=5, **kw): # $ cfgdefines=kitchen_sink cfgdefines=a cfgdefines=b cfgdefines=args cfgdefines=k1 cfgdefines=k2 cfgdefines=kw
pass
# Methods get `self` / `cls`.
class C: # $ cfgdefines=C
def method(self, x): # $ cfgdefines=method cfgdefines=self cfgdefines=x
pass
@classmethod
def cmethod(cls, x): # $ cfgdefines=cmethod cfgdefines=cls cfgdefines=x
pass
# Lambda parameter.
_ = lambda p: p + 1 # $ cfgdefines=_ cfgdefines=p
# PEP 570 positional-only.
def pos_only(a, b, /, c): # $ cfgdefines=pos_only cfgdefines=a cfgdefines=b cfgdefines=c
pass

View File

@@ -0,0 +1,14 @@
# Simple bindings that should already work in the new CFG.
# No MISSING annotations expected.
x = 1 # $ cfgdefines=x
y = x + 1 # $ cfgdefines=y
def f(): # $ cfgdefines=f
pass
class C: # $ cfgdefines=C
pass
# Re-assignment.
x = 2 # $ cfgdefines=x

View File

@@ -0,0 +1,21 @@
# PEP 695 type parameters (Python 3.12+).
# PEP 695 type-param names on `def`/`class` bind in an annotation scope
# that nests the function/class body — they have no CFG node in the
# enclosing scope (matching the legacy CFG).
def func[T](x: T) -> T: # $ cfgdefines=func cfgdefines=x
return x
class Box[T]: # $ cfgdefines=Box
item: T # $ cfgdefines=item
# Multi-parameter, with bound and variadics.
def multi[T: int, *Ts, **P](x: T, *args: *Ts, **kwargs: P.kwargs) -> T: # $ cfgdefines=multi cfgdefines=x cfgdefines=args cfgdefines=kwargs
return x
# `type` statement (PEP 695).
type Alias[T] = list[T] # $ cfgdefines=Alias cfgdefines=T

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