mirror of
https://github.com/github/codeql.git
synced 2026-07-06 03:55:30 +02:00
Compare commits
387 Commits
codeql-cli
...
28-strsafe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e64412bad | ||
|
|
79dcb4b48c | ||
|
|
bdae2af0e2 | ||
|
|
c3ff181198 | ||
|
|
68e7f84c23 | ||
|
|
6b434d10ce | ||
|
|
e68826bf99 | ||
|
|
512c6a59c5 | ||
|
|
d8e75e66d7 | ||
|
|
3586231e7d | ||
|
|
6d4e000c7c | ||
|
|
43d9d2ceb7 | ||
|
|
4ae35d179e | ||
|
|
d510739ca2 | ||
|
|
795e32c681 | ||
|
|
b1c3915fd9 | ||
|
|
d78a7b9d94 | ||
|
|
0cf00ebb5d | ||
|
|
ab64d9a9d6 | ||
|
|
69e8621062 | ||
|
|
5442cdb49c | ||
|
|
f643fd7d74 | ||
|
|
45ae4ed362 | ||
|
|
a8eed6bd7e | ||
|
|
3f95dd6916 | ||
|
|
b63294764b | ||
|
|
69502d0c31 | ||
|
|
12f9e3a1dd | ||
|
|
ae577d1e44 | ||
|
|
dd20a9b009 | ||
|
|
df256e601a | ||
|
|
5a9867c5b0 | ||
|
|
1c8f474848 | ||
|
|
2787f0a0fc | ||
|
|
2d43eec3c3 | ||
|
|
91b29eee53 | ||
|
|
a04830b8b2 | ||
|
|
21cb4909cf | ||
|
|
12cba7909b | ||
|
|
f2ca52d951 | ||
|
|
b2512eb212 | ||
|
|
dc8ca70ab5 | ||
|
|
7ea8f88d47 | ||
|
|
697a7b8a60 | ||
|
|
2b7ce23653 | ||
|
|
33de177fea | ||
|
|
bbde709b3f | ||
|
|
a70d9691da | ||
|
|
af7b295c59 | ||
|
|
9dca6697fb | ||
|
|
0f31fc7cbe | ||
|
|
5220a8d3f8 | ||
|
|
9f43108ba8 | ||
|
|
904a8b1ea9 | ||
|
|
ccaa792343 | ||
|
|
6669cf805f | ||
|
|
0fd4d4a114 | ||
|
|
e8a466a02c | ||
|
|
022c9eb3cd | ||
|
|
6bf2d47321 | ||
|
|
1dc08941f8 | ||
|
|
a0e73eaab0 | ||
|
|
a17cd9bc1c | ||
|
|
4ce8d953d2 | ||
|
|
cff9bcfabc | ||
|
|
4e70e674fd | ||
|
|
ae21bbf0b2 | ||
|
|
3465c34cb6 | ||
|
|
c85bdcd5ab | ||
|
|
4455ed982d | ||
|
|
1c6a4b8cbf | ||
|
|
84594e66bc | ||
|
|
127f819762 | ||
|
|
e0c89a700f | ||
|
|
426bdc0011 | ||
|
|
d38fa13299 | ||
|
|
e91987b1a9 | ||
|
|
d544f47746 | ||
|
|
e4f6b1ac27 | ||
|
|
77e48f72ec | ||
|
|
9ec5e6e35e | ||
|
|
424046d238 | ||
|
|
80c4b7357a | ||
|
|
31c2a3be98 | ||
|
|
decbaa9dc7 | ||
|
|
3f0be47c7b | ||
|
|
49428c4585 | ||
|
|
43f1d092f1 | ||
|
|
d86293f9b4 | ||
|
|
ff30308a2b | ||
|
|
4b9430d59e | ||
|
|
cd2eec0aa0 | ||
|
|
f6ae7523b5 | ||
|
|
12cd1c1011 | ||
|
|
4e214e1c7c | ||
|
|
68da5e2bbe | ||
|
|
c6193ebc0c | ||
|
|
838a00bbc9 | ||
|
|
2abdf7dbbd | ||
|
|
602d16d73f | ||
|
|
b99e44c3ca | ||
|
|
4bcf9e50a0 | ||
|
|
467854ba4b | ||
|
|
2d9ff85753 | ||
|
|
3e3ea51e69 | ||
|
|
2a33a86c9d | ||
|
|
aa521ecd59 | ||
|
|
abcb5a7a95 | ||
|
|
e621d208e4 | ||
|
|
55ec27f47f | ||
|
|
e90b630c9b | ||
|
|
c6bc1a3f3a | ||
|
|
07eba4e3b1 | ||
|
|
041dc19055 | ||
|
|
989a546796 | ||
|
|
d0ca7045d4 | ||
|
|
a59ed5bc49 | ||
|
|
06191922c3 | ||
|
|
71ad6a8262 | ||
|
|
0d7943031c | ||
|
|
f969274a29 | ||
|
|
245f475fdb | ||
|
|
df4f2a367b | ||
|
|
31f602cd47 | ||
|
|
4689bdb468 | ||
|
|
1054e7a4ee | ||
|
|
003166af13 | ||
|
|
e7e6529df6 | ||
|
|
8d3ed68b68 | ||
|
|
49add7d8ce | ||
|
|
eb228b6e68 | ||
|
|
62dd86bacb | ||
|
|
7b91be6c52 | ||
|
|
11505d6842 | ||
|
|
56a70da28f | ||
|
|
70996a4c7e | ||
|
|
576eda3ec6 | ||
|
|
4cebb7e848 | ||
|
|
f8d427336e | ||
|
|
7bbf1a24d4 | ||
|
|
c6c00e7179 | ||
|
|
3a7df994cb | ||
|
|
387a241efd | ||
|
|
506b911767 | ||
|
|
4009f03087 | ||
|
|
9807a8e1d3 | ||
|
|
af524f0043 | ||
|
|
894f9ab8fa | ||
|
|
7082efa037 | ||
|
|
c34ad25cf9 | ||
|
|
13e60d7b11 | ||
|
|
132cc03e3b | ||
|
|
679d64f0e8 | ||
|
|
30a512c96b | ||
|
|
81d77bf37c | ||
|
|
947e0274c7 | ||
|
|
ac0fd93cb3 | ||
|
|
2f4eea5a0d | ||
|
|
f404d7a5f8 | ||
|
|
392b2af923 | ||
|
|
b82dfa9a21 | ||
|
|
5487b404ed | ||
|
|
0bf2d77a7e | ||
|
|
a161d6e666 | ||
|
|
9ea6ef06ef | ||
|
|
f2b52650d5 | ||
|
|
a35bda2946 | ||
|
|
f82f1df5d6 | ||
|
|
7bf271fb6c | ||
|
|
a9e2f55b61 | ||
|
|
484d0fe4cd | ||
|
|
12d856737a | ||
|
|
8f4509f434 | ||
|
|
431d9d58f1 | ||
|
|
242399817a | ||
|
|
fd757b0089 | ||
|
|
58bf70d61b | ||
|
|
613831b2e1 | ||
|
|
c937230f1a | ||
|
|
c26c68c286 | ||
|
|
7c3684dbb7 | ||
|
|
400910e4d3 | ||
|
|
155073c498 | ||
|
|
48c3db2290 | ||
|
|
206acea41c | ||
|
|
727a7e804c | ||
|
|
f8ab64dff0 | ||
|
|
c717e346fb | ||
|
|
ac115e0a6f | ||
|
|
bb2bbd2d4d | ||
|
|
f6794fe859 | ||
|
|
8e9aa5b560 | ||
|
|
a7f3ef1a6c | ||
|
|
8e2b17cd86 | ||
|
|
6d859daf3d | ||
|
|
b54b5ae0a9 | ||
|
|
b3fa59d94b | ||
|
|
3c86aad16d | ||
|
|
4ce1b680c2 | ||
|
|
048a7c4e42 | ||
|
|
48291dd32d | ||
|
|
0b45b63bd2 | ||
|
|
0c5b528d54 | ||
|
|
1366247f4c | ||
|
|
f7a8a8ae19 | ||
|
|
9736936e54 | ||
|
|
ddb145f15f | ||
|
|
38b811b050 | ||
|
|
1ec1dd368d | ||
|
|
6e385cabd8 | ||
|
|
37a536baf9 | ||
|
|
3478890090 | ||
|
|
b79a5fee14 | ||
|
|
554007b305 | ||
|
|
c82eb4dff3 | ||
|
|
b9ac038de2 | ||
|
|
ceb3d14fe0 | ||
|
|
07ded4278f | ||
|
|
051a77fd79 | ||
|
|
18c8d90a1a | ||
|
|
688afddaf2 | ||
|
|
8f58685b38 | ||
|
|
567aa1102a | ||
|
|
bc34374075 | ||
|
|
e25a655509 | ||
|
|
b9dfeb3aac | ||
|
|
34b9791e46 | ||
|
|
322e6c91be | ||
|
|
8b6c940e76 | ||
|
|
6d6f89e71e | ||
|
|
a39a94ca8e | ||
|
|
19644a8f07 | ||
|
|
7f6ae8b2ab | ||
|
|
11152deeb5 | ||
|
|
f76cde36bb | ||
|
|
e1f7f3cbd4 | ||
|
|
e75562e508 | ||
|
|
5cc94e1105 | ||
|
|
21b7a51d0a | ||
|
|
1479509d93 | ||
|
|
377da9fa66 | ||
|
|
4a1bf95a87 | ||
|
|
e8c18a3883 | ||
|
|
98032d58b8 | ||
|
|
5b17066e6c | ||
|
|
ea04b500a3 | ||
|
|
b841d5f923 | ||
|
|
81b3ff2bb8 | ||
|
|
79e1aa0498 | ||
|
|
05a4c7fdc1 | ||
|
|
66f4eccc30 | ||
|
|
5407b57261 | ||
|
|
aac6cf60ee | ||
|
|
ffff10a7e8 | ||
|
|
7bae2d9192 | ||
|
|
6b031a4623 | ||
|
|
785175e77f | ||
|
|
bfd852aacd | ||
|
|
ec72150893 | ||
|
|
435b7df764 | ||
|
|
8913638b25 | ||
|
|
b259a0ff6a | ||
|
|
c8706e2ad7 | ||
|
|
65081a9a1f | ||
|
|
08b528b5c4 | ||
|
|
0837e400a2 | ||
|
|
efe064284b | ||
|
|
86fe5b47db | ||
|
|
2b939fdf08 | ||
|
|
f81a3ec464 | ||
|
|
375f0ea8b6 | ||
|
|
1e699ec0e5 | ||
|
|
c8edf3151b | ||
|
|
45cf50c2af | ||
|
|
c233094846 | ||
|
|
fa3d401226 | ||
|
|
7cf5210063 | ||
|
|
9a95b9bcda | ||
|
|
c09df2e3f1 | ||
|
|
8f115bfd06 | ||
|
|
91d224eea5 | ||
|
|
fb0f9ec601 | ||
|
|
b8d45ae927 | ||
|
|
e2ef0dc71d | ||
|
|
d46442245b | ||
|
|
435638a5bb | ||
|
|
954b0612d5 | ||
|
|
14db0dfcc7 | ||
|
|
c040d4847b | ||
|
|
dc9f171ee6 | ||
|
|
b4958e7d58 | ||
|
|
a077b70d66 | ||
|
|
535d1e2565 | ||
|
|
55df481e5c | ||
|
|
083be305e1 | ||
|
|
38ecde0cc1 | ||
|
|
3a9ffe189e | ||
|
|
9e2f0b5ed0 | ||
|
|
bf3fb685ad | ||
|
|
14cfb82a8c | ||
|
|
60f3598da9 | ||
|
|
e25c0498d4 | ||
|
|
28eb2caacb | ||
|
|
6538a7645d | ||
|
|
1f8a51cffe | ||
|
|
e745df6478 | ||
|
|
6ad8a4db1c | ||
|
|
0cf702a74f | ||
|
|
3c5b9ce0cd | ||
|
|
104700f6d3 | ||
|
|
7af3d239ab | ||
|
|
08cc8b8e80 | ||
|
|
f42bd28ca9 | ||
|
|
741735cc83 | ||
|
|
3939167ba2 | ||
|
|
9d90c24006 | ||
|
|
f288ddc3d5 | ||
|
|
d923784ae4 | ||
|
|
90c63ab6b0 | ||
|
|
2fb4dfeb90 | ||
|
|
665b140a8a | ||
|
|
700201556c | ||
|
|
58dae6d1c6 | ||
|
|
2a91743477 | ||
|
|
a28f19c857 | ||
|
|
c689065f83 | ||
|
|
855d96db66 | ||
|
|
d85284da55 | ||
|
|
02c98fae5f | ||
|
|
1ad06f3293 | ||
|
|
9c15cf18e8 | ||
|
|
3b0b5e403c | ||
|
|
a2bcc97a74 | ||
|
|
743814a234 | ||
|
|
c2d072e3f8 | ||
|
|
22d968fba3 | ||
|
|
31b069041f | ||
|
|
a8eb95a688 | ||
|
|
64d23d4f9b | ||
|
|
5b2d226c35 | ||
|
|
1edca19419 | ||
|
|
24c809b3b5 | ||
|
|
72a1289eba | ||
|
|
c6641dfbf3 | ||
|
|
a85df81b67 | ||
|
|
0612b3795a | ||
|
|
3ee0fa9bc4 | ||
|
|
b77b3763be | ||
|
|
8eeb861963 | ||
|
|
2f53adf2c2 | ||
|
|
dbb5aa9aad | ||
|
|
083a5068c3 | ||
|
|
886c85ddc1 | ||
|
|
958c6ff289 | ||
|
|
ee6cb96d07 | ||
|
|
3219edc603 | ||
|
|
6b94b77a0a | ||
|
|
f8c3b2977a | ||
|
|
f783ca7940 | ||
|
|
96d6ecb108 | ||
|
|
35e19eac96 | ||
|
|
4f8908106b | ||
|
|
f7c07d55ed | ||
|
|
49218cdbfb | ||
|
|
18661eee77 | ||
|
|
66486b08dc | ||
|
|
4aec302fb7 | ||
|
|
be494b73d4 | ||
|
|
fb470e4140 | ||
|
|
bf503849ea | ||
|
|
bf6e6a1e68 | ||
|
|
a245d0019e | ||
|
|
9196939384 | ||
|
|
d2d70cc782 | ||
|
|
79f675cdb7 | ||
|
|
a5206028b0 | ||
|
|
d3063e849e | ||
|
|
4cf40ed259 | ||
|
|
2f0ee12584 | ||
|
|
f22d60f011 | ||
|
|
3f1e145d2c | ||
|
|
36f1070b93 | ||
|
|
fc1fc05d16 | ||
|
|
fbfafbfdd4 | ||
|
|
eb3e140008 | ||
|
|
0a0ce1f202 | ||
|
|
3ac3169278 |
@@ -29,6 +29,7 @@ provide:
|
|||||||
- "swift/extractor-pack/codeql-extractor.yml"
|
- "swift/extractor-pack/codeql-extractor.yml"
|
||||||
- "swift/integration-tests/qlpack.yml"
|
- "swift/integration-tests/qlpack.yml"
|
||||||
- "ql/extractor-pack/codeql-extractor.yml"
|
- "ql/extractor-pack/codeql-extractor.yml"
|
||||||
|
- ".github/codeql/extensions/**/codeql-pack.yml"
|
||||||
|
|
||||||
versionPolicies:
|
versionPolicies:
|
||||||
default:
|
default:
|
||||||
|
|||||||
2231
cpp/downgrades/8cba93a44180e0d50a80a660950800d822b981fc/old.dbscheme
Normal file
2231
cpp/downgrades/8cba93a44180e0d50a80a660950800d822b981fc/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
|||||||
|
description: Removed @assignpaddexpr and @assignpsubexpr from @assign_bitwise_expr
|
||||||
|
compatibility: full
|
||||||
4
cpp/ql/lib/change-notes/2023-10-30-realloc-flow.md
Normal file
4
cpp/ql/lib/change-notes/2023-10-30-realloc-flow.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* Added taint models for `realloc` and related functions.
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: breaking
|
||||||
|
---
|
||||||
|
* The expressions `AssignPointerAddExpr` and `AssignPointerSubExpr` are no longer subtypes of `AssignBitwiseOperation`.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/cpp-all
|
name: codeql/cpp-all
|
||||||
version: 0.11.0
|
version: 0.11.1-dev
|
||||||
groups: cpp
|
groups: cpp
|
||||||
dbscheme: semmlecode.cpp.dbscheme
|
dbscheme: semmlecode.cpp.dbscheme
|
||||||
extractor: cpp
|
extractor: cpp
|
||||||
|
|||||||
@@ -31,6 +31,11 @@ abstract class MustFlowConfiguration extends string {
|
|||||||
*/
|
*/
|
||||||
abstract predicate isSink(Operand sink);
|
abstract predicate isSink(Operand sink);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if data flow through `instr` is prohibited.
|
||||||
|
*/
|
||||||
|
predicate isBarrier(Instruction instr) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the additional flow step from `node1` to `node2` must be taken
|
* Holds if the additional flow step from `node1` to `node2` must be taken
|
||||||
* into account in the analysis.
|
* into account in the analysis.
|
||||||
@@ -48,19 +53,22 @@ abstract class MustFlowConfiguration extends string {
|
|||||||
*/
|
*/
|
||||||
final predicate hasFlowPath(MustFlowPathNode source, MustFlowPathSink sink) {
|
final predicate hasFlowPath(MustFlowPathNode source, MustFlowPathSink sink) {
|
||||||
this.isSource(source.getInstruction()) and
|
this.isSource(source.getInstruction()) and
|
||||||
source.getASuccessor+() = sink
|
source.getASuccessor*() = sink
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if `node` flows from a source. */
|
/** Holds if `node` flows from a source. */
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate flowsFromSource(Instruction node, MustFlowConfiguration config) {
|
private predicate flowsFromSource(Instruction node, MustFlowConfiguration config) {
|
||||||
|
not config.isBarrier(node) and
|
||||||
|
(
|
||||||
config.isSource(node)
|
config.isSource(node)
|
||||||
or
|
or
|
||||||
exists(Instruction mid |
|
exists(Instruction mid |
|
||||||
step(mid, node, config) and
|
step(mid, node, config) and
|
||||||
flowsFromSource(mid, pragma[only_bind_into](config))
|
flowsFromSource(mid, pragma[only_bind_into](config))
|
||||||
)
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if `node` flows to a sink. */
|
/** Holds if `node` flows to a sink. */
|
||||||
|
|||||||
@@ -44,11 +44,12 @@ private newtype TIRDataFlowNode =
|
|||||||
TIndirectArgumentOutNode(ArgumentOperand operand, int indirectionIndex) {
|
TIndirectArgumentOutNode(ArgumentOperand operand, int indirectionIndex) {
|
||||||
Ssa::isModifiableByCall(operand, indirectionIndex)
|
Ssa::isModifiableByCall(operand, indirectionIndex)
|
||||||
} or
|
} or
|
||||||
TRawIndirectOperand(Operand op, int indirectionIndex) {
|
TRawIndirectOperand0(Node0Impl node, int indirectionIndex) {
|
||||||
Ssa::hasRawIndirectOperand(op, indirectionIndex)
|
Ssa::hasRawIndirectOperand(node.asOperand(), indirectionIndex)
|
||||||
} or
|
} or
|
||||||
TRawIndirectInstruction(Instruction instr, int indirectionIndex) {
|
TRawIndirectInstruction0(Node0Impl node, int indirectionIndex) {
|
||||||
Ssa::hasRawIndirectInstruction(instr, indirectionIndex)
|
not exists(node.asOperand()) and
|
||||||
|
Ssa::hasRawIndirectInstruction(node.asInstruction(), indirectionIndex)
|
||||||
} or
|
} or
|
||||||
TFinalParameterNode(Parameter p, int indirectionIndex) {
|
TFinalParameterNode(Parameter p, int indirectionIndex) {
|
||||||
exists(Ssa::FinalParameterUse use |
|
exists(Ssa::FinalParameterUse use |
|
||||||
@@ -918,31 +919,34 @@ Type getTypeImpl(Type t, int indirectionIndex) {
|
|||||||
result instanceof UnknownType
|
result instanceof UnknownType
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private module RawIndirectNodes {
|
||||||
|
/**
|
||||||
* INTERNAL: Do not use.
|
* INTERNAL: Do not use.
|
||||||
*
|
*
|
||||||
* A node that represents the indirect value of an operand in the IR
|
* A node that represents the indirect value of an operand in the IR
|
||||||
* after `index` number of loads.
|
* after `index` number of loads.
|
||||||
*/
|
*/
|
||||||
class RawIndirectOperand extends Node, TRawIndirectOperand {
|
private class RawIndirectOperand0 extends Node, TRawIndirectOperand0 {
|
||||||
Operand operand;
|
Node0Impl node;
|
||||||
int indirectionIndex;
|
int indirectionIndex;
|
||||||
|
|
||||||
RawIndirectOperand() { this = TRawIndirectOperand(operand, indirectionIndex) }
|
RawIndirectOperand0() { this = TRawIndirectOperand0(node, indirectionIndex) }
|
||||||
|
|
||||||
/** Gets the underlying instruction. */
|
/** Gets the underlying instruction. */
|
||||||
Operand getOperand() { result = operand }
|
Operand getOperand() { result = node.asOperand() }
|
||||||
|
|
||||||
/** Gets the underlying indirection index. */
|
/** Gets the underlying indirection index. */
|
||||||
int getIndirectionIndex() { result = indirectionIndex }
|
int getIndirectionIndex() { result = indirectionIndex }
|
||||||
|
|
||||||
override Declaration getFunction() { result = this.getOperand().getDef().getEnclosingFunction() }
|
override Declaration getFunction() {
|
||||||
|
result = this.getOperand().getDef().getEnclosingFunction()
|
||||||
|
}
|
||||||
|
|
||||||
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
||||||
|
|
||||||
override DataFlowType getType() {
|
override DataFlowType getType() {
|
||||||
exists(int sub, DataFlowType type, boolean isGLValue |
|
exists(int sub, DataFlowType type, boolean isGLValue |
|
||||||
type = getOperandType(operand, isGLValue) and
|
type = getOperandType(this.getOperand(), isGLValue) and
|
||||||
if isGLValue = true then sub = 1 else sub = 0
|
if isGLValue = true then sub = 1 else sub = 0
|
||||||
|
|
|
|
||||||
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
|
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
|
||||||
@@ -958,8 +962,103 @@ class RawIndirectOperand extends Node, TRawIndirectOperand {
|
|||||||
override string toStringImpl() {
|
override string toStringImpl() {
|
||||||
result = operandNode(this.getOperand()).toStringImpl() + " indirection"
|
result = operandNode(this.getOperand()).toStringImpl() + " indirection"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INTERNAL: Do not use.
|
||||||
|
*
|
||||||
|
* A node that represents the indirect value of an instruction in the IR
|
||||||
|
* after `index` number of loads.
|
||||||
|
*/
|
||||||
|
private class RawIndirectInstruction0 extends Node, TRawIndirectInstruction0 {
|
||||||
|
Node0Impl node;
|
||||||
|
int indirectionIndex;
|
||||||
|
|
||||||
|
RawIndirectInstruction0() { this = TRawIndirectInstruction0(node, indirectionIndex) }
|
||||||
|
|
||||||
|
/** Gets the underlying instruction. */
|
||||||
|
Instruction getInstruction() { result = node.asInstruction() }
|
||||||
|
|
||||||
|
/** Gets the underlying indirection index. */
|
||||||
|
int getIndirectionIndex() { result = indirectionIndex }
|
||||||
|
|
||||||
|
override Declaration getFunction() { result = this.getInstruction().getEnclosingFunction() }
|
||||||
|
|
||||||
|
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
||||||
|
|
||||||
|
override DataFlowType getType() {
|
||||||
|
exists(int sub, DataFlowType type, boolean isGLValue |
|
||||||
|
type = getInstructionType(this.getInstruction(), isGLValue) and
|
||||||
|
if isGLValue = true then sub = 1 else sub = 0
|
||||||
|
|
|
||||||
|
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
final override Location getLocationImpl() {
|
||||||
|
if exists(this.getInstruction().getLocation())
|
||||||
|
then result = this.getInstruction().getLocation()
|
||||||
|
else result instanceof UnknownDefaultLocation
|
||||||
|
}
|
||||||
|
|
||||||
|
override string toStringImpl() {
|
||||||
|
result = instructionNode(this.getInstruction()).toStringImpl() + " indirection"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INTERNAL: Do not use.
|
||||||
|
*
|
||||||
|
* A node that represents the indirect value of an operand in the IR
|
||||||
|
* after a number of loads.
|
||||||
|
*/
|
||||||
|
class RawIndirectOperand extends Node {
|
||||||
|
int indirectionIndex;
|
||||||
|
Operand operand;
|
||||||
|
|
||||||
|
RawIndirectOperand() {
|
||||||
|
exists(Node0Impl node | operand = node.asOperand() |
|
||||||
|
this = TRawIndirectOperand0(node, indirectionIndex)
|
||||||
|
or
|
||||||
|
this = TRawIndirectInstruction0(node, indirectionIndex)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the operand associated with this node. */
|
||||||
|
Operand getOperand() { result = operand }
|
||||||
|
|
||||||
|
/** Gets the underlying indirection index. */
|
||||||
|
int getIndirectionIndex() { result = indirectionIndex }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INTERNAL: Do not use.
|
||||||
|
*
|
||||||
|
* A node that represents the indirect value of an instruction in the IR
|
||||||
|
* after a number of loads.
|
||||||
|
*/
|
||||||
|
class RawIndirectInstruction extends Node {
|
||||||
|
int indirectionIndex;
|
||||||
|
Instruction instr;
|
||||||
|
|
||||||
|
RawIndirectInstruction() {
|
||||||
|
exists(Node0Impl node | instr = node.asInstruction() |
|
||||||
|
this = TRawIndirectOperand0(node, indirectionIndex)
|
||||||
|
or
|
||||||
|
this = TRawIndirectInstruction0(node, indirectionIndex)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the instruction associated with this node. */
|
||||||
|
Instruction getInstruction() { result = instr }
|
||||||
|
|
||||||
|
/** Gets the underlying indirection index. */
|
||||||
|
int getIndirectionIndex() { result = indirectionIndex }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import RawIndirectNodes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* INTERNAL: do not use.
|
* INTERNAL: do not use.
|
||||||
*
|
*
|
||||||
@@ -1021,48 +1120,6 @@ class UninitializedNode extends Node {
|
|||||||
LocalVariable getLocalVariable() { result = v }
|
LocalVariable getLocalVariable() { result = v }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* INTERNAL: Do not use.
|
|
||||||
*
|
|
||||||
* A node that represents the indirect value of an instruction in the IR
|
|
||||||
* after `index` number of loads.
|
|
||||||
*/
|
|
||||||
class RawIndirectInstruction extends Node, TRawIndirectInstruction {
|
|
||||||
Instruction instr;
|
|
||||||
int indirectionIndex;
|
|
||||||
|
|
||||||
RawIndirectInstruction() { this = TRawIndirectInstruction(instr, indirectionIndex) }
|
|
||||||
|
|
||||||
/** Gets the underlying instruction. */
|
|
||||||
Instruction getInstruction() { result = instr }
|
|
||||||
|
|
||||||
/** Gets the underlying indirection index. */
|
|
||||||
int getIndirectionIndex() { result = indirectionIndex }
|
|
||||||
|
|
||||||
override Declaration getFunction() { result = this.getInstruction().getEnclosingFunction() }
|
|
||||||
|
|
||||||
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
|
||||||
|
|
||||||
override DataFlowType getType() {
|
|
||||||
exists(int sub, DataFlowType type, boolean isGLValue |
|
|
||||||
type = getInstructionType(instr, isGLValue) and
|
|
||||||
if isGLValue = true then sub = 1 else sub = 0
|
|
||||||
|
|
|
||||||
result = getTypeImpl(type.getUnspecifiedType(), indirectionIndex - sub)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
final override Location getLocationImpl() {
|
|
||||||
if exists(this.getInstruction().getLocation())
|
|
||||||
then result = this.getInstruction().getLocation()
|
|
||||||
else result instanceof UnknownDefaultLocation
|
|
||||||
}
|
|
||||||
|
|
||||||
override string toStringImpl() {
|
|
||||||
result = instructionNode(this.getInstruction()).toStringImpl() + " indirection"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private module GetConvertedResultExpression {
|
private module GetConvertedResultExpression {
|
||||||
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr
|
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr
|
||||||
private import semmle.code.cpp.ir.implementation.raw.internal.InstructionTag
|
private import semmle.code.cpp.ir.implementation.raw.internal.InstructionTag
|
||||||
@@ -1600,6 +1657,8 @@ private module Cached {
|
|||||||
predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFrom, nodeTo) }
|
predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFrom, nodeTo) }
|
||||||
|
|
||||||
private predicate indirectionOperandFlow(RawIndirectOperand nodeFrom, Node nodeTo) {
|
private predicate indirectionOperandFlow(RawIndirectOperand nodeFrom, Node nodeTo) {
|
||||||
|
nodeFrom != nodeTo and
|
||||||
|
(
|
||||||
// Reduce the indirection count by 1 if we're passing through a `LoadInstruction`.
|
// Reduce the indirection count by 1 if we're passing through a `LoadInstruction`.
|
||||||
exists(int ind, LoadInstruction load |
|
exists(int ind, LoadInstruction load |
|
||||||
hasOperandAndIndex(nodeFrom, load.getSourceAddressOperand(), ind) and
|
hasOperandAndIndex(nodeFrom, load.getSourceAddressOperand(), ind) and
|
||||||
@@ -1621,6 +1680,7 @@ private module Cached {
|
|||||||
pragma[only_bind_into](indirectionIndex)) and
|
pragma[only_bind_into](indirectionIndex)) and
|
||||||
hasInstructionAndIndex(nodeTo, pointerArith, pragma[only_bind_into](indirectionIndex))
|
hasInstructionAndIndex(nodeTo, pointerArith, pragma[only_bind_into](indirectionIndex))
|
||||||
)
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1645,6 +1705,7 @@ private module Cached {
|
|||||||
private predicate indirectionInstructionFlow(
|
private predicate indirectionInstructionFlow(
|
||||||
RawIndirectInstruction nodeFrom, IndirectOperand nodeTo
|
RawIndirectInstruction nodeFrom, IndirectOperand nodeTo
|
||||||
) {
|
) {
|
||||||
|
nodeFrom != nodeTo and
|
||||||
// If there's flow from an instruction to an operand, then there's also flow from the
|
// If there's flow from an instruction to an operand, then there's also flow from the
|
||||||
// indirect instruction to the indirect operand.
|
// indirect instruction to the indirect operand.
|
||||||
exists(Operand operand, Instruction instr, int indirectionIndex |
|
exists(Operand operand, Instruction instr, int indirectionIndex |
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ private import implementations.Accept
|
|||||||
private import implementations.Poll
|
private import implementations.Poll
|
||||||
private import implementations.Select
|
private import implementations.Select
|
||||||
private import implementations.MySql
|
private import implementations.MySql
|
||||||
|
private import implementations.ODBC
|
||||||
private import implementations.SqLite3
|
private import implementations.SqLite3
|
||||||
private import implementations.PostgreSql
|
private import implementations.PostgreSql
|
||||||
private import implementations.System
|
private import implementations.System
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import semmle.code.cpp.models.interfaces.Allocation
|
import semmle.code.cpp.models.interfaces.Allocation
|
||||||
|
import semmle.code.cpp.models.interfaces.Taint
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An allocation function (such as `malloc`) that has an argument for the size
|
* An allocation function (such as `malloc`) that has an argument for the size
|
||||||
@@ -121,7 +122,7 @@ private class CallocAllocationFunction extends AllocationFunction {
|
|||||||
* An allocation function (such as `realloc`) that has an argument for the size
|
* An allocation function (such as `realloc`) that has an argument for the size
|
||||||
* in bytes, and an argument for an existing pointer that is to be reallocated.
|
* in bytes, and an argument for an existing pointer that is to be reallocated.
|
||||||
*/
|
*/
|
||||||
private class ReallocAllocationFunction extends AllocationFunction {
|
private class ReallocAllocationFunction extends AllocationFunction, TaintFunction {
|
||||||
int sizeArg;
|
int sizeArg;
|
||||||
int reallocArg;
|
int reallocArg;
|
||||||
|
|
||||||
@@ -151,6 +152,10 @@ private class ReallocAllocationFunction extends AllocationFunction {
|
|||||||
override int getSizeArg() { result = sizeArg }
|
override int getSizeArg() { result = sizeArg }
|
||||||
|
|
||||||
override int getReallocPtrArg() { result = reallocArg }
|
override int getReallocPtrArg() { result = reallocArg }
|
||||||
|
|
||||||
|
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||||
|
input.isParameterDeref(this.getReallocPtrArg()) and output.isReturnValueDeref()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ private class Getaddrinfo extends TaintFunction, ArrayFunction, RemoteFlowSource
|
|||||||
override predicate hasArrayWithNullTerminator(int bufParam) { bufParam in [0, 1] }
|
override predicate hasArrayWithNullTerminator(int bufParam) { bufParam in [0, 1] }
|
||||||
|
|
||||||
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
|
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
|
||||||
output.isParameterDeref(3) and
|
output.isParameterDeref(3, 2) and
|
||||||
description = "address returned by " + this.getName()
|
description = "address returned by " + this.getName()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,18 +9,17 @@ import semmle.code.cpp.models.interfaces.DataFlow
|
|||||||
import semmle.code.cpp.models.interfaces.Alias
|
import semmle.code.cpp.models.interfaces.Alias
|
||||||
import semmle.code.cpp.models.interfaces.SideEffect
|
import semmle.code.cpp.models.interfaces.SideEffect
|
||||||
|
|
||||||
/**
|
private class MemsetFunctionModel extends ArrayFunction, DataFlowFunction, AliasFunction,
|
||||||
* The standard function `memset` and its assorted variants
|
|
||||||
*/
|
|
||||||
private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunction,
|
|
||||||
SideEffectFunction
|
SideEffectFunction
|
||||||
{
|
{
|
||||||
MemsetFunction() {
|
MemsetFunctionModel() {
|
||||||
this.hasGlobalOrStdOrBslName("memset")
|
this.hasGlobalOrStdOrBslName("memset")
|
||||||
or
|
or
|
||||||
this.hasGlobalOrStdName("wmemset")
|
this.hasGlobalOrStdName("wmemset")
|
||||||
or
|
or
|
||||||
this.hasGlobalName([bzero(), "__builtin_memset", "__builtin_memset_chk"])
|
this.hasGlobalName([
|
||||||
|
bzero(), "__builtin_memset", "__builtin_memset_chk", "RtlZeroMemory", "RtlSecureZeroMemory"
|
||||||
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
|
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
|
||||||
@@ -60,3 +59,8 @@ private class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunct
|
|||||||
}
|
}
|
||||||
|
|
||||||
private string bzero() { result = ["bzero", "explicit_bzero"] }
|
private string bzero() { result = ["bzero", "explicit_bzero"] }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The standard function `memset` and its assorted variants
|
||||||
|
*/
|
||||||
|
class MemsetFunction extends Function instanceof MemsetFunctionModel { }
|
||||||
|
|||||||
28
cpp/ql/lib/semmle/code/cpp/models/implementations/ODBC.qll
Normal file
28
cpp/ql/lib/semmle/code/cpp/models/implementations/ODBC.qll
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Provides implementation classes modeling the ODBC C/C++ API.
|
||||||
|
* See `semmle.code.cpp.models.Models` for usage information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private import semmle.code.cpp.models.interfaces.Sql
|
||||||
|
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `SQLExecDirect`, and `SQLPrepare` from the ODBC C/C++ API:
|
||||||
|
* https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlexecdirect-function?view=sql-server-ver16
|
||||||
|
* https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlprepare-function?view=sql-server-ver16
|
||||||
|
*
|
||||||
|
* Note, `SQLExecute` is not included because it operates on a SQLHSTMT type, not a string.
|
||||||
|
* The SQLHSTMT parameter for `SQLExecute` is set through a `SQLPrepare`, which is modeled.
|
||||||
|
* The other source of input to a `SQLExecute` is via a `SQLBindParameter`, which sanitizes user input,
|
||||||
|
* and would be considered a barrier to SQL injection.
|
||||||
|
*/
|
||||||
|
private class ODBCExecutionFunction extends SqlExecutionFunction {
|
||||||
|
ODBCExecutionFunction() { this.hasGlobalName(["SQLExecDirect", "SQLPrepare"]) }
|
||||||
|
|
||||||
|
override predicate hasSqlArgument(FunctionInput input) { input.isParameterDeref(1) }
|
||||||
|
}
|
||||||
|
// NOTE: no need to define a barrier explicitly.
|
||||||
|
// `SQLBindParameter` is the typical means for sanitizing user input.
|
||||||
|
// https://learn.microsoft.com/en-us/sql/odbc/reference/syntax/sqlbindparameter-function?view=sql-server-ver16
|
||||||
|
// First a query is establisehed via `SQLPrepare`, then parameters are bound via `SQLBindParameter`, before
|
||||||
|
// the query is executed via `SQLExecute`. We are not modeling SQLExecute, so we do not need to model SQLBindParameter.
|
||||||
@@ -147,19 +147,32 @@ private class SnprintfImpl extends Snprintf {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The Microsoft `StringCchPrintf` function and variants.
|
* The Microsoft `StringCchPrintf` function and variants.
|
||||||
|
* See: https://learn.microsoft.com/en-us/windows/win32/api/strsafe/
|
||||||
|
* and
|
||||||
|
* https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms860435(v=msdn.10)
|
||||||
*/
|
*/
|
||||||
private class StringCchPrintf extends FormattingFunction {
|
private class StringCchPrintf extends FormattingFunction {
|
||||||
StringCchPrintf() {
|
StringCchPrintf() {
|
||||||
this instanceof TopLevelFunction and
|
this instanceof TopLevelFunction and
|
||||||
this.hasGlobalName([
|
exists(string baseName |
|
||||||
"StringCchPrintf", "StringCchPrintfEx", "StringCchPrintf_l", "StringCchPrintf_lEx",
|
baseName in [
|
||||||
"StringCbPrintf", "StringCbPrintfEx", "StringCbPrintf_l", "StringCbPrintf_lEx"
|
"StringCchPrintf", //StringCchPrintf(pszDest, cchDest, pszFormat, …)
|
||||||
]) and
|
"StringCchPrintfEx", //StringCchPrintfEx(pszDest,cchDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, ...);
|
||||||
|
"StringCchPrintf_l", //StringCchPrintf_l(pszDest, cbDest, pszFormat, locale, …)
|
||||||
|
"StringCchPrintf_lEx", //StringCchPrintf_lEx(pszDest, cchDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, locale, …)
|
||||||
|
"StringCbPrintf", //StringCbPrintf(pszDest, cbDest, pszFormat, …)
|
||||||
|
"StringCbPrintfEx", //StringCbPrintfEx(pszDest, cbDest, ppszDestEnd, pcbRemaining, dwFlags, pszFormat, …)
|
||||||
|
"StringCbPrintf_l", //StringCbPrintf_l(pszDest, cbDest, pszFormat, locale, …)
|
||||||
|
"StringCbPrintf_lEx" //StringCbPrintf_lEx(pszDest, cbDest, ppszDestEnd, pcbRemaining, dwFlags, pszFormat, locale, …)
|
||||||
|
]
|
||||||
|
|
|
||||||
|
this.hasGlobalName(baseName + ["", "A", "W"])
|
||||||
|
) and
|
||||||
not exists(this.getDefinition().getFile().getRelativePath())
|
not exists(this.getDefinition().getFile().getRelativePath())
|
||||||
}
|
}
|
||||||
|
|
||||||
override int getFormatParameterIndex() {
|
override int getFormatParameterIndex() {
|
||||||
if this.getName().matches("%Ex") then result = 5 else result = 2
|
if this.getName().matches("%Ex" + ["", "A", "W"]) then result = 5 else result = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = false }
|
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = false }
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ private class Send extends AliasFunction, ArrayFunction, SideEffectFunction, Rem
|
|||||||
override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 1 and result = 2 }
|
override ParameterIndex getParameterSizeIndex(ParameterIndex i) { i = 1 and result = 2 }
|
||||||
|
|
||||||
override predicate hasRemoteFlowSink(FunctionInput input, string description) {
|
override predicate hasRemoteFlowSink(FunctionInput input, string description) {
|
||||||
input.isParameterDeref(1) and description = "buffer sent by " + this.getName()
|
input.isParameterDeref(1, 1) and description = "buffer sent by " + this.getName()
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate hasSocketInput(FunctionInput input) { input.isParameter(0) }
|
override predicate hasSocketInput(FunctionInput input) { input.isParameter(0) }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import semmle.code.cpp.Parameter
|
|||||||
|
|
||||||
private newtype TFunctionInput =
|
private newtype TFunctionInput =
|
||||||
TInParameter(ParameterIndex i) or
|
TInParameter(ParameterIndex i) or
|
||||||
TInParameterDeref(ParameterIndex i) or
|
TInParameterDeref(ParameterIndex i, int indirectionIndex) { indirectionIndex = [1, 2] } or
|
||||||
TInQualifierObject() or
|
TInQualifierObject() or
|
||||||
TInQualifierAddress() or
|
TInQualifierAddress() or
|
||||||
TInReturnValueDeref()
|
TInReturnValueDeref()
|
||||||
@@ -245,15 +245,18 @@ class InParameter extends FunctionInput, TInParameter {
|
|||||||
*/
|
*/
|
||||||
class InParameterDeref extends FunctionInput, TInParameterDeref {
|
class InParameterDeref extends FunctionInput, TInParameterDeref {
|
||||||
ParameterIndex index;
|
ParameterIndex index;
|
||||||
|
int indirectionIndex;
|
||||||
|
|
||||||
InParameterDeref() { this = TInParameterDeref(index) }
|
InParameterDeref() { this = TInParameterDeref(index, indirectionIndex) }
|
||||||
|
|
||||||
override string toString() { result = "InParameterDeref " + index.toString() }
|
override string toString() { result = "InParameterDeref " + index.toString() }
|
||||||
|
|
||||||
/** Gets the zero-based index of the parameter. */
|
/** Gets the zero-based index of the parameter. */
|
||||||
ParameterIndex getIndex() { result = index }
|
ParameterIndex getIndex() { result = index }
|
||||||
|
|
||||||
override predicate isParameterDeref(ParameterIndex i) { i = index }
|
override predicate isParameterDeref(ParameterIndex i, int indirection) {
|
||||||
|
i = index and indirectionIndex = indirection
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -321,10 +324,10 @@ class InReturnValueDeref extends FunctionInput, TInReturnValueDeref {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private newtype TFunctionOutput =
|
private newtype TFunctionOutput =
|
||||||
TOutParameterDeref(ParameterIndex i) or
|
TOutParameterDeref(ParameterIndex i, int indirectionIndex) { indirectionIndex = [1, 2] } or
|
||||||
TOutQualifierObject() or
|
TOutQualifierObject() or
|
||||||
TOutReturnValue() or
|
TOutReturnValue() or
|
||||||
TOutReturnValueDeref()
|
TOutReturnValueDeref(int indirections) { indirections = [1, 2] }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An output from a function. This can be:
|
* An output from a function. This can be:
|
||||||
@@ -498,17 +501,16 @@ class FunctionOutput extends TFunctionOutput {
|
|||||||
*/
|
*/
|
||||||
class OutParameterDeref extends FunctionOutput, TOutParameterDeref {
|
class OutParameterDeref extends FunctionOutput, TOutParameterDeref {
|
||||||
ParameterIndex index;
|
ParameterIndex index;
|
||||||
|
int indirectionIndex;
|
||||||
|
|
||||||
OutParameterDeref() { this = TOutParameterDeref(index) }
|
OutParameterDeref() { this = TOutParameterDeref(index, indirectionIndex) }
|
||||||
|
|
||||||
override string toString() { result = "OutParameterDeref " + index.toString() }
|
override string toString() { result = "OutParameterDeref " + index.toString() }
|
||||||
|
|
||||||
ParameterIndex getIndex() { result = index }
|
ParameterIndex getIndex() { result = index }
|
||||||
|
|
||||||
override predicate isParameterDeref(ParameterIndex i) { i = index }
|
|
||||||
|
|
||||||
override predicate isParameterDeref(ParameterIndex i, int ind) {
|
override predicate isParameterDeref(ParameterIndex i, int ind) {
|
||||||
this.isParameterDeref(i) and ind = 1
|
i = index and ind = indirectionIndex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,4 +574,8 @@ class OutReturnValueDeref extends FunctionOutput, TOutReturnValueDeref {
|
|||||||
override string toString() { result = "OutReturnValueDeref" }
|
override string toString() { result = "OutReturnValueDeref" }
|
||||||
|
|
||||||
override predicate isReturnValueDeref() { any() }
|
override predicate isReturnValueDeref() { any() }
|
||||||
|
|
||||||
|
override predicate isReturnValueDeref(int indirectionIndex) {
|
||||||
|
this = TOutReturnValueDeref(indirectionIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,7 @@ private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
|||||||
* `upper` is true, and can be traced back to a guard represented by `reason`.
|
* `upper` is true, and can be traced back to a guard represented by `reason`.
|
||||||
*/
|
*/
|
||||||
predicate bounded(Expr e, Bound b, float delta, boolean upper, Reason reason) {
|
predicate bounded(Expr e, Bound b, float delta, boolean upper, Reason reason) {
|
||||||
exists(SemanticExprConfig::Expr semExpr |
|
exists(SemanticExprConfig::Expr semExpr | semExpr.getUnconvertedResultExpression() = e |
|
||||||
semExpr.getUnconverted().getUnconvertedResultExpression() = e
|
|
||||||
|
|
|
||||||
semBounded(semExpr, b, delta, upper, reason)
|
semBounded(semExpr, b, delta, upper, reason)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -30,9 +28,7 @@ predicate bounded(Expr e, Bound b, float delta, boolean upper, Reason reason) {
|
|||||||
* The `Expr` may be a conversion.
|
* The `Expr` may be a conversion.
|
||||||
*/
|
*/
|
||||||
predicate convertedBounded(Expr e, Bound b, float delta, boolean upper, Reason reason) {
|
predicate convertedBounded(Expr e, Bound b, float delta, boolean upper, Reason reason) {
|
||||||
exists(SemanticExprConfig::Expr semExpr |
|
exists(SemanticExprConfig::Expr semExpr | semExpr.getConvertedResultExpression() = e |
|
||||||
semExpr.getConverted().getConvertedResultExpression() = e
|
|
||||||
|
|
|
||||||
semBounded(semExpr, b, delta, upper, reason)
|
semBounded(semExpr, b, delta, upper, reason)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ predicate exprMightOverflowNegatively(Expr expr) {
|
|||||||
lowerBound(expr) < exprMinVal(expr)
|
lowerBound(expr) < exprMinVal(expr)
|
||||||
or
|
or
|
||||||
exists(SemanticExprConfig::Expr semExpr |
|
exists(SemanticExprConfig::Expr semExpr |
|
||||||
semExpr.getUnconverted().getAst() = expr and
|
semExpr.getAst() = expr and
|
||||||
ConstantStage::potentiallyOverflowingExpr(false, semExpr) and
|
ConstantStage::potentiallyOverflowingExpr(false, semExpr) and
|
||||||
not ConstantStage::initialBounded(semExpr, _, _, false, _, _, _)
|
not ConstantStage::initialBounded(semExpr, _, _, false, _, _, _)
|
||||||
)
|
)
|
||||||
@@ -126,7 +126,7 @@ predicate exprMightOverflowPositively(Expr expr) {
|
|||||||
upperBound(expr) > exprMaxVal(expr)
|
upperBound(expr) > exprMaxVal(expr)
|
||||||
or
|
or
|
||||||
exists(SemanticExprConfig::Expr semExpr |
|
exists(SemanticExprConfig::Expr semExpr |
|
||||||
semExpr.getUnconverted().getAst() = expr and
|
semExpr.getAst() = expr and
|
||||||
ConstantStage::potentiallyOverflowingExpr(true, semExpr) and
|
ConstantStage::potentiallyOverflowingExpr(true, semExpr) and
|
||||||
not ConstantStage::initialBounded(semExpr, _, _, true, _, _, _)
|
not ConstantStage::initialBounded(semExpr, _, _, true, _, _, _)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,9 +12,6 @@ class SemBasicBlock extends Specific::BasicBlock {
|
|||||||
/** Holds if this block (transitively) dominates `otherblock`. */
|
/** Holds if this block (transitively) dominates `otherblock`. */
|
||||||
final predicate bbDominates(SemBasicBlock otherBlock) { Specific::bbDominates(this, otherBlock) }
|
final predicate bbDominates(SemBasicBlock otherBlock) { Specific::bbDominates(this, otherBlock) }
|
||||||
|
|
||||||
/** Holds if this block has dominance information. */
|
|
||||||
final predicate hasDominanceInformation() { Specific::hasDominanceInformation(this) }
|
|
||||||
|
|
||||||
/** Gets an expression that is evaluated in this basic block. */
|
/** Gets an expression that is evaluated in this basic block. */
|
||||||
final SemExpr getAnExpr() { result.getBasicBlock() = this }
|
final SemExpr getAnExpr() { result.getBasicBlock() = this }
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
private import Semantic
|
private import Semantic
|
||||||
private import SemanticExprSpecific::SemanticExprConfig as Specific
|
private import SemanticExprSpecific::SemanticExprConfig as Specific
|
||||||
|
private import SemanticType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An language-neutral expression.
|
* An language-neutral expression.
|
||||||
@@ -241,8 +242,21 @@ class SemConvertExpr extends SemUnaryExpr {
|
|||||||
SemConvertExpr() { opcode instanceof Opcode::Convert }
|
SemConvertExpr() { opcode instanceof Opcode::Convert }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private import semmle.code.cpp.ir.IR as IR
|
||||||
|
|
||||||
|
/** A conversion instruction which is guaranteed to not overflow. */
|
||||||
|
private class SafeConversion extends IR::ConvertInstruction {
|
||||||
|
SafeConversion() {
|
||||||
|
exists(SemType tFrom, SemType tTo |
|
||||||
|
tFrom = getSemanticType(super.getUnary().getResultIRType()) and
|
||||||
|
tTo = getSemanticType(super.getResultIRType()) and
|
||||||
|
conversionCannotOverflow(tFrom, tTo)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class SemCopyValueExpr extends SemUnaryExpr {
|
class SemCopyValueExpr extends SemUnaryExpr {
|
||||||
SemCopyValueExpr() { opcode instanceof Opcode::CopyValue }
|
SemCopyValueExpr() { opcode instanceof Opcode::CopyValue or this instanceof SafeConversion }
|
||||||
}
|
}
|
||||||
|
|
||||||
class SemNegateExpr extends SemUnaryExpr {
|
class SemNegateExpr extends SemUnaryExpr {
|
||||||
|
|||||||
@@ -12,87 +12,10 @@ private import semmle.code.cpp.ir.ValueNumbering
|
|||||||
module SemanticExprConfig {
|
module SemanticExprConfig {
|
||||||
class Location = Cpp::Location;
|
class Location = Cpp::Location;
|
||||||
|
|
||||||
/** A `ConvertInstruction` or a `CopyValueInstruction`. */
|
|
||||||
private class Conversion extends IR::UnaryInstruction {
|
|
||||||
Conversion() {
|
|
||||||
this instanceof IR::CopyValueInstruction
|
|
||||||
or
|
|
||||||
this instanceof IR::ConvertInstruction
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Holds if this instruction converts a value of type `tFrom` to a value of type `tTo`. */
|
|
||||||
predicate converts(SemType tFrom, SemType tTo) {
|
|
||||||
tFrom = getSemanticType(this.getUnary().getResultIRType()) and
|
|
||||||
tTo = getSemanticType(this.getResultIRType())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a conversion-like instruction that consumes `op`, and
|
|
||||||
* which is guaranteed to not overflow.
|
|
||||||
*/
|
|
||||||
private IR::Instruction safeConversion(IR::Operand op) {
|
|
||||||
exists(Conversion conv, SemType tFrom, SemType tTo |
|
|
||||||
conv.converts(tFrom, tTo) and
|
|
||||||
conversionCannotOverflow(tFrom, tTo) and
|
|
||||||
conv.getUnaryOperand() = op and
|
|
||||||
result = conv
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Holds if `i1 = i2` or if `i2` is a safe conversion that consumes `i1`. */
|
|
||||||
private predicate idOrSafeConversion(IR::Instruction i1, IR::Instruction i2) {
|
|
||||||
not i1.getResultIRType() instanceof IR::IRVoidType and
|
|
||||||
(
|
|
||||||
i1 = i2
|
|
||||||
or
|
|
||||||
i2 = safeConversion(i1.getAUse()) and
|
|
||||||
i1.getBlock() = i2.getBlock()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
module Equiv = QlBuiltins::EquivalenceRelation<IR::Instruction, idOrSafeConversion/2>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The expressions on which we perform range analysis.
|
* The expressions on which we perform range analysis.
|
||||||
*/
|
*/
|
||||||
class Expr extends Equiv::EquivalenceClass {
|
class Expr = IR::Instruction;
|
||||||
/** Gets the n'th instruction in this equivalence class. */
|
|
||||||
private IR::Instruction getInstruction(int n) {
|
|
||||||
result =
|
|
||||||
rank[n + 1](IR::Instruction instr, int i, IR::IRBlock block |
|
|
||||||
this = Equiv::getEquivalenceClass(instr) and block.getInstruction(i) = instr
|
|
||||||
|
|
|
||||||
instr order by i
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets a textual representation of this element. */
|
|
||||||
string toString() { result = this.getUnconverted().toString() }
|
|
||||||
|
|
||||||
/** Gets the basic block of this expression. */
|
|
||||||
IR::IRBlock getBlock() { result = this.getUnconverted().getBlock() }
|
|
||||||
|
|
||||||
/** Gets the unconverted instruction associated with this expression. */
|
|
||||||
IR::Instruction getUnconverted() { result = this.getInstruction(0) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the final instruction associated with this expression. This
|
|
||||||
* represents the result after applying all the safe conversions.
|
|
||||||
*/
|
|
||||||
IR::Instruction getConverted() {
|
|
||||||
exists(int n |
|
|
||||||
result = this.getInstruction(n) and
|
|
||||||
not exists(this.getInstruction(n + 1))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets the type of the result produced by this instruction. */
|
|
||||||
IR::IRType getResultIRType() { result = this.getConverted().getResultIRType() }
|
|
||||||
|
|
||||||
/** Gets the location of the source code for this expression. */
|
|
||||||
Location getLocation() { result = this.getUnconverted().getLocation() }
|
|
||||||
}
|
|
||||||
|
|
||||||
SemBasicBlock getExprBasicBlock(Expr e) { result = getSemanticBasicBlock(e.getBlock()) }
|
SemBasicBlock getExprBasicBlock(Expr e) { result = getSemanticBasicBlock(e.getBlock()) }
|
||||||
|
|
||||||
@@ -139,12 +62,12 @@ module SemanticExprConfig {
|
|||||||
|
|
||||||
predicate stringLiteral(Expr expr, SemType type, string value) {
|
predicate stringLiteral(Expr expr, SemType type, string value) {
|
||||||
anyConstantExpr(expr, type, value) and
|
anyConstantExpr(expr, type, value) and
|
||||||
expr.getUnconverted() instanceof IR::StringConstantInstruction
|
expr instanceof IR::StringConstantInstruction
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate binaryExpr(Expr expr, Opcode opcode, SemType type, Expr leftOperand, Expr rightOperand) {
|
predicate binaryExpr(Expr expr, Opcode opcode, SemType type, Expr leftOperand, Expr rightOperand) {
|
||||||
exists(IR::BinaryInstruction instr |
|
exists(IR::BinaryInstruction instr |
|
||||||
instr = expr.getUnconverted() and
|
instr = expr and
|
||||||
type = getSemanticType(instr.getResultIRType()) and
|
type = getSemanticType(instr.getResultIRType()) and
|
||||||
leftOperand = getSemanticExpr(instr.getLeft()) and
|
leftOperand = getSemanticExpr(instr.getLeft()) and
|
||||||
rightOperand = getSemanticExpr(instr.getRight()) and
|
rightOperand = getSemanticExpr(instr.getRight()) and
|
||||||
@@ -154,14 +77,14 @@ module SemanticExprConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
predicate unaryExpr(Expr expr, Opcode opcode, SemType type, Expr operand) {
|
predicate unaryExpr(Expr expr, Opcode opcode, SemType type, Expr operand) {
|
||||||
exists(IR::UnaryInstruction instr | instr = expr.getUnconverted() |
|
exists(IR::UnaryInstruction instr | instr = expr |
|
||||||
type = getSemanticType(instr.getResultIRType()) and
|
type = getSemanticType(instr.getResultIRType()) and
|
||||||
operand = getSemanticExpr(instr.getUnary()) and
|
operand = getSemanticExpr(instr.getUnary()) and
|
||||||
// REVIEW: Merge the two operand types.
|
// REVIEW: Merge the two operand types.
|
||||||
opcode.toString() = instr.getOpcode().toString()
|
opcode.toString() = instr.getOpcode().toString()
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(IR::StoreInstruction instr | instr = expr.getUnconverted() |
|
exists(IR::StoreInstruction instr | instr = expr |
|
||||||
type = getSemanticType(instr.getResultIRType()) and
|
type = getSemanticType(instr.getResultIRType()) and
|
||||||
operand = getSemanticExpr(instr.getSourceValue()) and
|
operand = getSemanticExpr(instr.getSourceValue()) and
|
||||||
opcode instanceof Opcode::Store
|
opcode instanceof Opcode::Store
|
||||||
@@ -170,13 +93,13 @@ module SemanticExprConfig {
|
|||||||
|
|
||||||
predicate nullaryExpr(Expr expr, Opcode opcode, SemType type) {
|
predicate nullaryExpr(Expr expr, Opcode opcode, SemType type) {
|
||||||
exists(IR::LoadInstruction load |
|
exists(IR::LoadInstruction load |
|
||||||
load = expr.getUnconverted() and
|
load = expr and
|
||||||
type = getSemanticType(load.getResultIRType()) and
|
type = getSemanticType(load.getResultIRType()) and
|
||||||
opcode instanceof Opcode::Load
|
opcode instanceof Opcode::Load
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(IR::InitializeParameterInstruction init |
|
exists(IR::InitializeParameterInstruction init |
|
||||||
init = expr.getUnconverted() and
|
init = expr and
|
||||||
type = getSemanticType(init.getResultIRType()) and
|
type = getSemanticType(init.getResultIRType()) and
|
||||||
opcode instanceof Opcode::InitializeParameter
|
opcode instanceof Opcode::InitializeParameter
|
||||||
)
|
)
|
||||||
@@ -199,8 +122,6 @@ module SemanticExprConfig {
|
|||||||
dominator.dominates(dominated)
|
dominator.dominates(dominated)
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate hasDominanceInformation(BasicBlock block) { any() }
|
|
||||||
|
|
||||||
private predicate id(Cpp::Locatable x, Cpp::Locatable y) { x = y }
|
private predicate id(Cpp::Locatable x, Cpp::Locatable y) { x = y }
|
||||||
|
|
||||||
private predicate idOf(Cpp::Locatable x, int y) = equivalenceRelation(id/2)(x, y)
|
private predicate idOf(Cpp::Locatable x, int y) = equivalenceRelation(id/2)(x, y)
|
||||||
@@ -209,17 +130,7 @@ module SemanticExprConfig {
|
|||||||
|
|
||||||
newtype TSsaVariable =
|
newtype TSsaVariable =
|
||||||
TSsaInstruction(IR::Instruction instr) { instr.hasMemoryResult() } or
|
TSsaInstruction(IR::Instruction instr) { instr.hasMemoryResult() } or
|
||||||
TSsaOperand(IR::Operand op) { op.isDefinitionInexact() } or
|
TSsaOperand(IR::Operand op) { op.isDefinitionInexact() }
|
||||||
TSsaPointerArithmeticGuard(ValueNumber instr) {
|
|
||||||
exists(Guard g, IR::Operand use |
|
|
||||||
use = instr.getAUse() and use.getIRType() instanceof IR::IRAddressType
|
|
||||||
|
|
|
||||||
g.comparesLt(use, _, _, _, _) or
|
|
||||||
g.comparesLt(_, use, _, _, _) or
|
|
||||||
g.comparesEq(use, _, _, _, _) or
|
|
||||||
g.comparesEq(_, use, _, _, _)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
class SsaVariable extends TSsaVariable {
|
class SsaVariable extends TSsaVariable {
|
||||||
string toString() { none() }
|
string toString() { none() }
|
||||||
@@ -228,8 +139,6 @@ module SemanticExprConfig {
|
|||||||
|
|
||||||
IR::Instruction asInstruction() { none() }
|
IR::Instruction asInstruction() { none() }
|
||||||
|
|
||||||
ValueNumber asPointerArithGuard() { none() }
|
|
||||||
|
|
||||||
IR::Operand asOperand() { none() }
|
IR::Operand asOperand() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,18 +154,6 @@ module SemanticExprConfig {
|
|||||||
final override IR::Instruction asInstruction() { result = instr }
|
final override IR::Instruction asInstruction() { result = instr }
|
||||||
}
|
}
|
||||||
|
|
||||||
class SsaPointerArithmeticGuard extends SsaVariable, TSsaPointerArithmeticGuard {
|
|
||||||
ValueNumber vn;
|
|
||||||
|
|
||||||
SsaPointerArithmeticGuard() { this = TSsaPointerArithmeticGuard(vn) }
|
|
||||||
|
|
||||||
final override string toString() { result = vn.toString() }
|
|
||||||
|
|
||||||
final override Location getLocation() { result = vn.getLocation() }
|
|
||||||
|
|
||||||
final override ValueNumber asPointerArithGuard() { result = vn }
|
|
||||||
}
|
|
||||||
|
|
||||||
class SsaOperand extends SsaVariable, TSsaOperand {
|
class SsaOperand extends SsaVariable, TSsaOperand {
|
||||||
IR::Operand op;
|
IR::Operand op;
|
||||||
|
|
||||||
@@ -289,11 +186,7 @@ module SemanticExprConfig {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr getAUse(SsaVariable v) {
|
Expr getAUse(SsaVariable v) { result.(IR::LoadInstruction).getSourceValue() = v.asInstruction() }
|
||||||
result.getUnconverted().(IR::LoadInstruction).getSourceValue() = v.asInstruction()
|
|
||||||
or
|
|
||||||
result.getUnconverted() = v.asPointerArithGuard().getAnInstruction()
|
|
||||||
}
|
|
||||||
|
|
||||||
SemType getSsaVariableType(SsaVariable v) {
|
SemType getSsaVariableType(SsaVariable v) {
|
||||||
result = getSemanticType(v.asInstruction().getResultIRType())
|
result = getSemanticType(v.asInstruction().getResultIRType())
|
||||||
@@ -332,10 +225,7 @@ module SemanticExprConfig {
|
|||||||
final override Location getLocation() { result = block.getLocation() }
|
final override Location getLocation() { result = block.getLocation() }
|
||||||
|
|
||||||
final override predicate hasRead(SsaVariable v) {
|
final override predicate hasRead(SsaVariable v) {
|
||||||
exists(IR::Operand operand |
|
exists(IR::Operand operand | operand.getDef() = v.asInstruction() |
|
||||||
operand.getDef() = v.asInstruction() or
|
|
||||||
operand.getDef() = v.asPointerArithGuard().getAnInstruction()
|
|
||||||
|
|
|
||||||
not operand instanceof IR::PhiInputOperand and
|
not operand instanceof IR::PhiInputOperand and
|
||||||
operand.getUse().getBlock() = block
|
operand.getUse().getBlock() = block
|
||||||
)
|
)
|
||||||
@@ -353,10 +243,7 @@ module SemanticExprConfig {
|
|||||||
final override Location getLocation() { result = succ.getLocation() }
|
final override Location getLocation() { result = succ.getLocation() }
|
||||||
|
|
||||||
final override predicate hasRead(SsaVariable v) {
|
final override predicate hasRead(SsaVariable v) {
|
||||||
exists(IR::PhiInputOperand operand |
|
exists(IR::PhiInputOperand operand | operand.getDef() = v.asInstruction() |
|
||||||
operand.getDef() = v.asInstruction() or
|
|
||||||
operand.getDef() = v.asPointerArithGuard().getAnInstruction()
|
|
||||||
|
|
|
||||||
operand.getPredecessorBlock() = pred and
|
operand.getPredecessorBlock() = pred and
|
||||||
operand.getUse().getBlock() = succ
|
operand.getUse().getBlock() = succ
|
||||||
)
|
)
|
||||||
@@ -433,7 +320,7 @@ module SemanticExprConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the expression associated with `instr`. */
|
/** Gets the expression associated with `instr`. */
|
||||||
SemExpr getSemanticExpr(IR::Instruction instr) { result = Equiv::getEquivalenceClass(instr) }
|
SemExpr getSemanticExpr(IR::Instruction instr) { result = instr }
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate getSemanticExpr = SemanticExprConfig::getSemanticExpr/1;
|
predicate getSemanticExpr = SemanticExprConfig::getSemanticExpr/1;
|
||||||
|
|||||||
@@ -35,32 +35,4 @@ predicate semImplies_v2(SemGuard g1, boolean b1, SemGuard g2, boolean b2) {
|
|||||||
Specific::implies_v2(g1, b1, g2, b2)
|
Specific::implies_v2(g1, b1, g2, b2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `guard` directly controls the position `controlled` with the
|
|
||||||
* value `testIsTrue`.
|
|
||||||
*/
|
|
||||||
pragma[nomagic]
|
|
||||||
predicate semGuardDirectlyControlsSsaRead(
|
|
||||||
SemGuard guard, SemSsaReadPosition controlled, boolean testIsTrue
|
|
||||||
) {
|
|
||||||
guard.directlyControls(controlled.(SemSsaReadPositionBlock).getBlock(), testIsTrue)
|
|
||||||
or
|
|
||||||
exists(SemSsaReadPositionPhiInputEdge controlledEdge | controlledEdge = controlled |
|
|
||||||
guard.directlyControls(controlledEdge.getOrigBlock(), testIsTrue) or
|
|
||||||
guard.hasBranchEdge(controlledEdge.getOrigBlock(), controlledEdge.getPhiBlock(), testIsTrue)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
|
|
||||||
*/
|
|
||||||
predicate semGuardControlsSsaRead(SemGuard guard, SemSsaReadPosition controlled, boolean testIsTrue) {
|
|
||||||
semGuardDirectlyControlsSsaRead(guard, controlled, testIsTrue)
|
|
||||||
or
|
|
||||||
exists(SemGuard guard0, boolean testIsTrue0 |
|
|
||||||
semImplies_v2(guard0, testIsTrue0, guard, testIsTrue) and
|
|
||||||
semGuardControlsSsaRead(guard0, controlled, testIsTrue0)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
SemGuard semGetComparisonGuard(SemRelationalExpr e) { result = Specific::comparisonGuard(e) }
|
SemGuard semGetComparisonGuard(SemRelationalExpr e) { result = Specific::comparisonGuard(e) }
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ class SemSsaExplicitUpdate extends SemSsaVariable {
|
|||||||
SemSsaExplicitUpdate() { Specific::explicitUpdate(this, sourceExpr) }
|
SemSsaExplicitUpdate() { Specific::explicitUpdate(this, sourceExpr) }
|
||||||
|
|
||||||
final SemExpr getSourceExpr() { result = sourceExpr }
|
final SemExpr getSourceExpr() { result = sourceExpr }
|
||||||
|
|
||||||
|
final SemExpr getDefiningExpr() { result = sourceExpr }
|
||||||
}
|
}
|
||||||
|
|
||||||
class SemSsaPhiNode extends SemSsaVariable {
|
class SemSsaPhiNode extends SemSsaVariable {
|
||||||
@@ -61,36 +63,3 @@ class SemSsaReadPositionBlock extends SemSsaReadPosition {
|
|||||||
|
|
||||||
SemExpr getAnExpr() { result = this.getBlock().getAnExpr() }
|
SemExpr getAnExpr() { result = this.getBlock().getAnExpr() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `inp` is an input to `phi` along a back edge.
|
|
||||||
*/
|
|
||||||
predicate semBackEdge(SemSsaPhiNode phi, SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge) {
|
|
||||||
edge.phiInput(phi, inp) and
|
|
||||||
// Conservatively assume that every edge is a back edge if we don't have dominance information.
|
|
||||||
(
|
|
||||||
phi.getBasicBlock().bbDominates(edge.getOrigBlock()) or
|
|
||||||
irreducibleSccEdge(edge.getOrigBlock(), phi.getBasicBlock()) or
|
|
||||||
not edge.getOrigBlock().hasDominanceInformation()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the edge from b1 to b2 is part of a multiple-entry cycle in an irreducible control flow
|
|
||||||
* graph.
|
|
||||||
*
|
|
||||||
* An ireducible control flow graph is one where the usual dominance-based back edge detection does
|
|
||||||
* not work, because there is a cycle with multiple entry points, meaning there are
|
|
||||||
* mutually-reachable basic blocks where neither dominates the other. For such a graph, we first
|
|
||||||
* remove all detectable back-edges using the normal condition that the predecessor block is
|
|
||||||
* dominated by the successor block, then mark all edges in a cycle in the resulting graph as back
|
|
||||||
* edges.
|
|
||||||
*/
|
|
||||||
private predicate irreducibleSccEdge(SemBasicBlock b1, SemBasicBlock b2) {
|
|
||||||
trimmedEdge(b1, b2) and trimmedEdge+(b2, b1)
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate trimmedEdge(SemBasicBlock pred, SemBasicBlock succ) {
|
|
||||||
pred.getASuccessor() = succ and
|
|
||||||
not succ.bbDominates(pred)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,328 +0,0 @@
|
|||||||
/**
|
|
||||||
* Provides inferences of the form: `e` equals `b + v` modulo `m` where `e` is
|
|
||||||
* an expression, `b` is a `Bound` (typically zero or the value of an SSA
|
|
||||||
* variable), and `v` is an integer in the range `[0 .. m-1]`.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The main recursion has base cases in both `ssaModulus` (for guarded reads) and `semExprModulus`
|
|
||||||
* (for constant values). The most interesting recursive case is `phiModulusRankStep`, which
|
|
||||||
* handles phi inputs.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private import ModulusAnalysisSpecific::Private
|
|
||||||
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
|
|
||||||
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticLocation
|
|
||||||
private import ConstantAnalysis
|
|
||||||
private import RangeUtils
|
|
||||||
private import codeql.rangeanalysis.RangeAnalysis
|
|
||||||
private import RangeAnalysisImpl
|
|
||||||
|
|
||||||
module ModulusAnalysis<DeltaSig D, BoundSig<SemLocation, Sem, D> Bounds, UtilSig<Sem, D> U> {
|
|
||||||
pragma[nomagic]
|
|
||||||
private predicate valueFlowStepSsaEqFlowCond(
|
|
||||||
SemSsaReadPosition pos, SemSsaVariable v, SemExpr e, int delta
|
|
||||||
) {
|
|
||||||
exists(SemGuard guard, boolean testIsTrue |
|
|
||||||
guard = U::semEqFlowCond(v, e, D::fromInt(delta), true, testIsTrue) and
|
|
||||||
semGuardDirectlyControlsSsaRead(guard, pos, testIsTrue)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `e + delta` equals `v` at `pos`.
|
|
||||||
*/
|
|
||||||
pragma[nomagic]
|
|
||||||
private predicate valueFlowStepSsa(SemSsaVariable v, SemSsaReadPosition pos, SemExpr e, int delta) {
|
|
||||||
U::semSsaUpdateStep(v, e, D::fromInt(delta)) and pos.hasReadOfVar(v)
|
|
||||||
or
|
|
||||||
pos.hasReadOfVar(v) and
|
|
||||||
valueFlowStepSsaEqFlowCond(pos, v, e, delta)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `add` is the addition of `larg` and `rarg`, neither of which are
|
|
||||||
* `ConstantIntegerExpr`s.
|
|
||||||
*/
|
|
||||||
private predicate nonConstAddition(SemExpr add, SemExpr larg, SemExpr rarg) {
|
|
||||||
exists(SemAddExpr a | a = add |
|
|
||||||
larg = a.getLeftOperand() and
|
|
||||||
rarg = a.getRightOperand()
|
|
||||||
) and
|
|
||||||
not larg instanceof SemConstantIntegerExpr and
|
|
||||||
not rarg instanceof SemConstantIntegerExpr
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `sub` is the subtraction of `larg` and `rarg`, where `rarg` is not
|
|
||||||
* a `ConstantIntegerExpr`.
|
|
||||||
*/
|
|
||||||
private predicate nonConstSubtraction(SemExpr sub, SemExpr larg, SemExpr rarg) {
|
|
||||||
exists(SemSubExpr s | s = sub |
|
|
||||||
larg = s.getLeftOperand() and
|
|
||||||
rarg = s.getRightOperand()
|
|
||||||
) and
|
|
||||||
not rarg instanceof SemConstantIntegerExpr
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gets an expression that is the remainder modulo `mod` of `arg`. */
|
|
||||||
private SemExpr modExpr(SemExpr arg, int mod) {
|
|
||||||
exists(SemRemExpr rem |
|
|
||||||
result = rem and
|
|
||||||
arg = rem.getLeftOperand() and
|
|
||||||
rem.getRightOperand().(SemConstantIntegerExpr).getIntValue() = mod and
|
|
||||||
mod >= 2
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(SemConstantIntegerExpr c |
|
|
||||||
mod = 2.pow([1 .. 30]) and
|
|
||||||
c.getIntValue() = mod - 1 and
|
|
||||||
result.(SemBitAndExpr).hasOperands(arg, c)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a guard that tests whether `v` is congruent with `val` modulo `mod` on
|
|
||||||
* its `testIsTrue` branch.
|
|
||||||
*/
|
|
||||||
private SemGuard moduloCheck(SemSsaVariable v, int val, int mod, boolean testIsTrue) {
|
|
||||||
exists(SemExpr rem, SemConstantIntegerExpr c, int r, boolean polarity |
|
|
||||||
result.isEquality(rem, c, polarity) and
|
|
||||||
c.getIntValue() = r and
|
|
||||||
rem = modExpr(v.getAUse(), mod) and
|
|
||||||
(
|
|
||||||
testIsTrue = polarity and val = r
|
|
||||||
or
|
|
||||||
testIsTrue = polarity.booleanNot() and
|
|
||||||
mod = 2 and
|
|
||||||
val = 1 - r and
|
|
||||||
(r = 0 or r = 1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if a guard ensures that `v` at `pos` is congruent with `val` modulo `mod`.
|
|
||||||
*/
|
|
||||||
private predicate moduloGuardedRead(SemSsaVariable v, SemSsaReadPosition pos, int val, int mod) {
|
|
||||||
exists(SemGuard guard, boolean testIsTrue |
|
|
||||||
pos.hasReadOfVar(v) and
|
|
||||||
guard = moduloCheck(v, val, mod, testIsTrue) and
|
|
||||||
semGuardControlsSsaRead(guard, pos, testIsTrue)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Holds if `factor` is a power of 2 that divides `mask`. */
|
|
||||||
bindingset[mask]
|
|
||||||
private predicate andmaskFactor(int mask, int factor) {
|
|
||||||
mask % factor = 0 and
|
|
||||||
factor = 2.pow([1 .. 30])
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Holds if `e` is evenly divisible by `factor`. */
|
|
||||||
private predicate evenlyDivisibleExpr(SemExpr e, int factor) {
|
|
||||||
exists(SemConstantIntegerExpr c, int k | k = c.getIntValue() |
|
|
||||||
e.(SemMulExpr).getAnOperand() = c and factor = k.abs() and factor >= 2
|
|
||||||
or
|
|
||||||
e.(SemShiftLeftExpr).getRightOperand() = c and factor = 2.pow(k) and k > 0
|
|
||||||
or
|
|
||||||
e.(SemBitAndExpr).getAnOperand() = c and factor = max(int f | andmaskFactor(k, f))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the remainder of `val` modulo `mod`.
|
|
||||||
*
|
|
||||||
* For `mod = 0` the result equals `val` and for `mod > 1` the result is within
|
|
||||||
* the range `[0 .. mod-1]`.
|
|
||||||
*/
|
|
||||||
bindingset[val, mod]
|
|
||||||
private int remainder(int val, int mod) {
|
|
||||||
mod = 0 and result = val
|
|
||||||
or
|
|
||||||
mod > 1 and result = ((val % mod) + mod) % mod
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `inp` is an input to `phi` and equals `phi` modulo `mod` along `edge`.
|
|
||||||
*/
|
|
||||||
private predicate phiSelfModulus(
|
|
||||||
SemSsaPhiNode phi, SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge, int mod
|
|
||||||
) {
|
|
||||||
exists(Bounds::SemSsaBound phibound, int v, int m |
|
|
||||||
edge.phiInput(phi, inp) and
|
|
||||||
phibound.getAVariable() = phi and
|
|
||||||
ssaModulus(inp, edge, phibound, v, m) and
|
|
||||||
mod = m.gcd(v) and
|
|
||||||
mod != 1
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `b + val` modulo `mod` is a candidate congruence class for `phi`.
|
|
||||||
*/
|
|
||||||
private predicate phiModulusInit(SemSsaPhiNode phi, Bounds::SemBound b, int val, int mod) {
|
|
||||||
exists(SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge |
|
|
||||||
edge.phiInput(phi, inp) and
|
|
||||||
ssaModulus(inp, edge, b, val, mod)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if all inputs to `phi` numbered `1` to `rix` are equal to `b + val` modulo `mod`.
|
|
||||||
*/
|
|
||||||
pragma[nomagic]
|
|
||||||
private predicate phiModulusRankStep(
|
|
||||||
SemSsaPhiNode phi, Bounds::SemBound b, int val, int mod, int rix
|
|
||||||
) {
|
|
||||||
/*
|
|
||||||
* base case. If any phi input is equal to `b + val` modulo `mod`, that's a potential congruence
|
|
||||||
* class for the phi node.
|
|
||||||
*/
|
|
||||||
|
|
||||||
rix = 0 and
|
|
||||||
phiModulusInit(phi, b, val, mod)
|
|
||||||
or
|
|
||||||
exists(SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge, int v1, int m1 |
|
|
||||||
mod != 1 and
|
|
||||||
val = remainder(v1, mod)
|
|
||||||
|
|
|
||||||
/*
|
|
||||||
* Recursive case. If `inp` = `b + v2` mod `m2`, we combine that with the preceding potential
|
|
||||||
* congruence class `b + v1` mod `m1`. The result will be the congruence class of `v1` modulo
|
|
||||||
* the greatest common denominator of `m1`, `m2`, and `v1 - v2`.
|
|
||||||
*/
|
|
||||||
|
|
||||||
exists(int v2, int m2 |
|
|
||||||
rankedPhiInput(pragma[only_bind_out](phi), inp, edge, rix) and
|
|
||||||
phiModulusRankStep(phi, b, v1, m1, rix - 1) and
|
|
||||||
ssaModulus(inp, edge, b, v2, m2) and
|
|
||||||
mod = m1.gcd(m2).gcd(v1 - v2)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
/*
|
|
||||||
* Recursive case. If `inp` = `phi` mod `m2`, we combine that with the preceding potential
|
|
||||||
* congruence class `b + v1` mod `m1`. The result will be a congruence class modulo the greatest
|
|
||||||
* common denominator of `m1` and `m2`.
|
|
||||||
*/
|
|
||||||
|
|
||||||
exists(int m2 |
|
|
||||||
rankedPhiInput(phi, inp, edge, rix) and
|
|
||||||
phiModulusRankStep(phi, b, v1, m1, rix - 1) and
|
|
||||||
phiSelfModulus(phi, inp, edge, m2) and
|
|
||||||
mod = m1.gcd(m2)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `phi` is equal to `b + val` modulo `mod`.
|
|
||||||
*/
|
|
||||||
private predicate phiModulus(SemSsaPhiNode phi, Bounds::SemBound b, int val, int mod) {
|
|
||||||
exists(int r |
|
|
||||||
maxPhiInputRank(phi, r) and
|
|
||||||
phiModulusRankStep(phi, b, val, mod, r)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `v` at `pos` is equal to `b + val` modulo `mod`.
|
|
||||||
*/
|
|
||||||
private predicate ssaModulus(
|
|
||||||
SemSsaVariable v, SemSsaReadPosition pos, Bounds::SemBound b, int val, int mod
|
|
||||||
) {
|
|
||||||
phiModulus(v, b, val, mod) and pos.hasReadOfVar(v)
|
|
||||||
or
|
|
||||||
b.(Bounds::SemSsaBound).getAVariable() = v and pos.hasReadOfVar(v) and val = 0 and mod = 0
|
|
||||||
or
|
|
||||||
exists(SemExpr e, int val0, int delta |
|
|
||||||
semExprModulus(e, b, val0, mod) and
|
|
||||||
valueFlowStepSsa(v, pos, e, delta) and
|
|
||||||
val = remainder(val0 + delta, mod)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
moduloGuardedRead(v, pos, val, mod) and b instanceof Bounds::SemZeroBound
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `e` is equal to `b + val` modulo `mod`.
|
|
||||||
*
|
|
||||||
* There are two cases for the modulus:
|
|
||||||
* - `mod = 0`: The equality `e = b + val` is an ordinary equality.
|
|
||||||
* - `mod > 1`: `val` lies within the range `[0 .. mod-1]`.
|
|
||||||
*/
|
|
||||||
cached
|
|
||||||
predicate semExprModulus(SemExpr e, Bounds::SemBound b, int val, int mod) {
|
|
||||||
not ignoreExprModulus(e) and
|
|
||||||
(
|
|
||||||
e = b.getExpr(D::fromInt(val)) and mod = 0
|
|
||||||
or
|
|
||||||
evenlyDivisibleExpr(e, mod) and
|
|
||||||
val = 0 and
|
|
||||||
b instanceof Bounds::SemZeroBound
|
|
||||||
or
|
|
||||||
exists(SemSsaVariable v, SemSsaReadPositionBlock bb |
|
|
||||||
ssaModulus(v, bb, b, val, mod) and
|
|
||||||
e = v.getAUse() and
|
|
||||||
bb.getAnExpr() = e
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(SemExpr mid, int val0, int delta |
|
|
||||||
semExprModulus(mid, b, val0, mod) and
|
|
||||||
U::semValueFlowStep(e, mid, D::fromInt(delta)) and
|
|
||||||
val = remainder(val0 + delta, mod)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(SemConditionalExpr cond, int v1, int v2, int m1, int m2 |
|
|
||||||
cond = e and
|
|
||||||
condExprBranchModulus(cond, true, b, v1, m1) and
|
|
||||||
condExprBranchModulus(cond, false, b, v2, m2) and
|
|
||||||
mod = m1.gcd(m2).gcd(v1 - v2) and
|
|
||||||
mod != 1 and
|
|
||||||
val = remainder(v1, mod)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(Bounds::SemBound b1, Bounds::SemBound b2, int v1, int v2, int m1, int m2 |
|
|
||||||
addModulus(e, true, b1, v1, m1) and
|
|
||||||
addModulus(e, false, b2, v2, m2) and
|
|
||||||
mod = m1.gcd(m2) and
|
|
||||||
mod != 1 and
|
|
||||||
val = remainder(v1 + v2, mod)
|
|
||||||
|
|
|
||||||
b = b1 and b2 instanceof Bounds::SemZeroBound
|
|
||||||
or
|
|
||||||
b = b2 and b1 instanceof Bounds::SemZeroBound
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(int v1, int v2, int m1, int m2 |
|
|
||||||
subModulus(e, true, b, v1, m1) and
|
|
||||||
subModulus(e, false, any(Bounds::SemZeroBound zb), v2, m2) and
|
|
||||||
mod = m1.gcd(m2) and
|
|
||||||
mod != 1 and
|
|
||||||
val = remainder(v1 - v2, mod)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate condExprBranchModulus(
|
|
||||||
SemConditionalExpr cond, boolean branch, Bounds::SemBound b, int val, int mod
|
|
||||||
) {
|
|
||||||
semExprModulus(cond.getBranchExpr(branch), b, val, mod)
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate addModulus(SemExpr add, boolean isLeft, Bounds::SemBound b, int val, int mod) {
|
|
||||||
exists(SemExpr larg, SemExpr rarg | nonConstAddition(add, larg, rarg) |
|
|
||||||
semExprModulus(larg, b, val, mod) and isLeft = true
|
|
||||||
or
|
|
||||||
semExprModulus(rarg, b, val, mod) and isLeft = false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate subModulus(SemExpr sub, boolean isLeft, Bounds::SemBound b, int val, int mod) {
|
|
||||||
exists(SemExpr larg, SemExpr rarg | nonConstSubtraction(sub, larg, rarg) |
|
|
||||||
semExprModulus(larg, b, val, mod) and isLeft = true
|
|
||||||
or
|
|
||||||
semExprModulus(rarg, b, val, mod) and isLeft = false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
/**
|
|
||||||
* C++-specific implementation of modulus analysis.
|
|
||||||
*/
|
|
||||||
module Private {
|
|
||||||
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
|
|
||||||
|
|
||||||
predicate ignoreExprModulus(SemExpr e) { none() }
|
|
||||||
}
|
|
||||||
@@ -8,14 +8,6 @@ private import RangeAnalysisImpl
|
|||||||
private import codeql.rangeanalysis.RangeAnalysis
|
private import codeql.rangeanalysis.RangeAnalysis
|
||||||
|
|
||||||
module CppLangImplConstant implements LangSig<Sem, FloatDelta> {
|
module CppLangImplConstant implements LangSig<Sem, FloatDelta> {
|
||||||
/**
|
|
||||||
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
|
|
||||||
*
|
|
||||||
* This predicate is to keep the results identical to the original Java implementation. It should be
|
|
||||||
* removed once we have the new implementation matching the old results exactly.
|
|
||||||
*/
|
|
||||||
predicate ignoreSsaReadCopy(SemExpr e) { none() }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ignore the bound on this expression.
|
* Ignore the bound on this expression.
|
||||||
*
|
*
|
||||||
@@ -24,40 +16,6 @@ module CppLangImplConstant implements LangSig<Sem, FloatDelta> {
|
|||||||
*/
|
*/
|
||||||
predicate ignoreExprBound(SemExpr e) { none() }
|
predicate ignoreExprBound(SemExpr e) { none() }
|
||||||
|
|
||||||
/**
|
|
||||||
* Ignore any inferred zero lower bound on this expression.
|
|
||||||
*
|
|
||||||
* This predicate is to keep the results identical to the original Java implementation. It should be
|
|
||||||
* removed once we have the new implementation matching the old results exactly.
|
|
||||||
*/
|
|
||||||
predicate ignoreZeroLowerBound(SemExpr e) { none() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
|
|
||||||
*
|
|
||||||
* This predicate is to keep the results identical to the original Java implementation. It should be
|
|
||||||
* removed once we have the new implementation matching the old results exactly.
|
|
||||||
*/
|
|
||||||
predicate ignoreSsaReadArithmeticExpr(SemExpr e) { none() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the specified variable should be excluded from the result of `ssaRead()`.
|
|
||||||
*
|
|
||||||
* This predicate is to keep the results identical to the original Java implementation. It should be
|
|
||||||
* removed once we have the new implementation matching the old results exactly.
|
|
||||||
*/
|
|
||||||
predicate ignoreSsaReadAssignment(SemSsaVariable v) { none() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds additional results to `ssaRead()` that are specific to Java.
|
|
||||||
*
|
|
||||||
* This predicate handles propagation of offsets for post-increment and post-decrement expressions
|
|
||||||
* in exactly the same way as the old Java implementation. Once the new implementation matches the
|
|
||||||
* old one, we should remove this predicate and propagate deltas for all similar patterns, whether
|
|
||||||
* or not they come from a post-increment/decrement expression.
|
|
||||||
*/
|
|
||||||
SemExpr specificSsaRead(SemSsaVariable v, float delta) { none() }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `e >= bound` (if `upper = false`) or `e <= bound` (if `upper = true`).
|
* Holds if `e >= bound` (if `upper = false`) or `e <= bound` (if `upper = true`).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -52,20 +52,32 @@ module Sem implements Semantic {
|
|||||||
|
|
||||||
class NegateExpr = SemNegateExpr;
|
class NegateExpr = SemNegateExpr;
|
||||||
|
|
||||||
class AddOneExpr = SemAddOneExpr;
|
class PreIncExpr = SemAddOneExpr;
|
||||||
|
|
||||||
class SubOneExpr = SemSubOneExpr;
|
class PreDecExpr = SemSubOneExpr;
|
||||||
|
|
||||||
|
class PostIncExpr extends SemUnaryExpr {
|
||||||
|
PostIncExpr() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
class PostDecExpr extends SemUnaryExpr {
|
||||||
|
PostDecExpr() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
class CopyValueExpr extends SemUnaryExpr {
|
||||||
|
CopyValueExpr() { this instanceof SemCopyValueExpr or this instanceof SemStoreExpr }
|
||||||
|
}
|
||||||
|
|
||||||
class ConditionalExpr = SemConditionalExpr;
|
class ConditionalExpr = SemConditionalExpr;
|
||||||
|
|
||||||
class BasicBlock = SemBasicBlock;
|
class BasicBlock = SemBasicBlock;
|
||||||
|
|
||||||
|
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
|
||||||
|
|
||||||
class Guard = SemGuard;
|
class Guard = SemGuard;
|
||||||
|
|
||||||
predicate implies_v2 = semImplies_v2/4;
|
predicate implies_v2 = semImplies_v2/4;
|
||||||
|
|
||||||
predicate guardDirectlyControlsSsaRead = semGuardDirectlyControlsSsaRead/3;
|
|
||||||
|
|
||||||
class Type = SemType;
|
class Type = SemType;
|
||||||
|
|
||||||
class IntegerType = SemIntegerType;
|
class IntegerType = SemIntegerType;
|
||||||
@@ -86,8 +98,6 @@ module Sem implements Semantic {
|
|||||||
|
|
||||||
class SsaReadPositionBlock = SemSsaReadPositionBlock;
|
class SsaReadPositionBlock = SemSsaReadPositionBlock;
|
||||||
|
|
||||||
predicate backEdge = semBackEdge/3;
|
|
||||||
|
|
||||||
predicate conversionCannotOverflow(Type fromType, Type toType) {
|
predicate conversionCannotOverflow(Type fromType, Type toType) {
|
||||||
SemanticType::conversionCannotOverflow(fromType, toType)
|
SemanticType::conversionCannotOverflow(fromType, toType)
|
||||||
}
|
}
|
||||||
@@ -116,7 +126,7 @@ module ConstantBounds implements BoundSig<SemLocation, Sem, FloatDelta> {
|
|||||||
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
|
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
|
||||||
|
|
||||||
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
|
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
|
||||||
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
|
SemSsaVariable getVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +144,7 @@ module RelativeBounds implements BoundSig<SemLocation, Sem, FloatDelta> {
|
|||||||
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
|
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
|
||||||
|
|
||||||
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
|
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
|
||||||
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
|
SemSsaVariable getVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,15 +160,15 @@ module AllBounds implements BoundSig<SemLocation, Sem, FloatDelta> {
|
|||||||
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
|
class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { }
|
||||||
|
|
||||||
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
|
class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound {
|
||||||
SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
|
SemSsaVariable getVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private module ModulusAnalysisInstantiated implements ModulusAnalysisSig<Sem> {
|
private module ModulusAnalysisInstantiated implements ModulusAnalysisSig<Sem> {
|
||||||
class ModBound = AllBounds::SemBound;
|
class ModBound = AllBounds::SemBound;
|
||||||
|
|
||||||
private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.ModulusAnalysis as MA
|
private import codeql.rangeanalysis.ModulusAnalysis as MA
|
||||||
import MA::ModulusAnalysis<FloatDelta, AllBounds, Util>
|
import MA::ModulusAnalysis<SemLocation, Sem, FloatDelta, AllBounds, Util>
|
||||||
}
|
}
|
||||||
|
|
||||||
module Util = RangeUtil<FloatDelta, CppLangImplConstant>;
|
module Util = RangeUtil<FloatDelta, CppLangImplConstant>;
|
||||||
|
|||||||
@@ -9,14 +9,6 @@ private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
|
|||||||
private import codeql.rangeanalysis.RangeAnalysis
|
private import codeql.rangeanalysis.RangeAnalysis
|
||||||
|
|
||||||
module CppLangImplRelative implements LangSig<Sem, FloatDelta> {
|
module CppLangImplRelative implements LangSig<Sem, FloatDelta> {
|
||||||
/**
|
|
||||||
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
|
|
||||||
*
|
|
||||||
* This predicate is to keep the results identical to the original Java implementation. It should be
|
|
||||||
* removed once we have the new implementation matching the old results exactly.
|
|
||||||
*/
|
|
||||||
predicate ignoreSsaReadCopy(SemExpr e) { none() }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ignore the bound on this expression.
|
* Ignore the bound on this expression.
|
||||||
*
|
*
|
||||||
@@ -56,40 +48,6 @@ module CppLangImplRelative implements LangSig<Sem, FloatDelta> {
|
|||||||
t instanceof SemFloatingPointType and lb = -(1.0 / 0.0) and ub = 1.0 / 0.0
|
t instanceof SemFloatingPointType and lb = -(1.0 / 0.0) and ub = 1.0 / 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Ignore any inferred zero lower bound on this expression.
|
|
||||||
*
|
|
||||||
* This predicate is to keep the results identical to the original Java implementation. It should be
|
|
||||||
* removed once we have the new implementation matching the old results exactly.
|
|
||||||
*/
|
|
||||||
predicate ignoreZeroLowerBound(SemExpr e) { none() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the specified expression should be excluded from the result of `ssaRead()`.
|
|
||||||
*
|
|
||||||
* This predicate is to keep the results identical to the original Java implementation. It should be
|
|
||||||
* removed once we have the new implementation matching the old results exactly.
|
|
||||||
*/
|
|
||||||
predicate ignoreSsaReadArithmeticExpr(SemExpr e) { none() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the specified variable should be excluded from the result of `ssaRead()`.
|
|
||||||
*
|
|
||||||
* This predicate is to keep the results identical to the original Java implementation. It should be
|
|
||||||
* removed once we have the new implementation matching the old results exactly.
|
|
||||||
*/
|
|
||||||
predicate ignoreSsaReadAssignment(SemSsaVariable v) { none() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds additional results to `ssaRead()` that are specific to Java.
|
|
||||||
*
|
|
||||||
* This predicate handles propagation of offsets for post-increment and post-decrement expressions
|
|
||||||
* in exactly the same way as the old Java implementation. Once the new implementation matches the
|
|
||||||
* old one, we should remove this predicate and propagate deltas for all similar patterns, whether
|
|
||||||
* or not they come from a post-increment/decrement expression.
|
|
||||||
*/
|
|
||||||
SemExpr specificSsaRead(SemSsaVariable v, float delta) { none() }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `e >= bound` (if `upper = false`) or `e <= bound` (if `upper = true`).
|
* Holds if `e >= bound` (if `upper = false`) or `e <= bound` (if `upper = true`).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -12,33 +12,27 @@ module RangeUtil<DeltaSig D, LangSig<Sem, D> Lang> implements UtilSig<Sem, D> {
|
|||||||
/**
|
/**
|
||||||
* Gets an expression that equals `v - d`.
|
* Gets an expression that equals `v - d`.
|
||||||
*/
|
*/
|
||||||
SemExpr semSsaRead(SemSsaVariable v, D::Delta delta) {
|
private SemExpr semSsaRead(SemSsaVariable v, D::Delta delta) {
|
||||||
// There are various language-specific extension points that can be removed once we no longer
|
// There are various language-specific extension points that can be removed once we no longer
|
||||||
// expect to match the original Java implementation's results exactly.
|
// expect to match the original Java implementation's results exactly.
|
||||||
result = v.getAUse() and delta = D::fromInt(0)
|
result = v.getAUse() and delta = D::fromInt(0)
|
||||||
or
|
or
|
||||||
exists(D::Delta d1, SemConstantIntegerExpr c |
|
exists(D::Delta d1, SemConstantIntegerExpr c |
|
||||||
result.(SemAddExpr).hasOperands(semSsaRead(v, d1), c) and
|
result.(SemAddExpr).hasOperands(semSsaRead(v, d1), c) and
|
||||||
delta = D::fromFloat(D::toFloat(d1) - c.getIntValue()) and
|
delta = D::fromFloat(D::toFloat(d1) - c.getIntValue())
|
||||||
not Lang::ignoreSsaReadArithmeticExpr(result)
|
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(SemSubExpr sub, D::Delta d1, SemConstantIntegerExpr c |
|
exists(SemSubExpr sub, D::Delta d1, SemConstantIntegerExpr c |
|
||||||
result = sub and
|
result = sub and
|
||||||
sub.getLeftOperand() = semSsaRead(v, d1) and
|
sub.getLeftOperand() = semSsaRead(v, d1) and
|
||||||
sub.getRightOperand() = c and
|
sub.getRightOperand() = c and
|
||||||
delta = D::fromFloat(D::toFloat(d1) + c.getIntValue()) and
|
delta = D::fromFloat(D::toFloat(d1) + c.getIntValue())
|
||||||
not Lang::ignoreSsaReadArithmeticExpr(result)
|
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
result = v.(SemSsaExplicitUpdate).getSourceExpr() and
|
result = v.(SemSsaExplicitUpdate).getSourceExpr() and
|
||||||
delta = D::fromFloat(0) and
|
delta = D::fromFloat(0)
|
||||||
not Lang::ignoreSsaReadAssignment(v)
|
|
||||||
or
|
or
|
||||||
result = Lang::specificSsaRead(v, delta)
|
result.(SemCopyValueExpr).getOperand() = semSsaRead(v, delta)
|
||||||
or
|
|
||||||
result.(SemCopyValueExpr).getOperand() = semSsaRead(v, delta) and
|
|
||||||
not Lang::ignoreSsaReadCopy(result)
|
|
||||||
or
|
or
|
||||||
result.(SemStoreExpr).getOperand() = semSsaRead(v, delta)
|
result.(SemStoreExpr).getOperand() = semSsaRead(v, delta)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ private import RangeUtils
|
|||||||
private import Sign
|
private import Sign
|
||||||
|
|
||||||
module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
|
module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
|
||||||
|
private import codeql.rangeanalysis.internal.RangeUtils::MakeUtils<Sem, D>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An SSA definition for which the analysis can compute the sign.
|
* An SSA definition for which the analysis can compute the sign.
|
||||||
*
|
*
|
||||||
@@ -292,17 +294,17 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
|
|||||||
) {
|
) {
|
||||||
exists(boolean testIsTrue, SemRelationalExpr comp |
|
exists(boolean testIsTrue, SemRelationalExpr comp |
|
||||||
pos.hasReadOfVar(v) and
|
pos.hasReadOfVar(v) and
|
||||||
semGuardControlsSsaRead(semGetComparisonGuard(comp), pos, testIsTrue) and
|
guardControlsSsaRead(semGetComparisonGuard(comp), pos, testIsTrue) and
|
||||||
not unknownSign(lowerbound)
|
not unknownSign(lowerbound)
|
||||||
|
|
|
|
||||||
testIsTrue = true and
|
testIsTrue = true and
|
||||||
comp.getLesserOperand() = lowerbound and
|
comp.getLesserOperand() = lowerbound and
|
||||||
comp.getGreaterOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
|
comp.getGreaterOperand() = ssaRead(v, D::fromInt(0)) and
|
||||||
(if comp.isStrict() then isStrict = true else isStrict = false)
|
(if comp.isStrict() then isStrict = true else isStrict = false)
|
||||||
or
|
or
|
||||||
testIsTrue = false and
|
testIsTrue = false and
|
||||||
comp.getGreaterOperand() = lowerbound and
|
comp.getGreaterOperand() = lowerbound and
|
||||||
comp.getLesserOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
|
comp.getLesserOperand() = ssaRead(v, D::fromInt(0)) and
|
||||||
(if comp.isStrict() then isStrict = false else isStrict = true)
|
(if comp.isStrict() then isStrict = false else isStrict = true)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -316,17 +318,17 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
|
|||||||
) {
|
) {
|
||||||
exists(boolean testIsTrue, SemRelationalExpr comp |
|
exists(boolean testIsTrue, SemRelationalExpr comp |
|
||||||
pos.hasReadOfVar(v) and
|
pos.hasReadOfVar(v) and
|
||||||
semGuardControlsSsaRead(semGetComparisonGuard(comp), pos, testIsTrue) and
|
guardControlsSsaRead(semGetComparisonGuard(comp), pos, testIsTrue) and
|
||||||
not unknownSign(upperbound)
|
not unknownSign(upperbound)
|
||||||
|
|
|
|
||||||
testIsTrue = true and
|
testIsTrue = true and
|
||||||
comp.getGreaterOperand() = upperbound and
|
comp.getGreaterOperand() = upperbound and
|
||||||
comp.getLesserOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
|
comp.getLesserOperand() = ssaRead(v, D::fromInt(0)) and
|
||||||
(if comp.isStrict() then isStrict = true else isStrict = false)
|
(if comp.isStrict() then isStrict = true else isStrict = false)
|
||||||
or
|
or
|
||||||
testIsTrue = false and
|
testIsTrue = false and
|
||||||
comp.getLesserOperand() = upperbound and
|
comp.getLesserOperand() = upperbound and
|
||||||
comp.getGreaterOperand() = Utils::semSsaRead(v, D::fromInt(0)) and
|
comp.getGreaterOperand() = ssaRead(v, D::fromInt(0)) and
|
||||||
(if comp.isStrict() then isStrict = false else isStrict = true)
|
(if comp.isStrict() then isStrict = false else isStrict = true)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -341,8 +343,8 @@ module SignAnalysis<DeltaSig D, UtilSig<Sem, D> Utils> {
|
|||||||
private predicate eqBound(SemExpr eqbound, SemSsaVariable v, SemSsaReadPosition pos, boolean isEq) {
|
private predicate eqBound(SemExpr eqbound, SemSsaVariable v, SemSsaReadPosition pos, boolean isEq) {
|
||||||
exists(SemGuard guard, boolean testIsTrue, boolean polarity, SemExpr e |
|
exists(SemGuard guard, boolean testIsTrue, boolean polarity, SemExpr e |
|
||||||
pos.hasReadOfVar(pragma[only_bind_into](v)) and
|
pos.hasReadOfVar(pragma[only_bind_into](v)) and
|
||||||
semGuardControlsSsaRead(guard, pragma[only_bind_into](pos), testIsTrue) and
|
guardControlsSsaRead(guard, pragma[only_bind_into](pos), testIsTrue) and
|
||||||
e = Utils::semSsaRead(pragma[only_bind_into](v), D::fromInt(0)) and
|
e = ssaRead(pragma[only_bind_into](v), D::fromInt(0)) and
|
||||||
guard.isEquality(eqbound, e, polarity) and
|
guard.isEquality(eqbound, e, polarity) and
|
||||||
isEq = polarity.booleanXor(testIsTrue).booleanNot() and
|
isEq = polarity.booleanXor(testIsTrue).booleanNot() and
|
||||||
not unknownSign(eqbound)
|
not unknownSign(eqbound)
|
||||||
|
|||||||
@@ -23,9 +23,7 @@
|
|||||||
* configuration (see `InvalidPointerToDerefConfig`).
|
* configuration (see `InvalidPointerToDerefConfig`).
|
||||||
*
|
*
|
||||||
* The dataflow traversal defines the set of sources as any dataflow node `n` such that there exists a pointer-arithmetic
|
* The dataflow traversal defines the set of sources as any dataflow node `n` such that there exists a pointer-arithmetic
|
||||||
* instruction `pai` found by `AllocationToInvalidPointer.qll` and a `n.asInstruction() >= pai + deltaDerefSourceAndPai`.
|
* instruction `pai` found by `AllocationToInvalidPointer.qll` and a `n.asInstruction() = pai`.
|
||||||
* Here, `deltaDerefSourceAndPai` is the constant difference between the source we track for finding a dereference and the
|
|
||||||
* pointer-arithmetic instruction.
|
|
||||||
*
|
*
|
||||||
* The set of sinks is defined as any dataflow node `n` such that `addr <= n.asInstruction() + deltaDerefSinkAndDerefAddress`
|
* The set of sinks is defined as any dataflow node `n` such that `addr <= n.asInstruction() + deltaDerefSinkAndDerefAddress`
|
||||||
* for some address operand `addr` and constant difference `deltaDerefSinkAndDerefAddress`. Since an address operand is
|
* for some address operand `addr` and constant difference `deltaDerefSinkAndDerefAddress`. Since an address operand is
|
||||||
@@ -37,9 +35,8 @@
|
|||||||
* `deltaDerefSinkAndDerefAddress >= 0`. The load attached to `*p` is the "operation". To ensure that the path makes
|
* `deltaDerefSinkAndDerefAddress >= 0`. The load attached to `*p` is the "operation". To ensure that the path makes
|
||||||
* intuitive sense, we only pick operations that are control-flow reachable from the dereference sink.
|
* intuitive sense, we only pick operations that are control-flow reachable from the dereference sink.
|
||||||
*
|
*
|
||||||
* To compute how many elements the dereference is beyond the end position of the allocation, we sum the two deltas
|
* We use the `deltaDerefSinkAndDerefAddress` to compute how many elements the dereference is beyond the end position of
|
||||||
* `deltaDerefSourceAndPai` and `deltaDerefSinkAndDerefAddress`. This is done in the `operationIsOffBy` predicate
|
* the allocation. This is done in the `operationIsOffBy` predicate (which is the only predicate exposed by this file).
|
||||||
* (which is the only predicate exposed by this file).
|
|
||||||
*
|
*
|
||||||
* Handling false positives:
|
* Handling false positives:
|
||||||
*
|
*
|
||||||
@@ -96,7 +93,7 @@ int invalidPointerToDereferenceFieldFlowBranchLimit() { result = 0 }
|
|||||||
private module InvalidPointerToDerefBarrier {
|
private module InvalidPointerToDerefBarrier {
|
||||||
private module BarrierConfig implements DataFlow::ConfigSig {
|
private module BarrierConfig implements DataFlow::ConfigSig {
|
||||||
additional predicate isSource(DataFlow::Node source, PointerArithmeticInstruction pai) {
|
additional predicate isSource(DataFlow::Node source, PointerArithmeticInstruction pai) {
|
||||||
invalidPointerToDerefSource(_, pai, _, _) and
|
invalidPointerToDerefSource(_, pai, _) and
|
||||||
// source <= pai
|
// source <= pai
|
||||||
bounded2(source.asInstruction(), pai, any(int d | d <= 0))
|
bounded2(source.asInstruction(), pai, any(int d | d <= 0))
|
||||||
}
|
}
|
||||||
@@ -169,11 +166,11 @@ private module InvalidPointerToDerefBarrier {
|
|||||||
*/
|
*/
|
||||||
private module InvalidPointerToDerefConfig implements DataFlow::StateConfigSig {
|
private module InvalidPointerToDerefConfig implements DataFlow::StateConfigSig {
|
||||||
class FlowState extends PointerArithmeticInstruction {
|
class FlowState extends PointerArithmeticInstruction {
|
||||||
FlowState() { invalidPointerToDerefSource(_, this, _, _) }
|
FlowState() { invalidPointerToDerefSource(_, this, _) }
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate isSource(DataFlow::Node source, FlowState pai) {
|
predicate isSource(DataFlow::Node source, FlowState pai) {
|
||||||
invalidPointerToDerefSource(_, pai, source, _)
|
invalidPointerToDerefSource(_, pai, source)
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma[inline]
|
pragma[inline]
|
||||||
@@ -198,24 +195,17 @@ private import DataFlow::GlobalWithState<InvalidPointerToDerefConfig>
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `allocSource` is dataflow node that represents an allocation that flows to the
|
* Holds if `allocSource` is dataflow node that represents an allocation that flows to the
|
||||||
* left-hand side of the pointer-arithmetic `pai`, and `derefSource <= pai + derefSourcePaiDelta`.
|
* left-hand side of the pointer-arithmetic instruction represented by `derefSource`.
|
||||||
*
|
|
||||||
* For example, if `pai` is a pointer-arithmetic operation `p + size` in an expression such
|
|
||||||
* as `(p + size) + 1` and `derefSource` is the node representing `(p + size) + 1`. In this
|
|
||||||
* case `derefSourcePaiDelta` is 1.
|
|
||||||
*/
|
*/
|
||||||
private predicate invalidPointerToDerefSource(
|
private predicate invalidPointerToDerefSource(
|
||||||
DataFlow::Node allocSource, PointerArithmeticInstruction pai, DataFlow::Node derefSource,
|
DataFlow::Node allocSource, PointerArithmeticInstruction pai, DataFlow::Node derefSource
|
||||||
int deltaDerefSourceAndPai
|
|
||||||
) {
|
) {
|
||||||
// Note that `deltaDerefSourceAndPai` is not necessarily equal to `rhsSizeDelta`:
|
// Note that `deltaDerefSourceAndPai` is not necessarily equal to `rhsSizeDelta`:
|
||||||
// `rhsSizeDelta` is the constant offset added to the size of the allocation, and
|
// `rhsSizeDelta` is the constant offset added to the size of the allocation, and
|
||||||
// `deltaDerefSourceAndPai` is the constant difference between the pointer-arithmetic instruction
|
// `deltaDerefSourceAndPai` is the constant difference between the pointer-arithmetic instruction
|
||||||
// and the instruction computing the address for which we will search for a dereference.
|
// and the instruction computing the address for which we will search for a dereference.
|
||||||
AllocToInvalidPointer::pointerAddInstructionHasBounds(allocSource, pai, _, _) and
|
AllocToInvalidPointer::pointerAddInstructionHasBounds(allocSource, pai, _, _) and
|
||||||
// derefSource <= pai + deltaDerefSourceAndPai
|
derefSource.asInstruction() = pai
|
||||||
bounded2(derefSource.asInstruction(), pai, deltaDerefSourceAndPai) and
|
|
||||||
deltaDerefSourceAndPai >= 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -258,11 +248,9 @@ private Instruction getASuccessor(Instruction instr) {
|
|||||||
instr.getBlock().getASuccessor+() = result.getBlock()
|
instr.getBlock().getASuccessor+() = result.getBlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate paiForDereferenceSink(
|
private predicate paiForDereferenceSink(PointerArithmeticInstruction pai, DataFlow::Node derefSink) {
|
||||||
PointerArithmeticInstruction pai, DataFlow::Node derefSink, int deltaDerefSourceAndPai
|
|
||||||
) {
|
|
||||||
exists(DataFlow::Node derefSource |
|
exists(DataFlow::Node derefSource |
|
||||||
invalidPointerToDerefSource(_, pai, derefSource, deltaDerefSourceAndPai) and
|
invalidPointerToDerefSource(_, pai, derefSource) and
|
||||||
flow(derefSource, derefSink)
|
flow(derefSource, derefSink)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -274,10 +262,10 @@ private predicate paiForDereferenceSink(
|
|||||||
*/
|
*/
|
||||||
private predicate derefSinkToOperation(
|
private predicate derefSinkToOperation(
|
||||||
DataFlow::Node derefSink, PointerArithmeticInstruction pai, DataFlow::Node operation,
|
DataFlow::Node derefSink, PointerArithmeticInstruction pai, DataFlow::Node operation,
|
||||||
string description, int deltaDerefSourceAndPai, int deltaDerefSinkAndDerefAddress
|
string description, int deltaDerefSinkAndDerefAddress
|
||||||
) {
|
) {
|
||||||
exists(Instruction operationInstr, AddressOperand addr |
|
exists(Instruction operationInstr, AddressOperand addr |
|
||||||
paiForDereferenceSink(pai, pragma[only_bind_into](derefSink), deltaDerefSourceAndPai) and
|
paiForDereferenceSink(pai, pragma[only_bind_into](derefSink)) and
|
||||||
isInvalidPointerDerefSink(derefSink, addr, operationInstr, description,
|
isInvalidPointerDerefSink(derefSink, addr, operationInstr, description,
|
||||||
deltaDerefSinkAndDerefAddress) and
|
deltaDerefSinkAndDerefAddress) and
|
||||||
operationInstr = getASuccessor(derefSink.asInstruction()) and
|
operationInstr = getASuccessor(derefSink.asInstruction()) and
|
||||||
@@ -298,11 +286,7 @@ predicate operationIsOffBy(
|
|||||||
DataFlow::Node allocation, PointerArithmeticInstruction pai, DataFlow::Node derefSource,
|
DataFlow::Node allocation, PointerArithmeticInstruction pai, DataFlow::Node derefSource,
|
||||||
DataFlow::Node derefSink, string description, DataFlow::Node operation, int delta
|
DataFlow::Node derefSink, string description, DataFlow::Node operation, int delta
|
||||||
) {
|
) {
|
||||||
exists(int deltaDerefSourceAndPai, int deltaDerefSinkAndDerefAddress |
|
invalidPointerToDerefSource(allocation, pai, derefSource) and
|
||||||
invalidPointerToDerefSource(allocation, pai, derefSource, deltaDerefSourceAndPai) and
|
|
||||||
flow(derefSource, derefSink) and
|
flow(derefSource, derefSink) and
|
||||||
derefSinkToOperation(derefSink, pai, operation, description, deltaDerefSourceAndPai,
|
derefSinkToOperation(derefSink, pai, operation, description, delta)
|
||||||
deltaDerefSinkAndDerefAddress) and
|
|
||||||
delta = deltaDerefSourceAndPai + deltaDerefSinkAndDerefAddress
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1334,11 +1334,16 @@ funbind(
|
|||||||
| @assignxorexpr
|
| @assignxorexpr
|
||||||
| @assignlshiftexpr
|
| @assignlshiftexpr
|
||||||
| @assignrshiftexpr
|
| @assignrshiftexpr
|
||||||
| @assignpaddexpr
|
;
|
||||||
|
|
||||||
|
@assign_pointer_expr = @assignpaddexpr
|
||||||
| @assignpsubexpr
|
| @assignpsubexpr
|
||||||
;
|
;
|
||||||
|
|
||||||
@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr
|
@assign_op_expr = @assign_arith_expr
|
||||||
|
| @assign_bitwise_expr
|
||||||
|
| @assign_pointer_expr
|
||||||
|
;
|
||||||
|
|
||||||
@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
|
@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
|||||||
|
description: Removed @assignpaddexpr and @assignpsubexpr from @assign_bitwise_expr
|
||||||
|
compatibility: full
|
||||||
@@ -13,7 +13,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import cpp
|
import cpp
|
||||||
import semmle.code.cpp.controlflow.StackVariableReachability
|
import semmle.code.cpp.ir.IR
|
||||||
|
import semmle.code.cpp.ir.dataflow.MustFlow
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auxiliary predicate: Types that don't require initialization
|
* Auxiliary predicate: Types that don't require initialization
|
||||||
@@ -33,31 +34,6 @@ predicate allocatedType(Type t) {
|
|||||||
allocatedType(t.getUnspecifiedType())
|
allocatedType(t.getUnspecifiedType())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A declaration of a local variable that leaves the
|
|
||||||
* variable uninitialized.
|
|
||||||
*/
|
|
||||||
DeclStmt declWithNoInit(LocalVariable v) {
|
|
||||||
result.getADeclaration() = v and
|
|
||||||
not exists(v.getInitializer()) and
|
|
||||||
/* The type of the variable is not stack-allocated. */
|
|
||||||
exists(Type t | t = v.getType() | not allocatedType(t))
|
|
||||||
}
|
|
||||||
|
|
||||||
class UninitialisedLocalReachability extends StackVariableReachability {
|
|
||||||
UninitialisedLocalReachability() { this = "UninitialisedLocal" }
|
|
||||||
|
|
||||||
override predicate isSource(ControlFlowNode node, StackVariable v) { node = declWithNoInit(v) }
|
|
||||||
|
|
||||||
override predicate isSink(ControlFlowNode node, StackVariable v) { useOfVarActual(v, node) }
|
|
||||||
|
|
||||||
override predicate isBarrier(ControlFlowNode node, StackVariable v) {
|
|
||||||
// only report the _first_ possibly uninitialized use
|
|
||||||
useOfVarActual(v, node) or
|
|
||||||
definitionBarrier(v, node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
predicate containsInlineAssembly(Function f) { exists(AsmStmt s | s.getEnclosingFunction() = f) }
|
predicate containsInlineAssembly(Function f) { exists(AsmStmt s | s.getEnclosingFunction() = f) }
|
||||||
|
|
||||||
@@ -82,8 +58,33 @@ VariableAccess commonException() {
|
|||||||
containsInlineAssembly(result.getEnclosingFunction())
|
containsInlineAssembly(result.getEnclosingFunction())
|
||||||
}
|
}
|
||||||
|
|
||||||
from UninitialisedLocalReachability r, LocalVariable v, VariableAccess va
|
predicate isSinkImpl(Instruction sink, VariableAccess va) {
|
||||||
|
exists(LoadInstruction load |
|
||||||
|
va = load.getUnconvertedResultExpression() and
|
||||||
|
not va = commonException() and
|
||||||
|
sink = load.getSourceValue()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
class MustFlow extends MustFlowConfiguration {
|
||||||
|
MustFlow() { this = "MustFlow" }
|
||||||
|
|
||||||
|
override predicate isSource(Instruction source) {
|
||||||
|
source instanceof UninitializedInstruction and
|
||||||
|
exists(Type t | t = source.getResultType() | not allocatedType(t))
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate isSink(Operand sink) { isSinkImpl(sink.getDef(), _) }
|
||||||
|
|
||||||
|
override predicate allowInterproceduralFlow() { none() }
|
||||||
|
|
||||||
|
override predicate isBarrier(Instruction instr) { instr instanceof ChiInstruction }
|
||||||
|
}
|
||||||
|
|
||||||
|
from
|
||||||
|
VariableAccess va, LocalVariable v, MustFlow conf, MustFlowPathNode source, MustFlowPathNode sink
|
||||||
where
|
where
|
||||||
r.reaches(_, v, va) and
|
conf.hasFlowPath(source, sink) and
|
||||||
not va = commonException()
|
isSinkImpl(sink.getInstruction(), va) and
|
||||||
|
v = va.getTarget()
|
||||||
select va, "The variable $@ may not be initialized at this access.", v, v.getName()
|
select va, "The variable $@ may not be initialized at this access.", v, v.getName()
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
* @id cpp/invalid-pointer-deref
|
* @id cpp/invalid-pointer-deref
|
||||||
* @tags reliability
|
* @tags reliability
|
||||||
* security
|
* security
|
||||||
* experimental
|
|
||||||
* external/cwe/cwe-119
|
* external/cwe/cwe-119
|
||||||
* external/cwe/cwe-125
|
* external/cwe/cwe-125
|
||||||
* external/cwe/cwe-193
|
* external/cwe/cwe-193
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
import cpp
|
import cpp
|
||||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||||
import semmle.code.cpp.models.interfaces.FlowSource
|
import semmle.code.cpp.models.interfaces.FlowSource
|
||||||
|
import semmle.code.cpp.models.implementations.Memset
|
||||||
import ExposedSystemData::PathGraph
|
import ExposedSystemData::PathGraph
|
||||||
import SystemData
|
import SystemData
|
||||||
|
|
||||||
@@ -28,6 +29,10 @@ module ExposedSystemDataConfig implements DataFlow::ConfigSig {
|
|||||||
fc.getArgument(arg).getAChild*() = sink.asIndirectExpr()
|
fc.getArgument(arg).getAChild*() = sink.asIndirectExpr()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
predicate isBarrier(DataFlow::Node node) {
|
||||||
|
node.asIndirectArgument() = any(MemsetFunction func).getACallToThisFunction().getAnArgument()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module ExposedSystemData = TaintTracking::Global<ExposedSystemDataConfig>;
|
module ExposedSystemData = TaintTracking::Global<ExposedSystemDataConfig>;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import cpp
|
|||||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||||
import semmle.code.cpp.models.interfaces.FlowSource
|
import semmle.code.cpp.models.interfaces.FlowSource
|
||||||
import semmle.code.cpp.security.OutputWrite
|
import semmle.code.cpp.security.OutputWrite
|
||||||
|
import semmle.code.cpp.models.implementations.Memset
|
||||||
import PotentiallyExposedSystemData::PathGraph
|
import PotentiallyExposedSystemData::PathGraph
|
||||||
import SystemData
|
import SystemData
|
||||||
|
|
||||||
@@ -49,6 +50,10 @@ module PotentiallyExposedSystemDataConfig implements DataFlow::ConfigSig {
|
|||||||
else child = sink.asExpr()
|
else child = sink.asExpr()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
predicate isBarrier(DataFlow::Node node) {
|
||||||
|
node.asIndirectArgument() = any(MemsetFunction func).getACallToThisFunction().getAnArgument()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module PotentiallyExposedSystemData = TaintTracking::Global<PotentiallyExposedSystemDataConfig>;
|
module PotentiallyExposedSystemData = TaintTracking::Global<PotentiallyExposedSystemDataConfig>;
|
||||||
|
|||||||
4
cpp/ql/src/change-notes/2023-10-31-odbc-models.md
Normal file
4
cpp/ql/src/change-notes/2023-10-31-odbc-models.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* Added SQL API models for `ODBC`.
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* The `cpp/uninitialized-local` query has been improved to produce fewer false positives.
|
||||||
4
cpp/ql/src/change-notes/2023-11-08-strsafe-models.md
Normal file
4
cpp/ql/src/change-notes/2023-11-08-strsafe-models.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* Added models for the `sprintf` variants from the `StrSafe.h` header.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/cpp-queries
|
name: codeql/cpp-queries
|
||||||
version: 0.8.2
|
version: 0.8.3-dev
|
||||||
groups:
|
groups:
|
||||||
- cpp
|
- cpp
|
||||||
- queries
|
- queries
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ edges
|
|||||||
| test.cpp:69:10:69:10 | arr indirection [post update] [p] | test.cpp:70:5:70:7 | arr indirection [p] |
|
| test.cpp:69:10:69:10 | arr indirection [post update] [p] | test.cpp:70:5:70:7 | arr indirection [p] |
|
||||||
| test.cpp:69:14:69:19 | call to malloc | test.cpp:69:5:69:25 | ... = ... |
|
| test.cpp:69:14:69:19 | call to malloc | test.cpp:69:5:69:25 | ... = ... |
|
||||||
| test.cpp:70:5:70:7 | arr indirection [p] | test.cpp:67:10:67:19 | mk_array_p indirection [p] |
|
| test.cpp:70:5:70:7 | arr indirection [p] | test.cpp:67:10:67:19 | mk_array_p indirection [p] |
|
||||||
| test.cpp:70:5:70:7 | arr indirection [p] | test.cpp:70:5:70:7 | arr indirection [p] |
|
|
||||||
| test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | test.cpp:79:9:79:11 | arr indirection [p] |
|
| test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | test.cpp:79:9:79:11 | arr indirection [p] |
|
||||||
| test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | test.cpp:83:9:83:11 | arr indirection [p] |
|
| test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | test.cpp:83:9:83:11 | arr indirection [p] |
|
||||||
| test.cpp:79:9:79:11 | arr indirection [p] | test.cpp:79:14:79:14 | p |
|
| test.cpp:79:9:79:11 | arr indirection [p] | test.cpp:79:14:79:14 | p |
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ postWithInFlow
|
|||||||
| example.c:26:9:26:9 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
| example.c:26:9:26:9 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
| example.c:26:19:26:24 | coords [inner post update] | PostUpdateNode should not be the target of local flow. |
|
| example.c:26:19:26:24 | coords [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
| example.c:28:23:28:25 | pos [inner post update] | PostUpdateNode should not be the target of local flow. |
|
| example.c:28:23:28:25 | pos [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
|
| flowOut.cpp:5:5:5:12 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
|
| flowOut.cpp:5:6:5:12 | toTaint [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
|
| flowOut.cpp:18:17:18:17 | x [inner post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
| globals.cpp:13:5:13:19 | flowTestGlobal1 [post update] | PostUpdateNode should not be the target of local flow. |
|
| globals.cpp:13:5:13:19 | flowTestGlobal1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
| globals.cpp:23:5:23:19 | flowTestGlobal2 [post update] | PostUpdateNode should not be the target of local flow. |
|
| globals.cpp:23:5:23:19 | flowTestGlobal2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
| lambdas.cpp:23:3:23:14 | v [post update] | PostUpdateNode should not be the target of local flow. |
|
| lambdas.cpp:23:3:23:14 | v [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
int source();
|
||||||
|
void sink(int);
|
||||||
|
|
||||||
|
void source_ref(int *toTaint) { // $ ir-def=*toTaint ast-def=toTaint
|
||||||
|
*toTaint = source();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void modify_copy(int* ptr) { // $ ast-def=ptr
|
||||||
|
int deref = *ptr;
|
||||||
|
int* other = &deref;
|
||||||
|
source_ref(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_output() {
|
||||||
|
int x = 0;
|
||||||
|
modify_copy(&x);
|
||||||
|
sink(x); // $ SPURIOUS: ir
|
||||||
|
}
|
||||||
@@ -83,7 +83,6 @@ edges
|
|||||||
| A.cpp:152:10:152:10 | d indirection [b] | A.cpp:152:10:152:13 | b |
|
| A.cpp:152:10:152:10 | d indirection [b] | A.cpp:152:10:152:13 | b |
|
||||||
| A.cpp:153:10:153:10 | d indirection [b indirection, c] | A.cpp:153:13:153:13 | b indirection [c] |
|
| A.cpp:153:10:153:10 | d indirection [b indirection, c] | A.cpp:153:13:153:13 | b indirection [c] |
|
||||||
| A.cpp:153:13:153:13 | b indirection [c] | A.cpp:153:10:153:16 | c |
|
| A.cpp:153:13:153:13 | b indirection [c] | A.cpp:153:10:153:16 | c |
|
||||||
| A.cpp:153:13:153:13 | b indirection [c] | A.cpp:153:13:153:13 | b indirection [c] |
|
|
||||||
| A.cpp:154:10:154:10 | b indirection [c] | A.cpp:154:10:154:13 | c |
|
| A.cpp:154:10:154:10 | b indirection [c] | A.cpp:154:10:154:13 | c |
|
||||||
| A.cpp:159:12:159:18 | new | A.cpp:160:29:160:29 | b |
|
| A.cpp:159:12:159:18 | new | A.cpp:160:29:160:29 | b |
|
||||||
| A.cpp:160:18:160:60 | call to MyList [head] | A.cpp:161:38:161:39 | l1 indirection [head] |
|
| A.cpp:160:18:160:60 | call to MyList [head] | A.cpp:161:38:161:39 | l1 indirection [head] |
|
||||||
@@ -97,10 +96,8 @@ edges
|
|||||||
| A.cpp:162:38:162:39 | l2 indirection [next indirection, head] | A.cpp:162:18:162:40 | call to MyList [next indirection, next indirection, head] |
|
| A.cpp:162:38:162:39 | l2 indirection [next indirection, head] | A.cpp:162:18:162:40 | call to MyList [next indirection, next indirection, head] |
|
||||||
| A.cpp:162:38:162:39 | l2 indirection [next indirection, head] | A.cpp:181:32:181:35 | next indirection [next indirection, head] |
|
| A.cpp:162:38:162:39 | l2 indirection [next indirection, head] | A.cpp:181:32:181:35 | next indirection [next indirection, head] |
|
||||||
| A.cpp:165:10:165:11 | l3 indirection [next indirection, next indirection, head] | A.cpp:165:14:165:17 | next indirection [next indirection, head] |
|
| A.cpp:165:10:165:11 | l3 indirection [next indirection, next indirection, head] | A.cpp:165:14:165:17 | next indirection [next indirection, head] |
|
||||||
| A.cpp:165:14:165:17 | next indirection [next indirection, head] | A.cpp:165:14:165:17 | next indirection [next indirection, head] |
|
|
||||||
| A.cpp:165:14:165:17 | next indirection [next indirection, head] | A.cpp:165:20:165:23 | next indirection [head] |
|
| A.cpp:165:14:165:17 | next indirection [next indirection, head] | A.cpp:165:20:165:23 | next indirection [head] |
|
||||||
| A.cpp:165:20:165:23 | next indirection [head] | A.cpp:165:10:165:29 | head |
|
| A.cpp:165:20:165:23 | next indirection [head] | A.cpp:165:10:165:29 | head |
|
||||||
| A.cpp:165:20:165:23 | next indirection [head] | A.cpp:165:20:165:23 | next indirection [head] |
|
|
||||||
| A.cpp:167:44:167:44 | l indirection [next indirection, head] | A.cpp:167:47:167:50 | next indirection [head] |
|
| A.cpp:167:44:167:44 | l indirection [next indirection, head] | A.cpp:167:47:167:50 | next indirection [head] |
|
||||||
| A.cpp:167:44:167:44 | l indirection [next indirection, next indirection, head] | A.cpp:167:47:167:50 | next indirection [next indirection, head] |
|
| A.cpp:167:44:167:44 | l indirection [next indirection, next indirection, head] | A.cpp:167:47:167:50 | next indirection [next indirection, head] |
|
||||||
| A.cpp:167:47:167:50 | next indirection [head] | A.cpp:169:12:169:12 | l indirection [head] |
|
| A.cpp:167:47:167:50 | next indirection [head] | A.cpp:169:12:169:12 | l indirection [head] |
|
||||||
@@ -121,7 +118,6 @@ edges
|
|||||||
| B.cpp:8:25:8:26 | b1 indirection [elem1] | B.cpp:44:16:44:17 | b1 indirection [elem1] |
|
| B.cpp:8:25:8:26 | b1 indirection [elem1] | B.cpp:44:16:44:17 | b1 indirection [elem1] |
|
||||||
| B.cpp:9:10:9:11 | b2 indirection [box1 indirection, elem1] | B.cpp:9:14:9:17 | box1 indirection [elem1] |
|
| B.cpp:9:10:9:11 | b2 indirection [box1 indirection, elem1] | B.cpp:9:14:9:17 | box1 indirection [elem1] |
|
||||||
| B.cpp:9:14:9:17 | box1 indirection [elem1] | B.cpp:9:10:9:24 | elem1 |
|
| B.cpp:9:14:9:17 | box1 indirection [elem1] | B.cpp:9:10:9:24 | elem1 |
|
||||||
| B.cpp:9:14:9:17 | box1 indirection [elem1] | B.cpp:9:14:9:17 | box1 indirection [elem1] |
|
|
||||||
| B.cpp:15:15:15:27 | new | B.cpp:16:37:16:37 | e |
|
| B.cpp:15:15:15:27 | new | B.cpp:16:37:16:37 | e |
|
||||||
| B.cpp:16:16:16:38 | call to Box1 [elem2] | B.cpp:17:25:17:26 | b1 indirection [elem2] |
|
| B.cpp:16:16:16:38 | call to Box1 [elem2] | B.cpp:17:25:17:26 | b1 indirection [elem2] |
|
||||||
| B.cpp:16:37:16:37 | e | B.cpp:16:16:16:38 | call to Box1 [elem2] |
|
| B.cpp:16:37:16:37 | e | B.cpp:16:16:16:38 | call to Box1 [elem2] |
|
||||||
@@ -131,7 +127,6 @@ edges
|
|||||||
| B.cpp:17:25:17:26 | b1 indirection [elem2] | B.cpp:44:16:44:17 | b1 indirection [elem2] |
|
| B.cpp:17:25:17:26 | b1 indirection [elem2] | B.cpp:44:16:44:17 | b1 indirection [elem2] |
|
||||||
| B.cpp:19:10:19:11 | b2 indirection [box1 indirection, elem2] | B.cpp:19:14:19:17 | box1 indirection [elem2] |
|
| B.cpp:19:10:19:11 | b2 indirection [box1 indirection, elem2] | B.cpp:19:14:19:17 | box1 indirection [elem2] |
|
||||||
| B.cpp:19:14:19:17 | box1 indirection [elem2] | B.cpp:19:10:19:24 | elem2 |
|
| B.cpp:19:14:19:17 | box1 indirection [elem2] | B.cpp:19:10:19:24 | elem2 |
|
||||||
| B.cpp:19:14:19:17 | box1 indirection [elem2] | B.cpp:19:14:19:17 | box1 indirection [elem2] |
|
|
||||||
| B.cpp:33:16:33:17 | e1 | B.cpp:35:7:35:22 | ... = ... |
|
| B.cpp:33:16:33:17 | e1 | B.cpp:35:7:35:22 | ... = ... |
|
||||||
| B.cpp:33:26:33:27 | e2 | B.cpp:36:7:36:22 | ... = ... |
|
| B.cpp:33:26:33:27 | e2 | B.cpp:36:7:36:22 | ... = ... |
|
||||||
| B.cpp:35:7:35:22 | ... = ... | B.cpp:35:13:35:17 | this indirection [post update] [elem1] |
|
| B.cpp:35:7:35:22 | ... = ... | B.cpp:35:13:35:17 | this indirection [post update] [elem1] |
|
||||||
@@ -196,17 +191,12 @@ edges
|
|||||||
| D.cpp:58:20:58:23 | box indirection [post update] [elem] | D.cpp:58:15:58:17 | boxfield indirection [post update] [box indirection, elem] |
|
| D.cpp:58:20:58:23 | box indirection [post update] [elem] | D.cpp:58:15:58:17 | boxfield indirection [post update] [box indirection, elem] |
|
||||||
| D.cpp:59:5:59:7 | this indirection [boxfield indirection, box indirection, elem] | D.cpp:63:8:63:10 | this indirection [boxfield indirection, box indirection, elem] |
|
| D.cpp:59:5:59:7 | this indirection [boxfield indirection, box indirection, elem] | D.cpp:63:8:63:10 | this indirection [boxfield indirection, box indirection, elem] |
|
||||||
| D.cpp:63:8:63:10 | this indirection [boxfield indirection, box indirection, elem] | D.cpp:64:10:64:17 | this indirection [boxfield indirection, box indirection, elem] |
|
| D.cpp:63:8:63:10 | this indirection [boxfield indirection, box indirection, elem] | D.cpp:64:10:64:17 | this indirection [boxfield indirection, box indirection, elem] |
|
||||||
| D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] |
|
|
||||||
| D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | D.cpp:64:20:64:22 | box indirection [elem] |
|
| D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | D.cpp:64:20:64:22 | box indirection [elem] |
|
||||||
| D.cpp:64:10:64:17 | this indirection [boxfield indirection, box indirection, elem] | D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] |
|
| D.cpp:64:10:64:17 | this indirection [boxfield indirection, box indirection, elem] | D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] |
|
||||||
| D.cpp:64:20:64:22 | box indirection [elem] | D.cpp:64:10:64:28 | elem |
|
| D.cpp:64:20:64:22 | box indirection [elem] | D.cpp:64:10:64:28 | elem |
|
||||||
| D.cpp:64:20:64:22 | box indirection [elem] | D.cpp:64:20:64:22 | box indirection [elem] |
|
|
||||||
| E.cpp:19:27:19:27 | p indirection [data, buffer indirection] | E.cpp:21:10:21:10 | p indirection [data, buffer indirection] |
|
| E.cpp:19:27:19:27 | p indirection [data, buffer indirection] | E.cpp:21:10:21:10 | p indirection [data, buffer indirection] |
|
||||||
| E.cpp:21:10:21:10 | p indirection [data, buffer indirection] | E.cpp:21:13:21:16 | data indirection [buffer indirection] |
|
| E.cpp:21:10:21:10 | p indirection [data, buffer indirection] | E.cpp:21:13:21:16 | data indirection [buffer indirection] |
|
||||||
| E.cpp:21:13:21:16 | data indirection [buffer indirection] | E.cpp:21:18:21:23 | buffer indirection |
|
| E.cpp:21:13:21:16 | data indirection [buffer indirection] | E.cpp:21:18:21:23 | buffer indirection |
|
||||||
| E.cpp:21:13:21:16 | data indirection [buffer indirection] | E.cpp:21:18:21:23 | buffer indirection |
|
|
||||||
| E.cpp:21:18:21:23 | buffer indirection | E.cpp:21:18:21:23 | buffer indirection |
|
|
||||||
| E.cpp:21:18:21:23 | buffer indirection | E.cpp:21:18:21:23 | buffer indirection |
|
|
||||||
| E.cpp:28:21:28:23 | argument_source output argument | E.cpp:31:10:31:12 | raw indirection |
|
| E.cpp:28:21:28:23 | argument_source output argument | E.cpp:31:10:31:12 | raw indirection |
|
||||||
| E.cpp:29:21:29:29 | argument_source output argument | E.cpp:29:24:29:29 | b indirection [post update] [buffer indirection] |
|
| E.cpp:29:21:29:29 | argument_source output argument | E.cpp:29:24:29:29 | b indirection [post update] [buffer indirection] |
|
||||||
| E.cpp:29:24:29:29 | b indirection [post update] [buffer indirection] | E.cpp:32:10:32:10 | b indirection [buffer indirection] |
|
| E.cpp:29:24:29:29 | b indirection [post update] [buffer indirection] | E.cpp:32:10:32:10 | b indirection [buffer indirection] |
|
||||||
@@ -214,9 +204,6 @@ edges
|
|||||||
| E.cpp:30:23:30:26 | p indirection [post update] [data, buffer indirection] | E.cpp:33:18:33:19 | & ... indirection [data, buffer indirection] |
|
| E.cpp:30:23:30:26 | p indirection [post update] [data, buffer indirection] | E.cpp:33:18:33:19 | & ... indirection [data, buffer indirection] |
|
||||||
| E.cpp:30:28:30:33 | data indirection [post update] [buffer indirection] | E.cpp:30:23:30:26 | p indirection [post update] [data, buffer indirection] |
|
| E.cpp:30:28:30:33 | data indirection [post update] [buffer indirection] | E.cpp:30:23:30:26 | p indirection [post update] [data, buffer indirection] |
|
||||||
| E.cpp:32:10:32:10 | b indirection [buffer indirection] | E.cpp:32:13:32:18 | buffer indirection |
|
| E.cpp:32:10:32:10 | b indirection [buffer indirection] | E.cpp:32:13:32:18 | buffer indirection |
|
||||||
| E.cpp:32:10:32:10 | b indirection [buffer indirection] | E.cpp:32:13:32:18 | buffer indirection |
|
|
||||||
| E.cpp:32:13:32:18 | buffer indirection | E.cpp:32:13:32:18 | buffer indirection |
|
|
||||||
| E.cpp:32:13:32:18 | buffer indirection | E.cpp:32:13:32:18 | buffer indirection |
|
|
||||||
| E.cpp:33:18:33:19 | & ... indirection [data, buffer indirection] | E.cpp:19:27:19:27 | p indirection [data, buffer indirection] |
|
| E.cpp:33:18:33:19 | & ... indirection [data, buffer indirection] | E.cpp:19:27:19:27 | p indirection [data, buffer indirection] |
|
||||||
| aliasing.cpp:9:3:9:22 | ... = ... | aliasing.cpp:9:6:9:7 | s indirection [post update] [m1] |
|
| aliasing.cpp:9:3:9:22 | ... = ... | aliasing.cpp:9:6:9:7 | s indirection [post update] [m1] |
|
||||||
| aliasing.cpp:9:6:9:7 | s indirection [post update] [m1] | aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] |
|
| aliasing.cpp:9:6:9:7 | s indirection [post update] [m1] | aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] |
|
||||||
@@ -311,11 +298,9 @@ edges
|
|||||||
| arrays.cpp:43:8:43:8 | o indirection [indirect indirection, arr, data] | arrays.cpp:43:10:43:17 | indirect indirection [arr, data] |
|
| arrays.cpp:43:8:43:8 | o indirection [indirect indirection, arr, data] | arrays.cpp:43:10:43:17 | indirect indirection [arr, data] |
|
||||||
| arrays.cpp:43:8:43:25 | access to array indirection [data] | arrays.cpp:43:27:43:30 | data |
|
| arrays.cpp:43:8:43:25 | access to array indirection [data] | arrays.cpp:43:27:43:30 | data |
|
||||||
| arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | arrays.cpp:43:8:43:25 | access to array indirection [data] |
|
| arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | arrays.cpp:43:8:43:25 | access to array indirection [data] |
|
||||||
| arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | arrays.cpp:43:10:43:17 | indirect indirection [arr, data] |
|
|
||||||
| arrays.cpp:44:8:44:8 | o indirection [indirect indirection, arr, data] | arrays.cpp:44:10:44:17 | indirect indirection [arr, data] |
|
| arrays.cpp:44:8:44:8 | o indirection [indirect indirection, arr, data] | arrays.cpp:44:10:44:17 | indirect indirection [arr, data] |
|
||||||
| arrays.cpp:44:8:44:25 | access to array indirection [data] | arrays.cpp:44:27:44:30 | data |
|
| arrays.cpp:44:8:44:25 | access to array indirection [data] | arrays.cpp:44:27:44:30 | data |
|
||||||
| arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | arrays.cpp:44:8:44:25 | access to array indirection [data] |
|
| arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | arrays.cpp:44:8:44:25 | access to array indirection [data] |
|
||||||
| arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | arrays.cpp:44:10:44:17 | indirect indirection [arr, data] |
|
|
||||||
| arrays.cpp:48:3:48:40 | ... = ... | arrays.cpp:48:22:48:25 | access to array indirection [post update] [data] |
|
| arrays.cpp:48:3:48:40 | ... = ... | arrays.cpp:48:22:48:25 | access to array indirection [post update] [data] |
|
||||||
| arrays.cpp:48:5:48:12 | o indirection [post update] [indirect indirection, ptr indirection, data] | arrays.cpp:49:8:49:8 | o indirection [indirect indirection, ptr indirection, data] |
|
| arrays.cpp:48:5:48:12 | o indirection [post update] [indirect indirection, ptr indirection, data] | arrays.cpp:49:8:49:8 | o indirection [indirect indirection, ptr indirection, data] |
|
||||||
| arrays.cpp:48:5:48:12 | o indirection [post update] [indirect indirection, ptr indirection, data] | arrays.cpp:50:8:50:8 | o indirection [indirect indirection, ptr indirection, data] |
|
| arrays.cpp:48:5:48:12 | o indirection [post update] [indirect indirection, ptr indirection, data] | arrays.cpp:50:8:50:8 | o indirection [indirect indirection, ptr indirection, data] |
|
||||||
@@ -325,13 +310,11 @@ edges
|
|||||||
| arrays.cpp:49:8:49:8 | o indirection [indirect indirection, ptr indirection, data] | arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] |
|
| arrays.cpp:49:8:49:8 | o indirection [indirect indirection, ptr indirection, data] | arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] |
|
||||||
| arrays.cpp:49:8:49:25 | access to array indirection [data] | arrays.cpp:49:27:49:30 | data |
|
| arrays.cpp:49:8:49:25 | access to array indirection [data] | arrays.cpp:49:27:49:30 | data |
|
||||||
| arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | arrays.cpp:49:8:49:25 | access to array indirection [data] |
|
| arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | arrays.cpp:49:8:49:25 | access to array indirection [data] |
|
||||||
| arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] |
|
|
||||||
| arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | arrays.cpp:49:20:49:22 | ptr indirection [data] |
|
| arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | arrays.cpp:49:20:49:22 | ptr indirection [data] |
|
||||||
| arrays.cpp:49:20:49:22 | ptr indirection [data] | arrays.cpp:49:8:49:25 | access to array indirection [data] |
|
| arrays.cpp:49:20:49:22 | ptr indirection [data] | arrays.cpp:49:8:49:25 | access to array indirection [data] |
|
||||||
| arrays.cpp:50:8:50:8 | o indirection [indirect indirection, ptr indirection, data] | arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] |
|
| arrays.cpp:50:8:50:8 | o indirection [indirect indirection, ptr indirection, data] | arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] |
|
||||||
| arrays.cpp:50:8:50:25 | access to array indirection [data] | arrays.cpp:50:27:50:30 | data |
|
| arrays.cpp:50:8:50:25 | access to array indirection [data] | arrays.cpp:50:27:50:30 | data |
|
||||||
| arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | arrays.cpp:50:8:50:25 | access to array indirection [data] |
|
| arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | arrays.cpp:50:8:50:25 | access to array indirection [data] |
|
||||||
| arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] |
|
|
||||||
| arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | arrays.cpp:50:20:50:22 | ptr indirection [data] |
|
| arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | arrays.cpp:50:20:50:22 | ptr indirection [data] |
|
||||||
| arrays.cpp:50:20:50:22 | ptr indirection [data] | arrays.cpp:50:8:50:25 | access to array indirection [data] |
|
| arrays.cpp:50:20:50:22 | ptr indirection [data] | arrays.cpp:50:8:50:25 | access to array indirection [data] |
|
||||||
| by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | ... = ... |
|
| by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | ... = ... |
|
||||||
@@ -411,13 +394,11 @@ edges
|
|||||||
| by_reference.cpp:110:8:110:12 | outer indirection [inner_nested, a] | by_reference.cpp:110:14:110:25 | inner_nested indirection [a] |
|
| by_reference.cpp:110:8:110:12 | outer indirection [inner_nested, a] | by_reference.cpp:110:14:110:25 | inner_nested indirection [a] |
|
||||||
| by_reference.cpp:110:14:110:25 | inner_nested indirection [a] | by_reference.cpp:110:27:110:27 | a |
|
| by_reference.cpp:110:14:110:25 | inner_nested indirection [a] | by_reference.cpp:110:27:110:27 | a |
|
||||||
| by_reference.cpp:111:8:111:12 | outer indirection [inner_ptr indirection, a] | by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] |
|
| by_reference.cpp:111:8:111:12 | outer indirection [inner_ptr indirection, a] | by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] |
|
||||||
| by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] |
|
|
||||||
| by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | by_reference.cpp:111:25:111:25 | a |
|
| by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | by_reference.cpp:111:25:111:25 | a |
|
||||||
| by_reference.cpp:112:8:112:12 | outer indirection [a] | by_reference.cpp:112:14:112:14 | a |
|
| by_reference.cpp:112:8:112:12 | outer indirection [a] | by_reference.cpp:112:14:112:14 | a |
|
||||||
| by_reference.cpp:114:8:114:13 | pouter indirection [inner_nested, a] | by_reference.cpp:114:16:114:27 | inner_nested indirection [a] |
|
| by_reference.cpp:114:8:114:13 | pouter indirection [inner_nested, a] | by_reference.cpp:114:16:114:27 | inner_nested indirection [a] |
|
||||||
| by_reference.cpp:114:16:114:27 | inner_nested indirection [a] | by_reference.cpp:114:29:114:29 | a |
|
| by_reference.cpp:114:16:114:27 | inner_nested indirection [a] | by_reference.cpp:114:29:114:29 | a |
|
||||||
| by_reference.cpp:115:8:115:13 | pouter indirection [inner_ptr indirection, a] | by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] |
|
| by_reference.cpp:115:8:115:13 | pouter indirection [inner_ptr indirection, a] | by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] |
|
||||||
| by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] |
|
|
||||||
| by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | by_reference.cpp:115:27:115:27 | a |
|
| by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | by_reference.cpp:115:27:115:27 | a |
|
||||||
| by_reference.cpp:116:8:116:13 | pouter indirection [a] | by_reference.cpp:116:16:116:16 | a |
|
| by_reference.cpp:116:8:116:13 | pouter indirection [a] | by_reference.cpp:116:16:116:16 | a |
|
||||||
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | by_reference.cpp:122:27:122:38 | outer indirection [post update] [inner_nested, a] |
|
| by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | by_reference.cpp:122:27:122:38 | outer indirection [post update] [inner_nested, a] |
|
||||||
@@ -435,13 +416,11 @@ edges
|
|||||||
| by_reference.cpp:130:8:130:12 | outer indirection [inner_nested, a] | by_reference.cpp:130:14:130:25 | inner_nested indirection [a] |
|
| by_reference.cpp:130:8:130:12 | outer indirection [inner_nested, a] | by_reference.cpp:130:14:130:25 | inner_nested indirection [a] |
|
||||||
| by_reference.cpp:130:14:130:25 | inner_nested indirection [a] | by_reference.cpp:130:27:130:27 | a |
|
| by_reference.cpp:130:14:130:25 | inner_nested indirection [a] | by_reference.cpp:130:27:130:27 | a |
|
||||||
| by_reference.cpp:131:8:131:12 | outer indirection [inner_ptr indirection, a] | by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] |
|
| by_reference.cpp:131:8:131:12 | outer indirection [inner_ptr indirection, a] | by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] |
|
||||||
| by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] |
|
|
||||||
| by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | by_reference.cpp:131:25:131:25 | a |
|
| by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | by_reference.cpp:131:25:131:25 | a |
|
||||||
| by_reference.cpp:132:8:132:12 | outer indirection [a] | by_reference.cpp:132:14:132:14 | a |
|
| by_reference.cpp:132:8:132:12 | outer indirection [a] | by_reference.cpp:132:14:132:14 | a |
|
||||||
| by_reference.cpp:134:8:134:13 | pouter indirection [inner_nested, a] | by_reference.cpp:134:16:134:27 | inner_nested indirection [a] |
|
| by_reference.cpp:134:8:134:13 | pouter indirection [inner_nested, a] | by_reference.cpp:134:16:134:27 | inner_nested indirection [a] |
|
||||||
| by_reference.cpp:134:16:134:27 | inner_nested indirection [a] | by_reference.cpp:134:29:134:29 | a |
|
| by_reference.cpp:134:16:134:27 | inner_nested indirection [a] | by_reference.cpp:134:29:134:29 | a |
|
||||||
| by_reference.cpp:135:8:135:13 | pouter indirection [inner_ptr indirection, a] | by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] |
|
| by_reference.cpp:135:8:135:13 | pouter indirection [inner_ptr indirection, a] | by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] |
|
||||||
| by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] |
|
|
||||||
| by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | by_reference.cpp:135:27:135:27 | a |
|
| by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | by_reference.cpp:135:27:135:27 | a |
|
||||||
| by_reference.cpp:136:8:136:13 | pouter indirection [a] | by_reference.cpp:136:16:136:16 | a |
|
| by_reference.cpp:136:8:136:13 | pouter indirection [a] | by_reference.cpp:136:16:136:16 | a |
|
||||||
| clearning.cpp:32:3:32:25 | ... = ... | clearning.cpp:32:6:32:6 | s indirection [post update] [x indirection] |
|
| clearning.cpp:32:3:32:25 | ... = ... | clearning.cpp:32:6:32:6 | s indirection [post update] [x indirection] |
|
||||||
@@ -460,9 +439,6 @@ edges
|
|||||||
| clearning.cpp:54:5:54:5 | s indirection [post update] [x indirection] | clearning.cpp:55:8:55:8 | s indirection [x indirection] |
|
| clearning.cpp:54:5:54:5 | s indirection [post update] [x indirection] | clearning.cpp:55:8:55:8 | s indirection [x indirection] |
|
||||||
| clearning.cpp:54:5:54:5 | x indirection | clearning.cpp:54:3:54:7 | ... ++ indirection |
|
| clearning.cpp:54:5:54:5 | x indirection | clearning.cpp:54:3:54:7 | ... ++ indirection |
|
||||||
| clearning.cpp:55:8:55:8 | s indirection [x indirection] | clearning.cpp:55:10:55:10 | x indirection |
|
| clearning.cpp:55:8:55:8 | s indirection [x indirection] | clearning.cpp:55:10:55:10 | x indirection |
|
||||||
| clearning.cpp:55:8:55:8 | s indirection [x indirection] | clearning.cpp:55:10:55:10 | x indirection |
|
|
||||||
| clearning.cpp:55:10:55:10 | x indirection | clearning.cpp:55:10:55:10 | x indirection |
|
|
||||||
| clearning.cpp:55:10:55:10 | x indirection | clearning.cpp:55:10:55:10 | x indirection |
|
|
||||||
| clearning.cpp:60:3:60:22 | ... = ... | clearning.cpp:60:7:60:7 | s indirection [post update] [x indirection] |
|
| clearning.cpp:60:3:60:22 | ... = ... | clearning.cpp:60:7:60:7 | s indirection [post update] [x indirection] |
|
||||||
| clearning.cpp:60:7:60:7 | s indirection [post update] [x indirection] | clearning.cpp:61:3:61:3 | s indirection [x indirection] |
|
| clearning.cpp:60:7:60:7 | s indirection [post update] [x indirection] | clearning.cpp:61:3:61:3 | s indirection [x indirection] |
|
||||||
| clearning.cpp:60:11:60:20 | call to user_input | clearning.cpp:60:3:60:22 | ... = ... |
|
| clearning.cpp:60:11:60:20 | call to user_input | clearning.cpp:60:3:60:22 | ... = ... |
|
||||||
@@ -474,9 +450,6 @@ edges
|
|||||||
| clearning.cpp:61:5:61:5 | s indirection [post update] [x indirection] | clearning.cpp:62:8:62:8 | s indirection [x indirection] |
|
| clearning.cpp:61:5:61:5 | s indirection [post update] [x indirection] | clearning.cpp:62:8:62:8 | s indirection [x indirection] |
|
||||||
| clearning.cpp:61:5:61:5 | x indirection | clearning.cpp:61:3:61:7 | ... ++ indirection |
|
| clearning.cpp:61:5:61:5 | x indirection | clearning.cpp:61:3:61:7 | ... ++ indirection |
|
||||||
| clearning.cpp:62:8:62:8 | s indirection [x indirection] | clearning.cpp:62:10:62:10 | x indirection |
|
| clearning.cpp:62:8:62:8 | s indirection [x indirection] | clearning.cpp:62:10:62:10 | x indirection |
|
||||||
| clearning.cpp:62:8:62:8 | s indirection [x indirection] | clearning.cpp:62:10:62:10 | x indirection |
|
|
||||||
| clearning.cpp:62:10:62:10 | x indirection | clearning.cpp:62:10:62:10 | x indirection |
|
|
||||||
| clearning.cpp:62:10:62:10 | x indirection | clearning.cpp:62:10:62:10 | x indirection |
|
|
||||||
| clearning.cpp:74:20:74:22 | argument_source output argument | clearning.cpp:74:20:74:22 | s indirection [post update] [val indirection] |
|
| clearning.cpp:74:20:74:22 | argument_source output argument | clearning.cpp:74:20:74:22 | s indirection [post update] [val indirection] |
|
||||||
| clearning.cpp:74:20:74:22 | s indirection [post update] [val indirection] | clearning.cpp:76:8:76:8 | s indirection [val indirection] |
|
| clearning.cpp:74:20:74:22 | s indirection [post update] [val indirection] | clearning.cpp:76:8:76:8 | s indirection [val indirection] |
|
||||||
| clearning.cpp:76:8:76:8 | s indirection [val indirection] | clearning.cpp:76:7:76:12 | * ... |
|
| clearning.cpp:76:8:76:8 | s indirection [val indirection] | clearning.cpp:76:7:76:12 | * ... |
|
||||||
@@ -620,14 +593,12 @@ edges
|
|||||||
| conflated.cpp:54:13:54:13 | next indirection [post update] [y] | conflated.cpp:54:7:54:10 | ll indirection [post update] [next indirection, y] |
|
| conflated.cpp:54:13:54:13 | next indirection [post update] [y] | conflated.cpp:54:7:54:10 | ll indirection [post update] [next indirection, y] |
|
||||||
| conflated.cpp:54:17:54:26 | call to user_input | conflated.cpp:54:3:54:28 | ... = ... |
|
| conflated.cpp:54:17:54:26 | call to user_input | conflated.cpp:54:3:54:28 | ... = ... |
|
||||||
| conflated.cpp:55:8:55:9 | ll indirection [next indirection, y] | conflated.cpp:55:12:55:15 | next indirection [y] |
|
| conflated.cpp:55:8:55:9 | ll indirection [next indirection, y] | conflated.cpp:55:12:55:15 | next indirection [y] |
|
||||||
| conflated.cpp:55:12:55:15 | next indirection [y] | conflated.cpp:55:12:55:15 | next indirection [y] |
|
|
||||||
| conflated.cpp:55:12:55:15 | next indirection [y] | conflated.cpp:55:18:55:18 | y |
|
| conflated.cpp:55:12:55:15 | next indirection [y] | conflated.cpp:55:18:55:18 | y |
|
||||||
| conflated.cpp:60:3:60:28 | ... = ... | conflated.cpp:60:13:60:13 | next indirection [post update] [y] |
|
| conflated.cpp:60:3:60:28 | ... = ... | conflated.cpp:60:13:60:13 | next indirection [post update] [y] |
|
||||||
| conflated.cpp:60:7:60:10 | ll indirection [post update] [next indirection, y] | conflated.cpp:61:8:61:9 | ll indirection [next indirection, y] |
|
| conflated.cpp:60:7:60:10 | ll indirection [post update] [next indirection, y] | conflated.cpp:61:8:61:9 | ll indirection [next indirection, y] |
|
||||||
| conflated.cpp:60:13:60:13 | next indirection [post update] [y] | conflated.cpp:60:7:60:10 | ll indirection [post update] [next indirection, y] |
|
| conflated.cpp:60:13:60:13 | next indirection [post update] [y] | conflated.cpp:60:7:60:10 | ll indirection [post update] [next indirection, y] |
|
||||||
| conflated.cpp:60:17:60:26 | call to user_input | conflated.cpp:60:3:60:28 | ... = ... |
|
| conflated.cpp:60:17:60:26 | call to user_input | conflated.cpp:60:3:60:28 | ... = ... |
|
||||||
| conflated.cpp:61:8:61:9 | ll indirection [next indirection, y] | conflated.cpp:61:12:61:15 | next indirection [y] |
|
| conflated.cpp:61:8:61:9 | ll indirection [next indirection, y] | conflated.cpp:61:12:61:15 | next indirection [y] |
|
||||||
| conflated.cpp:61:12:61:15 | next indirection [y] | conflated.cpp:61:12:61:15 | next indirection [y] |
|
|
||||||
| conflated.cpp:61:12:61:15 | next indirection [y] | conflated.cpp:61:18:61:18 | y |
|
| conflated.cpp:61:12:61:15 | next indirection [y] | conflated.cpp:61:18:61:18 | y |
|
||||||
| constructors.cpp:18:9:18:9 | this indirection [a_] | constructors.cpp:18:22:18:23 | this indirection [a_] |
|
| constructors.cpp:18:9:18:9 | this indirection [a_] | constructors.cpp:18:22:18:23 | this indirection [a_] |
|
||||||
| constructors.cpp:18:22:18:23 | a_ | constructors.cpp:18:9:18:9 | a indirection |
|
| constructors.cpp:18:22:18:23 | a_ | constructors.cpp:18:9:18:9 | a indirection |
|
||||||
@@ -672,42 +643,36 @@ edges
|
|||||||
| qualifiers.cpp:22:23:22:23 | call to getInner indirection [post update] [a] | qualifiers.cpp:22:5:22:9 | getInner output argument [inner indirection, a] |
|
| qualifiers.cpp:22:23:22:23 | call to getInner indirection [post update] [a] | qualifiers.cpp:22:5:22:9 | getInner output argument [inner indirection, a] |
|
||||||
| qualifiers.cpp:22:27:22:36 | call to user_input | qualifiers.cpp:22:5:22:38 | ... = ... |
|
| qualifiers.cpp:22:27:22:36 | call to user_input | qualifiers.cpp:22:5:22:38 | ... = ... |
|
||||||
| qualifiers.cpp:23:10:23:14 | outer indirection [inner indirection, a] | qualifiers.cpp:23:16:23:20 | inner indirection [a] |
|
| qualifiers.cpp:23:10:23:14 | outer indirection [inner indirection, a] | qualifiers.cpp:23:16:23:20 | inner indirection [a] |
|
||||||
| qualifiers.cpp:23:16:23:20 | inner indirection [a] | qualifiers.cpp:23:16:23:20 | inner indirection [a] |
|
|
||||||
| qualifiers.cpp:23:16:23:20 | inner indirection [a] | qualifiers.cpp:23:23:23:23 | a |
|
| qualifiers.cpp:23:16:23:20 | inner indirection [a] | qualifiers.cpp:23:23:23:23 | a |
|
||||||
| qualifiers.cpp:27:5:27:9 | getInner output argument [inner indirection, a] | qualifiers.cpp:28:10:28:14 | outer indirection [inner indirection, a] |
|
| qualifiers.cpp:27:5:27:9 | getInner output argument [inner indirection, a] | qualifiers.cpp:28:10:28:14 | outer indirection [inner indirection, a] |
|
||||||
| qualifiers.cpp:27:11:27:18 | setA output argument [a] | qualifiers.cpp:27:5:27:9 | getInner output argument [inner indirection, a] |
|
| qualifiers.cpp:27:11:27:18 | setA output argument [a] | qualifiers.cpp:27:5:27:9 | getInner output argument [inner indirection, a] |
|
||||||
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:9:21:9:25 | value |
|
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:9:21:9:25 | value |
|
||||||
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:27:11:27:18 | setA output argument [a] |
|
| qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:27:11:27:18 | setA output argument [a] |
|
||||||
| qualifiers.cpp:28:10:28:14 | outer indirection [inner indirection, a] | qualifiers.cpp:28:16:28:20 | inner indirection [a] |
|
| qualifiers.cpp:28:10:28:14 | outer indirection [inner indirection, a] | qualifiers.cpp:28:16:28:20 | inner indirection [a] |
|
||||||
| qualifiers.cpp:28:16:28:20 | inner indirection [a] | qualifiers.cpp:28:16:28:20 | inner indirection [a] |
|
|
||||||
| qualifiers.cpp:28:16:28:20 | inner indirection [a] | qualifiers.cpp:28:23:28:23 | a |
|
| qualifiers.cpp:28:16:28:20 | inner indirection [a] | qualifiers.cpp:28:23:28:23 | a |
|
||||||
| qualifiers.cpp:32:17:32:21 | getInner output argument [inner indirection, a] | qualifiers.cpp:33:10:33:14 | outer indirection [inner indirection, a] |
|
| qualifiers.cpp:32:17:32:21 | getInner output argument [inner indirection, a] | qualifiers.cpp:33:10:33:14 | outer indirection [inner indirection, a] |
|
||||||
| qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] | qualifiers.cpp:32:17:32:21 | getInner output argument [inner indirection, a] |
|
| qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] | qualifiers.cpp:32:17:32:21 | getInner output argument [inner indirection, a] |
|
||||||
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value |
|
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value |
|
||||||
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] |
|
| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] |
|
||||||
| qualifiers.cpp:33:10:33:14 | outer indirection [inner indirection, a] | qualifiers.cpp:33:16:33:20 | inner indirection [a] |
|
| qualifiers.cpp:33:10:33:14 | outer indirection [inner indirection, a] | qualifiers.cpp:33:16:33:20 | inner indirection [a] |
|
||||||
| qualifiers.cpp:33:16:33:20 | inner indirection [a] | qualifiers.cpp:33:16:33:20 | inner indirection [a] |
|
|
||||||
| qualifiers.cpp:33:16:33:20 | inner indirection [a] | qualifiers.cpp:33:23:33:23 | a |
|
| qualifiers.cpp:33:16:33:20 | inner indirection [a] | qualifiers.cpp:33:23:33:23 | a |
|
||||||
| qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] | qualifiers.cpp:37:20:37:24 | getInner output argument [inner indirection, a] |
|
| qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] | qualifiers.cpp:37:20:37:24 | getInner output argument [inner indirection, a] |
|
||||||
| qualifiers.cpp:37:20:37:24 | getInner output argument [inner indirection, a] | qualifiers.cpp:38:10:38:14 | outer indirection [inner indirection, a] |
|
| qualifiers.cpp:37:20:37:24 | getInner output argument [inner indirection, a] | qualifiers.cpp:38:10:38:14 | outer indirection [inner indirection, a] |
|
||||||
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value |
|
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value |
|
||||||
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] |
|
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] |
|
||||||
| qualifiers.cpp:38:10:38:14 | outer indirection [inner indirection, a] | qualifiers.cpp:38:16:38:20 | inner indirection [a] |
|
| qualifiers.cpp:38:10:38:14 | outer indirection [inner indirection, a] | qualifiers.cpp:38:16:38:20 | inner indirection [a] |
|
||||||
| qualifiers.cpp:38:16:38:20 | inner indirection [a] | qualifiers.cpp:38:16:38:20 | inner indirection [a] |
|
|
||||||
| qualifiers.cpp:38:16:38:20 | inner indirection [a] | qualifiers.cpp:38:23:38:23 | a |
|
| qualifiers.cpp:38:16:38:20 | inner indirection [a] | qualifiers.cpp:38:23:38:23 | a |
|
||||||
| qualifiers.cpp:42:5:42:40 | ... = ... | qualifiers.cpp:42:25:42:25 | * ... indirection [post update] [a] |
|
| qualifiers.cpp:42:5:42:40 | ... = ... | qualifiers.cpp:42:25:42:25 | * ... indirection [post update] [a] |
|
||||||
| qualifiers.cpp:42:7:42:11 | getInner output argument [inner indirection, a] | qualifiers.cpp:43:10:43:14 | outer indirection [inner indirection, a] |
|
| qualifiers.cpp:42:7:42:11 | getInner output argument [inner indirection, a] | qualifiers.cpp:43:10:43:14 | outer indirection [inner indirection, a] |
|
||||||
| qualifiers.cpp:42:25:42:25 | * ... indirection [post update] [a] | qualifiers.cpp:42:7:42:11 | getInner output argument [inner indirection, a] |
|
| qualifiers.cpp:42:25:42:25 | * ... indirection [post update] [a] | qualifiers.cpp:42:7:42:11 | getInner output argument [inner indirection, a] |
|
||||||
| qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:42:5:42:40 | ... = ... |
|
| qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:42:5:42:40 | ... = ... |
|
||||||
| qualifiers.cpp:43:10:43:14 | outer indirection [inner indirection, a] | qualifiers.cpp:43:16:43:20 | inner indirection [a] |
|
| qualifiers.cpp:43:10:43:14 | outer indirection [inner indirection, a] | qualifiers.cpp:43:16:43:20 | inner indirection [a] |
|
||||||
| qualifiers.cpp:43:16:43:20 | inner indirection [a] | qualifiers.cpp:43:16:43:20 | inner indirection [a] |
|
|
||||||
| qualifiers.cpp:43:16:43:20 | inner indirection [a] | qualifiers.cpp:43:23:43:23 | a |
|
| qualifiers.cpp:43:16:43:20 | inner indirection [a] | qualifiers.cpp:43:23:43:23 | a |
|
||||||
| qualifiers.cpp:47:5:47:42 | ... = ... | qualifiers.cpp:47:27:47:27 | call to getInner indirection [post update] [a] |
|
| qualifiers.cpp:47:5:47:42 | ... = ... | qualifiers.cpp:47:27:47:27 | call to getInner indirection [post update] [a] |
|
||||||
| qualifiers.cpp:47:6:47:11 | getInner output argument [inner indirection, a] | qualifiers.cpp:48:10:48:14 | outer indirection [inner indirection, a] |
|
| qualifiers.cpp:47:6:47:11 | getInner output argument [inner indirection, a] | qualifiers.cpp:48:10:48:14 | outer indirection [inner indirection, a] |
|
||||||
| qualifiers.cpp:47:27:47:27 | call to getInner indirection [post update] [a] | qualifiers.cpp:47:6:47:11 | getInner output argument [inner indirection, a] |
|
| qualifiers.cpp:47:27:47:27 | call to getInner indirection [post update] [a] | qualifiers.cpp:47:6:47:11 | getInner output argument [inner indirection, a] |
|
||||||
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:47:5:47:42 | ... = ... |
|
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:47:5:47:42 | ... = ... |
|
||||||
| qualifiers.cpp:48:10:48:14 | outer indirection [inner indirection, a] | qualifiers.cpp:48:16:48:20 | inner indirection [a] |
|
| qualifiers.cpp:48:10:48:14 | outer indirection [inner indirection, a] | qualifiers.cpp:48:16:48:20 | inner indirection [a] |
|
||||||
| qualifiers.cpp:48:16:48:20 | inner indirection [a] | qualifiers.cpp:48:16:48:20 | inner indirection [a] |
|
|
||||||
| qualifiers.cpp:48:16:48:20 | inner indirection [a] | qualifiers.cpp:48:23:48:23 | a |
|
| qualifiers.cpp:48:16:48:20 | inner indirection [a] | qualifiers.cpp:48:23:48:23 | a |
|
||||||
| realistic.cpp:53:9:53:66 | ... = ... | realistic.cpp:53:35:53:43 | userInput indirection [post update] [bufferLen] |
|
| realistic.cpp:53:9:53:66 | ... = ... | realistic.cpp:53:35:53:43 | userInput indirection [post update] [bufferLen] |
|
||||||
| realistic.cpp:53:13:53:15 | foo indirection [post update] [bar, baz indirection, userInput, bufferLen] | realistic.cpp:61:21:61:23 | foo indirection [bar, baz indirection, userInput, bufferLen] |
|
| realistic.cpp:53:13:53:15 | foo indirection [post update] [bar, baz indirection, userInput, bufferLen] | realistic.cpp:61:21:61:23 | foo indirection [bar, baz indirection, userInput, bufferLen] |
|
||||||
@@ -717,7 +682,6 @@ edges
|
|||||||
| realistic.cpp:53:47:53:66 | call to user_input | realistic.cpp:53:9:53:66 | ... = ... |
|
| realistic.cpp:53:47:53:66 | call to user_input | realistic.cpp:53:9:53:66 | ... = ... |
|
||||||
| realistic.cpp:61:21:61:23 | foo indirection [bar, baz indirection, userInput, bufferLen] | realistic.cpp:61:21:61:30 | access to array indirection [baz indirection, userInput, bufferLen] |
|
| realistic.cpp:61:21:61:23 | foo indirection [bar, baz indirection, userInput, bufferLen] | realistic.cpp:61:21:61:30 | access to array indirection [baz indirection, userInput, bufferLen] |
|
||||||
| realistic.cpp:61:21:61:30 | access to array indirection [baz indirection, userInput, bufferLen] | realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] |
|
| realistic.cpp:61:21:61:30 | access to array indirection [baz indirection, userInput, bufferLen] | realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] |
|
||||||
| realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] |
|
|
||||||
| realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] |
|
| realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] |
|
||||||
| realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] | realistic.cpp:61:14:61:55 | bufferLen |
|
| realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] | realistic.cpp:61:14:61:55 | bufferLen |
|
||||||
| simple.cpp:18:9:18:9 | this indirection [a_] | simple.cpp:18:22:18:23 | this indirection [a_] |
|
| simple.cpp:18:9:18:9 | this indirection [a_] | simple.cpp:18:22:18:23 | this indirection [a_] |
|
||||||
@@ -796,7 +760,6 @@ edges
|
|||||||
| struct_init.c:31:8:31:12 | outer indirection [nestedAB, a] | struct_init.c:31:14:31:21 | nestedAB indirection [a] |
|
| struct_init.c:31:8:31:12 | outer indirection [nestedAB, a] | struct_init.c:31:14:31:21 | nestedAB indirection [a] |
|
||||||
| struct_init.c:31:14:31:21 | nestedAB indirection [a] | struct_init.c:31:23:31:23 | a |
|
| struct_init.c:31:14:31:21 | nestedAB indirection [a] | struct_init.c:31:23:31:23 | a |
|
||||||
| struct_init.c:33:8:33:12 | outer indirection [pointerAB indirection, a] | struct_init.c:33:14:33:22 | pointerAB indirection [a] |
|
| struct_init.c:33:8:33:12 | outer indirection [pointerAB indirection, a] | struct_init.c:33:14:33:22 | pointerAB indirection [a] |
|
||||||
| struct_init.c:33:14:33:22 | pointerAB indirection [a] | struct_init.c:33:14:33:22 | pointerAB indirection [a] |
|
|
||||||
| struct_init.c:33:14:33:22 | pointerAB indirection [a] | struct_init.c:33:25:33:25 | a |
|
| struct_init.c:33:14:33:22 | pointerAB indirection [a] | struct_init.c:33:25:33:25 | a |
|
||||||
| struct_init.c:36:10:36:24 | & ... indirection [a] | struct_init.c:14:24:14:25 | ab indirection [a] |
|
| struct_init.c:36:10:36:24 | & ... indirection [a] | struct_init.c:14:24:14:25 | ab indirection [a] |
|
||||||
| struct_init.c:36:11:36:15 | outer indirection [nestedAB, a] | struct_init.c:36:10:36:24 | & ... indirection [a] |
|
| struct_init.c:36:11:36:15 | outer indirection [nestedAB, a] | struct_init.c:36:10:36:24 | & ... indirection [a] |
|
||||||
@@ -808,7 +771,6 @@ edges
|
|||||||
| struct_init.c:43:5:43:7 | & ... indirection [a] | struct_init.c:41:23:44:3 | definition of outer indirection [post update] [pointerAB indirection, a] |
|
| struct_init.c:43:5:43:7 | & ... indirection [a] | struct_init.c:41:23:44:3 | definition of outer indirection [post update] [pointerAB indirection, a] |
|
||||||
| struct_init.c:46:10:46:14 | outer indirection [pointerAB indirection, a] | struct_init.c:46:16:46:24 | pointerAB indirection [a] |
|
| struct_init.c:46:10:46:14 | outer indirection [pointerAB indirection, a] | struct_init.c:46:16:46:24 | pointerAB indirection [a] |
|
||||||
| struct_init.c:46:16:46:24 | pointerAB indirection [a] | struct_init.c:14:24:14:25 | ab indirection [a] |
|
| struct_init.c:46:16:46:24 | pointerAB indirection [a] | struct_init.c:14:24:14:25 | ab indirection [a] |
|
||||||
| struct_init.c:46:16:46:24 | pointerAB indirection [a] | struct_init.c:46:16:46:24 | pointerAB indirection [a] |
|
|
||||||
nodes
|
nodes
|
||||||
| A.cpp:23:10:23:10 | c | semmle.label | c |
|
| A.cpp:23:10:23:10 | c | semmle.label | c |
|
||||||
| A.cpp:25:7:25:17 | ... = ... | semmle.label | ... = ... |
|
| A.cpp:25:7:25:17 | ... = ... | semmle.label | ... = ... |
|
||||||
@@ -1019,7 +981,6 @@ nodes
|
|||||||
| E.cpp:21:10:21:10 | p indirection [data, buffer indirection] | semmle.label | p indirection [data, buffer indirection] |
|
| E.cpp:21:10:21:10 | p indirection [data, buffer indirection] | semmle.label | p indirection [data, buffer indirection] |
|
||||||
| E.cpp:21:13:21:16 | data indirection [buffer indirection] | semmle.label | data indirection [buffer indirection] |
|
| E.cpp:21:13:21:16 | data indirection [buffer indirection] | semmle.label | data indirection [buffer indirection] |
|
||||||
| E.cpp:21:18:21:23 | buffer indirection | semmle.label | buffer indirection |
|
| E.cpp:21:18:21:23 | buffer indirection | semmle.label | buffer indirection |
|
||||||
| E.cpp:21:18:21:23 | buffer indirection | semmle.label | buffer indirection |
|
|
||||||
| E.cpp:28:21:28:23 | argument_source output argument | semmle.label | argument_source output argument |
|
| E.cpp:28:21:28:23 | argument_source output argument | semmle.label | argument_source output argument |
|
||||||
| E.cpp:29:21:29:29 | argument_source output argument | semmle.label | argument_source output argument |
|
| E.cpp:29:21:29:29 | argument_source output argument | semmle.label | argument_source output argument |
|
||||||
| E.cpp:29:24:29:29 | b indirection [post update] [buffer indirection] | semmle.label | b indirection [post update] [buffer indirection] |
|
| E.cpp:29:24:29:29 | b indirection [post update] [buffer indirection] | semmle.label | b indirection [post update] [buffer indirection] |
|
||||||
@@ -1029,7 +990,6 @@ nodes
|
|||||||
| E.cpp:31:10:31:12 | raw indirection | semmle.label | raw indirection |
|
| E.cpp:31:10:31:12 | raw indirection | semmle.label | raw indirection |
|
||||||
| E.cpp:32:10:32:10 | b indirection [buffer indirection] | semmle.label | b indirection [buffer indirection] |
|
| E.cpp:32:10:32:10 | b indirection [buffer indirection] | semmle.label | b indirection [buffer indirection] |
|
||||||
| E.cpp:32:13:32:18 | buffer indirection | semmle.label | buffer indirection |
|
| E.cpp:32:13:32:18 | buffer indirection | semmle.label | buffer indirection |
|
||||||
| E.cpp:32:13:32:18 | buffer indirection | semmle.label | buffer indirection |
|
|
||||||
| E.cpp:33:18:33:19 | & ... indirection [data, buffer indirection] | semmle.label | & ... indirection [data, buffer indirection] |
|
| E.cpp:33:18:33:19 | & ... indirection [data, buffer indirection] | semmle.label | & ... indirection [data, buffer indirection] |
|
||||||
| aliasing.cpp:9:3:9:22 | ... = ... | semmle.label | ... = ... |
|
| aliasing.cpp:9:3:9:22 | ... = ... | semmle.label | ... = ... |
|
||||||
| aliasing.cpp:9:6:9:7 | s indirection [post update] [m1] | semmle.label | s indirection [post update] [m1] |
|
| aliasing.cpp:9:6:9:7 | s indirection [post update] [m1] | semmle.label | s indirection [post update] [m1] |
|
||||||
@@ -1277,7 +1237,6 @@ nodes
|
|||||||
| clearning.cpp:54:5:54:5 | x indirection | semmle.label | x indirection |
|
| clearning.cpp:54:5:54:5 | x indirection | semmle.label | x indirection |
|
||||||
| clearning.cpp:55:8:55:8 | s indirection [x indirection] | semmle.label | s indirection [x indirection] |
|
| clearning.cpp:55:8:55:8 | s indirection [x indirection] | semmle.label | s indirection [x indirection] |
|
||||||
| clearning.cpp:55:10:55:10 | x indirection | semmle.label | x indirection |
|
| clearning.cpp:55:10:55:10 | x indirection | semmle.label | x indirection |
|
||||||
| clearning.cpp:55:10:55:10 | x indirection | semmle.label | x indirection |
|
|
||||||
| clearning.cpp:60:3:60:22 | ... = ... | semmle.label | ... = ... |
|
| clearning.cpp:60:3:60:22 | ... = ... | semmle.label | ... = ... |
|
||||||
| clearning.cpp:60:7:60:7 | s indirection [post update] [x indirection] | semmle.label | s indirection [post update] [x indirection] |
|
| clearning.cpp:60:7:60:7 | s indirection [post update] [x indirection] | semmle.label | s indirection [post update] [x indirection] |
|
||||||
| clearning.cpp:60:11:60:20 | call to user_input | semmle.label | call to user_input |
|
| clearning.cpp:60:11:60:20 | call to user_input | semmle.label | call to user_input |
|
||||||
@@ -1288,7 +1247,6 @@ nodes
|
|||||||
| clearning.cpp:61:5:61:5 | x indirection | semmle.label | x indirection |
|
| clearning.cpp:61:5:61:5 | x indirection | semmle.label | x indirection |
|
||||||
| clearning.cpp:62:8:62:8 | s indirection [x indirection] | semmle.label | s indirection [x indirection] |
|
| clearning.cpp:62:8:62:8 | s indirection [x indirection] | semmle.label | s indirection [x indirection] |
|
||||||
| clearning.cpp:62:10:62:10 | x indirection | semmle.label | x indirection |
|
| clearning.cpp:62:10:62:10 | x indirection | semmle.label | x indirection |
|
||||||
| clearning.cpp:62:10:62:10 | x indirection | semmle.label | x indirection |
|
|
||||||
| clearning.cpp:74:20:74:22 | argument_source output argument | semmle.label | argument_source output argument |
|
| clearning.cpp:74:20:74:22 | argument_source output argument | semmle.label | argument_source output argument |
|
||||||
| clearning.cpp:74:20:74:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] |
|
| clearning.cpp:74:20:74:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] |
|
||||||
| clearning.cpp:76:7:76:12 | * ... | semmle.label | * ... |
|
| clearning.cpp:76:7:76:12 | * ... | semmle.label | * ... |
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
failures
|
|
||||||
testFailures
|
testFailures
|
||||||
|
failures
|
||||||
|
|||||||
@@ -6643,6 +6643,20 @@ WARNING: Module TaintTracking has been deprecated and may be removed in future (
|
|||||||
| taint.cpp:729:27:729:32 | endptr | taint.cpp:729:26:729:32 | & ... | |
|
| taint.cpp:729:27:729:32 | endptr | taint.cpp:729:26:729:32 | & ... | |
|
||||||
| taint.cpp:731:7:731:12 | ref arg endptr | taint.cpp:732:8:732:13 | endptr | |
|
| taint.cpp:731:7:731:12 | ref arg endptr | taint.cpp:732:8:732:13 | endptr | |
|
||||||
| taint.cpp:732:8:732:13 | endptr | taint.cpp:732:7:732:13 | * ... | TAINT |
|
| taint.cpp:732:8:732:13 | endptr | taint.cpp:732:7:732:13 | * ... | TAINT |
|
||||||
|
| taint.cpp:738:17:738:31 | call to indirect_source | taint.cpp:739:30:739:35 | source | |
|
||||||
|
| taint.cpp:739:22:739:28 | call to realloc | taint.cpp:740:7:740:10 | dest | |
|
||||||
|
| taint.cpp:739:30:739:35 | source | taint.cpp:739:22:739:28 | call to realloc | TAINT |
|
||||||
|
| taint.cpp:743:40:743:45 | buffer | taint.cpp:744:5:744:10 | buffer | |
|
||||||
|
| taint.cpp:743:40:743:45 | buffer | taint.cpp:745:27:745:32 | buffer | |
|
||||||
|
| taint.cpp:744:4:744:10 | * ... | taint.cpp:744:3:744:10 | * ... | TAINT |
|
||||||
|
| taint.cpp:744:5:744:10 | buffer | taint.cpp:744:4:744:10 | * ... | TAINT |
|
||||||
|
| taint.cpp:744:14:744:19 | call to source | taint.cpp:744:3:744:21 | ... = ... | |
|
||||||
|
| taint.cpp:745:19:745:25 | call to realloc | taint.cpp:743:40:743:45 | buffer | |
|
||||||
|
| taint.cpp:745:19:745:25 | call to realloc | taint.cpp:745:3:745:37 | ... = ... | |
|
||||||
|
| taint.cpp:745:19:745:25 | call to realloc | taint.cpp:746:10:746:15 | buffer | |
|
||||||
|
| taint.cpp:745:27:745:32 | buffer | taint.cpp:745:19:745:25 | call to realloc | TAINT |
|
||||||
|
| taint.cpp:746:9:746:15 | * ... | taint.cpp:746:8:746:15 | * ... | TAINT |
|
||||||
|
| taint.cpp:746:10:746:15 | buffer | taint.cpp:746:9:746:15 | * ... | TAINT |
|
||||||
| vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | |
|
| vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | |
|
||||||
| vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | |
|
| vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | |
|
||||||
| vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | |
|
| vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | |
|
||||||
|
|||||||
@@ -731,3 +731,17 @@ void test_strtol(char *source) {
|
|||||||
sink(endptr); // $ ast,ir
|
sink(endptr); // $ ast,ir
|
||||||
sink(*endptr); // $ ast,ir
|
sink(*endptr); // $ ast,ir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *realloc(void *, size_t);
|
||||||
|
|
||||||
|
void test_realloc() {
|
||||||
|
char *source = indirect_source();
|
||||||
|
char *dest = (char*)realloc(source, 16);
|
||||||
|
sink(dest); // $ ir MISSING: ast
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_realloc_2_indirections(int **buffer) {
|
||||||
|
**buffer = source();
|
||||||
|
buffer = (int**)realloc(buffer, 16);
|
||||||
|
sink(**buffer); // $ ir MISSING: ast
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import cpp
|
import cpp
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.ModulusAnalysis
|
import codeql.rangeanalysis.ModulusAnalysis
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic
|
||||||
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticLocation
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeUtils
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeUtils
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta
|
||||||
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisRelativeSpecific
|
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysisRelativeSpecific
|
||||||
@@ -10,7 +11,8 @@ import semmle.code.cpp.ir.IR as IR
|
|||||||
import TestUtilities.InlineExpectationsTest
|
import TestUtilities.InlineExpectationsTest
|
||||||
|
|
||||||
module ModulusAnalysisInstantiated =
|
module ModulusAnalysisInstantiated =
|
||||||
ModulusAnalysis<FloatDelta, ConstantBounds, RangeUtil<FloatDelta, CppLangImplRelative>>;
|
ModulusAnalysis<SemLocation, Sem, FloatDelta, ConstantBounds,
|
||||||
|
RangeUtil<FloatDelta, CppLangImplRelative>>;
|
||||||
|
|
||||||
module ModulusAnalysisTest implements TestSig {
|
module ModulusAnalysisTest implements TestSig {
|
||||||
string getARelevantTag() { result = "mod" }
|
string getARelevantTag() { result = "mod" }
|
||||||
@@ -31,7 +33,7 @@ import MakeTest<ModulusAnalysisTest>
|
|||||||
|
|
||||||
private string getAModString(SemExpr e) {
|
private string getAModString(SemExpr e) {
|
||||||
exists(SemBound b, int delta, int mod |
|
exists(SemBound b, int delta, int mod |
|
||||||
ModulusAnalysisInstantiated::semExprModulus(e, b, delta, mod) and
|
ModulusAnalysisInstantiated::exprModulus(e, b, delta, mod) and
|
||||||
result = b.toString() + "," + delta.toString() + "," + mod.toString() and
|
result = b.toString() + "," + delta.toString() + "," + mod.toString() and
|
||||||
not (delta = 0 and mod = 0)
|
not (delta = 0 and mod = 0)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ int test2(struct List* p) {
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
for (; p; p = p->next) {
|
for (; p; p = p->next) {
|
||||||
count = (count+1) % 10;
|
count = (count+1) % 10;
|
||||||
range(count); // $ range=<=9 range=>=-9 range="<=Phi: p | Store: count+1"
|
range(count); // $ range=<=9 range=>=-9
|
||||||
}
|
}
|
||||||
range(count); // $ range=>=-9 range=<=9
|
range(count); // $ range=>=-9 range=<=9
|
||||||
return count;
|
return count;
|
||||||
@@ -29,7 +29,7 @@ int test3(struct List* p) {
|
|||||||
for (; p; p = p->next) {
|
for (; p; p = p->next) {
|
||||||
range(count++); // $ range=>=-9 range=<=9
|
range(count++); // $ range=>=-9 range=<=9
|
||||||
count = count % 10;
|
count = count % 10;
|
||||||
range(count); // $ range=<=9 range=>=-9 range="<=Store: ... +++0" range="<=Phi: p | Store: count+1"
|
range(count); // $ range=<=9 range=>=-9
|
||||||
}
|
}
|
||||||
range(count); // $ range=>=-9 range=<=9
|
range(count); // $ range=>=-9 range=<=9
|
||||||
return count;
|
return count;
|
||||||
@@ -317,7 +317,7 @@ int test_mult01(int a, int b) {
|
|||||||
range(b); // $ range=<=23 range=>=-13
|
range(b); // $ range=<=23 range=>=-13
|
||||||
int r = a*b; // $ overflow=+- -143 .. 253
|
int r = a*b; // $ overflow=+- -143 .. 253
|
||||||
range(r);
|
range(r);
|
||||||
total += r; // $ overflow=+
|
total += r; // $ overflow=+-
|
||||||
range(total); // $ MISSING: range=">=... * ...+0"
|
range(total); // $ MISSING: range=">=... * ...+0"
|
||||||
}
|
}
|
||||||
if (3 <= a && a <= 11 && -13 <= b && b <= 0) {
|
if (3 <= a && a <= 11 && -13 <= b && b <= 0) {
|
||||||
@@ -365,7 +365,7 @@ int test_mult02(int a, int b) {
|
|||||||
range(b); // $ range=<=23 range=>=-13
|
range(b); // $ range=<=23 range=>=-13
|
||||||
int r = a*b; // $ overflow=+- -143 .. 253
|
int r = a*b; // $ overflow=+- -143 .. 253
|
||||||
range(r);
|
range(r);
|
||||||
total += r; // $ overflow=+
|
total += r; // $ overflow=+-
|
||||||
range(total); // $ MISSING: range=">=... * ...+0"
|
range(total); // $ MISSING: range=">=... * ...+0"
|
||||||
}
|
}
|
||||||
if (0 <= a && a <= 11 && -13 <= b && b <= 0) {
|
if (0 <= a && a <= 11 && -13 <= b && b <= 0) {
|
||||||
@@ -460,7 +460,7 @@ int test_mult04(int a, int b) {
|
|||||||
range(b); // $ range=<=23 range=>=-13
|
range(b); // $ range=<=23 range=>=-13
|
||||||
int r = a*b; // $ overflow=+- -391 .. 221
|
int r = a*b; // $ overflow=+- -391 .. 221
|
||||||
range(r);
|
range(r);
|
||||||
total += r; // $ overflow=-
|
total += r; // $ overflow=+-
|
||||||
range(total); // $ MISSING: range="<=... * ...+0"
|
range(total); // $ MISSING: range="<=... * ...+0"
|
||||||
}
|
}
|
||||||
if (-17 <= a && a <= 0 && -13 <= b && b <= 0) {
|
if (-17 <= a && a <= 0 && -13 <= b && b <= 0) {
|
||||||
@@ -508,7 +508,7 @@ int test_mult05(int a, int b) {
|
|||||||
range(b); // $ range=<=23 range=>=-13
|
range(b); // $ range=<=23 range=>=-13
|
||||||
int r = a*b; // $ overflow=+- -391 .. 221
|
int r = a*b; // $ overflow=+- -391 .. 221
|
||||||
range(r);
|
range(r);
|
||||||
total += r; // $ overflow=-
|
total += r; // $ overflow=+-
|
||||||
range(total); // $ MISSING: range="<=... * ...+0"
|
range(total); // $ MISSING: range="<=... * ...+0"
|
||||||
}
|
}
|
||||||
if (-17 <= a && a <= -2 && -13 <= b && b <= 0) {
|
if (-17 <= a && a <= -2 && -13 <= b && b <= 0) {
|
||||||
@@ -974,7 +974,7 @@ void test_mod_neg(int s) {
|
|||||||
|
|
||||||
void test_mod_ternary(int s, bool b) {
|
void test_mod_ternary(int s, bool b) {
|
||||||
int s2 = s % (b ? 5 : 500);
|
int s2 = s % (b ? 5 : 500);
|
||||||
range(s2); // $ range=>=-499 range=<=499 range="<=Phi: ... ? ... : ...-1"
|
range(s2); // $ range=>=-499 range=<=499
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_mod_ternary2(int s, bool b1, bool b2) {
|
void test_mod_ternary2(int s, bool b1, bool b2) {
|
||||||
@@ -1029,3 +1029,72 @@ void test_negate_signed(int s) {
|
|||||||
range<int>(-s); // $ range=<=-11 range=>=-19
|
range<int>(-s); // $ range=<=-11 range=>=-19
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// By setting the guard after the use in another guard we
|
||||||
|
// don't get the useful information
|
||||||
|
void test_guard_after_use(int pos, int size, int offset) {
|
||||||
|
if (pos + offset >= size) { // $ overflow=+-
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (offset != 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
range(pos + 1); // $ overflow=+ range="==InitializeParameter: pos+1" MISSING: range="<=InitializeParameter: size-1"
|
||||||
|
}
|
||||||
|
|
||||||
|
int cond();
|
||||||
|
|
||||||
|
|
||||||
|
// This is basically what we get when we have a loop that calls
|
||||||
|
// realloc in some iterations
|
||||||
|
void alloc_in_loop(int origLen) {
|
||||||
|
if (origLen <= 10) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int len = origLen;
|
||||||
|
int index = 0;
|
||||||
|
while (cond()) {
|
||||||
|
if (index == len) {
|
||||||
|
if (len >= 1000) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
len = len * 2; // $ overflow=-
|
||||||
|
}
|
||||||
|
// We want that index < len
|
||||||
|
range(index); // $ MISSING: range="<=InitializeParameter: len-1"
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This came from a case where it handled the leftovers before an unrolled loop
|
||||||
|
void mask_at_start(int len) {
|
||||||
|
if (len < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int leftOver = len & 63;
|
||||||
|
for (int i = 0; i < leftOver; i++) {
|
||||||
|
range(i); // $ range=<=62 range=>=0 range="<=Store: ... & ... | Store: leftOver-1" range="<=InitializeParameter: len-1"
|
||||||
|
}
|
||||||
|
// Do something with leftOver
|
||||||
|
for (int index = leftOver; index < len; index+=64) {
|
||||||
|
range(index); // $ range="<=InitializeParameter: len-64" range=">=Store: ... & ... | Store: leftOver+0"
|
||||||
|
range(index + 63); // $ range="<=InitializeParameter: len-1" range="==Phi: index+63" range=">=Store: ... & ... | Store: leftOver+63"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Same as above but with modulo
|
||||||
|
void mod_at_start(int len) {
|
||||||
|
if (len < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int leftOver = len % 64;
|
||||||
|
for (int i = 0; i < leftOver; i++) {
|
||||||
|
range(i); // $ range=<=62 range=>=0 range="<=Store: ... % ... | Store: leftOver-1" range="<=InitializeParameter: len-1"
|
||||||
|
}
|
||||||
|
// Do something with leftOver
|
||||||
|
for (int index = leftOver; index < len; index+=64) {
|
||||||
|
range(index); // $ range="<=InitializeParameter: len-64" range=">=Store: ... % ... | Store: leftOver+0"
|
||||||
|
range(index + 63); // $ range="<=InitializeParameter: len-1" range="==Phi: index+63" range=">=Store: ... % ... | Store: leftOver+63"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -130,3 +130,19 @@ void test_div(int x) {
|
|||||||
range(x >> 2); // $ range=>=0 range=<=2
|
range(x >> 2); // $ range=>=0 range=<=2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct X { int n; };
|
||||||
|
void read_argument(const X *);
|
||||||
|
|
||||||
|
// This test exists purely to ensure that modulus analysis terminates in the
|
||||||
|
// presence of inexact phi operands. The LoadInstruction on `while(x->n) { ... }`
|
||||||
|
// reads from a PhiInstruction with two input operands: an exact operand defined
|
||||||
|
// by the StoreInstruction generated by `x->n--` and an inexact operand coming
|
||||||
|
// from the WriteSideEffect generated by `read_argument(x)`. If we don't consider
|
||||||
|
// the inexact operand modulus analysis fails to terminate.
|
||||||
|
void nonterminating_without_operands_as_ssa(X *x) {
|
||||||
|
read_argument(x);
|
||||||
|
while (x->n) {
|
||||||
|
x->n--;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,9 @@ edges
|
|||||||
| test.cpp:15:27:15:30 | argv indirection | test.cpp:22:45:22:52 | userName indirection |
|
| test.cpp:15:27:15:30 | argv indirection | test.cpp:22:45:22:52 | userName indirection |
|
||||||
| test.cpp:22:13:22:20 | sprintf output argument | test.cpp:23:12:23:19 | command1 indirection |
|
| test.cpp:22:13:22:20 | sprintf output argument | test.cpp:23:12:23:19 | command1 indirection |
|
||||||
| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:13:22:20 | sprintf output argument |
|
| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:13:22:20 | sprintf output argument |
|
||||||
| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:45:22:52 | userName indirection |
|
|
||||||
| test.cpp:47:21:47:26 | call to getenv indirection | test.cpp:50:35:50:43 | envCflags indirection |
|
| test.cpp:47:21:47:26 | call to getenv indirection | test.cpp:50:35:50:43 | envCflags indirection |
|
||||||
| test.cpp:50:11:50:17 | sprintf output argument | test.cpp:51:10:51:16 | command indirection |
|
| test.cpp:50:11:50:17 | sprintf output argument | test.cpp:51:10:51:16 | command indirection |
|
||||||
| test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:11:50:17 | sprintf output argument |
|
| test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:11:50:17 | sprintf output argument |
|
||||||
| test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:35:50:43 | envCflags indirection |
|
|
||||||
| test.cpp:62:9:62:16 | fread output argument | test.cpp:64:20:64:27 | filename indirection |
|
| test.cpp:62:9:62:16 | fread output argument | test.cpp:64:20:64:27 | filename indirection |
|
||||||
| test.cpp:64:11:64:17 | strncat output argument | test.cpp:65:10:65:16 | command indirection |
|
| test.cpp:64:11:64:17 | strncat output argument | test.cpp:65:10:65:16 | command indirection |
|
||||||
| test.cpp:64:20:64:27 | filename indirection | test.cpp:64:11:64:17 | strncat output argument |
|
| test.cpp:64:20:64:27 | filename indirection | test.cpp:64:11:64:17 | strncat output argument |
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ edges
|
|||||||
| test.c:35:16:35:23 | userName indirection | test.c:40:25:40:32 | username indirection |
|
| test.c:35:16:35:23 | userName indirection | test.c:40:25:40:32 | username indirection |
|
||||||
| test.c:38:7:38:20 | globalUsername indirection | test.c:51:18:51:23 | query1 indirection |
|
| test.c:38:7:38:20 | globalUsername indirection | test.c:51:18:51:23 | query1 indirection |
|
||||||
| test.c:40:25:40:32 | username indirection | test.c:38:7:38:20 | globalUsername indirection |
|
| test.c:40:25:40:32 | username indirection | test.c:38:7:38:20 | globalUsername indirection |
|
||||||
|
| test.c:75:8:75:16 | gets output argument | test.c:76:17:76:25 | userInput indirection |
|
||||||
|
| test.c:75:8:75:16 | gets output argument | test.c:77:20:77:28 | userInput indirection |
|
||||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection |
|
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection |
|
||||||
nodes
|
nodes
|
||||||
| test.c:14:27:14:30 | argv indirection | semmle.label | argv indirection |
|
| test.c:14:27:14:30 | argv indirection | semmle.label | argv indirection |
|
||||||
@@ -12,10 +14,15 @@ nodes
|
|||||||
| test.c:38:7:38:20 | globalUsername indirection | semmle.label | globalUsername indirection |
|
| test.c:38:7:38:20 | globalUsername indirection | semmle.label | globalUsername indirection |
|
||||||
| test.c:40:25:40:32 | username indirection | semmle.label | username indirection |
|
| test.c:40:25:40:32 | username indirection | semmle.label | username indirection |
|
||||||
| test.c:51:18:51:23 | query1 indirection | semmle.label | query1 indirection |
|
| test.c:51:18:51:23 | query1 indirection | semmle.label | query1 indirection |
|
||||||
|
| test.c:75:8:75:16 | gets output argument | semmle.label | gets output argument |
|
||||||
|
| test.c:76:17:76:25 | userInput indirection | semmle.label | userInput indirection |
|
||||||
|
| test.c:77:20:77:28 | userInput indirection | semmle.label | userInput indirection |
|
||||||
| test.cpp:39:27:39:30 | argv indirection | semmle.label | argv indirection |
|
| test.cpp:39:27:39:30 | argv indirection | semmle.label | argv indirection |
|
||||||
| test.cpp:43:27:43:33 | access to array indirection | semmle.label | access to array indirection |
|
| test.cpp:43:27:43:33 | access to array indirection | semmle.label | access to array indirection |
|
||||||
subpaths
|
subpaths
|
||||||
#select
|
#select
|
||||||
| test.c:21:18:21:23 | query1 | test.c:14:27:14:30 | argv indirection | test.c:21:18:21:23 | query1 indirection | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:14:27:14:30 | argv indirection | user input (a command-line argument) |
|
| test.c:21:18:21:23 | query1 | test.c:14:27:14:30 | argv indirection | test.c:21:18:21:23 | query1 indirection | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:14:27:14:30 | argv indirection | user input (a command-line argument) |
|
||||||
| test.c:51:18:51:23 | query1 | test.c:14:27:14:30 | argv indirection | test.c:51:18:51:23 | query1 indirection | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:14:27:14:30 | argv indirection | user input (a command-line argument) |
|
| test.c:51:18:51:23 | query1 | test.c:14:27:14:30 | argv indirection | test.c:51:18:51:23 | query1 indirection | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:14:27:14:30 | argv indirection | user input (a command-line argument) |
|
||||||
|
| test.c:76:17:76:25 | userInput | test.c:75:8:75:16 | gets output argument | test.c:76:17:76:25 | userInput indirection | This argument to a SQL query function is derived from $@ and then passed to SQLPrepare(StatementText). | test.c:75:8:75:16 | gets output argument | user input (string read by gets) |
|
||||||
|
| test.c:77:20:77:28 | userInput | test.c:75:8:75:16 | gets output argument | test.c:77:20:77:28 | userInput indirection | This argument to a SQL query function is derived from $@ and then passed to SQLExecDirect(StatementText). | test.c:75:8:75:16 | gets output argument | user input (string read by gets) |
|
||||||
| test.cpp:43:27:43:33 | access to array | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)). | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
| test.cpp:43:27:43:33 | access to array | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)). | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||||
|
|||||||
@@ -50,3 +50,29 @@ void badFunc() {
|
|||||||
snprintf(query1, 1000, "SELECT UID FROM USERS where name = \"%s\"", userName);
|
snprintf(query1, 1000, "SELECT UID FROM USERS where name = \"%s\"", userName);
|
||||||
mysql_query(0, query1); // BAD
|
mysql_query(0, query1); // BAD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ODBC Library Rountines
|
||||||
|
typedef unsigned char SQLCHAR;
|
||||||
|
typedef long int SQLINTEGER;
|
||||||
|
typedef int SQLRETURN;
|
||||||
|
typedef void* SQLHSTMT;
|
||||||
|
|
||||||
|
char* gets(char *str);
|
||||||
|
|
||||||
|
|
||||||
|
SQLRETURN SQLPrepare(
|
||||||
|
SQLHSTMT StatementHandle,
|
||||||
|
SQLCHAR * StatementText,
|
||||||
|
SQLINTEGER TextLength);
|
||||||
|
|
||||||
|
SQLRETURN SQLExecDirect(
|
||||||
|
SQLHSTMT StatementHandle,
|
||||||
|
SQLCHAR * StatementText,
|
||||||
|
SQLINTEGER TextLength);
|
||||||
|
|
||||||
|
void ODBCTests(){
|
||||||
|
char userInput[100];
|
||||||
|
gets(userInput);
|
||||||
|
SQLPrepare(0, userInput, 100); // BAD
|
||||||
|
SQLExecDirect(0, userInput, 100); // BAD
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ edges
|
|||||||
| test.cpp:18:10:18:15 | str indirection [post update] [string] | test.cpp:19:5:19:7 | str indirection [string] |
|
| test.cpp:18:10:18:15 | str indirection [post update] [string] | test.cpp:19:5:19:7 | str indirection [string] |
|
||||||
| test.cpp:18:19:18:24 | call to malloc | test.cpp:18:5:18:30 | ... = ... |
|
| test.cpp:18:19:18:24 | call to malloc | test.cpp:18:5:18:30 | ... = ... |
|
||||||
| test.cpp:19:5:19:7 | str indirection [string] | test.cpp:16:11:16:21 | mk_string_t indirection [string] |
|
| test.cpp:19:5:19:7 | str indirection [string] | test.cpp:16:11:16:21 | mk_string_t indirection [string] |
|
||||||
| test.cpp:19:5:19:7 | str indirection [string] | test.cpp:19:5:19:7 | str indirection [string] |
|
|
||||||
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:42:13:42:15 | str indirection [string] |
|
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:42:13:42:15 | str indirection [string] |
|
||||||
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:72:17:72:19 | str indirection [string] |
|
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:72:17:72:19 | str indirection [string] |
|
||||||
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:80:17:80:19 | str indirection [string] |
|
| test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:80:17:80:19 | str indirection [string] |
|
||||||
@@ -16,7 +15,6 @@ edges
|
|||||||
| test.cpp:90:10:90:15 | str indirection [post update] [string] | test.cpp:91:5:91:7 | str indirection [string] |
|
| test.cpp:90:10:90:15 | str indirection [post update] [string] | test.cpp:91:5:91:7 | str indirection [string] |
|
||||||
| test.cpp:90:19:90:24 | call to malloc | test.cpp:90:5:90:34 | ... = ... |
|
| test.cpp:90:19:90:24 | call to malloc | test.cpp:90:5:90:34 | ... = ... |
|
||||||
| test.cpp:91:5:91:7 | str indirection [string] | test.cpp:88:11:88:30 | mk_string_t_plus_one indirection [string] |
|
| test.cpp:91:5:91:7 | str indirection [string] | test.cpp:88:11:88:30 | mk_string_t_plus_one indirection [string] |
|
||||||
| test.cpp:91:5:91:7 | str indirection [string] | test.cpp:91:5:91:7 | str indirection [string] |
|
|
||||||
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:99:13:99:15 | str indirection [string] |
|
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:99:13:99:15 | str indirection [string] |
|
||||||
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:129:17:129:19 | str indirection [string] |
|
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:129:17:129:19 | str indirection [string] |
|
||||||
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:137:17:137:19 | str indirection [string] |
|
| test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:137:17:137:19 | str indirection [string] |
|
||||||
@@ -26,7 +24,6 @@ edges
|
|||||||
| test.cpp:147:5:147:34 | ... = ... | test.cpp:147:10:147:15 | str indirection [post update] [string] |
|
| test.cpp:147:5:147:34 | ... = ... | test.cpp:147:10:147:15 | str indirection [post update] [string] |
|
||||||
| test.cpp:147:10:147:15 | str indirection [post update] [string] | test.cpp:148:5:148:7 | str indirection [string] |
|
| test.cpp:147:10:147:15 | str indirection [post update] [string] | test.cpp:148:5:148:7 | str indirection [string] |
|
||||||
| test.cpp:147:19:147:24 | call to malloc | test.cpp:147:5:147:34 | ... = ... |
|
| test.cpp:147:19:147:24 | call to malloc | test.cpp:147:5:147:34 | ... = ... |
|
||||||
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:148:5:148:7 | str indirection [string] |
|
|
||||||
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:152:13:152:15 | str indirection [string] |
|
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:152:13:152:15 | str indirection [string] |
|
||||||
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:154:13:154:15 | str indirection [string] |
|
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:154:13:154:15 | str indirection [string] |
|
||||||
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:156:13:156:15 | str indirection [string] |
|
| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:156:13:156:15 | str indirection [string] |
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
edges
|
edges
|
||||||
| test.cpp:4:15:4:33 | call to malloc | test.cpp:5:15:5:22 | ... + ... |
|
| test.cpp:4:15:4:33 | call to malloc | test.cpp:5:15:5:22 | ... + ... |
|
||||||
| test.cpp:4:15:4:33 | call to malloc | test.cpp:5:15:5:22 | ... + ... |
|
|
||||||
| test.cpp:4:15:4:33 | call to malloc | test.cpp:6:14:6:15 | * ... |
|
|
||||||
| test.cpp:4:15:4:33 | call to malloc | test.cpp:6:14:6:15 | * ... |
|
|
||||||
| test.cpp:4:15:4:33 | call to malloc | test.cpp:8:14:8:21 | * ... |
|
|
||||||
| test.cpp:5:15:5:22 | ... + ... | test.cpp:5:15:5:22 | ... + ... |
|
| test.cpp:5:15:5:22 | ... + ... | test.cpp:5:15:5:22 | ... + ... |
|
||||||
| test.cpp:5:15:5:22 | ... + ... | test.cpp:6:14:6:15 | * ... |
|
| test.cpp:5:15:5:22 | ... + ... | test.cpp:6:14:6:15 | * ... |
|
||||||
| test.cpp:5:15:5:22 | ... + ... | test.cpp:6:14:6:15 | * ... |
|
| test.cpp:5:15:5:22 | ... + ... | test.cpp:6:14:6:15 | * ... |
|
||||||
@@ -14,10 +10,6 @@ edges
|
|||||||
| test.cpp:6:14:6:15 | * ... | test.cpp:8:14:8:21 | * ... |
|
| test.cpp:6:14:6:15 | * ... | test.cpp:8:14:8:21 | * ... |
|
||||||
| test.cpp:16:15:16:33 | call to malloc | test.cpp:20:14:20:21 | * ... |
|
| test.cpp:16:15:16:33 | call to malloc | test.cpp:20:14:20:21 | * ... |
|
||||||
| test.cpp:28:15:28:37 | call to malloc | test.cpp:29:15:29:28 | ... + ... |
|
| test.cpp:28:15:28:37 | call to malloc | test.cpp:29:15:29:28 | ... + ... |
|
||||||
| test.cpp:28:15:28:37 | call to malloc | test.cpp:29:15:29:28 | ... + ... |
|
|
||||||
| test.cpp:28:15:28:37 | call to malloc | test.cpp:30:14:30:15 | * ... |
|
|
||||||
| test.cpp:28:15:28:37 | call to malloc | test.cpp:30:14:30:15 | * ... |
|
|
||||||
| test.cpp:28:15:28:37 | call to malloc | test.cpp:32:14:32:21 | * ... |
|
|
||||||
| test.cpp:29:15:29:28 | ... + ... | test.cpp:29:15:29:28 | ... + ... |
|
| test.cpp:29:15:29:28 | ... + ... | test.cpp:29:15:29:28 | ... + ... |
|
||||||
| test.cpp:29:15:29:28 | ... + ... | test.cpp:30:14:30:15 | * ... |
|
| test.cpp:29:15:29:28 | ... + ... | test.cpp:30:14:30:15 | * ... |
|
||||||
| test.cpp:29:15:29:28 | ... + ... | test.cpp:30:14:30:15 | * ... |
|
| test.cpp:29:15:29:28 | ... + ... | test.cpp:30:14:30:15 | * ... |
|
||||||
@@ -27,29 +19,14 @@ edges
|
|||||||
| test.cpp:29:15:29:28 | ... + ... | test.cpp:32:14:32:21 | * ... |
|
| test.cpp:29:15:29:28 | ... + ... | test.cpp:32:14:32:21 | * ... |
|
||||||
| test.cpp:30:14:30:15 | * ... | test.cpp:32:14:32:21 | * ... |
|
| test.cpp:30:14:30:15 | * ... | test.cpp:32:14:32:21 | * ... |
|
||||||
| test.cpp:51:33:51:35 | end | test.cpp:60:34:60:37 | mk_array output argument |
|
| test.cpp:51:33:51:35 | end | test.cpp:60:34:60:37 | mk_array output argument |
|
||||||
| test.cpp:52:19:52:37 | call to malloc | test.cpp:53:5:53:23 | ... = ... |
|
|
||||||
| test.cpp:52:19:52:37 | call to malloc | test.cpp:53:12:53:23 | ... + ... |
|
| test.cpp:52:19:52:37 | call to malloc | test.cpp:53:12:53:23 | ... + ... |
|
||||||
| test.cpp:53:5:53:23 | ... = ... | test.cpp:51:33:51:35 | end |
|
| test.cpp:53:12:53:23 | ... + ... | test.cpp:51:33:51:35 | end |
|
||||||
| test.cpp:53:12:53:23 | ... + ... | test.cpp:53:5:53:23 | ... = ... |
|
|
||||||
| test.cpp:60:34:60:37 | mk_array output argument | test.cpp:67:9:67:14 | ... = ... |
|
| test.cpp:60:34:60:37 | mk_array output argument | test.cpp:67:9:67:14 | ... = ... |
|
||||||
| test.cpp:194:15:194:33 | call to malloc | test.cpp:195:17:195:23 | ... + ... |
|
|
||||||
| test.cpp:194:15:194:33 | call to malloc | test.cpp:195:17:195:23 | ... + ... |
|
|
||||||
| test.cpp:194:15:194:33 | call to malloc | test.cpp:201:5:201:19 | ... = ... |
|
|
||||||
| test.cpp:195:17:195:23 | ... + ... | test.cpp:195:17:195:23 | ... + ... |
|
|
||||||
| test.cpp:195:17:195:23 | ... + ... | test.cpp:201:5:201:19 | ... = ... |
|
|
||||||
| test.cpp:195:17:195:23 | ... + ... | test.cpp:201:5:201:19 | ... = ... |
|
|
||||||
| test.cpp:205:15:205:33 | call to malloc | test.cpp:206:17:206:23 | ... + ... |
|
| test.cpp:205:15:205:33 | call to malloc | test.cpp:206:17:206:23 | ... + ... |
|
||||||
| test.cpp:205:15:205:33 | call to malloc | test.cpp:206:17:206:23 | ... + ... |
|
|
||||||
| test.cpp:205:15:205:33 | call to malloc | test.cpp:213:5:213:13 | ... = ... |
|
|
||||||
| test.cpp:206:17:206:23 | ... + ... | test.cpp:206:17:206:23 | ... + ... |
|
| test.cpp:206:17:206:23 | ... + ... | test.cpp:206:17:206:23 | ... + ... |
|
||||||
| test.cpp:206:17:206:23 | ... + ... | test.cpp:213:5:213:13 | ... = ... |
|
| test.cpp:206:17:206:23 | ... + ... | test.cpp:213:5:213:13 | ... = ... |
|
||||||
| test.cpp:206:17:206:23 | ... + ... | test.cpp:213:5:213:13 | ... = ... |
|
| test.cpp:206:17:206:23 | ... + ... | test.cpp:213:5:213:13 | ... = ... |
|
||||||
| test.cpp:231:18:231:30 | new[] | test.cpp:232:3:232:20 | ... = ... |
|
|
||||||
| test.cpp:238:20:238:32 | new[] | test.cpp:239:5:239:22 | ... = ... |
|
|
||||||
| test.cpp:260:13:260:24 | new[] | test.cpp:261:14:261:21 | ... + ... |
|
| test.cpp:260:13:260:24 | new[] | test.cpp:261:14:261:21 | ... + ... |
|
||||||
| test.cpp:260:13:260:24 | new[] | test.cpp:261:14:261:21 | ... + ... |
|
|
||||||
| test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | * ... |
|
|
||||||
| test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | * ... |
|
|
||||||
| test.cpp:261:14:261:21 | ... + ... | test.cpp:261:14:261:21 | ... + ... |
|
| test.cpp:261:14:261:21 | ... + ... | test.cpp:261:14:261:21 | ... + ... |
|
||||||
| test.cpp:261:14:261:21 | ... + ... | test.cpp:264:13:264:14 | * ... |
|
| test.cpp:261:14:261:21 | ... + ... | test.cpp:264:13:264:14 | * ... |
|
||||||
| test.cpp:261:14:261:21 | ... + ... | test.cpp:264:13:264:14 | * ... |
|
| test.cpp:261:14:261:21 | ... + ... | test.cpp:264:13:264:14 | * ... |
|
||||||
@@ -58,107 +35,48 @@ edges
|
|||||||
| test.cpp:264:13:264:14 | * ... | test.cpp:264:13:264:14 | * ... |
|
| test.cpp:264:13:264:14 | * ... | test.cpp:264:13:264:14 | * ... |
|
||||||
| test.cpp:264:13:264:14 | * ... | test.cpp:264:13:264:14 | * ... |
|
| test.cpp:264:13:264:14 | * ... | test.cpp:264:13:264:14 | * ... |
|
||||||
| test.cpp:270:13:270:24 | new[] | test.cpp:271:14:271:21 | ... + ... |
|
| test.cpp:270:13:270:24 | new[] | test.cpp:271:14:271:21 | ... + ... |
|
||||||
| test.cpp:270:13:270:24 | new[] | test.cpp:271:14:271:21 | ... + ... |
|
|
||||||
| test.cpp:270:13:270:24 | new[] | test.cpp:274:5:274:10 | ... = ... |
|
|
||||||
| test.cpp:271:14:271:21 | ... + ... | test.cpp:271:14:271:21 | ... + ... |
|
| test.cpp:271:14:271:21 | ... + ... | test.cpp:271:14:271:21 | ... + ... |
|
||||||
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... |
|
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... |
|
||||||
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... |
|
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... |
|
||||||
| test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:23 | ... + ... |
|
| test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:23 | ... + ... |
|
||||||
| test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:23 | ... + ... |
|
|
||||||
| test.cpp:355:14:355:27 | new[] | test.cpp:357:24:357:30 | ... + ... |
|
|
||||||
| test.cpp:355:14:355:27 | new[] | test.cpp:357:24:357:30 | ... + ... |
|
|
||||||
| test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | end_plus_one indirection |
|
|
||||||
| test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | ... + ... indirection |
|
|
||||||
| test.cpp:356:15:356:23 | ... + ... | test.cpp:356:15:356:23 | ... + ... |
|
| test.cpp:356:15:356:23 | ... + ... | test.cpp:356:15:356:23 | ... + ... |
|
||||||
| test.cpp:356:15:356:23 | ... + ... | test.cpp:358:14:358:26 | end_plus_one indirection |
|
| test.cpp:356:15:356:23 | ... + ... | test.cpp:358:14:358:26 | end_plus_one indirection |
|
||||||
| test.cpp:356:15:356:23 | ... + ... | test.cpp:358:14:358:26 | end_plus_one indirection |
|
| test.cpp:356:15:356:23 | ... + ... | test.cpp:358:14:358:26 | end_plus_one indirection |
|
||||||
| test.cpp:356:15:356:23 | ... + ... | test.cpp:359:14:359:32 | ... + ... indirection |
|
| test.cpp:356:15:356:23 | ... + ... | test.cpp:359:14:359:32 | ... + ... indirection |
|
||||||
| test.cpp:356:15:356:23 | ... + ... | test.cpp:359:14:359:32 | ... + ... indirection |
|
| test.cpp:356:15:356:23 | ... + ... | test.cpp:359:14:359:32 | ... + ... indirection |
|
||||||
| test.cpp:357:24:357:30 | ... + ... | test.cpp:357:24:357:30 | ... + ... |
|
|
||||||
| test.cpp:357:24:357:30 | ... + ... | test.cpp:358:14:358:26 | end_plus_one indirection |
|
|
||||||
| test.cpp:357:24:357:30 | ... + ... | test.cpp:358:14:358:26 | end_plus_one indirection |
|
|
||||||
| test.cpp:357:24:357:30 | ... + ... | test.cpp:359:14:359:32 | ... + ... indirection |
|
|
||||||
| test.cpp:357:24:357:30 | ... + ... | test.cpp:359:14:359:32 | ... + ... indirection |
|
|
||||||
| test.cpp:377:14:377:27 | new[] | test.cpp:378:15:378:23 | ... + ... |
|
| test.cpp:377:14:377:27 | new[] | test.cpp:378:15:378:23 | ... + ... |
|
||||||
| test.cpp:377:14:377:27 | new[] | test.cpp:378:15:378:23 | ... + ... |
|
|
||||||
| test.cpp:377:14:377:27 | new[] | test.cpp:381:5:381:9 | ... ++ |
|
|
||||||
| test.cpp:377:14:377:27 | new[] | test.cpp:381:5:381:9 | ... ++ |
|
|
||||||
| test.cpp:377:14:377:27 | new[] | test.cpp:384:13:384:16 | end indirection |
|
|
||||||
| test.cpp:378:15:378:23 | ... + ... | test.cpp:378:15:378:23 | ... + ... |
|
| test.cpp:378:15:378:23 | ... + ... | test.cpp:378:15:378:23 | ... + ... |
|
||||||
| test.cpp:378:15:378:23 | ... + ... | test.cpp:384:13:384:16 | end indirection |
|
| test.cpp:378:15:378:23 | ... + ... | test.cpp:384:13:384:16 | end indirection |
|
||||||
| test.cpp:378:15:378:23 | ... + ... | test.cpp:384:13:384:16 | end indirection |
|
| test.cpp:378:15:378:23 | ... + ... | test.cpp:384:13:384:16 | end indirection |
|
||||||
| test.cpp:381:5:381:9 | ... ++ | test.cpp:381:5:381:9 | ... ++ |
|
|
||||||
| test.cpp:381:5:381:9 | ... ++ | test.cpp:384:13:384:16 | end indirection |
|
|
||||||
| test.cpp:410:14:410:27 | new[] | test.cpp:411:15:411:23 | & ... |
|
| test.cpp:410:14:410:27 | new[] | test.cpp:411:15:411:23 | & ... |
|
||||||
| test.cpp:410:14:410:27 | new[] | test.cpp:411:15:411:23 | & ... |
|
|
||||||
| test.cpp:410:14:410:27 | new[] | test.cpp:413:5:413:8 | ... ++ |
|
|
||||||
| test.cpp:410:14:410:27 | new[] | test.cpp:413:5:413:8 | ... ++ |
|
|
||||||
| test.cpp:410:14:410:27 | new[] | test.cpp:415:7:415:15 | ... = ... |
|
| test.cpp:410:14:410:27 | new[] | test.cpp:415:7:415:15 | ... = ... |
|
||||||
| test.cpp:411:15:411:23 | & ... | test.cpp:411:15:411:23 | & ... |
|
| test.cpp:411:15:411:23 | & ... | test.cpp:411:15:411:23 | & ... |
|
||||||
| test.cpp:411:15:411:23 | & ... | test.cpp:415:7:415:15 | ... = ... |
|
| test.cpp:411:15:411:23 | & ... | test.cpp:415:7:415:15 | ... = ... |
|
||||||
| test.cpp:411:15:411:23 | & ... | test.cpp:415:7:415:15 | ... = ... |
|
| test.cpp:411:15:411:23 | & ... | test.cpp:415:7:415:15 | ... = ... |
|
||||||
| test.cpp:413:5:413:8 | ... ++ | test.cpp:413:5:413:8 | ... ++ |
|
|
||||||
| test.cpp:413:5:413:8 | ... ++ | test.cpp:415:7:415:15 | ... = ... |
|
|
||||||
| test.cpp:413:5:413:8 | ... ++ | test.cpp:415:7:415:15 | ... = ... |
|
|
||||||
| test.cpp:421:14:421:27 | new[] | test.cpp:422:15:422:23 | & ... |
|
| test.cpp:421:14:421:27 | new[] | test.cpp:422:15:422:23 | & ... |
|
||||||
| test.cpp:421:14:421:27 | new[] | test.cpp:422:15:422:23 | & ... |
|
|
||||||
| test.cpp:421:14:421:27 | new[] | test.cpp:424:5:424:8 | ... ++ |
|
|
||||||
| test.cpp:421:14:421:27 | new[] | test.cpp:424:5:424:8 | ... ++ |
|
|
||||||
| test.cpp:421:14:421:27 | new[] | test.cpp:426:7:426:15 | ... = ... |
|
| test.cpp:421:14:421:27 | new[] | test.cpp:426:7:426:15 | ... = ... |
|
||||||
| test.cpp:422:15:422:23 | & ... | test.cpp:422:15:422:23 | & ... |
|
| test.cpp:422:15:422:23 | & ... | test.cpp:422:15:422:23 | & ... |
|
||||||
| test.cpp:422:15:422:23 | & ... | test.cpp:426:7:426:15 | ... = ... |
|
| test.cpp:422:15:422:23 | & ... | test.cpp:426:7:426:15 | ... = ... |
|
||||||
| test.cpp:422:15:422:23 | & ... | test.cpp:426:7:426:15 | ... = ... |
|
| test.cpp:422:15:422:23 | & ... | test.cpp:426:7:426:15 | ... = ... |
|
||||||
| test.cpp:424:5:424:8 | ... ++ | test.cpp:424:5:424:8 | ... ++ |
|
|
||||||
| test.cpp:424:5:424:8 | ... ++ | test.cpp:426:7:426:15 | ... = ... |
|
|
||||||
| test.cpp:424:5:424:8 | ... ++ | test.cpp:426:7:426:15 | ... = ... |
|
|
||||||
| test.cpp:432:14:432:27 | new[] | test.cpp:433:15:433:23 | & ... |
|
| test.cpp:432:14:432:27 | new[] | test.cpp:433:15:433:23 | & ... |
|
||||||
| test.cpp:432:14:432:27 | new[] | test.cpp:433:15:433:23 | & ... |
|
|
||||||
| test.cpp:432:14:432:27 | new[] | test.cpp:436:5:436:8 | ... ++ |
|
|
||||||
| test.cpp:432:14:432:27 | new[] | test.cpp:436:5:436:8 | ... ++ |
|
|
||||||
| test.cpp:432:14:432:27 | new[] | test.cpp:438:7:438:15 | ... = ... |
|
| test.cpp:432:14:432:27 | new[] | test.cpp:438:7:438:15 | ... = ... |
|
||||||
| test.cpp:433:15:433:23 | & ... | test.cpp:433:15:433:23 | & ... |
|
| test.cpp:433:15:433:23 | & ... | test.cpp:433:15:433:23 | & ... |
|
||||||
| test.cpp:433:15:433:23 | & ... | test.cpp:438:7:438:15 | ... = ... |
|
| test.cpp:433:15:433:23 | & ... | test.cpp:438:7:438:15 | ... = ... |
|
||||||
| test.cpp:433:15:433:23 | & ... | test.cpp:438:7:438:15 | ... = ... |
|
| test.cpp:433:15:433:23 | & ... | test.cpp:438:7:438:15 | ... = ... |
|
||||||
| test.cpp:436:5:436:8 | ... ++ | test.cpp:436:5:436:8 | ... ++ |
|
|
||||||
| test.cpp:436:5:436:8 | ... ++ | test.cpp:438:7:438:15 | ... = ... |
|
|
||||||
| test.cpp:436:5:436:8 | ... ++ | test.cpp:438:7:438:15 | ... = ... |
|
|
||||||
| test.cpp:444:14:444:27 | new[] | test.cpp:445:15:445:23 | & ... |
|
| test.cpp:444:14:444:27 | new[] | test.cpp:445:15:445:23 | & ... |
|
||||||
| test.cpp:444:14:444:27 | new[] | test.cpp:445:15:445:23 | & ... |
|
|
||||||
| test.cpp:444:14:444:27 | new[] | test.cpp:448:5:448:8 | ... ++ |
|
|
||||||
| test.cpp:444:14:444:27 | new[] | test.cpp:448:5:448:8 | ... ++ |
|
|
||||||
| test.cpp:444:14:444:27 | new[] | test.cpp:450:7:450:15 | ... = ... |
|
| test.cpp:444:14:444:27 | new[] | test.cpp:450:7:450:15 | ... = ... |
|
||||||
| test.cpp:445:15:445:23 | & ... | test.cpp:445:15:445:23 | & ... |
|
| test.cpp:445:15:445:23 | & ... | test.cpp:445:15:445:23 | & ... |
|
||||||
| test.cpp:445:15:445:23 | & ... | test.cpp:450:7:450:15 | ... = ... |
|
| test.cpp:445:15:445:23 | & ... | test.cpp:450:7:450:15 | ... = ... |
|
||||||
| test.cpp:445:15:445:23 | & ... | test.cpp:450:7:450:15 | ... = ... |
|
| test.cpp:445:15:445:23 | & ... | test.cpp:450:7:450:15 | ... = ... |
|
||||||
| test.cpp:448:5:448:8 | ... ++ | test.cpp:448:5:448:8 | ... ++ |
|
|
||||||
| test.cpp:448:5:448:8 | ... ++ | test.cpp:450:7:450:15 | ... = ... |
|
|
||||||
| test.cpp:448:5:448:8 | ... ++ | test.cpp:450:7:450:15 | ... = ... |
|
|
||||||
| test.cpp:480:14:480:27 | new[] | test.cpp:481:15:481:23 | & ... |
|
| test.cpp:480:14:480:27 | new[] | test.cpp:481:15:481:23 | & ... |
|
||||||
| test.cpp:480:14:480:27 | new[] | test.cpp:481:15:481:23 | & ... |
|
|
||||||
| test.cpp:480:14:480:27 | new[] | test.cpp:484:5:484:8 | ... ++ |
|
|
||||||
| test.cpp:480:14:480:27 | new[] | test.cpp:484:5:484:8 | ... ++ |
|
|
||||||
| test.cpp:480:14:480:27 | new[] | test.cpp:486:7:486:15 | ... = ... |
|
| test.cpp:480:14:480:27 | new[] | test.cpp:486:7:486:15 | ... = ... |
|
||||||
| test.cpp:481:15:481:23 | & ... | test.cpp:481:15:481:23 | & ... |
|
| test.cpp:481:15:481:23 | & ... | test.cpp:481:15:481:23 | & ... |
|
||||||
| test.cpp:481:15:481:23 | & ... | test.cpp:486:7:486:15 | ... = ... |
|
| test.cpp:481:15:481:23 | & ... | test.cpp:486:7:486:15 | ... = ... |
|
||||||
| test.cpp:481:15:481:23 | & ... | test.cpp:486:7:486:15 | ... = ... |
|
| test.cpp:481:15:481:23 | & ... | test.cpp:486:7:486:15 | ... = ... |
|
||||||
| test.cpp:484:5:484:8 | ... ++ | test.cpp:484:5:484:8 | ... ++ |
|
|
||||||
| test.cpp:484:5:484:8 | ... ++ | test.cpp:486:7:486:15 | ... = ... |
|
|
||||||
| test.cpp:484:5:484:8 | ... ++ | test.cpp:486:7:486:15 | ... = ... |
|
|
||||||
| test.cpp:543:14:543:27 | new[] | test.cpp:548:5:548:19 | ... = ... |
|
| test.cpp:543:14:543:27 | new[] | test.cpp:548:5:548:19 | ... = ... |
|
||||||
| test.cpp:554:14:554:27 | new[] | test.cpp:559:5:559:19 | ... = ... |
|
| test.cpp:554:14:554:27 | new[] | test.cpp:559:5:559:19 | ... = ... |
|
||||||
| test.cpp:642:14:642:31 | new[] | test.cpp:647:5:647:19 | ... = ... |
|
| test.cpp:642:14:642:31 | new[] | test.cpp:647:5:647:19 | ... = ... |
|
||||||
| test.cpp:695:13:695:26 | new[] | test.cpp:698:5:698:10 | ... += ... |
|
|
||||||
| test.cpp:695:13:695:26 | new[] | test.cpp:698:5:698:10 | ... += ... |
|
|
||||||
| test.cpp:698:5:698:10 | ... += ... | test.cpp:698:5:698:10 | ... += ... |
|
|
||||||
| test.cpp:698:5:698:10 | ... += ... | test.cpp:701:15:701:16 | p indirection |
|
|
||||||
| test.cpp:705:18:705:18 | q | test.cpp:705:18:705:18 | q |
|
|
||||||
| test.cpp:705:18:705:18 | q | test.cpp:706:12:706:13 | * ... |
|
|
||||||
| test.cpp:705:18:705:18 | q | test.cpp:706:12:706:13 | * ... |
|
|
||||||
| test.cpp:711:13:711:26 | new[] | test.cpp:714:11:714:11 | q |
|
|
||||||
| test.cpp:714:11:714:11 | q | test.cpp:705:18:705:18 | q |
|
|
||||||
| test.cpp:730:12:730:28 | new[] | test.cpp:732:16:732:26 | ... + ... |
|
| test.cpp:730:12:730:28 | new[] | test.cpp:732:16:732:26 | ... + ... |
|
||||||
| test.cpp:730:12:730:28 | new[] | test.cpp:732:16:732:26 | ... + ... |
|
|
||||||
| test.cpp:730:12:730:28 | new[] | test.cpp:733:5:733:12 | ... = ... |
|
|
||||||
| test.cpp:732:16:732:26 | ... + ... | test.cpp:732:16:732:26 | ... + ... |
|
| test.cpp:732:16:732:26 | ... + ... | test.cpp:732:16:732:26 | ... + ... |
|
||||||
| test.cpp:732:16:732:26 | ... + ... | test.cpp:733:5:733:12 | ... = ... |
|
| test.cpp:732:16:732:26 | ... + ... | test.cpp:733:5:733:12 | ... = ... |
|
||||||
| test.cpp:732:16:732:26 | ... + ... | test.cpp:733:5:733:12 | ... = ... |
|
| test.cpp:732:16:732:26 | ... + ... | test.cpp:733:5:733:12 | ... = ... |
|
||||||
@@ -169,10 +87,8 @@ edges
|
|||||||
| test.cpp:781:14:781:27 | new[] | test.cpp:786:18:786:27 | access to array |
|
| test.cpp:781:14:781:27 | new[] | test.cpp:786:18:786:27 | access to array |
|
||||||
| test.cpp:792:60:792:62 | end | test.cpp:800:40:800:43 | mk_array_no_field_flow output argument |
|
| test.cpp:792:60:792:62 | end | test.cpp:800:40:800:43 | mk_array_no_field_flow output argument |
|
||||||
| test.cpp:792:60:792:62 | end | test.cpp:832:40:832:43 | mk_array_no_field_flow output argument |
|
| test.cpp:792:60:792:62 | end | test.cpp:832:40:832:43 | mk_array_no_field_flow output argument |
|
||||||
| test.cpp:793:14:793:32 | call to malloc | test.cpp:794:5:794:24 | ... = ... |
|
|
||||||
| test.cpp:793:14:793:32 | call to malloc | test.cpp:794:12:794:24 | ... + ... |
|
| test.cpp:793:14:793:32 | call to malloc | test.cpp:794:12:794:24 | ... + ... |
|
||||||
| test.cpp:794:5:794:24 | ... = ... | test.cpp:792:60:792:62 | end |
|
| test.cpp:794:12:794:24 | ... + ... | test.cpp:792:60:792:62 | end |
|
||||||
| test.cpp:794:12:794:24 | ... + ... | test.cpp:794:5:794:24 | ... = ... |
|
|
||||||
| test.cpp:800:40:800:43 | mk_array_no_field_flow output argument | test.cpp:807:7:807:12 | ... = ... |
|
| test.cpp:800:40:800:43 | mk_array_no_field_flow output argument | test.cpp:807:7:807:12 | ... = ... |
|
||||||
| test.cpp:815:52:815:54 | end | test.cpp:815:52:815:54 | end |
|
| test.cpp:815:52:815:54 | end | test.cpp:815:52:815:54 | end |
|
||||||
| test.cpp:815:52:815:54 | end | test.cpp:821:7:821:12 | ... = ... |
|
| test.cpp:815:52:815:54 | end | test.cpp:821:7:821:12 | ... = ... |
|
||||||
@@ -182,8 +98,6 @@ edges
|
|||||||
| test.cpp:841:18:841:35 | call to malloc | test.cpp:842:3:842:20 | ... = ... |
|
| test.cpp:841:18:841:35 | call to malloc | test.cpp:842:3:842:20 | ... = ... |
|
||||||
| test.cpp:848:20:848:37 | call to malloc | test.cpp:849:5:849:22 | ... = ... |
|
| test.cpp:848:20:848:37 | call to malloc | test.cpp:849:5:849:22 | ... = ... |
|
||||||
| test.cpp:856:12:856:35 | call to malloc | test.cpp:857:16:857:29 | ... + ... |
|
| test.cpp:856:12:856:35 | call to malloc | test.cpp:857:16:857:29 | ... + ... |
|
||||||
| test.cpp:856:12:856:35 | call to malloc | test.cpp:857:16:857:29 | ... + ... |
|
|
||||||
| test.cpp:856:12:856:35 | call to malloc | test.cpp:860:5:860:11 | ... = ... |
|
|
||||||
| test.cpp:857:16:857:29 | ... + ... | test.cpp:857:16:857:29 | ... + ... |
|
| test.cpp:857:16:857:29 | ... + ... | test.cpp:857:16:857:29 | ... + ... |
|
||||||
| test.cpp:857:16:857:29 | ... + ... | test.cpp:860:5:860:11 | ... = ... |
|
| test.cpp:857:16:857:29 | ... + ... | test.cpp:860:5:860:11 | ... = ... |
|
||||||
| test.cpp:857:16:857:29 | ... + ... | test.cpp:860:5:860:11 | ... = ... |
|
| test.cpp:857:16:857:29 | ... + ... | test.cpp:860:5:860:11 | ... = ... |
|
||||||
@@ -204,22 +118,13 @@ nodes
|
|||||||
| test.cpp:32:14:32:21 | * ... | semmle.label | * ... |
|
| test.cpp:32:14:32:21 | * ... | semmle.label | * ... |
|
||||||
| test.cpp:51:33:51:35 | end | semmle.label | end |
|
| test.cpp:51:33:51:35 | end | semmle.label | end |
|
||||||
| test.cpp:52:19:52:37 | call to malloc | semmle.label | call to malloc |
|
| test.cpp:52:19:52:37 | call to malloc | semmle.label | call to malloc |
|
||||||
| test.cpp:53:5:53:23 | ... = ... | semmle.label | ... = ... |
|
|
||||||
| test.cpp:53:12:53:23 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:53:12:53:23 | ... + ... | semmle.label | ... + ... |
|
||||||
| test.cpp:60:34:60:37 | mk_array output argument | semmle.label | mk_array output argument |
|
| test.cpp:60:34:60:37 | mk_array output argument | semmle.label | mk_array output argument |
|
||||||
| test.cpp:67:9:67:14 | ... = ... | semmle.label | ... = ... |
|
| test.cpp:67:9:67:14 | ... = ... | semmle.label | ... = ... |
|
||||||
| test.cpp:194:15:194:33 | call to malloc | semmle.label | call to malloc |
|
|
||||||
| test.cpp:195:17:195:23 | ... + ... | semmle.label | ... + ... |
|
|
||||||
| test.cpp:195:17:195:23 | ... + ... | semmle.label | ... + ... |
|
|
||||||
| test.cpp:201:5:201:19 | ... = ... | semmle.label | ... = ... |
|
|
||||||
| test.cpp:205:15:205:33 | call to malloc | semmle.label | call to malloc |
|
| test.cpp:205:15:205:33 | call to malloc | semmle.label | call to malloc |
|
||||||
| test.cpp:206:17:206:23 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:206:17:206:23 | ... + ... | semmle.label | ... + ... |
|
||||||
| test.cpp:206:17:206:23 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:206:17:206:23 | ... + ... | semmle.label | ... + ... |
|
||||||
| test.cpp:213:5:213:13 | ... = ... | semmle.label | ... = ... |
|
| test.cpp:213:5:213:13 | ... = ... | semmle.label | ... = ... |
|
||||||
| test.cpp:231:18:231:30 | new[] | semmle.label | new[] |
|
|
||||||
| test.cpp:232:3:232:20 | ... = ... | semmle.label | ... = ... |
|
|
||||||
| test.cpp:238:20:238:32 | new[] | semmle.label | new[] |
|
|
||||||
| test.cpp:239:5:239:22 | ... = ... | semmle.label | ... = ... |
|
|
||||||
| test.cpp:260:13:260:24 | new[] | semmle.label | new[] |
|
| test.cpp:260:13:260:24 | new[] | semmle.label | new[] |
|
||||||
| test.cpp:261:14:261:21 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:261:14:261:21 | ... + ... | semmle.label | ... + ... |
|
||||||
| test.cpp:261:14:261:21 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:261:14:261:21 | ... + ... | semmle.label | ... + ... |
|
||||||
@@ -232,45 +137,31 @@ nodes
|
|||||||
| test.cpp:355:14:355:27 | new[] | semmle.label | new[] |
|
| test.cpp:355:14:355:27 | new[] | semmle.label | new[] |
|
||||||
| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... |
|
||||||
| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... |
|
||||||
| test.cpp:357:24:357:30 | ... + ... | semmle.label | ... + ... |
|
|
||||||
| test.cpp:357:24:357:30 | ... + ... | semmle.label | ... + ... |
|
|
||||||
| test.cpp:358:14:358:26 | end_plus_one indirection | semmle.label | end_plus_one indirection |
|
| test.cpp:358:14:358:26 | end_plus_one indirection | semmle.label | end_plus_one indirection |
|
||||||
| test.cpp:359:14:359:32 | ... + ... indirection | semmle.label | ... + ... indirection |
|
| test.cpp:359:14:359:32 | ... + ... indirection | semmle.label | ... + ... indirection |
|
||||||
| test.cpp:377:14:377:27 | new[] | semmle.label | new[] |
|
| test.cpp:377:14:377:27 | new[] | semmle.label | new[] |
|
||||||
| test.cpp:378:15:378:23 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:378:15:378:23 | ... + ... | semmle.label | ... + ... |
|
||||||
| test.cpp:378:15:378:23 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:378:15:378:23 | ... + ... | semmle.label | ... + ... |
|
||||||
| test.cpp:381:5:381:9 | ... ++ | semmle.label | ... ++ |
|
|
||||||
| test.cpp:381:5:381:9 | ... ++ | semmle.label | ... ++ |
|
|
||||||
| test.cpp:384:13:384:16 | end indirection | semmle.label | end indirection |
|
| test.cpp:384:13:384:16 | end indirection | semmle.label | end indirection |
|
||||||
| test.cpp:410:14:410:27 | new[] | semmle.label | new[] |
|
| test.cpp:410:14:410:27 | new[] | semmle.label | new[] |
|
||||||
| test.cpp:411:15:411:23 | & ... | semmle.label | & ... |
|
| test.cpp:411:15:411:23 | & ... | semmle.label | & ... |
|
||||||
| test.cpp:411:15:411:23 | & ... | semmle.label | & ... |
|
| test.cpp:411:15:411:23 | & ... | semmle.label | & ... |
|
||||||
| test.cpp:413:5:413:8 | ... ++ | semmle.label | ... ++ |
|
|
||||||
| test.cpp:413:5:413:8 | ... ++ | semmle.label | ... ++ |
|
|
||||||
| test.cpp:415:7:415:15 | ... = ... | semmle.label | ... = ... |
|
| test.cpp:415:7:415:15 | ... = ... | semmle.label | ... = ... |
|
||||||
| test.cpp:421:14:421:27 | new[] | semmle.label | new[] |
|
| test.cpp:421:14:421:27 | new[] | semmle.label | new[] |
|
||||||
| test.cpp:422:15:422:23 | & ... | semmle.label | & ... |
|
| test.cpp:422:15:422:23 | & ... | semmle.label | & ... |
|
||||||
| test.cpp:422:15:422:23 | & ... | semmle.label | & ... |
|
| test.cpp:422:15:422:23 | & ... | semmle.label | & ... |
|
||||||
| test.cpp:424:5:424:8 | ... ++ | semmle.label | ... ++ |
|
|
||||||
| test.cpp:424:5:424:8 | ... ++ | semmle.label | ... ++ |
|
|
||||||
| test.cpp:426:7:426:15 | ... = ... | semmle.label | ... = ... |
|
| test.cpp:426:7:426:15 | ... = ... | semmle.label | ... = ... |
|
||||||
| test.cpp:432:14:432:27 | new[] | semmle.label | new[] |
|
| test.cpp:432:14:432:27 | new[] | semmle.label | new[] |
|
||||||
| test.cpp:433:15:433:23 | & ... | semmle.label | & ... |
|
| test.cpp:433:15:433:23 | & ... | semmle.label | & ... |
|
||||||
| test.cpp:433:15:433:23 | & ... | semmle.label | & ... |
|
| test.cpp:433:15:433:23 | & ... | semmle.label | & ... |
|
||||||
| test.cpp:436:5:436:8 | ... ++ | semmle.label | ... ++ |
|
|
||||||
| test.cpp:436:5:436:8 | ... ++ | semmle.label | ... ++ |
|
|
||||||
| test.cpp:438:7:438:15 | ... = ... | semmle.label | ... = ... |
|
| test.cpp:438:7:438:15 | ... = ... | semmle.label | ... = ... |
|
||||||
| test.cpp:444:14:444:27 | new[] | semmle.label | new[] |
|
| test.cpp:444:14:444:27 | new[] | semmle.label | new[] |
|
||||||
| test.cpp:445:15:445:23 | & ... | semmle.label | & ... |
|
| test.cpp:445:15:445:23 | & ... | semmle.label | & ... |
|
||||||
| test.cpp:445:15:445:23 | & ... | semmle.label | & ... |
|
| test.cpp:445:15:445:23 | & ... | semmle.label | & ... |
|
||||||
| test.cpp:448:5:448:8 | ... ++ | semmle.label | ... ++ |
|
|
||||||
| test.cpp:448:5:448:8 | ... ++ | semmle.label | ... ++ |
|
|
||||||
| test.cpp:450:7:450:15 | ... = ... | semmle.label | ... = ... |
|
| test.cpp:450:7:450:15 | ... = ... | semmle.label | ... = ... |
|
||||||
| test.cpp:480:14:480:27 | new[] | semmle.label | new[] |
|
| test.cpp:480:14:480:27 | new[] | semmle.label | new[] |
|
||||||
| test.cpp:481:15:481:23 | & ... | semmle.label | & ... |
|
| test.cpp:481:15:481:23 | & ... | semmle.label | & ... |
|
||||||
| test.cpp:481:15:481:23 | & ... | semmle.label | & ... |
|
| test.cpp:481:15:481:23 | & ... | semmle.label | & ... |
|
||||||
| test.cpp:484:5:484:8 | ... ++ | semmle.label | ... ++ |
|
|
||||||
| test.cpp:484:5:484:8 | ... ++ | semmle.label | ... ++ |
|
|
||||||
| test.cpp:486:7:486:15 | ... = ... | semmle.label | ... = ... |
|
| test.cpp:486:7:486:15 | ... = ... | semmle.label | ... = ... |
|
||||||
| test.cpp:543:14:543:27 | new[] | semmle.label | new[] |
|
| test.cpp:543:14:543:27 | new[] | semmle.label | new[] |
|
||||||
| test.cpp:548:5:548:19 | ... = ... | semmle.label | ... = ... |
|
| test.cpp:548:5:548:19 | ... = ... | semmle.label | ... = ... |
|
||||||
@@ -278,15 +169,6 @@ nodes
|
|||||||
| test.cpp:559:5:559:19 | ... = ... | semmle.label | ... = ... |
|
| test.cpp:559:5:559:19 | ... = ... | semmle.label | ... = ... |
|
||||||
| test.cpp:642:14:642:31 | new[] | semmle.label | new[] |
|
| test.cpp:642:14:642:31 | new[] | semmle.label | new[] |
|
||||||
| test.cpp:647:5:647:19 | ... = ... | semmle.label | ... = ... |
|
| test.cpp:647:5:647:19 | ... = ... | semmle.label | ... = ... |
|
||||||
| test.cpp:695:13:695:26 | new[] | semmle.label | new[] |
|
|
||||||
| test.cpp:698:5:698:10 | ... += ... | semmle.label | ... += ... |
|
|
||||||
| test.cpp:698:5:698:10 | ... += ... | semmle.label | ... += ... |
|
|
||||||
| test.cpp:701:15:701:16 | p indirection | semmle.label | p indirection |
|
|
||||||
| test.cpp:705:18:705:18 | q | semmle.label | q |
|
|
||||||
| test.cpp:705:18:705:18 | q | semmle.label | q |
|
|
||||||
| test.cpp:706:12:706:13 | * ... | semmle.label | * ... |
|
|
||||||
| test.cpp:711:13:711:26 | new[] | semmle.label | new[] |
|
|
||||||
| test.cpp:714:11:714:11 | q | semmle.label | q |
|
|
||||||
| test.cpp:730:12:730:28 | new[] | semmle.label | new[] |
|
| test.cpp:730:12:730:28 | new[] | semmle.label | new[] |
|
||||||
| test.cpp:732:16:732:26 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:732:16:732:26 | ... + ... | semmle.label | ... + ... |
|
||||||
| test.cpp:732:16:732:26 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:732:16:732:26 | ... + ... | semmle.label | ... + ... |
|
||||||
@@ -300,7 +182,6 @@ nodes
|
|||||||
| test.cpp:786:18:786:27 | access to array | semmle.label | access to array |
|
| test.cpp:786:18:786:27 | access to array | semmle.label | access to array |
|
||||||
| test.cpp:792:60:792:62 | end | semmle.label | end |
|
| test.cpp:792:60:792:62 | end | semmle.label | end |
|
||||||
| test.cpp:793:14:793:32 | call to malloc | semmle.label | call to malloc |
|
| test.cpp:793:14:793:32 | call to malloc | semmle.label | call to malloc |
|
||||||
| test.cpp:794:5:794:24 | ... = ... | semmle.label | ... = ... |
|
|
||||||
| test.cpp:794:12:794:24 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:794:12:794:24 | ... + ... | semmle.label | ... + ... |
|
||||||
| test.cpp:800:40:800:43 | mk_array_no_field_flow output argument | semmle.label | mk_array_no_field_flow output argument |
|
| test.cpp:800:40:800:43 | mk_array_no_field_flow output argument | semmle.label | mk_array_no_field_flow output argument |
|
||||||
| test.cpp:807:7:807:12 | ... = ... | semmle.label | ... = ... |
|
| test.cpp:807:7:807:12 | ... = ... | semmle.label | ... = ... |
|
||||||
@@ -325,10 +206,7 @@ subpaths
|
|||||||
| test.cpp:30:14:30:15 | * ... | test.cpp:28:15:28:37 | call to malloc | test.cpp:30:14:30:15 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:28:15:28:37 | call to malloc | call to malloc | test.cpp:29:20:29:27 | ... + ... | ... + ... |
|
| test.cpp:30:14:30:15 | * ... | test.cpp:28:15:28:37 | call to malloc | test.cpp:30:14:30:15 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:28:15:28:37 | call to malloc | call to malloc | test.cpp:29:20:29:27 | ... + ... | ... + ... |
|
||||||
| test.cpp:32:14:32:21 | * ... | test.cpp:28:15:28:37 | call to malloc | test.cpp:32:14:32:21 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:28:15:28:37 | call to malloc | call to malloc | test.cpp:29:20:29:27 | ... + ... | ... + ... |
|
| test.cpp:32:14:32:21 | * ... | test.cpp:28:15:28:37 | call to malloc | test.cpp:32:14:32:21 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:28:15:28:37 | call to malloc | call to malloc | test.cpp:29:20:29:27 | ... + ... | ... + ... |
|
||||||
| test.cpp:67:9:67:14 | ... = ... | test.cpp:52:19:52:37 | call to malloc | test.cpp:67:9:67:14 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:52:19:52:37 | call to malloc | call to malloc | test.cpp:53:20:53:23 | size | size |
|
| test.cpp:67:9:67:14 | ... = ... | test.cpp:52:19:52:37 | call to malloc | test.cpp:67:9:67:14 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:52:19:52:37 | call to malloc | call to malloc | test.cpp:53:20:53:23 | size | size |
|
||||||
| test.cpp:201:5:201:19 | ... = ... | test.cpp:194:15:194:33 | call to malloc | test.cpp:201:5:201:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:194:15:194:33 | call to malloc | call to malloc | test.cpp:195:21:195:23 | len | len |
|
|
||||||
| test.cpp:213:5:213:13 | ... = ... | test.cpp:205:15:205:33 | call to malloc | test.cpp:213:5:213:13 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:205:15:205:33 | call to malloc | call to malloc | test.cpp:206:21:206:23 | len | len |
|
| test.cpp:213:5:213:13 | ... = ... | test.cpp:205:15:205:33 | call to malloc | test.cpp:213:5:213:13 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:205:15:205:33 | call to malloc | call to malloc | test.cpp:206:21:206:23 | len | len |
|
||||||
| test.cpp:232:3:232:20 | ... = ... | test.cpp:231:18:231:30 | new[] | test.cpp:232:3:232:20 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:231:18:231:30 | new[] | new[] | test.cpp:232:11:232:15 | index | index |
|
|
||||||
| test.cpp:239:5:239:22 | ... = ... | test.cpp:238:20:238:32 | new[] | test.cpp:239:5:239:22 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:238:20:238:32 | new[] | new[] | test.cpp:239:13:239:17 | index | index |
|
|
||||||
| test.cpp:264:13:264:14 | * ... | test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:260:13:260:24 | new[] | new[] | test.cpp:261:19:261:21 | len | len |
|
| test.cpp:264:13:264:14 | * ... | test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:260:13:260:24 | new[] | new[] | test.cpp:261:19:261:21 | len | len |
|
||||||
| test.cpp:274:5:274:10 | ... = ... | test.cpp:270:13:270:24 | new[] | test.cpp:274:5:274:10 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:270:13:270:24 | new[] | new[] | test.cpp:271:19:271:21 | len | len |
|
| test.cpp:274:5:274:10 | ... = ... | test.cpp:270:13:270:24 | new[] | test.cpp:274:5:274:10 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:270:13:270:24 | new[] | new[] | test.cpp:271:19:271:21 | len | len |
|
||||||
| test.cpp:358:14:358:26 | end_plus_one indirection | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | end_plus_one indirection | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size |
|
| test.cpp:358:14:358:26 | end_plus_one indirection | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | end_plus_one indirection | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size |
|
||||||
@@ -342,8 +220,6 @@ subpaths
|
|||||||
| test.cpp:548:5:548:19 | ... = ... | test.cpp:543:14:543:27 | new[] | test.cpp:548:5:548:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:543:14:543:27 | new[] | new[] | test.cpp:548:8:548:14 | src_pos | src_pos |
|
| test.cpp:548:5:548:19 | ... = ... | test.cpp:543:14:543:27 | new[] | test.cpp:548:5:548:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:543:14:543:27 | new[] | new[] | test.cpp:548:8:548:14 | src_pos | src_pos |
|
||||||
| test.cpp:559:5:559:19 | ... = ... | test.cpp:554:14:554:27 | new[] | test.cpp:559:5:559:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:554:14:554:27 | new[] | new[] | test.cpp:559:8:559:14 | src_pos | src_pos |
|
| test.cpp:559:5:559:19 | ... = ... | test.cpp:554:14:554:27 | new[] | test.cpp:559:5:559:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:554:14:554:27 | new[] | new[] | test.cpp:559:8:559:14 | src_pos | src_pos |
|
||||||
| test.cpp:647:5:647:19 | ... = ... | test.cpp:642:14:642:31 | new[] | test.cpp:647:5:647:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:642:14:642:31 | new[] | new[] | test.cpp:647:8:647:14 | src_pos | src_pos |
|
| test.cpp:647:5:647:19 | ... = ... | test.cpp:642:14:642:31 | new[] | test.cpp:647:5:647:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:642:14:642:31 | new[] | new[] | test.cpp:647:8:647:14 | src_pos | src_pos |
|
||||||
| test.cpp:701:15:701:16 | p indirection | test.cpp:695:13:695:26 | new[] | test.cpp:701:15:701:16 | p indirection | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:695:13:695:26 | new[] | new[] | test.cpp:696:19:696:22 | size | size |
|
|
||||||
| test.cpp:706:12:706:13 | * ... | test.cpp:711:13:711:26 | new[] | test.cpp:706:12:706:13 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:711:13:711:26 | new[] | new[] | test.cpp:712:19:712:22 | size | size |
|
|
||||||
| test.cpp:733:5:733:12 | ... = ... | test.cpp:730:12:730:28 | new[] | test.cpp:733:5:733:12 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:730:12:730:28 | new[] | new[] | test.cpp:732:21:732:25 | ... + ... | ... + ... |
|
| test.cpp:733:5:733:12 | ... = ... | test.cpp:730:12:730:28 | new[] | test.cpp:733:5:733:12 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:730:12:730:28 | new[] | new[] | test.cpp:732:21:732:25 | ... + ... | ... + ... |
|
||||||
| test.cpp:767:16:767:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:767:16:767:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:767:22:767:28 | ... + ... | ... + ... |
|
| test.cpp:767:16:767:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:767:16:767:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:767:22:767:28 | ... + ... | ... + ... |
|
||||||
| test.cpp:767:16:767:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:767:16:767:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:772:22:772:28 | ... + ... | ... + ... |
|
| test.cpp:767:16:767:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:767:16:767:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:772:22:772:28 | ... + ... | ... + ... |
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ using size_t = decltype(sizeof 0); void* malloc(size_t size);
|
|||||||
void test1(int size) {
|
void test1(int size) {
|
||||||
char* p = (char*)malloc(size);
|
char* p = (char*)malloc(size);
|
||||||
char* q = p + size; // $ alloc=L4
|
char* q = p + size; // $ alloc=L4
|
||||||
char a = *q; // $ deref=L6 // BAD
|
char a = *q; // $ deref=L5->L6 // BAD
|
||||||
char b = *(q - 1); // GOOD
|
char b = *(q - 1); // GOOD
|
||||||
char c = *(q + 1); // $ deref=L8+1 // BAD
|
char c = *(q + 1); // $ deref=L5->L8+1 // BAD
|
||||||
char d = *(q + size); // BAD [NOT DETECTED]
|
char d = *(q + size); // BAD [NOT DETECTED]
|
||||||
char e = *(q - size); // GOOD
|
char e = *(q - size); // GOOD
|
||||||
char f = *(q + size + 1); // BAD [NOT DETECTED]
|
char f = *(q + size + 1); // BAD [NOT DETECTED]
|
||||||
@@ -17,7 +17,7 @@ void test2(int size) {
|
|||||||
char* q = p + size - 1; // $ alloc=L16
|
char* q = p + size - 1; // $ alloc=L16
|
||||||
char a = *q; // GOOD
|
char a = *q; // GOOD
|
||||||
char b = *(q - 1); // GOOD
|
char b = *(q - 1); // GOOD
|
||||||
char c = *(q + 1); // $ deref=L20 // BAD
|
char c = *(q + 1); // $ deref=L17->L20 // BAD
|
||||||
char d = *(q + size); // BAD [NOT DETECTED]
|
char d = *(q + size); // BAD [NOT DETECTED]
|
||||||
char e = *(q - size); // GOOD
|
char e = *(q - size); // GOOD
|
||||||
char f = *(q + size + 1); // BAD [NOT DETECTED]
|
char f = *(q + size + 1); // BAD [NOT DETECTED]
|
||||||
@@ -27,9 +27,9 @@ void test2(int size) {
|
|||||||
void test3(int size) {
|
void test3(int size) {
|
||||||
char* p = (char*)malloc(size + 1);
|
char* p = (char*)malloc(size + 1);
|
||||||
char* q = p + (size + 1); // $ alloc=L28+1
|
char* q = p + (size + 1); // $ alloc=L28+1
|
||||||
char a = *q; // $ deref=L30 // BAD
|
char a = *q; // $ deref=L29->L30 // BAD
|
||||||
char b = *(q - 1); // GOOD
|
char b = *(q - 1); // GOOD
|
||||||
char c = *(q + 1); // $ deref=L32+1 // BAD
|
char c = *(q + 1); // $ deref=L29->L32+1 // BAD
|
||||||
char d = *(q + size); // BAD [NOT DETECTED]
|
char d = *(q + size); // BAD [NOT DETECTED]
|
||||||
char e = *(q - size); // GOOD
|
char e = *(q - size); // GOOD
|
||||||
char f = *(q + size + 1); // BAD [NOT DETECTED]
|
char f = *(q + size + 1); // BAD [NOT DETECTED]
|
||||||
@@ -198,7 +198,7 @@ void test12(unsigned len, unsigned index) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
p[index] = '\0'; // $ deref=L201 // BAD
|
p[index] = '\0'; // $ MISSING: deref=L195->L201 // BAD [NOT DETECTED]
|
||||||
}
|
}
|
||||||
|
|
||||||
void test13(unsigned len, unsigned index) {
|
void test13(unsigned len, unsigned index) {
|
||||||
@@ -210,7 +210,7 @@ void test13(unsigned len, unsigned index) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*q = '\0'; // $ deref=L213 // BAD
|
*q = '\0'; // $ deref=L206->L213 // BAD
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unknown();
|
bool unknown();
|
||||||
@@ -229,14 +229,14 @@ void test15(unsigned index) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int* newname = new int[size];
|
int* newname = new int[size];
|
||||||
newname[index] = 0; // $ alloc=L231 deref=L232 // GOOD [FALSE POSITIVE]
|
newname[index] = 0; // GOOD
|
||||||
}
|
}
|
||||||
|
|
||||||
void test16(unsigned index) {
|
void test16(unsigned index) {
|
||||||
unsigned size = index + 13;
|
unsigned size = index + 13;
|
||||||
if(size >= index) {
|
if(size >= index) {
|
||||||
int* newname = new int[size];
|
int* newname = new int[size];
|
||||||
newname[index] = 0; // $ alloc=L238 deref=L239 // GOOD [FALSE POSITIVE]
|
newname[index] = 0; // GOOD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,7 +261,7 @@ void test17(unsigned len)
|
|||||||
int *end = xs + len; // $ alloc=L260
|
int *end = xs + len; // $ alloc=L260
|
||||||
for (int *x = xs; x <= end; x++)
|
for (int *x = xs; x <= end; x++)
|
||||||
{
|
{
|
||||||
int i = *x; // $ deref=L264 // BAD
|
int i = *x; // $ deref=L261->L264 // BAD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +271,7 @@ void test18(unsigned len)
|
|||||||
int *end = xs + len; // $ alloc=L270
|
int *end = xs + len; // $ alloc=L270
|
||||||
for (int *x = xs; x <= end; x++)
|
for (int *x = xs; x <= end; x++)
|
||||||
{
|
{
|
||||||
*x = 0; // $ deref=L274 // BAD
|
*x = 0; // $ deref=L271->L274 // BAD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,8 +355,8 @@ void test25(unsigned size) {
|
|||||||
char *xs = new char[size];
|
char *xs = new char[size];
|
||||||
char *end = xs + size; // $ alloc=L355
|
char *end = xs + size; // $ alloc=L355
|
||||||
char *end_plus_one = end + 1;
|
char *end_plus_one = end + 1;
|
||||||
int val1 = *end_plus_one; // $ deref=L358+1 // BAD
|
int val1 = *end_plus_one; // $ deref=L356->L358+1 // BAD
|
||||||
int val2 = *(end_plus_one + 1); // $ deref=L359+2 // BAD
|
int val2 = *(end_plus_one + 1); // $ deref=L356->L359+2 // BAD
|
||||||
}
|
}
|
||||||
|
|
||||||
void test26(unsigned size) {
|
void test26(unsigned size) {
|
||||||
@@ -381,7 +381,7 @@ void test27(unsigned size, bool b) {
|
|||||||
end++;
|
end++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int val = *end; // $ deref=L384+1 // BAD
|
int val = *end; // $ deref=L378->L384+1 // BAD
|
||||||
}
|
}
|
||||||
|
|
||||||
void test28(unsigned size) {
|
void test28(unsigned size) {
|
||||||
@@ -412,7 +412,7 @@ void test28_simple2(unsigned size) {
|
|||||||
if (xs < end) {
|
if (xs < end) {
|
||||||
xs++;
|
xs++;
|
||||||
if (xs < end + 1) {
|
if (xs < end + 1) {
|
||||||
xs[0] = 0; // $ deref=L415 // BAD
|
xs[0] = 0; // $ deref=L411->L415 // BAD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -423,7 +423,7 @@ void test28_simple3(unsigned size) {
|
|||||||
if (xs < end) {
|
if (xs < end) {
|
||||||
xs++;
|
xs++;
|
||||||
if (xs - 1 < end) {
|
if (xs - 1 < end) {
|
||||||
xs[0] = 0; // $ deref=L426 // BAD
|
xs[0] = 0; // $ deref=L422->L426 // BAD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -435,7 +435,7 @@ void test28_simple4(unsigned size) {
|
|||||||
end++;
|
end++;
|
||||||
xs++;
|
xs++;
|
||||||
if (xs < end) {
|
if (xs < end) {
|
||||||
xs[0] = 0; // $ deref=L438 // BAD
|
xs[0] = 0; // $ deref=L433->L438 // BAD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -447,7 +447,7 @@ void test28_simple5(unsigned size) {
|
|||||||
if (xs < end) {
|
if (xs < end) {
|
||||||
xs++;
|
xs++;
|
||||||
if (xs < end) {
|
if (xs < end) {
|
||||||
xs[0] = 0; // $ deref=L450 // BAD
|
xs[0] = 0; // $ deref=L445->L450 // BAD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -483,7 +483,7 @@ void test28_simple8(unsigned size) {
|
|||||||
if (xs < end) {
|
if (xs < end) {
|
||||||
xs++;
|
xs++;
|
||||||
if (xs < end - 1) {
|
if (xs < end - 1) {
|
||||||
xs[0] = 0; // $ deref=L486+498 // BAD
|
xs[0] = 0; // $ deref=L481->L486+498 // BAD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -698,12 +698,12 @@ void test34(unsigned size) {
|
|||||||
p += 1;
|
p += 1;
|
||||||
}
|
}
|
||||||
if (p + 1 < end) {
|
if (p + 1 < end) {
|
||||||
int val = *p; // $ deref=L698->L700->L701 // GOOD [FALSE POSITIVE]
|
int val = *p; // GOOD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void deref(char* q) {
|
void deref(char* q) {
|
||||||
char x = *q; // $ deref=L714->L705->L706 // BAD
|
char x = *q; // $ MISSING: deref=L714->L705->L706 // BAD [NOT DETECTED]
|
||||||
}
|
}
|
||||||
|
|
||||||
void test35(size_t size, char* q)
|
void test35(size_t size, char* q)
|
||||||
@@ -730,7 +730,7 @@ void test36(unsigned size, unsigned n) {
|
|||||||
int* p = new int[size + 2];
|
int* p = new int[size + 2];
|
||||||
if(n < size + 1) {
|
if(n < size + 1) {
|
||||||
int* end = p + (n + 2); // $ alloc=L730+2
|
int* end = p + (n + 2); // $ alloc=L730+2
|
||||||
*end = 0; // $ deref=L733 // BAD
|
*end = 0; // $ deref=L732->L733 // BAD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -857,6 +857,6 @@ void test_regression(size_t size) {
|
|||||||
int* chend = p + (size + 1); // $ alloc=L856+1
|
int* chend = p + (size + 1); // $ alloc=L856+1
|
||||||
|
|
||||||
if(p <= chend) {
|
if(p <= chend) {
|
||||||
*p = 42; // $ deref=L860 // BAD
|
*p = 42; // $ deref=L857->L860 // BAD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,7 @@
|
|||||||
| test.cpp:12:6:12:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:11:6:11:8 | foo | foo |
|
| test.cpp:12:6:12:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:11:6:11:8 | foo | foo |
|
||||||
| test.cpp:30:6:30:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:26:6:26:8 | foo | foo |
|
|
||||||
| test.cpp:46:6:46:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:42:6:42:8 | foo | foo |
|
|
||||||
| test.cpp:55:7:55:9 | foo | The variable $@ may not be initialized at this access. | test.cpp:50:6:50:8 | foo | foo |
|
|
||||||
| test.cpp:67:7:67:9 | foo | The variable $@ may not be initialized at this access. | test.cpp:61:6:61:8 | foo | foo |
|
|
||||||
| test.cpp:92:6:92:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:82:6:82:8 | foo | foo |
|
|
||||||
| test.cpp:113:6:113:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:111:6:111:8 | foo | foo |
|
| test.cpp:113:6:113:8 | foo | The variable $@ may not be initialized at this access. | test.cpp:111:6:111:8 | foo | foo |
|
||||||
| test.cpp:132:9:132:9 | j | The variable $@ may not be initialized at this access. | test.cpp:126:6:126:6 | j | j |
|
|
||||||
| test.cpp:219:3:219:3 | x | The variable $@ may not be initialized at this access. | test.cpp:218:7:218:7 | x | x |
|
| test.cpp:219:3:219:3 | x | The variable $@ may not be initialized at this access. | test.cpp:218:7:218:7 | x | x |
|
||||||
| test.cpp:243:13:243:13 | i | The variable $@ may not be initialized at this access. | test.cpp:241:6:241:6 | i | i |
|
| test.cpp:243:13:243:13 | i | The variable $@ may not be initialized at this access. | test.cpp:241:6:241:6 | i | i |
|
||||||
| test.cpp:329:9:329:11 | val | The variable $@ may not be initialized at this access. | test.cpp:321:6:321:8 | val | val |
|
|
||||||
| test.cpp:336:10:336:10 | a | The variable $@ may not be initialized at this access. | test.cpp:333:7:333:7 | a | a |
|
| test.cpp:336:10:336:10 | a | The variable $@ may not be initialized at this access. | test.cpp:333:7:333:7 | a | a |
|
||||||
| test.cpp:369:10:369:10 | a | The variable $@ may not be initialized at this access. | test.cpp:358:7:358:7 | a | a |
|
| test.cpp:369:10:369:10 | a | The variable $@ may not be initialized at this access. | test.cpp:358:7:358:7 | a | a |
|
||||||
| test.cpp:378:9:378:11 | val | The variable $@ may not be initialized at this access. | test.cpp:359:6:359:8 | val | val |
|
| test.cpp:378:9:378:11 | val | The variable $@ may not be initialized at this access. | test.cpp:359:6:359:8 | val | val |
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ void test4(bool b) {
|
|||||||
if (b) {
|
if (b) {
|
||||||
foo = 1;
|
foo = 1;
|
||||||
}
|
}
|
||||||
use(foo); // BAD
|
use(foo); // BAD [NOT DETECTED]
|
||||||
}
|
}
|
||||||
|
|
||||||
void test5() {
|
void test5() {
|
||||||
@@ -43,7 +43,7 @@ void test5(int count) {
|
|||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
foo = i;
|
foo = i;
|
||||||
}
|
}
|
||||||
use(foo); // BAD
|
use(foo); // BAD [NOT DETECTED]
|
||||||
}
|
}
|
||||||
|
|
||||||
void test6(bool b) {
|
void test6(bool b) {
|
||||||
@@ -52,7 +52,7 @@ void test6(bool b) {
|
|||||||
foo = 42;
|
foo = 42;
|
||||||
}
|
}
|
||||||
if (b) {
|
if (b) {
|
||||||
use(foo); // GOOD (REPORTED, FP)
|
use(foo); // GOOD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ void test7(bool b) {
|
|||||||
set = true;
|
set = true;
|
||||||
}
|
}
|
||||||
if (set) {
|
if (set) {
|
||||||
use(foo); // GOOD (REPORTED, FP)
|
use(foo); // GOOD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ void test9(int count) {
|
|||||||
if (!set) {
|
if (!set) {
|
||||||
foo = 42;
|
foo = 42;
|
||||||
}
|
}
|
||||||
use(foo); // GOOD (REPORTED, FP)
|
use(foo); // GOOD
|
||||||
}
|
}
|
||||||
|
|
||||||
void test10() {
|
void test10() {
|
||||||
@@ -129,7 +129,7 @@ int absWrong(int i) {
|
|||||||
} else if (i < 0) {
|
} else if (i < 0) {
|
||||||
j = -i;
|
j = -i;
|
||||||
}
|
}
|
||||||
return j; // wrong: j may not be initialized before use
|
return j; // wrong: j may not be initialized before use [NOT DETECTED]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Example from qhelp
|
// Example from qhelp
|
||||||
@@ -326,7 +326,7 @@ int test28() {
|
|||||||
a = false;
|
a = false;
|
||||||
c = false;
|
c = false;
|
||||||
}
|
}
|
||||||
return val; // GOOD [FALSE POSITIVE]
|
return val; // GOOD
|
||||||
}
|
}
|
||||||
|
|
||||||
int test29() {
|
int test29() {
|
||||||
@@ -473,3 +473,63 @@ void test44() {
|
|||||||
|
|
||||||
void(x + y); // BAD
|
void(x + y); // BAD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class State { StateA, StateB, StateC };
|
||||||
|
|
||||||
|
int exhaustive_switch(State s) {
|
||||||
|
int y;
|
||||||
|
switch(s) {
|
||||||
|
case State::StateA:
|
||||||
|
y = 1;
|
||||||
|
break;
|
||||||
|
case State::StateB:
|
||||||
|
y = 2;
|
||||||
|
break;
|
||||||
|
case State::StateC:
|
||||||
|
y = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return y; // GOOD (y is always initialized)
|
||||||
|
}
|
||||||
|
|
||||||
|
int exhaustive_switch_2(State s) {
|
||||||
|
int y;
|
||||||
|
switch(s) {
|
||||||
|
case State::StateA:
|
||||||
|
y = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
y = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return y; // GOOD (y is always initialized)
|
||||||
|
}
|
||||||
|
|
||||||
|
int non_exhaustive_switch(State s) {
|
||||||
|
int y;
|
||||||
|
switch(s) {
|
||||||
|
case State::StateA:
|
||||||
|
y = 1;
|
||||||
|
break;
|
||||||
|
case State::StateB:
|
||||||
|
y = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return y; // BAD [NOT DETECTED] (y is not initialized when s = StateC)
|
||||||
|
}
|
||||||
|
|
||||||
|
int non_exhaustive_switch_2(State s) {
|
||||||
|
int y;
|
||||||
|
switch(s) {
|
||||||
|
case State::StateA:
|
||||||
|
y = 1;
|
||||||
|
break;
|
||||||
|
case State::StateB:
|
||||||
|
y = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(s != State::StateC) {
|
||||||
|
return y; // GOOD (y is not initialized when s = StateC, but if s = StateC we won't reach this point)
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ edges
|
|||||||
| tests.cpp:131:14:131:35 | call to getenv indirection | tests.cpp:107:30:107:32 | msg indirection |
|
| tests.cpp:131:14:131:35 | call to getenv indirection | tests.cpp:107:30:107:32 | msg indirection |
|
||||||
| tests.cpp:132:14:132:35 | call to getenv indirection | tests.cpp:114:30:114:32 | msg indirection |
|
| tests.cpp:132:14:132:35 | call to getenv indirection | tests.cpp:114:30:114:32 | msg indirection |
|
||||||
| tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:122:30:122:32 | msg indirection |
|
| tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:122:30:122:32 | msg indirection |
|
||||||
|
| tests.cpp:139:17:139:22 | call to getenv indirection | tests.cpp:141:15:141:20 | secret indirection |
|
||||||
| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:18:29:18:31 | pwd indirection |
|
| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:18:29:18:31 | pwd indirection |
|
||||||
| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:19:26:19:28 | pwd indirection |
|
| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:19:26:19:28 | pwd indirection |
|
||||||
nodes
|
nodes
|
||||||
@@ -37,6 +38,8 @@ nodes
|
|||||||
| tests.cpp:132:14:132:35 | call to getenv indirection | semmle.label | call to getenv indirection |
|
| tests.cpp:132:14:132:35 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||||
| tests.cpp:133:14:133:35 | call to getenv indirection | semmle.label | call to getenv indirection |
|
| tests.cpp:133:14:133:35 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||||
| tests.cpp:133:14:133:35 | call to getenv indirection | semmle.label | call to getenv indirection |
|
| tests.cpp:133:14:133:35 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||||
|
| tests.cpp:139:17:139:22 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||||
|
| tests.cpp:141:15:141:20 | secret indirection | semmle.label | secret indirection |
|
||||||
| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | semmle.label | call to getpwnam indirection |
|
| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | semmle.label | call to getpwnam indirection |
|
||||||
| tests_passwd.cpp:18:29:18:31 | pwd indirection | semmle.label | pwd indirection |
|
| tests_passwd.cpp:18:29:18:31 | pwd indirection | semmle.label | pwd indirection |
|
||||||
| tests_passwd.cpp:19:26:19:28 | pwd indirection | semmle.label | pwd indirection |
|
| tests_passwd.cpp:19:26:19:28 | pwd indirection | semmle.label | pwd indirection |
|
||||||
@@ -56,5 +59,6 @@ subpaths
|
|||||||
| tests.cpp:119:7:119:12 | buffer indirection | tests.cpp:132:14:132:35 | call to getenv indirection | tests.cpp:119:7:119:12 | buffer indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:132:14:132:35 | call to getenv indirection | call to getenv indirection |
|
| tests.cpp:119:7:119:12 | buffer indirection | tests.cpp:132:14:132:35 | call to getenv indirection | tests.cpp:119:7:119:12 | buffer indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:132:14:132:35 | call to getenv indirection | call to getenv indirection |
|
||||||
| tests.cpp:124:15:124:17 | msg indirection | tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:124:15:124:17 | msg indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:35 | call to getenv indirection | call to getenv indirection |
|
| tests.cpp:124:15:124:17 | msg indirection | tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:124:15:124:17 | msg indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:35 | call to getenv indirection | call to getenv indirection |
|
||||||
| tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:133:14:133:35 | call to getenv indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:35 | call to getenv indirection | call to getenv indirection |
|
| tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:133:14:133:35 | call to getenv indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:35 | call to getenv indirection | call to getenv indirection |
|
||||||
|
| tests.cpp:141:15:141:20 | secret indirection | tests.cpp:139:17:139:22 | call to getenv indirection | tests.cpp:141:15:141:20 | secret indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:139:17:139:22 | call to getenv indirection | call to getenv indirection |
|
||||||
| tests_passwd.cpp:18:29:18:31 | pwd indirection | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:18:29:18:31 | pwd indirection | This operation potentially exposes sensitive system data from $@. | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | call to getpwnam indirection |
|
| tests_passwd.cpp:18:29:18:31 | pwd indirection | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:18:29:18:31 | pwd indirection | This operation potentially exposes sensitive system data from $@. | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | call to getpwnam indirection |
|
||||||
| tests_passwd.cpp:19:26:19:28 | pwd indirection | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:19:26:19:28 | pwd indirection | This operation potentially exposes sensitive system data from $@. | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | call to getpwnam indirection |
|
| tests_passwd.cpp:19:26:19:28 | pwd indirection | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:19:26:19:28 | pwd indirection | This operation potentially exposes sensitive system data from $@. | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | call to getpwnam indirection |
|
||||||
|
|||||||
@@ -132,3 +132,13 @@ void test5()
|
|||||||
myOutputFn4(getenv("SECRET_TOKEN")); // BAD: outputs the SECRET_TOKEN environment variable
|
myOutputFn4(getenv("SECRET_TOKEN")); // BAD: outputs the SECRET_TOKEN environment variable
|
||||||
myOutputFn5(getenv("SECRET_TOKEN")); // BAD: outputs the SECRET_TOKEN environment variable
|
myOutputFn5(getenv("SECRET_TOKEN")); // BAD: outputs the SECRET_TOKEN environment variable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RtlZeroMemory(void* dst, size_t len);
|
||||||
|
|
||||||
|
void test_clear_memory(char *username) {
|
||||||
|
char* secret = getenv("SECRET_TOKEN");
|
||||||
|
|
||||||
|
printf("%s", secret); // BAD
|
||||||
|
RtlZeroMemory(secret, 1024);
|
||||||
|
printf("%s", secret); // GOOD
|
||||||
|
}
|
||||||
@@ -22,31 +22,19 @@ edges
|
|||||||
| tests5.cpp:88:2:88:2 | p indirection | tests5.cpp:89:2:89:2 | p indirection |
|
| tests5.cpp:88:2:88:2 | p indirection | tests5.cpp:89:2:89:2 | p indirection |
|
||||||
| tests.cpp:15:23:15:43 | call to XercesDOMParser | tests.cpp:17:2:17:2 | p indirection |
|
| tests.cpp:15:23:15:43 | call to XercesDOMParser | tests.cpp:17:2:17:2 | p indirection |
|
||||||
| tests.cpp:28:23:28:43 | call to XercesDOMParser | tests.cpp:31:2:31:2 | p indirection |
|
| tests.cpp:28:23:28:43 | call to XercesDOMParser | tests.cpp:31:2:31:2 | p indirection |
|
||||||
| tests.cpp:35:23:35:43 | call to XercesDOMParser | tests.cpp:37:2:37:2 | (AbstractDOMParser *)... indirection |
|
|
||||||
| tests.cpp:35:23:35:43 | call to XercesDOMParser | tests.cpp:37:2:37:2 | p indirection |
|
| tests.cpp:35:23:35:43 | call to XercesDOMParser | tests.cpp:37:2:37:2 | p indirection |
|
||||||
| tests.cpp:37:2:37:2 | (AbstractDOMParser *)... indirection | tests.cpp:37:2:37:2 | p indirection |
|
|
||||||
| tests.cpp:37:2:37:2 | p indirection | tests.cpp:37:2:37:2 | p indirection |
|
| tests.cpp:37:2:37:2 | p indirection | tests.cpp:37:2:37:2 | p indirection |
|
||||||
| tests.cpp:37:2:37:2 | p indirection | tests.cpp:38:2:38:2 | (AbstractDOMParser *)... indirection |
|
|
||||||
| tests.cpp:37:2:37:2 | p indirection | tests.cpp:38:2:38:2 | p indirection |
|
| tests.cpp:37:2:37:2 | p indirection | tests.cpp:38:2:38:2 | p indirection |
|
||||||
| tests.cpp:38:2:38:2 | (AbstractDOMParser *)... indirection | tests.cpp:38:2:38:2 | p indirection |
|
|
||||||
| tests.cpp:38:2:38:2 | p indirection | tests.cpp:38:2:38:2 | p indirection |
|
| tests.cpp:38:2:38:2 | p indirection | tests.cpp:38:2:38:2 | p indirection |
|
||||||
| tests.cpp:38:2:38:2 | p indirection | tests.cpp:39:2:39:2 | p indirection |
|
| tests.cpp:38:2:38:2 | p indirection | tests.cpp:39:2:39:2 | p indirection |
|
||||||
| tests.cpp:51:23:51:43 | call to XercesDOMParser | tests.cpp:53:2:53:2 | (AbstractDOMParser *)... indirection |
|
|
||||||
| tests.cpp:51:23:51:43 | call to XercesDOMParser | tests.cpp:53:2:53:2 | p indirection |
|
| tests.cpp:51:23:51:43 | call to XercesDOMParser | tests.cpp:53:2:53:2 | p indirection |
|
||||||
| tests.cpp:53:2:53:2 | (AbstractDOMParser *)... indirection | tests.cpp:53:2:53:2 | p indirection |
|
|
||||||
| tests.cpp:53:2:53:2 | p indirection | tests.cpp:53:2:53:2 | p indirection |
|
| tests.cpp:53:2:53:2 | p indirection | tests.cpp:53:2:53:2 | p indirection |
|
||||||
| tests.cpp:53:2:53:2 | p indirection | tests.cpp:55:2:55:2 | (AbstractDOMParser *)... indirection |
|
|
||||||
| tests.cpp:53:2:53:2 | p indirection | tests.cpp:55:2:55:2 | p indirection |
|
| tests.cpp:53:2:53:2 | p indirection | tests.cpp:55:2:55:2 | p indirection |
|
||||||
| tests.cpp:55:2:55:2 | (AbstractDOMParser *)... indirection | tests.cpp:55:2:55:2 | p indirection |
|
|
||||||
| tests.cpp:55:2:55:2 | p indirection | tests.cpp:55:2:55:2 | p indirection |
|
| tests.cpp:55:2:55:2 | p indirection | tests.cpp:55:2:55:2 | p indirection |
|
||||||
| tests.cpp:55:2:55:2 | p indirection | tests.cpp:56:2:56:2 | p indirection |
|
| tests.cpp:55:2:55:2 | p indirection | tests.cpp:56:2:56:2 | p indirection |
|
||||||
| tests.cpp:55:2:55:2 | p indirection | tests.cpp:57:2:57:2 | (AbstractDOMParser *)... indirection |
|
|
||||||
| tests.cpp:55:2:55:2 | p indirection | tests.cpp:57:2:57:2 | p indirection |
|
| tests.cpp:55:2:55:2 | p indirection | tests.cpp:57:2:57:2 | p indirection |
|
||||||
| tests.cpp:57:2:57:2 | (AbstractDOMParser *)... indirection | tests.cpp:57:2:57:2 | p indirection |
|
|
||||||
| tests.cpp:57:2:57:2 | p indirection | tests.cpp:57:2:57:2 | p indirection |
|
| tests.cpp:57:2:57:2 | p indirection | tests.cpp:57:2:57:2 | p indirection |
|
||||||
| tests.cpp:57:2:57:2 | p indirection | tests.cpp:59:2:59:2 | (AbstractDOMParser *)... indirection |
|
|
||||||
| tests.cpp:57:2:57:2 | p indirection | tests.cpp:59:2:59:2 | p indirection |
|
| tests.cpp:57:2:57:2 | p indirection | tests.cpp:59:2:59:2 | p indirection |
|
||||||
| tests.cpp:59:2:59:2 | (AbstractDOMParser *)... indirection | tests.cpp:59:2:59:2 | p indirection |
|
|
||||||
| tests.cpp:59:2:59:2 | p indirection | tests.cpp:59:2:59:2 | p indirection |
|
| tests.cpp:59:2:59:2 | p indirection | tests.cpp:59:2:59:2 | p indirection |
|
||||||
| tests.cpp:59:2:59:2 | p indirection | tests.cpp:60:2:60:2 | p indirection |
|
| tests.cpp:59:2:59:2 | p indirection | tests.cpp:60:2:60:2 | p indirection |
|
||||||
| tests.cpp:66:23:66:43 | call to XercesDOMParser | tests.cpp:69:2:69:2 | p indirection |
|
| tests.cpp:66:23:66:43 | call to XercesDOMParser | tests.cpp:69:2:69:2 | p indirection |
|
||||||
@@ -104,25 +92,19 @@ nodes
|
|||||||
| tests.cpp:28:23:28:43 | call to XercesDOMParser | semmle.label | call to XercesDOMParser |
|
| tests.cpp:28:23:28:43 | call to XercesDOMParser | semmle.label | call to XercesDOMParser |
|
||||||
| tests.cpp:31:2:31:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:31:2:31:2 | p indirection | semmle.label | p indirection |
|
||||||
| tests.cpp:35:23:35:43 | call to XercesDOMParser | semmle.label | call to XercesDOMParser |
|
| tests.cpp:35:23:35:43 | call to XercesDOMParser | semmle.label | call to XercesDOMParser |
|
||||||
| tests.cpp:37:2:37:2 | (AbstractDOMParser *)... indirection | semmle.label | (AbstractDOMParser *)... indirection |
|
|
||||||
| tests.cpp:37:2:37:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:37:2:37:2 | p indirection | semmle.label | p indirection |
|
||||||
| tests.cpp:37:2:37:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:37:2:37:2 | p indirection | semmle.label | p indirection |
|
||||||
| tests.cpp:38:2:38:2 | (AbstractDOMParser *)... indirection | semmle.label | (AbstractDOMParser *)... indirection |
|
|
||||||
| tests.cpp:38:2:38:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:38:2:38:2 | p indirection | semmle.label | p indirection |
|
||||||
| tests.cpp:38:2:38:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:38:2:38:2 | p indirection | semmle.label | p indirection |
|
||||||
| tests.cpp:39:2:39:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:39:2:39:2 | p indirection | semmle.label | p indirection |
|
||||||
| tests.cpp:51:23:51:43 | call to XercesDOMParser | semmle.label | call to XercesDOMParser |
|
| tests.cpp:51:23:51:43 | call to XercesDOMParser | semmle.label | call to XercesDOMParser |
|
||||||
| tests.cpp:53:2:53:2 | (AbstractDOMParser *)... indirection | semmle.label | (AbstractDOMParser *)... indirection |
|
|
||||||
| tests.cpp:53:2:53:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:53:2:53:2 | p indirection | semmle.label | p indirection |
|
||||||
| tests.cpp:53:2:53:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:53:2:53:2 | p indirection | semmle.label | p indirection |
|
||||||
| tests.cpp:55:2:55:2 | (AbstractDOMParser *)... indirection | semmle.label | (AbstractDOMParser *)... indirection |
|
|
||||||
| tests.cpp:55:2:55:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:55:2:55:2 | p indirection | semmle.label | p indirection |
|
||||||
| tests.cpp:55:2:55:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:55:2:55:2 | p indirection | semmle.label | p indirection |
|
||||||
| tests.cpp:56:2:56:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:56:2:56:2 | p indirection | semmle.label | p indirection |
|
||||||
| tests.cpp:57:2:57:2 | (AbstractDOMParser *)... indirection | semmle.label | (AbstractDOMParser *)... indirection |
|
|
||||||
| tests.cpp:57:2:57:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:57:2:57:2 | p indirection | semmle.label | p indirection |
|
||||||
| tests.cpp:57:2:57:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:57:2:57:2 | p indirection | semmle.label | p indirection |
|
||||||
| tests.cpp:59:2:59:2 | (AbstractDOMParser *)... indirection | semmle.label | (AbstractDOMParser *)... indirection |
|
|
||||||
| tests.cpp:59:2:59:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:59:2:59:2 | p indirection | semmle.label | p indirection |
|
||||||
| tests.cpp:59:2:59:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:59:2:59:2 | p indirection | semmle.label | p indirection |
|
||||||
| tests.cpp:60:2:60:2 | p indirection | semmle.label | p indirection |
|
| tests.cpp:60:2:60:2 | p indirection | semmle.label | p indirection |
|
||||||
|
|||||||
@@ -27,12 +27,18 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
if (File.Exists(path))
|
if (File.Exists(path))
|
||||||
{
|
{
|
||||||
pendingDllsToIndex.Enqueue(path);
|
pendingDllsToIndex.Enqueue(path);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (Directory.Exists(path))
|
||||||
{
|
{
|
||||||
progressMonitor.FindingFiles(path);
|
progressMonitor.FindingFiles(path);
|
||||||
AddReferenceDirectory(path);
|
AddReferenceDirectory(path);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
progressMonitor.LogInfo("AssemblyCache: Path not found: " + path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
IndexReferences();
|
IndexReferences();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,164 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Semmle.Util;
|
||||||
|
|
||||||
|
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class for parsing project.assets.json files.
|
||||||
|
/// </summary>
|
||||||
|
internal class Assets
|
||||||
|
{
|
||||||
|
private readonly ProgressMonitor progressMonitor;
|
||||||
|
|
||||||
|
private static readonly string[] netFrameworks = new[] {
|
||||||
|
"microsoft.aspnetcore.app.ref",
|
||||||
|
"microsoft.netcore.app.ref",
|
||||||
|
"microsoft.netframework.referenceassemblies",
|
||||||
|
"microsoft.windowsdesktop.app.ref",
|
||||||
|
"netstandard.library.ref"
|
||||||
|
};
|
||||||
|
|
||||||
|
internal Assets(ProgressMonitor progressMonitor)
|
||||||
|
{
|
||||||
|
this.progressMonitor = progressMonitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Class needed for deserializing parts of an assets file.
|
||||||
|
/// It holds information about a reference.
|
||||||
|
///
|
||||||
|
/// Type carries the type of the reference.
|
||||||
|
/// We are only interested in package references.
|
||||||
|
///
|
||||||
|
/// Compile holds information about the files needed for compilation.
|
||||||
|
/// However, if it is a .NET framework reference we assume that all files in the
|
||||||
|
/// package are needed for compilation.
|
||||||
|
/// </summary>
|
||||||
|
private record class ReferenceInfo(string? Type, Dictionary<string, object>? Compile);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add the package dependencies from the assets file to dependencies.
|
||||||
|
///
|
||||||
|
/// Parse a part of the JSon assets file and add the paths
|
||||||
|
/// to the dependencies required for compilation (and collect
|
||||||
|
/// information about used packages).
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// {
|
||||||
|
/// "Castle.Core/4.4.1": {
|
||||||
|
/// "type": "package",
|
||||||
|
/// "compile": {
|
||||||
|
/// "lib/netstandard1.5/Castle.Core.dll": {
|
||||||
|
/// "related": ".xml"
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// },
|
||||||
|
/// "Json.Net/1.0.33": {
|
||||||
|
/// "type": "package",
|
||||||
|
/// "compile": {
|
||||||
|
/// "lib/netstandard2.0/Json.Net.dll": {}
|
||||||
|
/// },
|
||||||
|
/// "runtime": {
|
||||||
|
/// "lib/netstandard2.0/Json.Net.dll": {}
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// Returns dependencies
|
||||||
|
/// RequiredPaths = {
|
||||||
|
/// "castle.core/4.4.1/lib/netstandard1.5/Castle.Core.dll",
|
||||||
|
/// "json.net/1.0.33/lib/netstandard2.0/Json.Net.dll"
|
||||||
|
/// }
|
||||||
|
/// UsedPackages = {
|
||||||
|
/// "castle.core",
|
||||||
|
/// "json.net"
|
||||||
|
/// }
|
||||||
|
/// </summary>
|
||||||
|
private DependencyContainer AddPackageDependencies(JObject json, DependencyContainer dependencies)
|
||||||
|
{
|
||||||
|
// If there are more than one framework we need to pick just one.
|
||||||
|
// To ensure stability we pick one based on the lexicographic order of
|
||||||
|
// the framework names.
|
||||||
|
var references = json
|
||||||
|
.GetProperty("targets")?
|
||||||
|
.Properties()?
|
||||||
|
.MaxBy(p => p.Name)?
|
||||||
|
.Value
|
||||||
|
.ToObject<Dictionary<string, ReferenceInfo>>();
|
||||||
|
|
||||||
|
if (references is null)
|
||||||
|
{
|
||||||
|
progressMonitor.LogDebug("No references found in the targets section in the assets file.");
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all the compile dependencies for each reference and
|
||||||
|
// create the relative path to the dependency.
|
||||||
|
references
|
||||||
|
.ForEach(r =>
|
||||||
|
{
|
||||||
|
var info = r.Value;
|
||||||
|
var name = r.Key.ToLowerInvariant();
|
||||||
|
if (info.Type != "package")
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is a .NET framework reference then include everything.
|
||||||
|
if (netFrameworks.Any(framework => name.StartsWith(framework)))
|
||||||
|
{
|
||||||
|
dependencies.Add(name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info.Compile?
|
||||||
|
.ForEach(r => dependencies.Add(name, r.Key));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse `json` as project.assets.json content and add relative paths to the dependencies
|
||||||
|
/// (together with used package information) required for compilation.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if parsing succeeds, otherwise false.</returns>
|
||||||
|
public bool TryParse(string json, DependencyContainer dependencies)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var obj = JObject.Parse(json);
|
||||||
|
AddPackageDependencies(obj, dependencies);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
progressMonitor.LogDebug($"Failed to parse assets file (unexpected error): {e.Message}");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DependencyContainer GetCompilationDependencies(ProgressMonitor progressMonitor, IEnumerable<string> assets)
|
||||||
|
{
|
||||||
|
var parser = new Assets(progressMonitor);
|
||||||
|
var dependencies = new DependencyContainer();
|
||||||
|
assets.ForEach(asset =>
|
||||||
|
{
|
||||||
|
var json = File.ReadAllText(asset);
|
||||||
|
parser.TryParse(json, dependencies);
|
||||||
|
});
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class JsonExtensions
|
||||||
|
{
|
||||||
|
internal static JObject? GetProperty(this JObject json, string property) =>
|
||||||
|
json[property] as JObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Container class for dependencies found in the assets file.
|
||||||
|
/// </summary>
|
||||||
|
internal class DependencyContainer
|
||||||
|
{
|
||||||
|
private readonly List<string> requiredPaths = new();
|
||||||
|
private readonly HashSet<string> usedPackages = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// In most cases paths in asset files point to dll's or the empty _._ file, which
|
||||||
|
/// is sometimes there to avoid the directory being empty.
|
||||||
|
/// That is, if the path specifically adds a .dll we use that, otherwise we as a fallback
|
||||||
|
/// add the entire directory (which should be fine in case of _._ as well).
|
||||||
|
/// </summary>
|
||||||
|
private static string ParseFilePath(string path)
|
||||||
|
{
|
||||||
|
if (path.EndsWith(".dll"))
|
||||||
|
{
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
return Path.GetDirectoryName(path) ?? path;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetPackageName(string package) =>
|
||||||
|
package
|
||||||
|
.Split(Path.DirectorySeparatorChar)
|
||||||
|
.First();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Paths to dependencies required for compilation.
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<string> RequiredPaths => requiredPaths;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Packages that are used as a part of the required dependencies.
|
||||||
|
/// </summary>
|
||||||
|
public HashSet<string> UsedPackages => usedPackages;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add a dependency inside a package.
|
||||||
|
/// </summary>
|
||||||
|
public void Add(string package, string dependency)
|
||||||
|
{
|
||||||
|
var p = package.Replace('/', Path.DirectorySeparatorChar);
|
||||||
|
var d = dependency.Replace('/', Path.DirectorySeparatorChar);
|
||||||
|
|
||||||
|
var path = Path.Combine(p, ParseFilePath(d));
|
||||||
|
requiredPaths.Add(path);
|
||||||
|
usedPackages.Add(GetPackageName(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add a dependency to an entire package
|
||||||
|
/// </summary>
|
||||||
|
public void Add(string package)
|
||||||
|
{
|
||||||
|
var p = package.Replace('/', Path.DirectorySeparatorChar);
|
||||||
|
|
||||||
|
requiredPaths.Add(p);
|
||||||
|
usedPackages.Add(GetPackageName(p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,9 +31,13 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
private readonly IDotNet dotnet;
|
private readonly IDotNet dotnet;
|
||||||
private readonly FileContent fileContent;
|
private readonly FileContent fileContent;
|
||||||
private readonly TemporaryDirectory packageDirectory;
|
private readonly TemporaryDirectory packageDirectory;
|
||||||
|
private readonly TemporaryDirectory missingPackageDirectory;
|
||||||
private readonly TemporaryDirectory tempWorkingDirectory;
|
private readonly TemporaryDirectory tempWorkingDirectory;
|
||||||
private readonly bool cleanupTempWorkingDirectory;
|
private readonly bool cleanupTempWorkingDirectory;
|
||||||
|
|
||||||
|
private readonly Lazy<Runtime> runtimeLazy;
|
||||||
|
private Runtime Runtime => runtimeLazy.Value;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs C# dependency fetching.
|
/// Performs C# dependency fetching.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -48,11 +52,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
this.sourceDir = new DirectoryInfo(srcDir);
|
this.sourceDir = new DirectoryInfo(srcDir);
|
||||||
|
|
||||||
packageDirectory = new TemporaryDirectory(ComputeTempDirectory(sourceDir.FullName));
|
packageDirectory = new TemporaryDirectory(ComputeTempDirectory(sourceDir.FullName));
|
||||||
|
missingPackageDirectory = new TemporaryDirectory(ComputeTempDirectory(sourceDir.FullName, "missingpackages"));
|
||||||
|
|
||||||
tempWorkingDirectory = new TemporaryDirectory(FileUtils.GetTemporaryWorkingDirectory(out cleanupTempWorkingDirectory));
|
tempWorkingDirectory = new TemporaryDirectory(FileUtils.GetTemporaryWorkingDirectory(out cleanupTempWorkingDirectory));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.dotnet = DotNet.Make(options, progressMonitor, tempWorkingDirectory);
|
this.dotnet = DotNet.Make(options, progressMonitor, tempWorkingDirectory);
|
||||||
|
runtimeLazy = new Lazy<Runtime>(() => new Runtime(dotnet));
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@@ -74,13 +81,12 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
var solutions = options.SolutionFile is not null
|
var solutions = options.SolutionFile is not null
|
||||||
? new[] { options.SolutionFile }
|
? new[] { options.SolutionFile }
|
||||||
: allNonBinaryFiles.SelectFileNamesByExtension(".sln");
|
: allNonBinaryFiles.SelectFileNamesByExtension(".sln");
|
||||||
var dllDirNames = options.DllDirs.Count == 0
|
var dllPaths = options.DllDirs.Count == 0
|
||||||
? allFiles.SelectFileNamesByExtension(".dll").ToList()
|
? allFiles.SelectFileNamesByExtension(".dll").ToHashSet()
|
||||||
: options.DllDirs.Select(Path.GetFullPath).ToList();
|
: options.DllDirs.Select(Path.GetFullPath).ToHashSet();
|
||||||
|
|
||||||
if (options.UseNuGet)
|
if (options.UseNuGet)
|
||||||
{
|
{
|
||||||
dllDirNames.Add(packageDirectory.DirInfo.FullName);
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var nuget = new NugetPackages(sourceDir.FullName, packageDirectory, progressMonitor);
|
var nuget = new NugetPackages(sourceDir.FullName, packageDirectory, progressMonitor);
|
||||||
@@ -91,33 +97,32 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
progressMonitor.MissingNuGet();
|
progressMonitor.MissingNuGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
var restoredProjects = RestoreSolutions(solutions);
|
var restoredProjects = RestoreSolutions(solutions, out var assets1);
|
||||||
var projects = allProjects.Except(restoredProjects);
|
var projects = allProjects.Except(restoredProjects);
|
||||||
RestoreProjects(projects);
|
RestoreProjects(projects, out var assets2);
|
||||||
DownloadMissingPackages(allNonBinaryFiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
var existsNetCoreRefNugetPackage = false;
|
var dependencies = Assets.GetCompilationDependencies(progressMonitor, assets1.Union(assets2));
|
||||||
var existsNetFrameworkRefNugetPackage = false;
|
|
||||||
|
var paths = dependencies
|
||||||
|
.RequiredPaths
|
||||||
|
.Select(d => Path.Combine(packageDirectory.DirInfo.FullName, d))
|
||||||
|
.ToList();
|
||||||
|
dllPaths.UnionWith(paths);
|
||||||
|
|
||||||
|
LogAllUnusedPackages(dependencies);
|
||||||
|
DownloadMissingPackages(allNonBinaryFiles, dllPaths);
|
||||||
|
}
|
||||||
|
|
||||||
// Find DLLs in the .Net / Asp.Net Framework
|
// Find DLLs in the .Net / Asp.Net Framework
|
||||||
// This block needs to come after the nuget restore, because the nuget restore might fetch the .NET Core/Framework reference assemblies.
|
// This block needs to come after the nuget restore, because the nuget restore might fetch the .NET Core/Framework reference assemblies.
|
||||||
if (options.ScanNetFrameworkDlls)
|
if (options.ScanNetFrameworkDlls)
|
||||||
{
|
{
|
||||||
existsNetCoreRefNugetPackage = IsNugetPackageAvailable("microsoft.netcore.app.ref");
|
AddNetFrameworkDlls(dllPaths);
|
||||||
existsNetFrameworkRefNugetPackage = IsNugetPackageAvailable("microsoft.netframework.referenceassemblies");
|
AddAspNetCoreFrameworkDlls(dllPaths);
|
||||||
|
AddMicrosoftWindowsDesktopDlls(dllPaths);
|
||||||
if (existsNetCoreRefNugetPackage || existsNetFrameworkRefNugetPackage)
|
|
||||||
{
|
|
||||||
progressMonitor.LogInfo("Found .NET Core/Framework DLLs in NuGet packages. Not adding installation directory.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddNetFrameworkDlls(dllDirNames);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assemblyCache = new AssemblyCache(dllDirNames, progressMonitor);
|
assemblyCache = new AssemblyCache(dllPaths, progressMonitor);
|
||||||
AnalyseSolutions(solutions);
|
AnalyseSolutions(solutions);
|
||||||
|
|
||||||
foreach (var filename in assemblyCache.AllAssemblies.Select(a => a.Filename))
|
foreach (var filename in assemblyCache.AllAssemblies.Select(a => a.Filename))
|
||||||
@@ -125,7 +130,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
UseReference(filename);
|
UseReference(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveUnnecessaryNugetPackages(existsNetCoreRefNugetPackage, existsNetFrameworkRefNugetPackage);
|
RemoveNugetAnalyzerReferences();
|
||||||
ResolveConflicts();
|
ResolveConflicts();
|
||||||
|
|
||||||
// Output the findings
|
// Output the findings
|
||||||
@@ -160,29 +165,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
DateTime.Now - startTime);
|
DateTime.Now - startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RemoveUnnecessaryNugetPackages(bool existsNetCoreRefNugetPackage, bool existsNetFrameworkRefNugetPackage)
|
|
||||||
{
|
|
||||||
RemoveNugetAnalyzerReferences();
|
|
||||||
RemoveRuntimeNugetPackageReferences();
|
|
||||||
|
|
||||||
if (fileContent.IsNewProjectStructureUsed
|
|
||||||
&& !fileContent.UseAspNetCoreDlls)
|
|
||||||
{
|
|
||||||
// This might have been restored by the CLI even though the project isn't an asp.net core one.
|
|
||||||
RemoveNugetPackageReference("microsoft.aspnetcore.app.ref");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existsNetCoreRefNugetPackage && existsNetFrameworkRefNugetPackage)
|
|
||||||
{
|
|
||||||
// Multiple packages are available, we keep only one:
|
|
||||||
RemoveNugetPackageReference("microsoft.netframework.referenceassemblies.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: There could be multiple `microsoft.netframework.referenceassemblies` packages,
|
|
||||||
// we could keep the newest one, but this is covered by the conflict resolution logic
|
|
||||||
// (if the file names match)
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RemoveNugetAnalyzerReferences()
|
private void RemoveNugetAnalyzerReferences()
|
||||||
{
|
{
|
||||||
if (!options.UseNuGet)
|
if (!options.UseNuGet)
|
||||||
@@ -222,58 +204,58 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void AddNetFrameworkDlls(List<string> dllDirNames)
|
|
||||||
|
private void AddNetFrameworkDlls(ISet<string> dllPaths)
|
||||||
{
|
{
|
||||||
var runtime = new Runtime(dotnet);
|
// Multiple dotnet framework packages could be present.
|
||||||
|
// The order of the packages is important, we're adding the first one that is present in the nuget cache.
|
||||||
|
var packagesInPrioOrder = new string[]
|
||||||
|
{
|
||||||
|
"microsoft.netcore.app.ref", // net7.0, ... net5.0, netcoreapp3.1, netcoreapp3.0
|
||||||
|
"microsoft.netframework.referenceassemblies.", // net48, ..., net20
|
||||||
|
"netstandard.library.ref", // netstandard2.1
|
||||||
|
"netstandard.library" // netstandard2.0
|
||||||
|
};
|
||||||
|
|
||||||
|
var frameworkPath = packagesInPrioOrder
|
||||||
|
.Select((s, index) => (Index: index, Path: GetPackageDirectory(s)))
|
||||||
|
.FirstOrDefault(pair => pair.Path is not null);
|
||||||
|
|
||||||
|
if (frameworkPath.Path is not null)
|
||||||
|
{
|
||||||
|
dllPaths.Add(frameworkPath.Path);
|
||||||
|
progressMonitor.LogInfo($"Found .NET Core/Framework DLLs in NuGet packages at {frameworkPath.Path}. Not adding installation directory.");
|
||||||
|
|
||||||
|
for (var i = frameworkPath.Index + 1; i < packagesInPrioOrder.Length; i++)
|
||||||
|
{
|
||||||
|
RemoveNugetPackageReference(packagesInPrioOrder[i], dllPaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
string? runtimeLocation = null;
|
string? runtimeLocation = null;
|
||||||
|
|
||||||
if (options.UseSelfContainedDotnet)
|
if (options.UseSelfContainedDotnet)
|
||||||
{
|
{
|
||||||
runtimeLocation = runtime.ExecutingRuntime;
|
runtimeLocation = Runtime.ExecutingRuntime;
|
||||||
}
|
}
|
||||||
else if (fileContent.IsNewProjectStructureUsed)
|
else if (fileContent.IsNewProjectStructureUsed)
|
||||||
{
|
{
|
||||||
runtimeLocation = runtime.NetCoreRuntime;
|
runtimeLocation = Runtime.NetCoreRuntime;
|
||||||
}
|
}
|
||||||
else if (fileContent.IsLegacyProjectStructureUsed)
|
else if (fileContent.IsLegacyProjectStructureUsed)
|
||||||
{
|
{
|
||||||
runtimeLocation = runtime.DesktopRuntime;
|
runtimeLocation = Runtime.DesktopRuntime;
|
||||||
}
|
}
|
||||||
|
|
||||||
runtimeLocation ??= runtime.ExecutingRuntime;
|
runtimeLocation ??= Runtime.ExecutingRuntime;
|
||||||
|
|
||||||
progressMonitor.LogInfo($".NET runtime location selected: {runtimeLocation}");
|
progressMonitor.LogInfo($".NET runtime location selected: {runtimeLocation}");
|
||||||
dllDirNames.Add(runtimeLocation);
|
dllPaths.Add(runtimeLocation);
|
||||||
|
|
||||||
if (fileContent.IsNewProjectStructureUsed
|
|
||||||
&& fileContent.UseAspNetCoreDlls
|
|
||||||
&& runtime.AspNetCoreRuntime is string aspRuntime)
|
|
||||||
{
|
|
||||||
progressMonitor.LogInfo($"ASP.NET runtime location selected: {aspRuntime}");
|
|
||||||
dllDirNames.Add(aspRuntime);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RemoveRuntimeNugetPackageReferences()
|
private void RemoveNugetPackageReference(string packagePrefix, ISet<string> dllPaths)
|
||||||
{
|
|
||||||
var runtimePackagePrefixes = new[]
|
|
||||||
{
|
|
||||||
"microsoft.netcore.app.runtime",
|
|
||||||
"microsoft.aspnetcore.app.runtime",
|
|
||||||
"microsoft.windowsdesktop.app.runtime",
|
|
||||||
|
|
||||||
// legacy runtime packages:
|
|
||||||
"runtime.linux-x64.microsoft.netcore.app",
|
|
||||||
"runtime.osx-x64.microsoft.netcore.app",
|
|
||||||
"runtime.win-x64.microsoft.netcore.app",
|
|
||||||
|
|
||||||
// Internal implementation packages not meant for direct consumption:
|
|
||||||
"runtime."
|
|
||||||
};
|
|
||||||
RemoveNugetPackageReference(runtimePackagePrefixes);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RemoveNugetPackageReference(params string[] packagePrefixes)
|
|
||||||
{
|
{
|
||||||
if (!options.UseNuGet)
|
if (!options.UseNuGet)
|
||||||
{
|
{
|
||||||
@@ -286,32 +268,74 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var packagePathPrefixes = packagePrefixes.Select(p => Path.Combine(packageFolder, p.ToLowerInvariant()));
|
var packagePathPrefix = Path.Combine(packageFolder, packagePrefix.ToLowerInvariant());
|
||||||
|
var toRemove = dllPaths.Where(s => s.ToLowerInvariant().StartsWith(packagePathPrefix));
|
||||||
foreach (var filename in usedReferences.Keys)
|
foreach (var path in toRemove)
|
||||||
{
|
{
|
||||||
var lowerFilename = filename.ToLowerInvariant();
|
dllPaths.Remove(path);
|
||||||
|
progressMonitor.RemovedReference(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (packagePathPrefixes.Any(prefix => lowerFilename.StartsWith(prefix)))
|
private void AddAspNetCoreFrameworkDlls(ISet<string> dllPaths)
|
||||||
{
|
{
|
||||||
usedReferences.Remove(filename);
|
if (!fileContent.IsNewProjectStructureUsed || !fileContent.UseAspNetCoreDlls)
|
||||||
progressMonitor.RemovedReference(filename);
|
{
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// First try to find ASP.NET Core assemblies in the NuGet packages
|
||||||
|
if (GetPackageDirectory("microsoft.aspnetcore.app.ref") is string aspNetCorePackage)
|
||||||
|
{
|
||||||
|
progressMonitor.LogInfo($"Found ASP.NET Core in NuGet packages. Not adding installation directory.");
|
||||||
|
dllPaths.Add(aspNetCorePackage);
|
||||||
|
}
|
||||||
|
else if (Runtime.AspNetCoreRuntime is string aspNetCoreRuntime)
|
||||||
|
{
|
||||||
|
progressMonitor.LogInfo($"ASP.NET runtime location selected: {aspNetCoreRuntime}");
|
||||||
|
dllPaths.Add(aspNetCoreRuntime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsNugetPackageAvailable(string packagePrefix)
|
private void AddMicrosoftWindowsDesktopDlls(ISet<string> dllPaths)
|
||||||
|
{
|
||||||
|
if (GetPackageDirectory("microsoft.windowsdesktop.app.ref") is string windowsDesktopApp)
|
||||||
|
{
|
||||||
|
progressMonitor.LogInfo($"Found Windows Desktop App in NuGet packages.");
|
||||||
|
dllPaths.Add(windowsDesktopApp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string? GetPackageDirectory(string packagePrefix)
|
||||||
{
|
{
|
||||||
if (!options.UseNuGet)
|
if (!options.UseNuGet)
|
||||||
{
|
{
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DirectoryInfo(packageDirectory.DirInfo.FullName)
|
return new DirectoryInfo(packageDirectory.DirInfo.FullName)
|
||||||
.EnumerateDirectories(packagePrefix + "*", new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive, RecurseSubdirectories = false })
|
.EnumerateDirectories(packagePrefix + "*", new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive, RecurseSubdirectories = false })
|
||||||
.Any();
|
.FirstOrDefault()?
|
||||||
|
.FullName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IEnumerable<string> GetAllPackageDirectories()
|
||||||
|
{
|
||||||
|
if (!options.UseNuGet)
|
||||||
|
{
|
||||||
|
return Enumerable.Empty<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DirectoryInfo(packageDirectory.DirInfo.FullName)
|
||||||
|
.EnumerateDirectories("*", new EnumerationOptions { MatchCasing = MatchCasing.CaseInsensitive, RecurseSubdirectories = false })
|
||||||
|
.Select(d => d.FullName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LogAllUnusedPackages(DependencyContainer dependencies) =>
|
||||||
|
GetAllPackageDirectories()
|
||||||
|
.Where(package => !dependencies.UsedPackages.Contains(package))
|
||||||
|
.ForEach(package => progressMonitor.LogInfo($"Unused package: {package}"));
|
||||||
|
|
||||||
private void GenerateSourceFileFromImplicitUsings()
|
private void GenerateSourceFileFromImplicitUsings()
|
||||||
{
|
{
|
||||||
var usings = new HashSet<string>();
|
var usings = new HashSet<string>();
|
||||||
@@ -401,7 +425,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
/// with this source tree. Use a SHA1 of the directory name.
|
/// with this source tree. Use a SHA1 of the directory name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The full path of the temp directory.</returns>
|
/// <returns>The full path of the temp directory.</returns>
|
||||||
private static string ComputeTempDirectory(string srcDir)
|
private static string ComputeTempDirectory(string srcDir, string packages = "packages")
|
||||||
{
|
{
|
||||||
var bytes = Encoding.Unicode.GetBytes(srcDir);
|
var bytes = Encoding.Unicode.GetBytes(srcDir);
|
||||||
var sha = SHA1.HashData(bytes);
|
var sha = SHA1.HashData(bytes);
|
||||||
@@ -409,7 +433,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
foreach (var b in sha.Take(8))
|
foreach (var b in sha.Take(8))
|
||||||
sb.AppendFormat("{0:x2}", b);
|
sb.AppendFormat("{0:x2}", b);
|
||||||
|
|
||||||
return Path.Combine(Path.GetTempPath(), "GitHub", "packages", sb.ToString());
|
return Path.Combine(Path.GetTempPath(), "GitHub", packages, sb.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -587,41 +611,52 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool RestoreProject(string project, bool forceDotnetRefAssemblyFetching, string? pathToNugetConfig = null) =>
|
private bool RestoreProject(string project, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, string? pathToNugetConfig = null) =>
|
||||||
dotnet.RestoreProjectToDirectory(project, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching, pathToNugetConfig);
|
dotnet.RestoreProjectToDirectory(project, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching, out assets, pathToNugetConfig);
|
||||||
|
|
||||||
private bool RestoreSolution(string solution, out IEnumerable<string> projects) =>
|
private bool RestoreSolution(string solution, out IEnumerable<string> projects, out IEnumerable<string> assets) =>
|
||||||
dotnet.RestoreSolutionToDirectory(solution, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: true, out projects);
|
dotnet.RestoreSolutionToDirectory(solution, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: true, out projects, out assets);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Executes `dotnet restore` on all solution files in solutions.
|
/// Executes `dotnet restore` on all solution files in solutions.
|
||||||
/// As opposed to RestoreProjects this is not run in parallel using PLINQ
|
/// As opposed to RestoreProjects this is not run in parallel using PLINQ
|
||||||
/// as `dotnet restore` on a solution already uses multiple threads for restoring
|
/// as `dotnet restore` on a solution already uses multiple threads for restoring
|
||||||
/// the projects (this can be disabled with the `--disable-parallel` flag).
|
/// the projects (this can be disabled with the `--disable-parallel` flag).
|
||||||
|
/// Populates assets with the relative paths to the assets files generated by the restore.
|
||||||
/// Returns a list of projects that are up to date with respect to restore.
|
/// Returns a list of projects that are up to date with respect to restore.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="solutions">A list of paths to solution files.</param>
|
/// <param name="solutions">A list of paths to solution files.</param>
|
||||||
private IEnumerable<string> RestoreSolutions(IEnumerable<string> solutions) =>
|
private IEnumerable<string> RestoreSolutions(IEnumerable<string> solutions, out IEnumerable<string> assets)
|
||||||
solutions.SelectMany(solution =>
|
|
||||||
{
|
{
|
||||||
RestoreSolution(solution, out var restoredProjects);
|
var assetFiles = new List<string>();
|
||||||
|
var projects = solutions.SelectMany(solution =>
|
||||||
|
{
|
||||||
|
RestoreSolution(solution, out var restoredProjects, out var a);
|
||||||
|
assetFiles.AddRange(a);
|
||||||
return restoredProjects;
|
return restoredProjects;
|
||||||
});
|
});
|
||||||
|
assets = assetFiles;
|
||||||
|
return projects;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Executes `dotnet restore` on all projects in projects.
|
/// Executes `dotnet restore` on all projects in projects.
|
||||||
/// This is done in parallel for performance reasons.
|
/// This is done in parallel for performance reasons.
|
||||||
|
/// Populates assets with the relative paths to the assets files generated by the restore.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="projects">A list of paths to project files.</param>
|
/// <param name="projects">A list of paths to project files.</param>
|
||||||
private void RestoreProjects(IEnumerable<string> projects)
|
private void RestoreProjects(IEnumerable<string> projects, out IEnumerable<string> assets)
|
||||||
{
|
{
|
||||||
|
var assetFiles = new List<string>();
|
||||||
Parallel.ForEach(projects, new ParallelOptions { MaxDegreeOfParallelism = options.Threads }, project =>
|
Parallel.ForEach(projects, new ParallelOptions { MaxDegreeOfParallelism = options.Threads }, project =>
|
||||||
{
|
{
|
||||||
RestoreProject(project, forceDotnetRefAssemblyFetching: true);
|
RestoreProject(project, forceDotnetRefAssemblyFetching: true, out var a);
|
||||||
|
assetFiles.AddRange(a);
|
||||||
});
|
});
|
||||||
|
assets = assetFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DownloadMissingPackages(List<FileInfo> allFiles)
|
private void DownloadMissingPackages(List<FileInfo> allFiles, ISet<string> dllPaths)
|
||||||
{
|
{
|
||||||
var nugetConfigs = allFiles.SelectFileNamesByName("nuget.config").ToArray();
|
var nugetConfigs = allFiles.SelectFileNamesByName("nuget.config").ToArray();
|
||||||
string? nugetConfig = null;
|
string? nugetConfig = null;
|
||||||
@@ -662,13 +697,15 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
success = RestoreProject(tempDir.DirInfo.FullName, forceDotnetRefAssemblyFetching: false, pathToNugetConfig: nugetConfig);
|
dotnet.RestoreProjectToDirectory(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: false, out var _, pathToNugetConfig: nugetConfig);
|
||||||
// TODO: the restore might fail, we could retry with a prerelease (*-* instead of *) version of the package.
|
// TODO: the restore might fail, we could retry with a prerelease (*-* instead of *) version of the package.
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
progressMonitor.FailedToRestoreNugetPackage(package);
|
progressMonitor.FailedToRestoreNugetPackage(package);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
dllPaths.Add(missingPackageDirectory.DirInfo.FullName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AnalyseSolutions(IEnumerable<string> solutions)
|
private void AnalyseSolutions(IEnumerable<string> solutions)
|
||||||
@@ -688,26 +725,25 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose(TemporaryDirectory? dir, string name)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dir?.Dispose();
|
||||||
|
}
|
||||||
|
catch (Exception exc)
|
||||||
|
{
|
||||||
|
progressMonitor.LogInfo($"Couldn't delete {name} directory {exc.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
try
|
Dispose(packageDirectory, "package");
|
||||||
{
|
Dispose(missingPackageDirectory, "missing package");
|
||||||
packageDirectory?.Dispose();
|
|
||||||
}
|
|
||||||
catch (Exception exc)
|
|
||||||
{
|
|
||||||
progressMonitor.LogInfo("Couldn't delete package directory: " + exc.Message);
|
|
||||||
}
|
|
||||||
if (cleanupTempWorkingDirectory)
|
if (cleanupTempWorkingDirectory)
|
||||||
{
|
{
|
||||||
try
|
Dispose(tempWorkingDirectory, "temporary working");
|
||||||
{
|
|
||||||
tempWorkingDirectory?.Dispose();
|
|
||||||
}
|
|
||||||
catch (Exception exc)
|
|
||||||
{
|
|
||||||
progressMonitor.LogInfo("Couldn't delete temporary working directory: " + exc.Message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
|
|
||||||
private string GetRestoreArgs(string projectOrSolutionFile, string packageDirectory, bool forceDotnetRefAssemblyFetching)
|
private string GetRestoreArgs(string projectOrSolutionFile, string packageDirectory, bool forceDotnetRefAssemblyFetching)
|
||||||
{
|
{
|
||||||
var args = $"restore --no-dependencies \"{projectOrSolutionFile}\" --packages \"{packageDirectory}\" /p:DisableImplicitNuGetFallbackFolder=true";
|
var args = $"restore --no-dependencies \"{projectOrSolutionFile}\" --packages \"{packageDirectory}\" /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal";
|
||||||
|
|
||||||
if (forceDotnetRefAssemblyFetching)
|
if (forceDotnetRefAssemblyFetching)
|
||||||
{
|
{
|
||||||
@@ -60,7 +60,19 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RestoreProjectToDirectory(string projectFile, string packageDirectory, bool forceDotnetRefAssemblyFetching, string? pathToNugetConfig = null)
|
private static IEnumerable<string> GetFirstGroupOnMatch(Regex regex, IEnumerable<string> lines) =>
|
||||||
|
lines
|
||||||
|
.Select(line => regex.Match(line))
|
||||||
|
.Where(match => match.Success)
|
||||||
|
.Select(match => match.Groups[1].Value);
|
||||||
|
|
||||||
|
private static IEnumerable<string> GetAssetsFilePaths(IEnumerable<string> lines) =>
|
||||||
|
GetFirstGroupOnMatch(AssetsFileRegex(), lines);
|
||||||
|
|
||||||
|
private static IEnumerable<string> GetRestoredProjects(IEnumerable<string> lines) =>
|
||||||
|
GetFirstGroupOnMatch(RestoredProjectRegex(), lines);
|
||||||
|
|
||||||
|
public bool RestoreProjectToDirectory(string projectFile, string packageDirectory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, string? pathToNugetConfig = null)
|
||||||
{
|
{
|
||||||
var args = GetRestoreArgs(projectFile, packageDirectory, forceDotnetRefAssemblyFetching);
|
var args = GetRestoreArgs(projectFile, packageDirectory, forceDotnetRefAssemblyFetching);
|
||||||
if (pathToNugetConfig != null)
|
if (pathToNugetConfig != null)
|
||||||
@@ -68,25 +80,18 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
args += $" --configfile \"{pathToNugetConfig}\"";
|
args += $" --configfile \"{pathToNugetConfig}\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
return dotnetCliInvoker.RunCommand(args);
|
var success = dotnetCliInvoker.RunCommand(args, out var output);
|
||||||
|
assets = success ? GetAssetsFilePaths(output) : Array.Empty<string>();
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RestoreSolutionToDirectory(string solutionFile, string packageDirectory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> projects)
|
public bool RestoreSolutionToDirectory(string solutionFile, string packageDirectory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> projects, out IEnumerable<string> assets)
|
||||||
{
|
{
|
||||||
var args = GetRestoreArgs(solutionFile, packageDirectory, forceDotnetRefAssemblyFetching);
|
var args = GetRestoreArgs(solutionFile, packageDirectory, forceDotnetRefAssemblyFetching);
|
||||||
args += " --verbosity normal";
|
var success = dotnetCliInvoker.RunCommand(args, out var output);
|
||||||
if (dotnetCliInvoker.RunCommand(args, out var output))
|
projects = success ? GetRestoredProjects(output) : Array.Empty<string>();
|
||||||
{
|
assets = success ? GetAssetsFilePaths(output) : Array.Empty<string>();
|
||||||
var regex = RestoreProjectRegex();
|
return success;
|
||||||
projects = output
|
|
||||||
.Select(line => regex.Match(line))
|
|
||||||
.Where(match => match.Success)
|
|
||||||
.Select(match => match.Groups[1].Value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
projects = Array.Empty<string>();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool New(string folder)
|
public bool New(string folder)
|
||||||
@@ -121,6 +126,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
}
|
}
|
||||||
|
|
||||||
[GeneratedRegex("Restored\\s+(.+\\.csproj)", RegexOptions.Compiled)]
|
[GeneratedRegex("Restored\\s+(.+\\.csproj)", RegexOptions.Compiled)]
|
||||||
private static partial Regex RestoreProjectRegex();
|
private static partial Regex RestoredProjectRegex();
|
||||||
|
|
||||||
|
[GeneratedRegex("[Assets\\sfile\\shas\\snot\\schanged.\\sSkipping\\sassets\\sfile\\swriting.|Writing\\sassets\\sfile\\sto\\sdisk.]\\sPath:\\s(.*)", RegexOptions.Compiled)]
|
||||||
|
private static partial Regex AssetsFileRegex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -197,19 +197,19 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[GeneratedRegex("<PackageReference.*\\sInclude=\"(.*?)\".*/?>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
[GeneratedRegex("(?<!<!--.*)<PackageReference.*\\sInclude=\"(.*?)\".*/?>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
||||||
private static partial Regex PackageReference();
|
private static partial Regex PackageReference();
|
||||||
|
|
||||||
[GeneratedRegex("<FrameworkReference.*\\sInclude=\"(.*?)\".*/?>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
[GeneratedRegex("(?<!<!--.*)<FrameworkReference.*\\sInclude=\"(.*?)\".*/?>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
||||||
private static partial Regex FrameworkReference();
|
private static partial Regex FrameworkReference();
|
||||||
|
|
||||||
[GeneratedRegex("<(.*\\s)?Project.*\\sSdk=\"(.*?)\".*/?>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
[GeneratedRegex("(?<!<!--.*)<(.*\\s)?Project.*\\sSdk=\"(.*?)\".*/?>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
||||||
private static partial Regex ProjectSdk();
|
private static partial Regex ProjectSdk();
|
||||||
|
|
||||||
[GeneratedRegex("<Using.*\\sInclude=\"(.*?)\".*/?>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
[GeneratedRegex("(?<!<!--.*)<Using.*\\sInclude=\"(.*?)\".*/?>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
||||||
private static partial Regex CustomImplicitUsingDeclarations();
|
private static partial Regex CustomImplicitUsingDeclarations();
|
||||||
|
|
||||||
[GeneratedRegex("<Import.*\\sProject=\".*Microsoft\\.CSharp\\.targets\".*/?>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
[GeneratedRegex("(?<!<!--.*)<Import.*\\sProject=\".*Microsoft\\.CSharp\\.targets\".*/?>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline)]
|
||||||
private static partial Regex MicrosoftCSharpTargets();
|
private static partial Regex MicrosoftCSharpTargets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||||||
{
|
{
|
||||||
internal interface IDotNet
|
internal interface IDotNet
|
||||||
{
|
{
|
||||||
bool RestoreProjectToDirectory(string project, string directory, bool forceDotnetRefAssemblyFetching, string? pathToNugetConfig = null);
|
bool RestoreProjectToDirectory(string project, string directory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, string? pathToNugetConfig = null);
|
||||||
bool RestoreSolutionToDirectory(string solutionFile, string packageDirectory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> projects);
|
bool RestoreSolutionToDirectory(string solutionFile, string packageDirectory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> projects, out IEnumerable<string> assets);
|
||||||
bool New(string folder);
|
bool New(string folder);
|
||||||
bool AddPackage(string folder, string package);
|
bool AddPackage(string folder, string package);
|
||||||
IList<string> GetListedRuntimes();
|
IList<string> GetListedRuntimes();
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
|||||||
// The current argument is not named
|
// The current argument is not named
|
||||||
// so the previous ones were also not named
|
// so the previous ones were also not named
|
||||||
// so the child index matches the parameter index.
|
// so the child index matches the parameter index.
|
||||||
isParamsParameter = Symbol?.AttributeConstructor?.Parameters[childIndex].IsParams == true;
|
isParamsParameter = Symbol.AttributeConstructor?.Parameters[childIndex].IsParams == true;
|
||||||
argSyntax = ctorArguments[childIndex];
|
argSyntax = ctorArguments[childIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
|||||||
Position.Span.Start.Line + 1, Position.Span.Start.Character + 1,
|
Position.Span.Start.Line + 1, Position.Span.Start.Character + 1,
|
||||||
Position.Span.End.Line + 1, Position.Span.End.Character);
|
Position.Span.End.Line + 1, Position.Span.End.Character);
|
||||||
|
|
||||||
var mapped = Symbol!.GetMappedLineSpan();
|
var mapped = Symbol.GetMappedLineSpan();
|
||||||
if (mapped.HasMappedPath && mapped.IsValid)
|
if (mapped.HasMappedPath && mapped.IsValid)
|
||||||
{
|
{
|
||||||
var mappedLoc = Create(Context, Location.Create(mapped.Path, default, mapped.Span));
|
var mappedLoc = Create(Context, Location.Create(mapped.Path, default, mapped.Span));
|
||||||
|
|||||||
206
csharp/extractor/Semmle.Extraction.Tests/Assets.cs
Normal file
206
csharp/extractor/Semmle.Extraction.Tests/Assets.cs
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
using Xunit;
|
||||||
|
using System.Linq;
|
||||||
|
using Semmle.Extraction.CSharp.DependencyFetching;
|
||||||
|
|
||||||
|
namespace Semmle.Extraction.Tests
|
||||||
|
{
|
||||||
|
public class AssetsTests
|
||||||
|
{
|
||||||
|
private static string FixExpectedPathOnWindows(string path) => path.Replace('\\', '/');
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestAssets1()
|
||||||
|
{
|
||||||
|
// Setup
|
||||||
|
var assets = new Assets(new ProgressMonitor(new LoggerStub()));
|
||||||
|
var json = assetsJson1;
|
||||||
|
var dependencies = new DependencyContainer();
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
var success = assets.TryParse(json, dependencies);
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
Assert.True(success);
|
||||||
|
Assert.Equal(5, dependencies.RequiredPaths.Count());
|
||||||
|
Assert.Equal(4, dependencies.UsedPackages.Count());
|
||||||
|
|
||||||
|
var normalizedPaths = dependencies.RequiredPaths.Select(FixExpectedPathOnWindows);
|
||||||
|
// Required references
|
||||||
|
Assert.Contains("castle.core/4.4.1/lib/netstandard1.5/Castle.Core.dll", normalizedPaths);
|
||||||
|
Assert.Contains("castle.core/4.4.1/lib/netstandard1.5/Castle.Core2.dll", normalizedPaths);
|
||||||
|
Assert.Contains("json.net/1.0.33/lib/netstandard2.0/Json.Net.dll", normalizedPaths);
|
||||||
|
Assert.Contains("microsoft.aspnetcore.cryptography.internal/6.0.8/lib/net6.0/Microsoft.AspNetCore.Cryptography.Internal.dll", normalizedPaths);
|
||||||
|
Assert.Contains("humanizer.core/2.8.26/lib/netstandard2.0", normalizedPaths);
|
||||||
|
// Used packages
|
||||||
|
Assert.Contains("castle.core", dependencies.UsedPackages);
|
||||||
|
Assert.Contains("json.net", dependencies.UsedPackages);
|
||||||
|
Assert.Contains("microsoft.aspnetcore.cryptography.internal", dependencies.UsedPackages);
|
||||||
|
Assert.Contains("humanizer.core", dependencies.UsedPackages);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestAssets2()
|
||||||
|
{
|
||||||
|
// Setup
|
||||||
|
var assets = new Assets(new ProgressMonitor(new LoggerStub()));
|
||||||
|
var json = assetsJson2;
|
||||||
|
var dependencies = new DependencyContainer();
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
var success = assets.TryParse(json, dependencies);
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
Assert.True(success);
|
||||||
|
Assert.Equal(2, dependencies.RequiredPaths.Count());
|
||||||
|
|
||||||
|
var normalizedPaths = dependencies.RequiredPaths.Select(FixExpectedPathOnWindows);
|
||||||
|
// Required references
|
||||||
|
Assert.Contains("microsoft.netframework.referenceassemblies/1.0.3", normalizedPaths);
|
||||||
|
Assert.Contains("microsoft.netframework.referenceassemblies.net48/1.0.3", normalizedPaths);
|
||||||
|
// Used packages
|
||||||
|
Assert.Contains("microsoft.netframework.referenceassemblies", dependencies.UsedPackages);
|
||||||
|
Assert.Contains("microsoft.netframework.referenceassemblies.net48", dependencies.UsedPackages);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TestAssets3()
|
||||||
|
{
|
||||||
|
// Setup
|
||||||
|
var assets = new Assets(new ProgressMonitor(new LoggerStub()));
|
||||||
|
var json = "garbage data";
|
||||||
|
var dependencies = new DependencyContainer();
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
var success = assets.TryParse(json, dependencies);
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
Assert.False(success);
|
||||||
|
Assert.Empty(dependencies.RequiredPaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly string assetsJson1 = """
|
||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"targets": {
|
||||||
|
"net7.0": {
|
||||||
|
"Castle.Core/4.4.1": {
|
||||||
|
"type": "package",
|
||||||
|
"dependencies": {
|
||||||
|
"NETStandard.Library": "1.6.1",
|
||||||
|
"System.Collections.Specialized": "4.3.0",
|
||||||
|
},
|
||||||
|
"compile": {
|
||||||
|
"lib/netstandard1.5/Castle.Core.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
},
|
||||||
|
"lib/netstandard1.5/Castle.Core2.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard1.5/Castle.Core.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Json.Net/1.0.33": {
|
||||||
|
"type": "package",
|
||||||
|
"compile": {
|
||||||
|
"lib/netstandard2.0/Json.Net.dll": {}
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/Json.Net.dll": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"MessagePackAnalyzer/2.1.152": {
|
||||||
|
"type": "package"
|
||||||
|
},
|
||||||
|
"Microsoft.AspNetCore.Cryptography.Internal/6.0.8": {
|
||||||
|
"type": "package",
|
||||||
|
"compile": {
|
||||||
|
"lib/net6.0/Microsoft.AspNetCore.Cryptography.Internal.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/net6.0/Microsoft.AspNetCore.Cryptography.Internal.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Humanizer.Core/2.8.26": {
|
||||||
|
"type": "package",
|
||||||
|
"compile": {
|
||||||
|
"lib/netstandard2.0/_._": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"lib/netstandard2.0/Humanizer.dll": {
|
||||||
|
"related": ".xml"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Nop.Core/4.5.0": {
|
||||||
|
"type": "project",
|
||||||
|
"compile": {
|
||||||
|
"bin/placeholder/Nop.Core.dll": {}
|
||||||
|
},
|
||||||
|
"runtime": {
|
||||||
|
"bin/placeholder/Nop.Core.dll": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"project": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"frameworks": {
|
||||||
|
"net7.0": {
|
||||||
|
"targetAlias": "net7.0",
|
||||||
|
"downloadDependencies": [
|
||||||
|
{
|
||||||
|
"name": "Microsoft.AspNetCore.App.Ref",
|
||||||
|
"version": "[7.0.2, 7.0.2]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Microsoft.NETCore.App.Ref",
|
||||||
|
"version": "[7.0.2, 7.0.2]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"frameworkReferences": {
|
||||||
|
"Microsoft.AspNetCore.App": {
|
||||||
|
"privateAssets": "none"
|
||||||
|
},
|
||||||
|
"Microsoft.NETCore.App": {
|
||||||
|
"privateAssets": "all"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
|
||||||
|
private readonly string assetsJson2 = """
|
||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"targets": {
|
||||||
|
".NETFramework,Version=v4.8": {
|
||||||
|
"Microsoft.NETFramework.ReferenceAssemblies/1.0.3": {
|
||||||
|
"type": "package",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETFramework.ReferenceAssemblies.net48": "1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Microsoft.NETFramework.ReferenceAssemblies.net48/1.0.3": {
|
||||||
|
"type": "package",
|
||||||
|
"build": {
|
||||||
|
"build/Microsoft.NETFramework.ReferenceAssemblies.net48.targets": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,9 +43,11 @@ namespace Semmle.Extraction.Tests
|
|||||||
private static IList<string> MakeDotnetRestoreOutput() =>
|
private static IList<string> MakeDotnetRestoreOutput() =>
|
||||||
new List<string> {
|
new List<string> {
|
||||||
" Determining projects to restore...",
|
" Determining projects to restore...",
|
||||||
|
" Writing assets file to disk. Path: /path/to/project.assets.json",
|
||||||
" Restored /path/to/project.csproj (in 1.23 sec).",
|
" Restored /path/to/project.csproj (in 1.23 sec).",
|
||||||
" Other output...",
|
" Other output...",
|
||||||
" More output...",
|
" More output...",
|
||||||
|
" Assets file has not changed. Skipping assets file writing. Path: /path/to/project2.assets.json",
|
||||||
" Restored /path/to/project2.csproj (in 4.56 sec).",
|
" Restored /path/to/project2.csproj (in 4.56 sec).",
|
||||||
" Other output...",
|
" Other output...",
|
||||||
};
|
};
|
||||||
@@ -99,26 +101,29 @@ namespace Semmle.Extraction.Tests
|
|||||||
var dotnet = MakeDotnet(dotnetCliInvoker);
|
var dotnet = MakeDotnet(dotnetCliInvoker);
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
dotnet.RestoreProjectToDirectory("myproject.csproj", "mypackages", false);
|
dotnet.RestoreProjectToDirectory("myproject.csproj", "mypackages", false, out var assets);
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
var lastArgs = dotnetCliInvoker.GetLastArgs();
|
var lastArgs = dotnetCliInvoker.GetLastArgs();
|
||||||
Assert.Equal("restore --no-dependencies \"myproject.csproj\" --packages \"mypackages\" /p:DisableImplicitNuGetFallbackFolder=true", lastArgs);
|
Assert.Equal("restore --no-dependencies \"myproject.csproj\" --packages \"mypackages\" /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal", lastArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void TestDotnetRestoreProjectToDirectory2()
|
public void TestDotnetRestoreProjectToDirectory2()
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
var dotnetCliInvoker = new DotNetCliInvokerStub(new List<string>());
|
var dotnetCliInvoker = new DotNetCliInvokerStub(MakeDotnetRestoreOutput());
|
||||||
var dotnet = MakeDotnet(dotnetCliInvoker);
|
var dotnet = MakeDotnet(dotnetCliInvoker);
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
dotnet.RestoreProjectToDirectory("myproject.csproj", "mypackages", false, "myconfig.config");
|
dotnet.RestoreProjectToDirectory("myproject.csproj", "mypackages", false, out var assets, "myconfig.config");
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
var lastArgs = dotnetCliInvoker.GetLastArgs();
|
var lastArgs = dotnetCliInvoker.GetLastArgs();
|
||||||
Assert.Equal("restore --no-dependencies \"myproject.csproj\" --packages \"mypackages\" /p:DisableImplicitNuGetFallbackFolder=true --configfile \"myconfig.config\"", lastArgs);
|
Assert.Equal("restore --no-dependencies \"myproject.csproj\" --packages \"mypackages\" /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal --configfile \"myconfig.config\"", lastArgs);
|
||||||
|
Assert.Equal(2, assets.Count());
|
||||||
|
Assert.Contains("/path/to/project.assets.json", assets);
|
||||||
|
Assert.Contains("/path/to/project2.assets.json", assets);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -129,7 +134,7 @@ namespace Semmle.Extraction.Tests
|
|||||||
var dotnet = MakeDotnet(dotnetCliInvoker);
|
var dotnet = MakeDotnet(dotnetCliInvoker);
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
dotnet.RestoreSolutionToDirectory("mysolution.sln", "mypackages", false, out var projects);
|
dotnet.RestoreSolutionToDirectory("mysolution.sln", "mypackages", false, out var projects, out var assets);
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
var lastArgs = dotnetCliInvoker.GetLastArgs();
|
var lastArgs = dotnetCliInvoker.GetLastArgs();
|
||||||
@@ -137,6 +142,9 @@ namespace Semmle.Extraction.Tests
|
|||||||
Assert.Equal(2, projects.Count());
|
Assert.Equal(2, projects.Count());
|
||||||
Assert.Contains("/path/to/project.csproj", projects);
|
Assert.Contains("/path/to/project.csproj", projects);
|
||||||
Assert.Contains("/path/to/project2.csproj", projects);
|
Assert.Contains("/path/to/project2.csproj", projects);
|
||||||
|
Assert.Equal(2, assets.Count());
|
||||||
|
Assert.Contains("/path/to/project.assets.json", assets);
|
||||||
|
Assert.Contains("/path/to/project2.assets.json", assets);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -148,12 +156,13 @@ namespace Semmle.Extraction.Tests
|
|||||||
dotnetCliInvoker.Success = false;
|
dotnetCliInvoker.Success = false;
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
dotnet.RestoreSolutionToDirectory("mysolution.sln", "mypackages", false, out var projects);
|
dotnet.RestoreSolutionToDirectory("mysolution.sln", "mypackages", false, out var projects, out var assets);
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
var lastArgs = dotnetCliInvoker.GetLastArgs();
|
var lastArgs = dotnetCliInvoker.GetLastArgs();
|
||||||
Assert.Equal("restore --no-dependencies \"mysolution.sln\" --packages \"mypackages\" /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal", lastArgs);
|
Assert.Equal("restore --no-dependencies \"mysolution.sln\" --packages \"mypackages\" /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal", lastArgs);
|
||||||
Assert.Empty(projects);
|
Assert.Empty(projects);
|
||||||
|
Assert.Empty(assets);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ namespace Semmle.Extraction.Tests
|
|||||||
"<PackageReference Include=\"DotNetAnalyzers.DocumentationAnalyzers\" Version=\"1.0.0-beta.59\" PrivateAssets=\"all\" />",
|
"<PackageReference Include=\"DotNetAnalyzers.DocumentationAnalyzers\" Version=\"1.0.0-beta.59\" PrivateAssets=\"all\" />",
|
||||||
"<PackageReference Version=\"7.0.0\" Include=\"Microsoft.CodeAnalysis.NetAnalyzers\"PrivateAssets=\"all\" />",
|
"<PackageReference Version=\"7.0.0\" Include=\"Microsoft.CodeAnalysis.NetAnalyzers\"PrivateAssets=\"all\" />",
|
||||||
"<PackageReference Include=\"StyleCop.Analyzers\" Version=\"1.2.0-beta.406\">",
|
"<PackageReference Include=\"StyleCop.Analyzers\" Version=\"1.2.0-beta.406\">",
|
||||||
|
"<!-- <PackageReference Include=\"NUnit\" Version=\"3.10.1\" /> -->",
|
||||||
"<FrameworkReference Include=\"My.Framework\"/>"
|
"<FrameworkReference Include=\"My.Framework\"/>"
|
||||||
};
|
};
|
||||||
var fileContent = new TestFileContent(lines);
|
var fileContent = new TestFileContent(lines);
|
||||||
|
|||||||
@@ -19,11 +19,16 @@ namespace Semmle.Extraction.Tests
|
|||||||
|
|
||||||
public bool New(string folder) => true;
|
public bool New(string folder) => true;
|
||||||
|
|
||||||
public bool RestoreProjectToDirectory(string project, string directory, bool forceDotnetRefAssemblyFetching, string? pathToNugetConfig = null) => true;
|
public bool RestoreProjectToDirectory(string project, string directory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, string? pathToNugetConfig = null)
|
||||||
|
{
|
||||||
|
assets = Array.Empty<string>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool RestoreSolutionToDirectory(string solution, string directory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> projects)
|
public bool RestoreSolutionToDirectory(string solution, string directory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> projects, out IEnumerable<string> assets)
|
||||||
{
|
{
|
||||||
projects = Array.Empty<string>();
|
projects = Array.Empty<string>();
|
||||||
|
assets = Array.Empty<string>();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ namespace Semmle.Extraction
|
|||||||
/// <typeparam name="TSymbol">The type of the symbol.</typeparam>
|
/// <typeparam name="TSymbol">The type of the symbol.</typeparam>
|
||||||
public abstract class CachedEntity<TSymbol> : CachedEntity where TSymbol : notnull
|
public abstract class CachedEntity<TSymbol> : CachedEntity where TSymbol : notnull
|
||||||
{
|
{
|
||||||
|
[NotNull]
|
||||||
public TSymbol Symbol { get; }
|
public TSymbol Symbol { get; }
|
||||||
|
|
||||||
protected CachedEntity(Context context, TSymbol symbol) : base(context)
|
protected CachedEntity(Context context, TSymbol symbol) : base(context)
|
||||||
|
|||||||
@@ -113,5 +113,11 @@ namespace Semmle.Util
|
|||||||
h = h * 7 + i.GetHashCode();
|
h = h * 7 + i.GetHashCode();
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the sequence with nulls removed.
|
||||||
|
/// </summary>
|
||||||
|
public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> items) where T : class =>
|
||||||
|
items.Where(i => i is not null)!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/csharp-solorigate-all
|
name: codeql/csharp-solorigate-all
|
||||||
version: 1.7.2
|
version: 1.7.3-dev
|
||||||
groups:
|
groups:
|
||||||
- csharp
|
- csharp
|
||||||
- solorigate
|
- solorigate
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/csharp-solorigate-queries
|
name: codeql/csharp-solorigate-queries
|
||||||
version: 1.7.2
|
version: 1.7.3-dev
|
||||||
groups:
|
groups:
|
||||||
- csharp
|
- csharp
|
||||||
- solorigate
|
- solorigate
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
@@ -14,4 +13,9 @@
|
|||||||
<PackageReference Include="coverlet.collector" Version="3.2.0" />
|
<PackageReference Include="coverlet.collector" Version="3.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Target Name="DeleteBinObjFolders" BeforeTargets="Clean">
|
||||||
|
<RemoveDir Directories=".\bin" />
|
||||||
|
<RemoveDir Directories=".\obj" />
|
||||||
|
<RemoveDir Directories=".\myout" />
|
||||||
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -8,3 +8,8 @@ check_diagnostics()
|
|||||||
# Explicitly build and then run tests.
|
# Explicitly build and then run tests.
|
||||||
run_codeql_database_create(['dotnet clean', 'rm -rf test-db', 'dotnet build -o myout', 'dotnet test myout/dotnet_test.dll'], test_db="test2-db", lang="csharp")
|
run_codeql_database_create(['dotnet clean', 'rm -rf test-db', 'dotnet build -o myout', 'dotnet test myout/dotnet_test.dll'], test_db="test2-db", lang="csharp")
|
||||||
check_diagnostics(test_db="test2-db")
|
check_diagnostics(test_db="test2-db")
|
||||||
|
|
||||||
|
thisDir = os.path.abspath(os.getcwd())
|
||||||
|
# Explicit build and then run tests using the absolute path.
|
||||||
|
run_codeql_database_create(['dotnet clean', 'rm -rf test2-db', 'dotnet build -o myout', f'dotnet test {thisDir}/myout/dotnet_test.dll'], test_db="test3-db", lang="csharp")
|
||||||
|
check_diagnostics(test_db="test3-db")
|
||||||
@@ -1,7 +1,3 @@
|
|||||||
| /avalara.avatax/21.10.0/lib/net20/Avalara.AvaTax.RestClient.net20.dll |
|
|
||||||
| /avalara.avatax/21.10.0/lib/net45/Avalara.AvaTax.RestClient.net45.dll |
|
|
||||||
| /avalara.avatax/21.10.0/lib/net461/Avalara.AvaTax.RestClient.net461.dll |
|
|
||||||
| /avalara.avatax/21.10.0/lib/netstandard16/Avalara.AvaTax.netstandard11.dll |
|
|
||||||
| /avalara.avatax/21.10.0/lib/netstandard20/Avalara.AvaTax.netstandard20.dll |
|
| /avalara.avatax/21.10.0/lib/netstandard20/Avalara.AvaTax.netstandard20.dll |
|
||||||
| /microsoft.bcl.asyncinterfaces/6.0.0/lib/netstandard2.1/Microsoft.Bcl.AsyncInterfaces.dll |
|
| /microsoft.bcl.asyncinterfaces/6.0.0/lib/netstandard2.1/Microsoft.Bcl.AsyncInterfaces.dll |
|
||||||
| /microsoft.netcore.app.ref/3.1.0/ref/netcoreapp3.1/System.Runtime.InteropServices.WindowsRuntime.dll |
|
| /microsoft.netcore.app.ref/3.1.0/ref/netcoreapp3.1/System.Runtime.InteropServices.WindowsRuntime.dll |
|
||||||
@@ -168,6 +164,4 @@
|
|||||||
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/WindowsBase.dll |
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/WindowsBase.dll |
|
||||||
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/mscorlib.dll |
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/mscorlib.dll |
|
||||||
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/netstandard.dll |
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/netstandard.dll |
|
||||||
| /netstandard.library/2.0.3/build/netstandard2.0/ref/System.ComponentModel.Composition.dll |
|
| /newtonsoft.json/12.0.1/lib/netstandard2.0/Newtonsoft.Json.dll |
|
||||||
| /newtonsoft.json/12.0.1/lib/portable-net45+win8+wp8+wpa81/Newtonsoft.Json.dll |
|
|
||||||
| /nunit/3.13.3/lib/netstandard2.0/nunit.framework.dll |
|
|
||||||
|
|||||||
@@ -0,0 +1,163 @@
|
|||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/Microsoft.CSharp.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/Microsoft.VisualBasic.Core.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/Microsoft.VisualBasic.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/Microsoft.Win32.Primitives.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/Microsoft.Win32.Registry.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.AppContext.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Buffers.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Collections.Concurrent.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Collections.Immutable.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Collections.NonGeneric.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Collections.Specialized.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Collections.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.ComponentModel.Annotations.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.ComponentModel.DataAnnotations.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.ComponentModel.EventBasedAsync.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.ComponentModel.Primitives.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.ComponentModel.TypeConverter.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.ComponentModel.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Configuration.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Console.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Core.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Data.Common.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Data.DataSetExtensions.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Data.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Diagnostics.Contracts.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Diagnostics.Debug.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Diagnostics.DiagnosticSource.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Diagnostics.FileVersionInfo.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Diagnostics.Process.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Diagnostics.StackTrace.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Diagnostics.TextWriterTraceListener.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Diagnostics.Tools.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Diagnostics.TraceSource.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Diagnostics.Tracing.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Drawing.Primitives.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Drawing.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Dynamic.Runtime.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Formats.Asn1.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Formats.Tar.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Globalization.Calendars.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Globalization.Extensions.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Globalization.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.IO.Compression.Brotli.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.IO.Compression.FileSystem.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.IO.Compression.ZipFile.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.IO.Compression.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.IO.FileSystem.AccessControl.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.IO.FileSystem.DriveInfo.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.IO.FileSystem.Primitives.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.IO.FileSystem.Watcher.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.IO.FileSystem.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.IO.IsolatedStorage.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.IO.MemoryMappedFiles.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.IO.Pipes.AccessControl.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.IO.Pipes.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.IO.UnmanagedMemoryStream.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.IO.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Linq.Expressions.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Linq.Parallel.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Linq.Queryable.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Linq.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Memory.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.Http.Json.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.Http.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.HttpListener.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.Mail.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.NameResolution.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.NetworkInformation.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.Ping.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.Primitives.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.Quic.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.Requests.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.Security.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.ServicePoint.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.Sockets.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.WebClient.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.WebHeaderCollection.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.WebProxy.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.WebSockets.Client.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.WebSockets.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Net.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Numerics.Vectors.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Numerics.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.ObjectModel.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Reflection.DispatchProxy.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Reflection.Emit.ILGeneration.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Reflection.Emit.Lightweight.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Reflection.Emit.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Reflection.Extensions.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Reflection.Metadata.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Reflection.Primitives.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Reflection.TypeExtensions.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Reflection.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Resources.Reader.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Resources.ResourceManager.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Resources.Writer.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.CompilerServices.Unsafe.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.CompilerServices.VisualC.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.Extensions.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.Handles.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.InteropServices.JavaScript.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.InteropServices.RuntimeInformation.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.InteropServices.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.Intrinsics.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.Loader.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.Numerics.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.Serialization.Formatters.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.Serialization.Json.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.Serialization.Primitives.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.Serialization.Xml.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.Serialization.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Runtime.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Security.AccessControl.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Security.Claims.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Security.Cryptography.Algorithms.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Security.Cryptography.Cng.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Security.Cryptography.Csp.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Security.Cryptography.Encoding.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Security.Cryptography.OpenSsl.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Security.Cryptography.Primitives.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Security.Cryptography.X509Certificates.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Security.Cryptography.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Security.Principal.Windows.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Security.Principal.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Security.SecureString.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Security.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.ServiceModel.Web.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.ServiceProcess.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Text.Encoding.CodePages.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Text.Encoding.Extensions.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Text.Encoding.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Text.Encodings.Web.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Text.Json.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Text.RegularExpressions.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Threading.Channels.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Threading.Overlapped.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Threading.Tasks.Dataflow.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Threading.Tasks.Extensions.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Threading.Tasks.Parallel.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Threading.Tasks.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Threading.Thread.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Threading.ThreadPool.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Threading.Timer.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Threading.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Transactions.Local.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Transactions.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.ValueTuple.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Web.HttpUtility.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Web.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Windows.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Xml.Linq.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Xml.ReaderWriter.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Xml.Serialization.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Xml.XDocument.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Xml.XPath.XDocument.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Xml.XPath.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Xml.XmlDocument.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Xml.XmlSerializer.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.Xml.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/System.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/WindowsBase.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/mscorlib.dll |
|
||||||
|
| /microsoft.netcore.app.ref/7.0.2/ref/net7.0/netstandard.dll |
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import csharp
|
||||||
|
|
||||||
|
private string getPath(Assembly a) {
|
||||||
|
not a.getCompilation().getOutputAssembly() = a and
|
||||||
|
exists(string s | s = a.getFile().getAbsolutePath() |
|
||||||
|
result =
|
||||||
|
s.substring(s.indexOf("GitHub/packages/") + "GitHub/packages/".length() + 16, s.length())
|
||||||
|
or
|
||||||
|
result = s and
|
||||||
|
not exists(s.indexOf("GitHub/packages/"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
from Assembly a
|
||||||
|
select getPath(a)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
var dummy = "dummy";
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"sdk": {
|
||||||
|
"version": "7.0.102"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net48</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
from create_database_utils import *
|
||||||
|
|
||||||
|
run_codeql_database_create([], lang="csharp", extra_args=["--extractor-option=buildless=true", "--extractor-option=cil=false"])
|
||||||
@@ -1,7 +1,3 @@
|
|||||||
| /avalara.avatax/21.10.0/lib/net20/Avalara.AvaTax.RestClient.net20.dll |
|
|
||||||
| /avalara.avatax/21.10.0/lib/net45/Avalara.AvaTax.RestClient.net45.dll |
|
|
||||||
| /avalara.avatax/21.10.0/lib/net461/Avalara.AvaTax.RestClient.net461.dll |
|
|
||||||
| /avalara.avatax/21.10.0/lib/netstandard16/Avalara.AvaTax.netstandard11.dll |
|
|
||||||
| /avalara.avatax/21.10.0/lib/netstandard20/Avalara.AvaTax.netstandard20.dll |
|
| /avalara.avatax/21.10.0/lib/netstandard20/Avalara.AvaTax.netstandard20.dll |
|
||||||
| /microsoft.bcl.asyncinterfaces/6.0.0/lib/netstandard2.1/Microsoft.Bcl.AsyncInterfaces.dll |
|
| /microsoft.bcl.asyncinterfaces/6.0.0/lib/netstandard2.1/Microsoft.Bcl.AsyncInterfaces.dll |
|
||||||
| /microsoft.netcore.app.ref/3.1.0/ref/netcoreapp3.1/System.Runtime.InteropServices.WindowsRuntime.dll |
|
| /microsoft.netcore.app.ref/3.1.0/ref/netcoreapp3.1/System.Runtime.InteropServices.WindowsRuntime.dll |
|
||||||
@@ -212,6 +208,4 @@
|
|||||||
| /microsoft.windowsdesktop.app.ref/7.0.2/ref/net7.0/UIAutomationTypes.dll |
|
| /microsoft.windowsdesktop.app.ref/7.0.2/ref/net7.0/UIAutomationTypes.dll |
|
||||||
| /microsoft.windowsdesktop.app.ref/7.0.2/ref/net7.0/WindowsBase.dll |
|
| /microsoft.windowsdesktop.app.ref/7.0.2/ref/net7.0/WindowsBase.dll |
|
||||||
| /microsoft.windowsdesktop.app.ref/7.0.2/ref/net7.0/WindowsFormsIntegration.dll |
|
| /microsoft.windowsdesktop.app.ref/7.0.2/ref/net7.0/WindowsFormsIntegration.dll |
|
||||||
| /netstandard.library/2.0.3/build/netstandard2.0/ref/System.ComponentModel.Composition.dll |
|
| /newtonsoft.json/12.0.1/lib/netstandard2.0/Newtonsoft.Json.dll |
|
||||||
| /newtonsoft.json/12.0.1/lib/portable-net45+win8+wp8+wpa81/Newtonsoft.Json.dll |
|
|
||||||
| /nunit/3.13.3/lib/netstandard2.0/nunit.framework.dll |
|
|
||||||
|
|||||||
6
csharp/ql/lib/ext/generated/AssemblyStripper.model.yml
Normal file
6
csharp/ql/lib/ext/generated/AssemblyStripper.model.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
extensions:
|
||||||
|
- addsTo:
|
||||||
|
pack: codeql/csharp-all
|
||||||
|
extensible: neutralModel
|
||||||
|
data:
|
||||||
|
- ["AssemblyStripper", "AssemblyStripper", "StripAssembly", "(System.String,System.String)", "summary", "df-generated"]
|
||||||
7
csharp/ql/lib/ext/generated/Generators.model.yml
Normal file
7
csharp/ql/lib/ext/generated/Generators.model.yml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
extensions:
|
||||||
|
- addsTo:
|
||||||
|
pack: codeql/csharp-all
|
||||||
|
extensible: neutralModel
|
||||||
|
data:
|
||||||
|
- ["Generators", "EventSourceGenerator", "Execute", "(Microsoft.CodeAnalysis.GeneratorExecutionContext)", "summary", "df-generated"]
|
||||||
|
- ["Generators", "EventSourceGenerator", "Initialize", "(Microsoft.CodeAnalysis.GeneratorInitializationContext)", "summary", "df-generated"]
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
extensions:
|
||||||
|
- addsTo:
|
||||||
|
pack: codeql/csharp-all
|
||||||
|
extensible: neutralModel
|
||||||
|
data:
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "Add<>", "(System.Void*,System.Int32)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "Add<>", "(T,System.Int32)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "Add<>", "(T,System.IntPtr)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "AddByteOffset<>", "(T,System.IntPtr)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "AreSame<>", "(T,T)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "As<,>", "(TFrom)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "As<>", "(System.Object)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "AsPointer<>", "(T)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "AsRef<>", "(System.Void*)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "AsRef<>", "(T)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "ByteOffset<>", "(T,T)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "InitBlockUnaligned", "(System.Byte,System.Byte,System.UInt32)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "IsAddressGreaterThan<>", "(T,T)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "IsAddressLessThan<>", "(T,T)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "IsNullRef<>", "(T)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "NullRef<>", "()", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "Read<>", "(System.Byte)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "Read<>", "(System.Void*)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "ReadUnaligned<>", "(System.Byte)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "ReadUnaligned<>", "(System.Void*)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "SizeOf<>", "()", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "SkipInit<>", "(T)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "Write<>", "(System.Byte,T)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "Write<>", "(System.Void*,T)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "WriteUnaligned<>", "(System.Byte,T)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.CompilerServices", "Unsafe", "WriteUnaligned<>", "(System.Void*,T)", "summary", "df-generated"]
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
extensions:
|
||||||
|
- addsTo:
|
||||||
|
pack: codeql/csharp-all
|
||||||
|
extensible: neutralModel
|
||||||
|
data:
|
||||||
|
- ["Internal.Runtime.InteropServices", "ComponentActivator", "GetFunctionPointer", "(System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr)", "summary", "df-generated"]
|
||||||
|
- ["Internal.Runtime.InteropServices", "ComponentActivator", "LoadAssemblyAndGetFunctionPointer", "(System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr)", "summary", "df-generated"]
|
||||||
9
csharp/ql/lib/ext/generated/Internal.model.yml
Normal file
9
csharp/ql/lib/ext/generated/Internal.model.yml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
extensions:
|
||||||
|
- addsTo:
|
||||||
|
pack: codeql/csharp-all
|
||||||
|
extensible: neutralModel
|
||||||
|
data:
|
||||||
|
- ["Internal", "Console", "Write", "(System.String)", "summary", "df-generated"]
|
||||||
|
- ["Internal", "Console", "WriteLine", "()", "summary", "df-generated"]
|
||||||
|
- ["Internal", "Console", "WriteLine", "(System.String)", "summary", "df-generated"]
|
||||||
|
- ["Internal", "Console+Error", "Write", "(System.String)", "summary", "df-generated"]
|
||||||
42
csharp/ql/lib/ext/generated/JsonToItemsTaskFactory.model.yml
Normal file
42
csharp/ql/lib/ext/generated/JsonToItemsTaskFactory.model.yml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
extensions:
|
||||||
|
- addsTo:
|
||||||
|
pack: codeql/csharp-all
|
||||||
|
extensible: summaryModel
|
||||||
|
data:
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory", False, "GetTaskParameters", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory", False, "Initialize", "(System.String,System.Collections.Generic.IDictionary<System.String,Microsoft.Build.Framework.TaskPropertyInfo>,System.String,Microsoft.Build.Framework.IBuildEngine)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+CaseInsensitiveDictionaryConverter", False, "Read", "(System.Text.Json.Utf8JsonReader,System.Type,System.Text.Json.JsonSerializerOptions)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonModelItemConverter", False, "Read", "(System.Text.Json.Utf8JsonReader,System.Type,System.Text.Json.JsonSerializerOptions)", "", "Argument[0]", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonToItemsTask", False, "SetPropertyValue", "(Microsoft.Build.Framework.TaskPropertyInfo,System.Object)", "", "Argument[1]", "Argument[this]", "taint", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonToItemsTask", False, "get_BuildEngine", "()", "", "Argument[this]", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonToItemsTask", False, "set_BuildEngine", "(Microsoft.Build.Framework.IBuildEngine)", "", "Argument[0]", "Argument[this]", "taint", "df-generated"]
|
||||||
|
- addsTo:
|
||||||
|
pack: codeql/csharp-all
|
||||||
|
extensible: neutralModel
|
||||||
|
data:
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory", "CleanupTask", "(Microsoft.Build.Framework.ITask)", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory", "CreateTask", "(Microsoft.Build.Framework.IBuildEngine)", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory", "JsonToItemsTaskFactory", "()", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory", "get_FactoryName", "()", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory", "get_TaskType", "()", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+CaseInsensitiveDictionaryConverter", "Write", "(System.Text.Json.Utf8JsonWriter,System.Collections.Generic.Dictionary<System.String,System.String>,System.Text.Json.JsonSerializerOptions)", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonModelItem", "JsonModelItem", "(System.String,System.Collections.Generic.Dictionary<System.String,System.String>)", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonModelItem", "get_Identity", "()", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonModelItem", "get_Metadata", "()", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonModelItemConverter", "JsonModelItemConverter", "()", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonModelItemConverter", "Write", "(System.Text.Json.Utf8JsonWriter,JsonToItemsTaskFactory.JsonToItemsTaskFactory+JsonModelItem,System.Text.Json.JsonSerializerOptions)", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonModelRoot", "JsonModelRoot", "()", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonModelRoot", "get_Items", "()", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonModelRoot", "get_Properties", "()", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonModelRoot", "set_Items", "(System.Collections.Generic.Dictionary<System.String,JsonToItemsTaskFactory.JsonToItemsTaskFactory+JsonModelItem[]>)", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonModelRoot", "set_Properties", "(System.Collections.Generic.Dictionary<System.String,System.String>)", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonToItemsTask", "ConvertItems", "(JsonToItemsTaskFactory.JsonToItemsTaskFactory+JsonModelItem[])", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonToItemsTask", "Execute", "()", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonToItemsTask", "GetJsonAsync", "(System.String,System.IO.FileStream)", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonToItemsTask", "GetPropertyValue", "(Microsoft.Build.Framework.TaskPropertyInfo)", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonToItemsTask", "JsonToItemsTask", "(System.String,System.Boolean)", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonToItemsTask", "TryGetJson", "(System.String,JsonToItemsTaskFactory.JsonToItemsTaskFactory+JsonModelRoot)", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonToItemsTask", "get_HostObject", "()", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonToItemsTask", "get_JsonOptions", "()", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonToItemsTask", "get_TaskName", "()", "summary", "df-generated"]
|
||||||
|
- ["JsonToItemsTaskFactory", "JsonToItemsTaskFactory+JsonToItemsTask", "set_HostObject", "(Microsoft.Build.Framework.ITaskHost)", "summary", "df-generated"]
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
extensions:
|
||||||
|
- addsTo:
|
||||||
|
pack: codeql/csharp-all
|
||||||
|
extensible: summaryModel
|
||||||
|
data:
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "BinaryOperation", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Linq.Expressions.ExpressionType,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "BinaryOperation", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Linq.Expressions.ExpressionType,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[3].Element", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "Convert", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Type,System.Type)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "GetIndex", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "GetIndex", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[2].Element", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "GetMember", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.String,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "GetMember", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.String,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[3].Element", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "Invoke", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "Invoke", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[2].Element", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "InvokeConstructor", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "InvokeConstructor", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[2].Element", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "InvokeMember", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.String,System.Collections.Generic.IEnumerable<System.Type>,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[4].Element", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "IsEvent", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.String,System.Type)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "SetIndex", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[1]", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "SetIndex", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[2].Element", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "SetMember", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.String,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "SetMember", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.String,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[3].Element", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "UnaryOperation", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Linq.Expressions.ExpressionType,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[2]", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "Binder", False, "UnaryOperation", "(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,System.Linq.Expressions.ExpressionType,System.Type,System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)", "", "Argument[3].Element", "ReturnValue", "taint", "df-generated"]
|
||||||
|
- addsTo:
|
||||||
|
pack: codeql/csharp-all
|
||||||
|
extensible: neutralModel
|
||||||
|
data:
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "CSharpArgumentInfo", "Create", "(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,System.String)", "summary", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "RuntimeBinderException", "RuntimeBinderException", "()", "summary", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "RuntimeBinderException", "RuntimeBinderException", "(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)", "summary", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "RuntimeBinderException", "RuntimeBinderException", "(System.String)", "summary", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "RuntimeBinderException", "RuntimeBinderException", "(System.String,System.Exception)", "summary", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "RuntimeBinderInternalCompilerException", "RuntimeBinderInternalCompilerException", "()", "summary", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "RuntimeBinderInternalCompilerException", "RuntimeBinderInternalCompilerException", "(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)", "summary", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "RuntimeBinderInternalCompilerException", "RuntimeBinderInternalCompilerException", "(System.String)", "summary", "df-generated"]
|
||||||
|
- ["Microsoft.CSharp.RuntimeBinder", "RuntimeBinderInternalCompilerException", "RuntimeBinderInternalCompilerException", "(System.String,System.Exception)", "summary", "df-generated"]
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user