mirror of
https://github.com/github/codeql.git
synced 2026-06-02 20:30:15 +02:00
Compare commits
1027 Commits
js/downwar
...
mbg/csharp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef78ad6c39 | ||
|
|
284f612965 | ||
|
|
b6c74fe306 | ||
|
|
95605935fa | ||
|
|
a8dde15a87 | ||
|
|
6b15f77168 | ||
|
|
0db6a269e4 | ||
|
|
726123c0cb | ||
|
|
11efb55aa1 | ||
|
|
63d5517d7c | ||
|
|
6b2f348c4c | ||
|
|
70232a34f3 | ||
|
|
933f3c6f77 | ||
|
|
d40ef0ddae | ||
|
|
474b8a5a31 | ||
|
|
60f96eee7e | ||
|
|
c17c0458dd | ||
|
|
82304832e8 | ||
|
|
c2309442d5 | ||
|
|
90774c03be | ||
|
|
35687ea698 | ||
|
|
7bfd47a924 | ||
|
|
ba13d7fffe | ||
|
|
ecb5e7ad07 | ||
|
|
b5a2f5d3ff | ||
|
|
4bd35b10fc | ||
|
|
6ba1d2ef14 | ||
|
|
9375e571b1 | ||
|
|
c7ff2f55b5 | ||
|
|
e01552c3f0 | ||
|
|
c5755ba8d4 | ||
|
|
0c17786ed0 | ||
|
|
66737402c2 | ||
|
|
908f48a22f | ||
|
|
9a8cb1a55b | ||
|
|
cf0b3b5727 | ||
|
|
a3ef137a8e | ||
|
|
563ffb8c27 | ||
|
|
de2fb037d0 | ||
|
|
7b5d604607 | ||
|
|
c3739d4f23 | ||
|
|
fba7bcd127 | ||
|
|
7f4905987e | ||
|
|
66a496fa82 | ||
|
|
45db4ae7c6 | ||
|
|
d23c8fd662 | ||
|
|
6f4e9ed136 | ||
|
|
0e5fa1b5eb | ||
|
|
470321e8b6 | ||
|
|
9cde2bb94d | ||
|
|
68b414d169 | ||
|
|
28d1152250 | ||
|
|
8cc39af190 | ||
|
|
3d643c02be | ||
|
|
255f06b65a | ||
|
|
e2699586db | ||
|
|
0fe77154e1 | ||
|
|
3bb89ea863 | ||
|
|
af91152f5c | ||
|
|
4681f28f92 | ||
|
|
0df2069575 | ||
|
|
de5c7efd63 | ||
|
|
dff66c7b28 | ||
|
|
36a524929f | ||
|
|
78280af570 | ||
|
|
4b02198652 | ||
|
|
a6ec8b6a25 | ||
|
|
2394f2fab8 | ||
|
|
795ba25895 | ||
|
|
fcdffc4e73 | ||
|
|
e8505ad33d | ||
|
|
62d4e6fe3f | ||
|
|
3a58611271 | ||
|
|
f30ebf1571 | ||
|
|
08ee51cbc4 | ||
|
|
1636abb81b | ||
|
|
5dff23de6b | ||
|
|
3640e5e425 | ||
|
|
03330ef24d | ||
|
|
6c9aa0e872 | ||
|
|
4917d64ce7 | ||
|
|
0c0158899e | ||
|
|
7712ca368a | ||
|
|
89410d07b3 | ||
|
|
1aa223652f | ||
|
|
b1edd9294b | ||
|
|
dd21dab055 | ||
|
|
8777bc42c7 | ||
|
|
209b9c6114 | ||
|
|
40375a0387 | ||
|
|
5eb9a535a4 | ||
|
|
72c7024c8b | ||
|
|
fa79dbc89a | ||
|
|
e05b172c88 | ||
|
|
10a9b78bc5 | ||
|
|
02051ff7b1 | ||
|
|
cd63e7cf54 | ||
|
|
aeb1acba97 | ||
|
|
66e8b2d7e5 | ||
|
|
0df652b297 | ||
|
|
64b57679bf | ||
|
|
ee6455a7b1 | ||
|
|
56f6a67d5f | ||
|
|
f8112945a8 | ||
|
|
df4f117a7c | ||
|
|
40903a9643 | ||
|
|
a5101bdae6 | ||
|
|
b76527fa84 | ||
|
|
e79cb443da | ||
|
|
f867e0fae8 | ||
|
|
bf24f7794f | ||
|
|
86bd3b8d26 | ||
|
|
8a8defd48f | ||
|
|
09986bc26c | ||
|
|
770920e738 | ||
|
|
184d23df46 | ||
|
|
b4016c144b | ||
|
|
b2e0eaf664 | ||
|
|
42f86a8234 | ||
|
|
312f201ce0 | ||
|
|
902b2ff641 | ||
|
|
4205d5ecea | ||
|
|
c43b2b167f | ||
|
|
0c99ae2800 | ||
|
|
cd0aebefa4 | ||
|
|
ca6f3ffa43 | ||
|
|
eddd724ea0 | ||
|
|
a574c9f276 | ||
|
|
9e8339db6d | ||
|
|
4a3e463918 | ||
|
|
979a5b4587 | ||
|
|
b3601b1ac2 | ||
|
|
f01737a4c0 | ||
|
|
269f9fa7c9 | ||
|
|
e17486a9d8 | ||
|
|
ea9b0462bf | ||
|
|
da720b8b6e | ||
|
|
daa57a9cb5 | ||
|
|
356b9e68c3 | ||
|
|
8599ab2503 | ||
|
|
044d0a13f0 | ||
|
|
4924a0faf3 | ||
|
|
dc7d7f121e | ||
|
|
371a72ecec | ||
|
|
1286420d39 | ||
|
|
120af3611a | ||
|
|
150aa5d1cf | ||
|
|
c15137e992 | ||
|
|
f42ae48ffa | ||
|
|
087c555796 | ||
|
|
4451e55bba | ||
|
|
6499e5458b | ||
|
|
e8c5e4d006 | ||
|
|
3991dc3aa3 | ||
|
|
a4f2264f17 | ||
|
|
1e0b78ebd3 | ||
|
|
744936fbd7 | ||
|
|
66ab3a8002 | ||
|
|
c001435258 | ||
|
|
22b36a86ce | ||
|
|
a900f2cea4 | ||
|
|
8b33dcd018 | ||
|
|
3191b2c6fc | ||
|
|
7c9edff33c | ||
|
|
b583e52a87 | ||
|
|
08c07f815f | ||
|
|
1ad8b4677d | ||
|
|
8f603251d7 | ||
|
|
e6884cf705 | ||
|
|
fa35d6c3ac | ||
|
|
73c0a93fc4 | ||
|
|
4a365857f1 | ||
|
|
13c701948a | ||
|
|
7717f92ec6 | ||
|
|
d1876251ee | ||
|
|
b48fd99913 | ||
|
|
b945466b9f | ||
|
|
4d02993efa | ||
|
|
f7d2abf3e3 | ||
|
|
91e9b23cf7 | ||
|
|
5c83644360 | ||
|
|
79e06153ed | ||
|
|
08c9f6fa1e | ||
|
|
0e965f7616 | ||
|
|
ca553bf1a2 | ||
|
|
0f201d2070 | ||
|
|
d84368eb54 | ||
|
|
75ed0d0b46 | ||
|
|
6a47678b60 | ||
|
|
c88eac486a | ||
|
|
0df893e280 | ||
|
|
6fe3a368eb | ||
|
|
b9dd594d69 | ||
|
|
f7532c09e6 | ||
|
|
122f68e525 | ||
|
|
8ee5b237e2 | ||
|
|
92dfdc8194 | ||
|
|
21d42bcd21 | ||
|
|
dad4838d3b | ||
|
|
017f458534 | ||
|
|
24c9b2ef9b | ||
|
|
ad63dd946c | ||
|
|
9c8e0a5537 | ||
|
|
21aa62c18c | ||
|
|
344fea2128 | ||
|
|
a16c2c80f7 | ||
|
|
b70643b1a1 | ||
|
|
26f0f7f6da | ||
|
|
d077d6807a | ||
|
|
1aa1829804 | ||
|
|
bb39955a24 | ||
|
|
aa35e82fc1 | ||
|
|
f48eab903f | ||
|
|
8cbc0aea05 | ||
|
|
13226edbeb | ||
|
|
9814aef71f | ||
|
|
f17f3758ed | ||
|
|
5855a12b03 | ||
|
|
58d7933d4f | ||
|
|
845f002124 | ||
|
|
8961a22a71 | ||
|
|
ff321194b7 | ||
|
|
e5b039702a | ||
|
|
fce637fc3a | ||
|
|
8ec8824cb7 | ||
|
|
9bba666929 | ||
|
|
c601adfc65 | ||
|
|
98a40967d2 | ||
|
|
e21a7f5336 | ||
|
|
75ca04f3dd | ||
|
|
8eb69079b7 | ||
|
|
0676c21a4b | ||
|
|
752fc64f42 | ||
|
|
b641caa508 | ||
|
|
179ea041f4 | ||
|
|
f9a7ac4e89 | ||
|
|
b06902a3b1 | ||
|
|
e73745d3ca | ||
|
|
3d0e44e156 | ||
|
|
3f8679a099 | ||
|
|
fe139e5bea | ||
|
|
cc902a6ad1 | ||
|
|
e0839a369c | ||
|
|
b2e3352aa8 | ||
|
|
d075466958 | ||
|
|
7a99dfaebe | ||
|
|
cef8f7b123 | ||
|
|
f58c72ed59 | ||
|
|
3903a90a11 | ||
|
|
b5ea34fcf3 | ||
|
|
5c0fc1f75b | ||
|
|
431586bb70 | ||
|
|
494f914070 | ||
|
|
abe14babb1 | ||
|
|
3508ca89e6 | ||
|
|
b1e53f5816 | ||
|
|
87ee191409 | ||
|
|
c9796ee297 | ||
|
|
82b7a19df1 | ||
|
|
e0f20b2bd1 | ||
|
|
fc186eb136 | ||
|
|
9cc26208d4 | ||
|
|
2a0e133768 | ||
|
|
5c3f21b20c | ||
|
|
c12c12c416 | ||
|
|
5a1991bb69 | ||
|
|
89040d0d06 | ||
|
|
0166e76cca | ||
|
|
1443f314a1 | ||
|
|
1e3b8625e6 | ||
|
|
da579c27fc | ||
|
|
6546bb1b1d | ||
|
|
97a3411c0c | ||
|
|
61c043fd4a | ||
|
|
a9ab39da1b | ||
|
|
5e722eecf7 | ||
|
|
9e6bdbbcbb | ||
|
|
947a85ed28 | ||
|
|
d95114fb1d | ||
|
|
fb3ce464be | ||
|
|
7e984ad48e | ||
|
|
7b2912376b | ||
|
|
cbe7edd9c6 | ||
|
|
2692b8fa9f | ||
|
|
0c091ffe31 | ||
|
|
32e1589745 | ||
|
|
ec063d0dbd | ||
|
|
1037626a28 | ||
|
|
63bfa36be8 | ||
|
|
a06de21f45 | ||
|
|
c73eeec814 | ||
|
|
dd7d5d031c | ||
|
|
35fbaf4ac3 | ||
|
|
361bdfac12 | ||
|
|
f2947f7066 | ||
|
|
0eec951218 | ||
|
|
a9d45a2aa2 | ||
|
|
b4c75d832c | ||
|
|
c6761db2fc | ||
|
|
a02735326a | ||
|
|
41e9a837e5 | ||
|
|
38bf9c6835 | ||
|
|
709d36b502 | ||
|
|
d884e5fe6b | ||
|
|
95d05ceab8 | ||
|
|
c9b75afc2a | ||
|
|
8086c25abe | ||
|
|
5c931fa897 | ||
|
|
8099423b6d | ||
|
|
9ea89cd63f | ||
|
|
c7f03df1eb | ||
|
|
d5ee93dbbc | ||
|
|
3b764b0640 | ||
|
|
fc5a49ef84 | ||
|
|
e835d8b168 | ||
|
|
c2b835da40 | ||
|
|
9af170f60e | ||
|
|
5551aebaa9 | ||
|
|
bf3d9ee6a9 | ||
|
|
e50ebfc8c2 | ||
|
|
f246ef764a | ||
|
|
795a2e1175 | ||
|
|
7a78766584 | ||
|
|
82062e2847 | ||
|
|
50a01b1244 | ||
|
|
746f022cfa | ||
|
|
324499e447 | ||
|
|
e2456ea59e | ||
|
|
5d3b40d514 | ||
|
|
88615f427b | ||
|
|
b8dd2e551e | ||
|
|
980ed23e63 | ||
|
|
45c4f3f898 | ||
|
|
e230166fe2 | ||
|
|
301ebcb12b | ||
|
|
e91911b4b4 | ||
|
|
c89e648738 | ||
|
|
07c041483d | ||
|
|
36908e8ef0 | ||
|
|
4d10c4110a | ||
|
|
1f13f0009f | ||
|
|
c22b05a6f4 | ||
|
|
e0d0dc9a80 | ||
|
|
6c89602691 | ||
|
|
f5eb2d94bc | ||
|
|
5a909aa69c | ||
|
|
4c0e5f62cf | ||
|
|
00b8c80c24 | ||
|
|
8474a47c2b | ||
|
|
122034fe8c | ||
|
|
f0993fc97e | ||
|
|
2f744ce3ec | ||
|
|
9e03b12ba0 | ||
|
|
39bba7f5c2 | ||
|
|
42eef9e4b7 | ||
|
|
2a29239b01 | ||
|
|
0d1865d718 | ||
|
|
96c0ca87fc | ||
|
|
2f7cdf1bfa | ||
|
|
b3447959fa | ||
|
|
d371723fe4 | ||
|
|
d82295c54a | ||
|
|
aa6779f19f | ||
|
|
35fd4d226f | ||
|
|
44e6691e6d | ||
|
|
7f56c67544 | ||
|
|
5d91f2e119 | ||
|
|
c0202f6085 | ||
|
|
fe6de2f672 | ||
|
|
1e05f327d6 | ||
|
|
3664d50772 | ||
|
|
ee83c42b71 | ||
|
|
381b5ebe8a | ||
|
|
fa5093f6ad | ||
|
|
2333c538d9 | ||
|
|
de6f3b1d04 | ||
|
|
ab7e08f40f | ||
|
|
ed418be97a | ||
|
|
a3749530d6 | ||
|
|
9740232df8 | ||
|
|
ee08e8b1fb | ||
|
|
1225c5c828 | ||
|
|
d8d882958d | ||
|
|
757067216d | ||
|
|
b0b95965f6 | ||
|
|
fbf7513f37 | ||
|
|
d162acf02c | ||
|
|
cb448db3ce | ||
|
|
7169c4be48 | ||
|
|
2e32e441b8 | ||
|
|
c8a89c4203 | ||
|
|
c3ad805fe8 | ||
|
|
d97d67359b | ||
|
|
c1ee20b2b9 | ||
|
|
2a194a53af | ||
|
|
193b26e938 | ||
|
|
33602ee52b | ||
|
|
c67c5854ba | ||
|
|
7bd01bf039 | ||
|
|
64d39da5f8 | ||
|
|
19cada38ff | ||
|
|
fd6a9c6144 | ||
|
|
b4ac2f7d73 | ||
|
|
87518ba60e | ||
|
|
bb67a0e9b0 | ||
|
|
0496de6c8f | ||
|
|
aade1e863d | ||
|
|
8ef51c495f | ||
|
|
87ed86e4fd | ||
|
|
605999454a | ||
|
|
dc28bb527b | ||
|
|
a1c13f02be | ||
|
|
2b33ed3671 | ||
|
|
6cf1334c6d | ||
|
|
7623ebb13b | ||
|
|
507a0918ad | ||
|
|
e634b31c27 | ||
|
|
4d7cbe6f60 | ||
|
|
764eb98809 | ||
|
|
976096540f | ||
|
|
49274d5f73 | ||
|
|
2d1aa3e00a | ||
|
|
9f8744680d | ||
|
|
3a535dbf68 | ||
|
|
db98dc6272 | ||
|
|
c79d355d26 | ||
|
|
7ed5398688 | ||
|
|
a1796bda8a | ||
|
|
2bed3a40bf | ||
|
|
9ef5a97b4e | ||
|
|
7fa63fa6ee | ||
|
|
69b2d197e6 | ||
|
|
360c76514c | ||
|
|
dbc079c880 | ||
|
|
4ca49fb4d8 | ||
|
|
29659647ea | ||
|
|
38be524b6a | ||
|
|
7c2394fab4 | ||
|
|
b734a3d804 | ||
|
|
1ee93cf51b | ||
|
|
0f23c33d3c | ||
|
|
cd788bc509 | ||
|
|
3f7f74b925 | ||
|
|
48760d66b2 | ||
|
|
260c66b3cf | ||
|
|
cea53371f2 | ||
|
|
cded75766f | ||
|
|
a0f8e28790 | ||
|
|
1fcebcec87 | ||
|
|
266ac09637 | ||
|
|
082e16b3d3 | ||
|
|
607b184a7f | ||
|
|
51fb3dad74 | ||
|
|
d298d8740f | ||
|
|
283b14207d | ||
|
|
92c3939457 | ||
|
|
0f8e85fa2f | ||
|
|
fc95702341 | ||
|
|
51b45598c4 | ||
|
|
e91a046a17 | ||
|
|
b54ff3b5b3 | ||
|
|
576dbcb020 | ||
|
|
f72cd21a55 | ||
|
|
d3de6d18a4 | ||
|
|
e745f42291 | ||
|
|
319ee2ccd5 | ||
|
|
c593853710 | ||
|
|
cf33db78cc | ||
|
|
c051b4c98d | ||
|
|
b095fe2a19 | ||
|
|
22c218d665 | ||
|
|
a9b263f465 | ||
|
|
287753187e | ||
|
|
426a871405 | ||
|
|
2c46e10678 | ||
|
|
e026b9e048 | ||
|
|
e5bee19b19 | ||
|
|
68fae9ded8 | ||
|
|
1f3c49638b | ||
|
|
f395651807 | ||
|
|
07a876b4e9 | ||
|
|
10a7294327 | ||
|
|
0453ded338 | ||
|
|
86932c51bc | ||
|
|
f5911c9e5a | ||
|
|
795c1100fc | ||
|
|
789a7bdb48 | ||
|
|
ac6547fd01 | ||
|
|
d0ce53ed82 | ||
|
|
426edd55f2 | ||
|
|
9be041e27d | ||
|
|
7e5c24a8ec | ||
|
|
79e2a758d7 | ||
|
|
2f2c9f8943 | ||
|
|
945bf80803 | ||
|
|
4f810df53c | ||
|
|
0445d886c7 | ||
|
|
c5eeaba2ec | ||
|
|
6b34d3f480 | ||
|
|
ad732a8f57 | ||
|
|
79e581f555 | ||
|
|
1577b40b45 | ||
|
|
178e90c2f1 | ||
|
|
94505af49e | ||
|
|
ee61fdcb6f | ||
|
|
ec2982f3df | ||
|
|
c4773c42c4 | ||
|
|
bc651af319 | ||
|
|
e0d4e5ea7f | ||
|
|
5b657035d2 | ||
|
|
7015a0af38 | ||
|
|
518f164c61 | ||
|
|
1b35c0b7c9 | ||
|
|
bb90b678a4 | ||
|
|
d11bbdb5a7 | ||
|
|
3c7fe264d1 | ||
|
|
5af7630841 | ||
|
|
b73e8dc74b | ||
|
|
ce82cb6424 | ||
|
|
998bec1efb | ||
|
|
51d916263d | ||
|
|
ac555ff0a3 | ||
|
|
93b11146d8 | ||
|
|
6c0aadfb57 | ||
|
|
28770c526d | ||
|
|
2dde9ab6b9 | ||
|
|
abc174858e | ||
|
|
160346f51b | ||
|
|
4e47da463e | ||
|
|
e08ae22ceb | ||
|
|
86c5d9f1cd | ||
|
|
3d19e2ad4a | ||
|
|
59e94521bc | ||
|
|
855dc09ea5 | ||
|
|
70bdeec3d5 | ||
|
|
76ad107c63 | ||
|
|
332f94e8a2 | ||
|
|
beeb417281 | ||
|
|
a94854bd72 | ||
|
|
f322cb7968 | ||
|
|
f7d95e4dcb | ||
|
|
ca0b363be3 | ||
|
|
f0951823ad | ||
|
|
a444bbc080 | ||
|
|
0f91323100 | ||
|
|
3487226116 | ||
|
|
c5284eb6fe | ||
|
|
63a4c8d697 | ||
|
|
4f204ee40f | ||
|
|
5e3ccc0cca | ||
|
|
1354bebd7c | ||
|
|
dbab845295 | ||
|
|
abb88e3dba | ||
|
|
c41add896f | ||
|
|
23fb139a87 | ||
|
|
91dd9f5d95 | ||
|
|
476fef49da | ||
|
|
e1ac5823ec | ||
|
|
83cdcdbb0b | ||
|
|
3956a1fea8 | ||
|
|
6857954569 | ||
|
|
bb7d227095 | ||
|
|
51ae7c6b8c | ||
|
|
4c28dbdc50 | ||
|
|
a11692707e | ||
|
|
0ef4c6f954 | ||
|
|
6dad937ce2 | ||
|
|
052792f7c4 | ||
|
|
90ea10e0b7 | ||
|
|
f34c3b16a2 | ||
|
|
baa4c509ca | ||
|
|
561a681e90 | ||
|
|
759f0583cb | ||
|
|
9458f073c6 | ||
|
|
2961320f02 | ||
|
|
cd9a7ec6a8 | ||
|
|
fc793fbc4d | ||
|
|
2a5ee847b8 | ||
|
|
3a67836eb2 | ||
|
|
6e53ebed47 | ||
|
|
cc5179a35e | ||
|
|
7593def620 | ||
|
|
457af87435 | ||
|
|
a7ac6b137b | ||
|
|
7d7498ee32 | ||
|
|
812315df27 | ||
|
|
2585c2f908 | ||
|
|
ff36d1916f | ||
|
|
07004bd6f9 | ||
|
|
11d145131f | ||
|
|
baa7e35589 | ||
|
|
26a96d9f65 | ||
|
|
0522f3f694 | ||
|
|
18a1ef55ea | ||
|
|
3360829a58 | ||
|
|
5c997859b0 | ||
|
|
994a8eea39 | ||
|
|
bb8f4529bf | ||
|
|
5f2e5ab8c3 | ||
|
|
2c3b48946d | ||
|
|
28e96449e7 | ||
|
|
bf77ffef37 | ||
|
|
d9ecb6255e | ||
|
|
bfcf9ea606 | ||
|
|
cbae16b392 | ||
|
|
17703ec908 | ||
|
|
83e442a266 | ||
|
|
d2105a7528 | ||
|
|
1bcc6ddb32 | ||
|
|
6089a75262 | ||
|
|
e8799e346d | ||
|
|
eff87d24fa | ||
|
|
2edc9af1e0 | ||
|
|
7eca4b4d82 | ||
|
|
92e1023d00 | ||
|
|
ae161f1654 | ||
|
|
694f01ab78 | ||
|
|
e2927b2fad | ||
|
|
f406914258 | ||
|
|
b2a595596b | ||
|
|
449150e6b5 | ||
|
|
ae3736bc25 | ||
|
|
b1b72b73ed | ||
|
|
a35510d937 | ||
|
|
f00f2c6f47 | ||
|
|
1f628d0f86 | ||
|
|
95cbd21a62 | ||
|
|
b40290683e | ||
|
|
57c4fd6f25 | ||
|
|
04476ca5f4 | ||
|
|
74a249597a | ||
|
|
c2e859c756 | ||
|
|
26e396732a | ||
|
|
53cb30dcd0 | ||
|
|
6fe7c7a233 | ||
|
|
f65a5b9a66 | ||
|
|
9e51b014d2 | ||
|
|
b2469ff8ba | ||
|
|
8dfb920e05 | ||
|
|
8064e8f1f9 | ||
|
|
5e5bc2afe9 | ||
|
|
089a491d5a | ||
|
|
978834bd9c | ||
|
|
2ce5920c5e | ||
|
|
0d994c1527 | ||
|
|
6437bd692e | ||
|
|
ddfb16899a | ||
|
|
6353dbf3f5 | ||
|
|
22b3dc8f43 | ||
|
|
22074afafb | ||
|
|
24411b61e9 | ||
|
|
7499df43d0 | ||
|
|
0583d85f20 | ||
|
|
d8dad7dff0 | ||
|
|
e8f86e41f4 | ||
|
|
97f9f0ccc5 | ||
|
|
a85131bf0f | ||
|
|
db7ec4a781 | ||
|
|
5eb305da93 | ||
|
|
11a0a9f8af | ||
|
|
09454f9f14 | ||
|
|
1af753cd0c | ||
|
|
782b6cfb9a | ||
|
|
8ef2029f3d | ||
|
|
81b6848a9c | ||
|
|
425fa0db09 | ||
|
|
6cb8f65076 | ||
|
|
fdc76dd06a | ||
|
|
3681ace746 | ||
|
|
1bce783623 | ||
|
|
7380ec8a55 | ||
|
|
fcb470330c | ||
|
|
88fe4faf9d | ||
|
|
09b2aeb53a | ||
|
|
689e7b8440 | ||
|
|
08913c551d | ||
|
|
1b2d842b44 | ||
|
|
d9d909a61e | ||
|
|
90758b37ef | ||
|
|
fd32355ca8 | ||
|
|
ae25399a47 | ||
|
|
547b082ac3 | ||
|
|
3aa1ba5876 | ||
|
|
32e4c741cc | ||
|
|
721b8c4ea6 | ||
|
|
57e985cc21 | ||
|
|
c93fb4cbc9 | ||
|
|
4e515bc2f5 | ||
|
|
cd0fd02e74 | ||
|
|
cd2c4d5e3a | ||
|
|
e2fe74ccd6 | ||
|
|
9acb58e8c2 | ||
|
|
24bd9fb7e5 | ||
|
|
4ef64cdf9f | ||
|
|
3587ba593a | ||
|
|
ab0241c1de | ||
|
|
e6e4ff1b72 | ||
|
|
1227a7eedc | ||
|
|
05690c21ed | ||
|
|
0f627ae59a | ||
|
|
967c1ad51c | ||
|
|
fd9475ea2f | ||
|
|
38f538e76a | ||
|
|
b77b5fc308 | ||
|
|
50d1bc6aa0 | ||
|
|
df2a110b41 | ||
|
|
65bce9d7e0 | ||
|
|
6932e000c6 | ||
|
|
1c616d10d4 | ||
|
|
44c5df5246 | ||
|
|
8aa9dd7092 | ||
|
|
26da997bb2 | ||
|
|
f7e094e887 | ||
|
|
45baceb2f5 | ||
|
|
311c1e1654 | ||
|
|
a1ba584b20 | ||
|
|
4567e02b8c | ||
|
|
fe34aa35a9 | ||
|
|
89355991df | ||
|
|
e77ebf0715 | ||
|
|
53c5b8ff9e | ||
|
|
b6f9055566 | ||
|
|
3954f5e45e | ||
|
|
c36e91855f | ||
|
|
cd49df0ff2 | ||
|
|
7b6a91e90e | ||
|
|
8c0cc077c8 | ||
|
|
22ed2e56a9 | ||
|
|
496f485375 | ||
|
|
8f0aced868 | ||
|
|
9162ce7d73 | ||
|
|
be6162edc0 | ||
|
|
1be903cb4f | ||
|
|
b6144c2f08 | ||
|
|
4a01a4df37 | ||
|
|
292b962513 | ||
|
|
8e609b19f5 | ||
|
|
1038f7c035 | ||
|
|
a8bb37c3c2 | ||
|
|
889ef33006 | ||
|
|
9d8e9975de | ||
|
|
3bf424b07d | ||
|
|
52515dda35 | ||
|
|
a1b7096125 | ||
|
|
22bf1af9f3 | ||
|
|
c22021ab55 | ||
|
|
485ee5c5ed | ||
|
|
d0461e2c08 | ||
|
|
b76e5f55c6 | ||
|
|
7e596032f1 | ||
|
|
4ddc5c9d75 | ||
|
|
b0a5e62003 | ||
|
|
17ae747b08 | ||
|
|
ed40035b9c | ||
|
|
291ea6f6eb | ||
|
|
5379506464 | ||
|
|
cf2136fbc7 | ||
|
|
75d320401b | ||
|
|
bc6ce32af2 | ||
|
|
54ebe9a8f4 | ||
|
|
7d3cc2eaf3 | ||
|
|
ce234bb2c6 | ||
|
|
11e3a08e44 | ||
|
|
fe4ee54b6f | ||
|
|
ae7e15d82f | ||
|
|
1d9a3dbd08 | ||
|
|
ebd6fd4156 | ||
|
|
a5fde9c3df | ||
|
|
3c00dc48b1 | ||
|
|
58c8b5fa2b | ||
|
|
462b6e6a0e | ||
|
|
4fa0019b55 | ||
|
|
b372af51b6 | ||
|
|
2cd9bd8a43 | ||
|
|
faef735ce9 | ||
|
|
9b6f0da1c1 | ||
|
|
c1df8d0e13 | ||
|
|
e1c280500e | ||
|
|
9865577bf5 | ||
|
|
2d991fc387 | ||
|
|
1a6c6a454d | ||
|
|
12d5a30703 | ||
|
|
8024fb6812 | ||
|
|
804a1a6cb0 | ||
|
|
7486742c37 | ||
|
|
ad4522c781 | ||
|
|
e40ee821c2 | ||
|
|
194afbb7f8 | ||
|
|
35f50bac97 | ||
|
|
d6dc91d191 | ||
|
|
411aff6748 | ||
|
|
11166fc42d | ||
|
|
d5ac5b4654 | ||
|
|
a4fee2e299 | ||
|
|
7e441d9eca | ||
|
|
77ccff6be8 | ||
|
|
6e272d07af | ||
|
|
ea08c60326 | ||
|
|
613323ee3a | ||
|
|
81b3035160 | ||
|
|
f80cd97232 | ||
|
|
5723d27428 | ||
|
|
c5e28842fb | ||
|
|
b62432fc80 | ||
|
|
36613e150b | ||
|
|
3822d149af | ||
|
|
d94dc5aa40 | ||
|
|
ab74d903fd | ||
|
|
f3a393f9da | ||
|
|
b3f7cd988b | ||
|
|
53557dbebd | ||
|
|
530bfccb7c | ||
|
|
38efd4a8a2 | ||
|
|
24e7aad6ba | ||
|
|
82a4b17218 | ||
|
|
e610683377 | ||
|
|
02249af781 | ||
|
|
9bb5fe837d | ||
|
|
c958702830 | ||
|
|
ad24f94a77 | ||
|
|
79525fa4ed | ||
|
|
975881c74a | ||
|
|
048f7dbd37 | ||
|
|
6f4562f3bd | ||
|
|
342bff6125 | ||
|
|
8bcfd00565 | ||
|
|
755140152c | ||
|
|
a54f0a74f1 | ||
|
|
6e074c301f | ||
|
|
df305d6b52 | ||
|
|
a253b77894 | ||
|
|
7fa41c438f | ||
|
|
a90bd68796 | ||
|
|
12a5766f31 | ||
|
|
b08f5356dd | ||
|
|
dcfe65bc66 | ||
|
|
4b53e1c034 | ||
|
|
4e325d9f1c | ||
|
|
6045d9bb22 | ||
|
|
08b9d934c0 | ||
|
|
352924fb8c | ||
|
|
33ab7db98a | ||
|
|
a74b203c86 | ||
|
|
d87534c7d0 | ||
|
|
e8d1703224 | ||
|
|
0c3e8a0f5b | ||
|
|
91b3d108bb | ||
|
|
8b3c1ab698 | ||
|
|
d79f429978 | ||
|
|
0ca9b2285b | ||
|
|
3644de007f | ||
|
|
180e45d66a | ||
|
|
e02577d3e9 | ||
|
|
5af60bba80 | ||
|
|
6ebffd59f6 | ||
|
|
55b8e8b748 | ||
|
|
01d70a6d73 | ||
|
|
3ec038e7b6 | ||
|
|
4097aa9f78 | ||
|
|
1fe46ccfd6 | ||
|
|
61a184c1d7 | ||
|
|
2bb6a3914b | ||
|
|
5f4871d609 | ||
|
|
31913c4a55 | ||
|
|
c0ebeb9c7b | ||
|
|
f1723321fa | ||
|
|
979d604bf6 | ||
|
|
ea0bd74728 | ||
|
|
283954d515 | ||
|
|
925d6ac234 | ||
|
|
89fd2876b6 | ||
|
|
5d2409e652 | ||
|
|
9a7ed7f3f7 | ||
|
|
99bb0f0b4f | ||
|
|
cf8abb7989 | ||
|
|
c84087cd19 | ||
|
|
28cb37364c | ||
|
|
a9b9410104 | ||
|
|
d8fe4d2698 | ||
|
|
083c756973 | ||
|
|
9cfd3391d2 | ||
|
|
71bc89beda | ||
|
|
9a29cebe58 | ||
|
|
632e0c82bd | ||
|
|
347e5ed029 | ||
|
|
250cbb6b05 | ||
|
|
e1f92b466f | ||
|
|
f28140bee9 | ||
|
|
7df3e647d1 | ||
|
|
25314b61db | ||
|
|
74f16ee866 | ||
|
|
1a52398a29 | ||
|
|
8fca15036e | ||
|
|
436f7ccc82 | ||
|
|
bee8b2fe32 | ||
|
|
fdcbbdfa08 | ||
|
|
2d9e1b3d16 | ||
|
|
84131dd068 | ||
|
|
c08bb257f3 | ||
|
|
f9a87cd0ea | ||
|
|
29f94f484c | ||
|
|
024fbf8f3a | ||
|
|
6c314739f6 | ||
|
|
c07a57bf6b | ||
|
|
9f9857b547 | ||
|
|
bd9eb7d564 | ||
|
|
1cfc8f6abc | ||
|
|
64c3f703fe | ||
|
|
09c44616a0 | ||
|
|
50584c8e82 | ||
|
|
5abcf13973 | ||
|
|
a6f58c9fd2 | ||
|
|
be1af88d23 | ||
|
|
aff03bd721 | ||
|
|
f9732c746b | ||
|
|
75b6855769 | ||
|
|
f597ea99e1 | ||
|
|
3f19279e98 | ||
|
|
a1069b1667 | ||
|
|
02fd23e53a | ||
|
|
e9c25037d4 | ||
|
|
c4724f42a3 | ||
|
|
26dcbf7a2a | ||
|
|
f531f4479b | ||
|
|
dd102c4cea | ||
|
|
63a853d8cb | ||
|
|
c537246310 | ||
|
|
eea295a3e6 | ||
|
|
b2ad98ae97 | ||
|
|
cb91fbf06e | ||
|
|
958c7d6ab6 | ||
|
|
253882c3d1 | ||
|
|
e9b8ec9324 | ||
|
|
3dd7f23d5a | ||
|
|
98ff406462 | ||
|
|
edda26c90d | ||
|
|
18cf39d063 | ||
|
|
1bd384564d | ||
|
|
ef9676f838 | ||
|
|
498828e91a | ||
|
|
f5b247d314 | ||
|
|
7476aeaabf | ||
|
|
efd9523079 | ||
|
|
3611673eec | ||
|
|
5da14252ed | ||
|
|
f46a2a1773 | ||
|
|
64f0908d0d | ||
|
|
5621eecc86 | ||
|
|
3218faee6c | ||
|
|
0442d24204 | ||
|
|
c602e82ac4 | ||
|
|
bf9563e78e | ||
|
|
f5521ca1b8 | ||
|
|
d0ed0fdeb3 | ||
|
|
f5ab6a6cd6 | ||
|
|
4f73429251 | ||
|
|
e7fdfd06bf | ||
|
|
9bd116fcf8 | ||
|
|
7e3f89842d | ||
|
|
4c3a2cd111 | ||
|
|
a69e3f5236 | ||
|
|
918c05c538 | ||
|
|
0912e3b024 | ||
|
|
9f9dde6655 | ||
|
|
921104306a | ||
|
|
61d5a692fb | ||
|
|
f5b9691e7d | ||
|
|
f3501819f7 | ||
|
|
9d810130e1 | ||
|
|
b3eaac0ab7 | ||
|
|
58fb592822 | ||
|
|
d7ffc3fc77 | ||
|
|
74155a0214 | ||
|
|
51a2d8c72f | ||
|
|
d9d0d3c18b | ||
|
|
8aa195d838 | ||
|
|
7af8fa75e6 | ||
|
|
78e3c89c68 | ||
|
|
bce4735062 | ||
|
|
a8a051234e | ||
|
|
d0f5aad085 | ||
|
|
1ff7a521d5 | ||
|
|
269f63d6b1 | ||
|
|
b8a720510c | ||
|
|
c597818c4b | ||
|
|
6966c96e7a | ||
|
|
ffc6b7abb6 | ||
|
|
d21c8d789b | ||
|
|
bd47dcc87d | ||
|
|
e8724ab220 | ||
|
|
4a4585a526 | ||
|
|
dce89c5419 | ||
|
|
5feb401607 | ||
|
|
60cc16cc0e | ||
|
|
59d454771d | ||
|
|
287cf0121d | ||
|
|
3802a73f47 | ||
|
|
e8adef18a3 | ||
|
|
aa2c84ea36 | ||
|
|
0bf8d4ec4b | ||
|
|
fa76bf3c9f | ||
|
|
526e235fc1 | ||
|
|
af073b78d9 | ||
|
|
9a37682851 | ||
|
|
a9f107ce06 | ||
|
|
2d76466405 | ||
|
|
0ccf4cecb8 | ||
|
|
9f3572d15a | ||
|
|
05fb22e8ff | ||
|
|
13f1f8fdff | ||
|
|
cf430da602 | ||
|
|
91b6b3ff1f | ||
|
|
b558119b51 | ||
|
|
4ac59795b9 | ||
|
|
55422d27fb | ||
|
|
9a7f14f717 | ||
|
|
68ab767189 | ||
|
|
6a8945c55d | ||
|
|
831cea663b | ||
|
|
4141b4fb8a | ||
|
|
a94ba25ebe | ||
|
|
460ed30d05 | ||
|
|
eb3a76ddce | ||
|
|
8744f158bd | ||
|
|
374b13e1bb | ||
|
|
1287f1befc | ||
|
|
d195273bf4 |
3
.bazelrc
3
.bazelrc
@@ -12,6 +12,9 @@ common --override_module=semmle_code=%workspace%/misc/bazel/semmle_code_stub
|
||||
|
||||
build --repo_env=CC=clang --repo_env=CXX=clang++
|
||||
|
||||
# print test output, like sembuild does.
|
||||
# Set to `errors` if this is too verbose.
|
||||
test --test_output all
|
||||
# we use transitions that break builds of `...`, so for `test` to work with that we need the following
|
||||
test --build_tests_only
|
||||
|
||||
|
||||
3
.github/codeql/codeql-config.yml
vendored
3
.github/codeql/codeql-config.yml
vendored
@@ -8,5 +8,8 @@ paths-ignore:
|
||||
- '/java/'
|
||||
- '/python/'
|
||||
- '/javascript/ql/test'
|
||||
- '/javascript/ql/integration-tests'
|
||||
- '/javascript/extractor/tests'
|
||||
- '/javascript/extractor/parser-tests'
|
||||
- '/javascript/ql/src/'
|
||||
- '/rust/ql'
|
||||
|
||||
7
.github/workflows/codeql-analysis.yml
vendored
7
.github/workflows/codeql-analysis.yml
vendored
@@ -18,6 +18,10 @@ on:
|
||||
|
||||
jobs:
|
||||
CodeQL-Build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: ['actions', 'csharp']
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -38,9 +42,8 @@ jobs:
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@main
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
with:
|
||||
languages: csharp
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql/codeql-config.yml
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
|
||||
1
.github/workflows/go-tests-other-os.yml
vendored
1
.github/workflows/go-tests-other-os.yml
vendored
@@ -3,6 +3,7 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "go/**"
|
||||
- "!go/documentation/**"
|
||||
- "!go/ql/**" # don't run other-os if only ql/ files changed
|
||||
- .github/workflows/go-tests-other-os.yml
|
||||
- .github/actions/**
|
||||
|
||||
2
.github/workflows/go-tests.yml
vendored
2
.github/workflows/go-tests.yml
vendored
@@ -3,6 +3,7 @@ on:
|
||||
push:
|
||||
paths:
|
||||
- "go/**"
|
||||
- "!go/documentation/**"
|
||||
- "shared/**"
|
||||
- .github/workflows/go-tests.yml
|
||||
- .github/actions/**
|
||||
@@ -13,6 +14,7 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "go/**"
|
||||
- "!go/documentation/**"
|
||||
- "shared/**"
|
||||
- .github/workflows/go-tests.yml
|
||||
- .github/actions/**
|
||||
|
||||
10
.vscode/tasks.json
vendored
10
.vscode/tasks.json
vendored
@@ -50,6 +50,11 @@
|
||||
"${input:name}",
|
||||
"${input:categoryQuery}"
|
||||
],
|
||||
"options": {
|
||||
"env": {
|
||||
"EDITOR": "code -r",
|
||||
}
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "never",
|
||||
"close": true
|
||||
@@ -67,6 +72,11 @@
|
||||
"${input:name}",
|
||||
"${input:categoryLibrary}"
|
||||
],
|
||||
"options": {
|
||||
"env": {
|
||||
"EDITOR": "code -r"
|
||||
}
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "never",
|
||||
"close": true
|
||||
|
||||
496
Cargo.lock
generated
496
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2006-2020 GitHub, Inc.
|
||||
Copyright (c) 2006-2025 GitHub, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
124
MODULE.bazel
124
MODULE.bazel
@@ -35,9 +35,9 @@ bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True
|
||||
|
||||
# Keep edition and version approximately in sync with internal repo.
|
||||
# the versions there are canonical, the versions here are used for CI in github/codeql, as well as for the vendoring of dependencies.
|
||||
RUST_EDITION = "2021"
|
||||
RUST_EDITION = "2024"
|
||||
|
||||
RUST_VERSION = "1.82.0"
|
||||
RUST_VERSION = "1.85.0"
|
||||
|
||||
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
|
||||
rust.toolchain(
|
||||
@@ -58,15 +58,12 @@ register_toolchains("@rust_toolchains//:all")
|
||||
py_deps = use_extension("//misc/bazel/3rdparty:py_deps_extension.bzl", "p")
|
||||
use_repo(
|
||||
py_deps,
|
||||
"vendor__anyhow-1.0.44",
|
||||
"vendor__cc-1.0.70",
|
||||
"vendor__clap-2.33.3",
|
||||
"vendor__regex-1.5.5",
|
||||
"vendor__smallvec-1.6.1",
|
||||
"vendor__string-interner-0.12.2",
|
||||
"vendor__thiserror-1.0.29",
|
||||
"vendor__tree-sitter-0.20.4",
|
||||
"vendor__tree-sitter-graph-0.7.0",
|
||||
"vendor_py__anyhow-1.0.95",
|
||||
"vendor_py__cc-1.2.14",
|
||||
"vendor_py__clap-4.5.30",
|
||||
"vendor_py__regex-1.11.1",
|
||||
"vendor_py__tree-sitter-0.20.4",
|
||||
"vendor_py__tree-sitter-graph-0.7.0",
|
||||
)
|
||||
|
||||
# deps for ruby+rust
|
||||
@@ -74,58 +71,59 @@ use_repo(
|
||||
tree_sitter_extractors_deps = use_extension("//misc/bazel/3rdparty:tree_sitter_extractors_extension.bzl", "r")
|
||||
use_repo(
|
||||
tree_sitter_extractors_deps,
|
||||
"vendor__anyhow-1.0.95",
|
||||
"vendor__argfile-0.2.1",
|
||||
"vendor__chrono-0.4.39",
|
||||
"vendor__clap-4.5.26",
|
||||
"vendor__dunce-1.0.5",
|
||||
"vendor__either-1.13.0",
|
||||
"vendor__encoding-0.2.33",
|
||||
"vendor__figment-0.10.19",
|
||||
"vendor__flate2-1.0.35",
|
||||
"vendor__glob-0.3.2",
|
||||
"vendor__globset-0.4.15",
|
||||
"vendor__itertools-0.14.0",
|
||||
"vendor__lazy_static-1.5.0",
|
||||
"vendor__log-0.4.22",
|
||||
"vendor__mustache-0.9.0",
|
||||
"vendor__num-traits-0.2.19",
|
||||
"vendor__num_cpus-1.16.0",
|
||||
"vendor__proc-macro2-1.0.93",
|
||||
"vendor__quote-1.0.38",
|
||||
"vendor__ra_ap_base_db-0.0.258",
|
||||
"vendor__ra_ap_cfg-0.0.258",
|
||||
"vendor__ra_ap_hir-0.0.258",
|
||||
"vendor__ra_ap_hir_def-0.0.258",
|
||||
"vendor__ra_ap_hir_expand-0.0.258",
|
||||
"vendor__ra_ap_ide_db-0.0.258",
|
||||
"vendor__ra_ap_intern-0.0.258",
|
||||
"vendor__ra_ap_load-cargo-0.0.258",
|
||||
"vendor__ra_ap_parser-0.0.258",
|
||||
"vendor__ra_ap_paths-0.0.258",
|
||||
"vendor__ra_ap_project_model-0.0.258",
|
||||
"vendor__ra_ap_span-0.0.258",
|
||||
"vendor__ra_ap_stdx-0.0.258",
|
||||
"vendor__ra_ap_syntax-0.0.258",
|
||||
"vendor__ra_ap_vfs-0.0.258",
|
||||
"vendor__rand-0.8.5",
|
||||
"vendor__rayon-1.10.0",
|
||||
"vendor__regex-1.11.1",
|
||||
"vendor__serde-1.0.217",
|
||||
"vendor__serde_json-1.0.135",
|
||||
"vendor__serde_with-3.12.0",
|
||||
"vendor__stderrlog-0.6.0",
|
||||
"vendor__syn-2.0.96",
|
||||
"vendor__toml-0.8.19",
|
||||
"vendor__tracing-0.1.41",
|
||||
"vendor__tracing-subscriber-0.3.19",
|
||||
"vendor__tree-sitter-0.24.6",
|
||||
"vendor__tree-sitter-embedded-template-0.23.2",
|
||||
"vendor__tree-sitter-json-0.24.8",
|
||||
"vendor__tree-sitter-ql-0.23.1",
|
||||
"vendor__tree-sitter-ruby-0.23.1",
|
||||
"vendor__triomphe-0.1.14",
|
||||
"vendor__ungrammar-1.16.1",
|
||||
"vendor_ts__anyhow-1.0.96",
|
||||
"vendor_ts__argfile-0.2.1",
|
||||
"vendor_ts__chalk-ir-0.99.0",
|
||||
"vendor_ts__chrono-0.4.39",
|
||||
"vendor_ts__clap-4.5.31",
|
||||
"vendor_ts__dunce-1.0.5",
|
||||
"vendor_ts__either-1.14.0",
|
||||
"vendor_ts__encoding-0.2.33",
|
||||
"vendor_ts__figment-0.10.19",
|
||||
"vendor_ts__flate2-1.1.0",
|
||||
"vendor_ts__glob-0.3.2",
|
||||
"vendor_ts__globset-0.4.15",
|
||||
"vendor_ts__itertools-0.14.0",
|
||||
"vendor_ts__lazy_static-1.5.0",
|
||||
"vendor_ts__mustache-0.9.0",
|
||||
"vendor_ts__num-traits-0.2.19",
|
||||
"vendor_ts__num_cpus-1.16.0",
|
||||
"vendor_ts__proc-macro2-1.0.93",
|
||||
"vendor_ts__quote-1.0.38",
|
||||
"vendor_ts__ra_ap_base_db-0.0.266",
|
||||
"vendor_ts__ra_ap_cfg-0.0.266",
|
||||
"vendor_ts__ra_ap_hir-0.0.266",
|
||||
"vendor_ts__ra_ap_hir_def-0.0.266",
|
||||
"vendor_ts__ra_ap_hir_expand-0.0.266",
|
||||
"vendor_ts__ra_ap_hir_ty-0.0.266",
|
||||
"vendor_ts__ra_ap_ide_db-0.0.266",
|
||||
"vendor_ts__ra_ap_intern-0.0.266",
|
||||
"vendor_ts__ra_ap_load-cargo-0.0.266",
|
||||
"vendor_ts__ra_ap_parser-0.0.266",
|
||||
"vendor_ts__ra_ap_paths-0.0.266",
|
||||
"vendor_ts__ra_ap_project_model-0.0.266",
|
||||
"vendor_ts__ra_ap_span-0.0.266",
|
||||
"vendor_ts__ra_ap_stdx-0.0.266",
|
||||
"vendor_ts__ra_ap_syntax-0.0.266",
|
||||
"vendor_ts__ra_ap_vfs-0.0.266",
|
||||
"vendor_ts__rand-0.9.0",
|
||||
"vendor_ts__rayon-1.10.0",
|
||||
"vendor_ts__regex-1.11.1",
|
||||
"vendor_ts__serde-1.0.218",
|
||||
"vendor_ts__serde_json-1.0.139",
|
||||
"vendor_ts__serde_with-3.12.0",
|
||||
"vendor_ts__syn-2.0.98",
|
||||
"vendor_ts__toml-0.8.20",
|
||||
"vendor_ts__tracing-0.1.41",
|
||||
"vendor_ts__tracing-flame-0.2.0",
|
||||
"vendor_ts__tracing-subscriber-0.3.19",
|
||||
"vendor_ts__tree-sitter-0.24.6",
|
||||
"vendor_ts__tree-sitter-embedded-template-0.23.2",
|
||||
"vendor_ts__tree-sitter-json-0.24.8",
|
||||
"vendor_ts__tree-sitter-ql-0.23.1",
|
||||
"vendor_ts__tree-sitter-ruby-0.23.1",
|
||||
"vendor_ts__triomphe-0.1.14",
|
||||
"vendor_ts__ungrammar-1.16.1",
|
||||
)
|
||||
|
||||
http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
@@ -4,7 +4,9 @@ codeql_pkg_files(
|
||||
name = "extractor",
|
||||
srcs = [
|
||||
"codeql-extractor.yml",
|
||||
] + glob(["tools/**"]),
|
||||
"//:LICENSE",
|
||||
],
|
||||
exes = glob(["tools/**"]),
|
||||
strip_prefix = strip_prefix.from_pkg(),
|
||||
visibility = ["//actions:__pkg__"],
|
||||
)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/actions-all
|
||||
extensible: immutableActionsDataModel
|
||||
data:
|
||||
- ["actions/checkout"]
|
||||
- ["actions/cache"]
|
||||
- ["actions/setup-node"]
|
||||
- ["actions/upload-artifact"]
|
||||
- ["actions/setup-python"]
|
||||
- ["actions/download-artifact"]
|
||||
- ["actions/github-script"]
|
||||
- ["actions/setup-java"]
|
||||
- ["actions/setup-go"]
|
||||
- ["actions/upload-pages-artifact"]
|
||||
- ["actions/deploy-pages"]
|
||||
- ["actions/setup-dotnet"]
|
||||
- ["actions/stale"]
|
||||
- ["actions/labeler"]
|
||||
- ["actions/create-github-app-token"]
|
||||
- ["actions/configure-pages"]
|
||||
- ["github/codeql-action/analyze"]
|
||||
- ["github/codeql-action/autobuild"]
|
||||
- ["github/codeql-action/init"]
|
||||
- ["github/codeql-action/resolve-environment"]
|
||||
- ["github/codeql-action/start-proxy"]
|
||||
- ["github/codeql-action/upload-sarif"]
|
||||
- ["octokit/request-action"]
|
||||
14
actions/ql/extensions/immutable-actions-list/qlpack.yml
Normal file
14
actions/ql/extensions/immutable-actions-list/qlpack.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
# Model pack containing the list of known immutable actions. The Immutable Actions feature is not
|
||||
# yet released, so this pack will only be used within GitHub. Once the feature is available to
|
||||
# customers, we will move the contents of this pack back into the standard library pack.
|
||||
name: codeql/immutable-actions-list
|
||||
version: 0.0.1-dev
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
extensionTargets:
|
||||
# We expect to need this model pack even after GA of Actions analysis, so make it compatible with
|
||||
# all future prereleases plus 1.x.x. We should be able to remove this back before we need to
|
||||
# bump the major version to 2.
|
||||
codeql/actions-all: ">=0.4.3 <2.0.0"
|
||||
dataExtensions:
|
||||
- ext/**/*.yml
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.4.3
|
||||
|
||||
### New Features
|
||||
|
||||
* The "Unpinned tag for a non-immutable Action in workflow" query (`actions/unpinned-tag`) now supports expanding the trusted action owner list using data extensions (`extensible: trustedActionsOwnerDataModel`). If you trust an Action publisher, you can include the owner name/organization in a model pack to add it to the allow list for this query. This addition will prevent security alerts when using unpinned tags for Actions published by that owner. For more information on creating a model pack, see [Creating a CodeQL Model Pack](https://docs.github.com/en/code-security/codeql-cli/using-the-advanced-functionality-of-the-codeql-cli/creating-and-working-with-codeql-packs#creating-a-codeql-model-pack).
|
||||
|
||||
## 0.4.2
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* The "Unpinned tag for a non-immutable Action in workflow" query (`actions/unpinned-tag`) now supports expanding the trusted action owner list using data extensions (`extensible: trustedActionsOwnerDataModel`). If you trust an Action publisher, you can include the owner name/organization in a model pack to add it to the allow list for this query. This addition will prevent security alerts when using unpinned tags for Actions published by that owner. For more information on creating a model pack, see [Creating a CodeQL Model Pack](https://docs.github.com/en/code-security/codeql-cli/using-the-advanced-functionality-of-the-codeql-cli/creating-and-working-with-codeql-packs#creating-a-codeql-model-pack).
|
||||
## 0.4.3
|
||||
|
||||
### New Features
|
||||
|
||||
* The "Unpinned tag for a non-immutable Action in workflow" query (`actions/unpinned-tag`) now supports expanding the trusted action owner list using data extensions (`extensible: trustedActionsOwnerDataModel`). If you trust an Action publisher, you can include the owner name/organization in a model pack to add it to the allow list for this query. This addition will prevent security alerts when using unpinned tags for Actions published by that owner. For more information on creating a model pack, see [Creating a CodeQL Model Pack](https://docs.github.com/en/code-security/codeql-cli/using-the-advanced-functionality-of-the-codeql-cli/creating-and-working-with-codeql-packs#creating-a-codeql-model-pack).
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.2
|
||||
lastReleaseVersion: 0.4.3
|
||||
|
||||
@@ -2,21 +2,9 @@ extensions:
|
||||
- addsTo:
|
||||
pack: codeql/actions-all
|
||||
extensible: immutableActionsDataModel
|
||||
data:
|
||||
- ["actions/checkout"]
|
||||
- ["actions/cache"]
|
||||
- ["actions/setup-node"]
|
||||
- ["actions/upload-artifact"]
|
||||
- ["actions/setup-python"]
|
||||
- ["actions/download-artifact"]
|
||||
- ["actions/github-script"]
|
||||
- ["actions/setup-java"]
|
||||
- ["actions/setup-go"]
|
||||
- ["actions/upload-pages-artifact"]
|
||||
- ["actions/deploy-pages"]
|
||||
- ["actions/setup-dotnet"]
|
||||
- ["actions/stale"]
|
||||
- ["actions/labeler"]
|
||||
- ["actions/create-github-app-token"]
|
||||
- ["actions/configure-pages"]
|
||||
- ["octokit/request-action"]
|
||||
# Since the Immutable Actions feature is not yet available to customers, we won't alert about
|
||||
# any unversioned immutable action references for now. Within GitHub, we'll include the
|
||||
# `codeql/immutable-actions-list` model pack, which will provide the necessary list of actions
|
||||
# for internal use. Once the feature is available to customers, we'll move that list back into
|
||||
# this file.
|
||||
data: []
|
||||
|
||||
@@ -5,4 +5,4 @@ extensions:
|
||||
data:
|
||||
- ["actions"]
|
||||
- ["github"]
|
||||
- ["advanced-security"]
|
||||
- ["advanced-security"]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.3-dev
|
||||
version: 0.4.4-dev
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
## 0.5.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* The following queries have been removed from the `code-scanning` and `security-extended` suites.
|
||||
Any existing alerts for these queries will be closed automatically.
|
||||
* `actions/if-expression-always-true/critical`
|
||||
* `actions/if-expression-always-true/high`
|
||||
* `actions/unnecessary-use-of-advanced-config`
|
||||
|
||||
* The following query has been moved from the `code-scanning` suite to the `security-extended`
|
||||
suite. Any existing alerts for this query will be closed automatically unless the analysis is
|
||||
configured to use the `security-extended` suite.
|
||||
* `actions/unpinned-tag`
|
||||
* The following queries have been added to the `security-extended` suite.
|
||||
* `actions/unversioned-immutable-action`
|
||||
* `actions/envpath-injection/medium`
|
||||
* `actions/envvar-injection/medium`
|
||||
* `actions/code-injection/medium`
|
||||
* `actions/artifact-poisoning/medium`
|
||||
* `actions/untrusted-checkout/medium`
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Fixed false positives in the query `actions/unpinned-tag` (CWE-829), which will no longer flag uses of Docker-based GitHub actions pinned by the container's SHA256 digest.
|
||||
|
||||
## 0.4.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
The following example, correctly creates a temporary directory and extracts the contents of the artifact there before calling `cmd.sh`.
|
||||
|
||||
```yaml
|
||||
name: Insecure Workflow
|
||||
name: Secure Workflow
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
The following example, correctly creates a temporary directory and extracts the contents of the artifact there before calling `cmd.sh`.
|
||||
|
||||
```yaml
|
||||
name: Insecure Workflow
|
||||
name: Secure Workflow
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
|
||||
@@ -23,6 +23,14 @@ private predicate isTrustedOwner(string nwo) {
|
||||
trustedActionsOwnerDataModel(nwo.substring(0, nwo.indexOf("/")))
|
||||
}
|
||||
|
||||
bindingset[version]
|
||||
private predicate isPinnedContainer(string version) {
|
||||
version.regexpMatch("^sha256:[A-Fa-f0-9]{64}$")
|
||||
}
|
||||
|
||||
bindingset[nwo]
|
||||
private predicate isContainerImage(string nwo) { nwo.regexpMatch("^docker://.+") }
|
||||
|
||||
from UsesStep uses, string nwo, string version, Workflow workflow, string name
|
||||
where
|
||||
uses.getCallee() = nwo and
|
||||
@@ -34,7 +42,7 @@ where
|
||||
) and
|
||||
uses.getVersion() = version and
|
||||
not isTrustedOwner(nwo) and
|
||||
not isPinnedCommit(version) and
|
||||
not (if isContainerImage(nwo) then isPinnedContainer(version) else isPinnedCommit(version)) and
|
||||
not isImmutableAction(uses, nwo)
|
||||
select uses.getCalleeNode(),
|
||||
"Unpinned 3rd party Action '" + name + "' step $@ uses '" + nwo + "' with ref '" + version +
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* The `actions/unversioned-immutable-action` query will no longer report any alerts, since the
|
||||
Immutable Actions feature is not yet available for customer use. The query has also been moved
|
||||
to the experimental folder and will not be used in code scanning unless it is explicitly added
|
||||
to a code scanning configuration. Once the Immutable Actions feature is available, the query will
|
||||
be updated to report alerts again.
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
## 0.5.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* The following queries have been removed from the `code-scanning` and `security-extended` suites.
|
||||
Any existing alerts for these queries will be closed automatically.
|
||||
* `actions/if-expression-always-true/critical`
|
||||
@@ -18,3 +19,7 @@ category: breaking
|
||||
* `actions/code-injection/medium`
|
||||
* `actions/artifact-poisoning/medium`
|
||||
* `actions/untrusted-checkout/medium`
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Fixed false positives in the query `actions/unpinned-tag` (CWE-829), which will no longer flag uses of Docker-based GitHub actions pinned by the container's SHA256 digest.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.2
|
||||
lastReleaseVersion: 0.5.0
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
- description: Security-and-quality queries for GitHub Actions
|
||||
- import: codeql-suites/actions-security-extended.qls
|
||||
- queries: .
|
||||
- apply: security-and-quality-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
- description: Extended and experimental security queries for GitHub Actions
|
||||
- import: codeql-suites/actions-code-scanning.qls
|
||||
- queries: .
|
||||
- apply: security-experimental-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* @tags security
|
||||
* actions
|
||||
* internal
|
||||
* experimental
|
||||
* external/cwe/cwe-829
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.4.3-dev
|
||||
version: 0.5.1-dev
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
@@ -8,3 +8,4 @@ extractor: actions
|
||||
defaultSuiteFile: codeql-suites/actions-code-scanning.qls
|
||||
dependencies:
|
||||
codeql/actions-all: ${workspace}
|
||||
codeql/suite-helpers: ${workspace}
|
||||
|
||||
@@ -3,6 +3,10 @@ groups: [codeql, test]
|
||||
dependencies:
|
||||
codeql/actions-all: ${workspace}
|
||||
codeql/actions-queries: ${workspace}
|
||||
# Use the `immutable-actions-list` model pack so that we have some actual data to test against.
|
||||
# We can remove this dependency when we incorporate the data from that model pack back into the
|
||||
# standard library pack.
|
||||
codeql/immutable-actions-list: ${workspace}
|
||||
extractor: actions
|
||||
tests: .
|
||||
warnOnImplicitThis: true
|
||||
|
||||
@@ -9,3 +9,5 @@ jobs:
|
||||
- uses: foo/bar
|
||||
- uses: foo/bar@v1
|
||||
- uses: foo/bar@25b062c917b0c75f8b47d8469aff6c94ffd89abb
|
||||
- uses: docker://foo/bar@latest
|
||||
- uses: docker://foo/bar@sha256:887a259a5a534f3c4f36cb02dca341673c6089431057242cdc931e9f133147e9
|
||||
|
||||
@@ -32,3 +32,4 @@
|
||||
| .github/workflows/test17.yml:20:21:20:63 | sonarsource/sonarcloud-github-action@master | Unpinned 3rd party Action 'Sonar' step $@ uses 'sonarsource/sonarcloud-github-action' with ref 'master', not a pinned commit hash | .github/workflows/test17.yml:19:15:23:58 | Uses Step | Uses Step |
|
||||
| .github/workflows/test18.yml:37:21:37:63 | sonarsource/sonarcloud-github-action@master | Unpinned 3rd party Action 'Sonar' step $@ uses 'sonarsource/sonarcloud-github-action' with ref 'master', not a pinned commit hash | .github/workflows/test18.yml:36:15:40:58 | Uses Step | Uses Step |
|
||||
| .github/workflows/unpinned_tags.yml:10:13:10:22 | foo/bar@v1 | Unpinned 3rd party Action 'unpinned_tags.yml' step $@ uses 'foo/bar' with ref 'v1', not a pinned commit hash | .github/workflows/unpinned_tags.yml:10:7:11:4 | Uses Step | Uses Step |
|
||||
| .github/workflows/unpinned_tags.yml:12:13:12:35 | docker://foo/bar@latest | Unpinned 3rd party Action 'unpinned_tags.yml' step $@ uses 'docker://foo/bar' with ref 'latest', not a pinned commit hash | .github/workflows/unpinned_tags.yml:12:7:13:4 | Uses Step | Uses Step |
|
||||
|
||||
@@ -299,7 +299,9 @@ edges
|
||||
| .github/workflows/test.yml:14:9:25:6 | Run Step | .github/workflows/test.yml:25:9:33:6 | Run Step |
|
||||
| .github/workflows/test.yml:25:9:33:6 | Run Step | .github/workflows/test.yml:33:9:37:34 | Run Step |
|
||||
| .github/workflows/unpinned_tags.yml:9:7:10:4 | Uses Step | .github/workflows/unpinned_tags.yml:10:7:11:4 | Uses Step |
|
||||
| .github/workflows/unpinned_tags.yml:10:7:11:4 | Uses Step | .github/workflows/unpinned_tags.yml:11:7:11:61 | Uses Step |
|
||||
| .github/workflows/unpinned_tags.yml:10:7:11:4 | Uses Step | .github/workflows/unpinned_tags.yml:11:7:12:4 | Uses Step |
|
||||
| .github/workflows/unpinned_tags.yml:11:7:12:4 | Uses Step | .github/workflows/unpinned_tags.yml:12:7:13:4 | Uses Step |
|
||||
| .github/workflows/unpinned_tags.yml:12:7:13:4 | Uses Step | .github/workflows/unpinned_tags.yml:13:7:13:101 | Uses Step |
|
||||
| .github/workflows/untrusted_checkout2.yml:7:9:14:6 | Run Step: pr_number | .github/workflows/untrusted_checkout2.yml:14:9:19:72 | Run Step |
|
||||
| .github/workflows/untrusted_checkout3.yml:11:9:12:6 | Uses Step | .github/workflows/untrusted_checkout3.yml:12:9:13:6 | Uses Step |
|
||||
| .github/workflows/untrusted_checkout3.yml:12:9:13:6 | Uses Step | .github/actions/dangerous-git-checkout/action.yml:6:7:11:4 | Uses Step |
|
||||
|
||||
@@ -1 +1 @@
|
||||
Security/CWE-829/UnversionedImmutableAction.ql
|
||||
experimental/Security/CWE-829/UnversionedImmutableAction.ql
|
||||
|
||||
@@ -17,7 +17,7 @@ provide:
|
||||
- "misc/legacy-support/*/qlpack.yml"
|
||||
- "misc/suite-helpers/qlpack.yml"
|
||||
- ".github/codeql/extensions/**/codeql-pack.yml"
|
||||
|
||||
- "actions/ql/extensions/**/qlpack.yml"
|
||||
versionPolicies:
|
||||
default:
|
||||
requireChangeNotes: true
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 4.0.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 4.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
4
cpp/ql/lib/change-notes/2025-02-20-getbuffersize.md
Normal file
4
cpp/ql/lib/change-notes/2025-02-20-getbuffersize.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Fixed an issue where the `getBufferSize` predicate in `commons/Buffer.qll` was returning results for references inside `offsetof` expressions, which are not accesses to a buffer.
|
||||
4
cpp/ql/lib/change-notes/2025-02-25-getbuffersize.md
Normal file
4
cpp/ql/lib/change-notes/2025-02-25-getbuffersize.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Modified the `getBufferSize` predicate in `commons/Buffer.qll` to be more tolerant in some cases involving member variables in a larger struct or class.
|
||||
4
cpp/ql/lib/change-notes/2025-03-13-ascertaindef.md
Normal file
4
cpp/ql/lib/change-notes/2025-03-13-ascertaindef.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added `Node.asUncertainDefinition` and `Node.asCertainDefinition` to the `DataFlow::Node` class for querying whether a definition overwrites the entire destination buffer.
|
||||
3
cpp/ql/lib/change-notes/released/4.0.1.md
Normal file
3
cpp/ql/lib/change-notes/released/4.0.1.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 4.0.1
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 4.0.0
|
||||
lastReleaseVersion: 4.0.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 4.0.1-dev
|
||||
version: 4.0.2-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -75,7 +75,10 @@ class Location extends @location {
|
||||
|
||||
/** Holds if `this` comes on a line strictly before `l`. */
|
||||
pragma[inline]
|
||||
predicate isBefore(Location l) { this.isBefore(l, false) }
|
||||
predicate isBefore(Location l) {
|
||||
this.getFile() = l.getFile() and
|
||||
this.getEndLine() < l.getStartLine()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `this` comes strictly before `l`. The boolean `sameLine` is
|
||||
|
||||
@@ -71,7 +71,7 @@ private int getSize(VariableAccess va) {
|
||||
result = t.getSize()
|
||||
)
|
||||
or
|
||||
exists(Class c |
|
||||
exists(Class c, int trueSize |
|
||||
// Otherwise, we find the "outermost" object and compute the size
|
||||
// as the difference between the size of the type of the "outermost
|
||||
// object" and the offset of the field relative to that type.
|
||||
@@ -91,7 +91,9 @@ private int getSize(VariableAccess va) {
|
||||
// of `y` relative to the type `S2` (i.e., `4`). So the size of the
|
||||
// buffer is `12 - 4 = 8`.
|
||||
c = getRootType(va) and
|
||||
result = c.getSize() - v.(Field).getOffsetInClass(c)
|
||||
// we calculate the size based on the last field, to avoid including any padding after it
|
||||
trueSize = max(Field f | | f.getOffsetInClass(c) + f.getUnspecifiedType().getSize()) and
|
||||
result = trueSize - v.(Field).getOffsetInClass(c)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -105,9 +107,16 @@ private int getSize(VariableAccess va) {
|
||||
private int isSource(Expr bufferExpr, Element why) {
|
||||
exists(Variable bufferVar | bufferVar = bufferExpr.(VariableAccess).getTarget() |
|
||||
// buffer is a fixed size array
|
||||
result = bufferVar.getUnspecifiedType().(ArrayType).getSize() and
|
||||
exists(bufferVar.getUnspecifiedType().(ArrayType).getSize()) and
|
||||
result =
|
||||
unique(int size | // more generous than .getSize() itself, when the array is a class field or similar.
|
||||
size = getSize(bufferExpr)
|
||||
|
|
||||
size
|
||||
) and
|
||||
why = bufferVar and
|
||||
not memberMayBeVarSize(_, bufferVar) and
|
||||
not exists(BuiltInOperationBuiltInOffsetOf offsetof | offsetof.getAChild*() = bufferExpr) and
|
||||
// zero sized arrays are likely to have special usage, for example
|
||||
// behaving a bit like a 'union' overlapping other fields.
|
||||
not result = 0
|
||||
|
||||
@@ -869,12 +869,11 @@ private predicate elementSpecMatchesSignature(
|
||||
bindingset[nameWithoutArgs]
|
||||
pragma[inline_late]
|
||||
private Class getClassAndNameImpl(Function method, string nameWithoutArgs) {
|
||||
exists(string memberName | result = method.getClassAndName(memberName) |
|
||||
nameWithoutArgs = "operator " + method.(ConversionOperator).getDestType()
|
||||
or
|
||||
not method instanceof ConversionOperator and
|
||||
memberName = nameWithoutArgs
|
||||
)
|
||||
result = method.getDeclaringType() and
|
||||
nameWithoutArgs = "operator " + method.(ConversionOperator).getDestType()
|
||||
or
|
||||
result = method.getClassAndName(nameWithoutArgs) and
|
||||
not method instanceof ConversionOperator
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1318,7 +1318,7 @@ predicate nodeIsHidden(Node n) {
|
||||
or
|
||||
n instanceof InitialGlobalValue
|
||||
or
|
||||
n instanceof SsaPhiInputNode
|
||||
n instanceof SsaSynthNode
|
||||
}
|
||||
|
||||
predicate neverSkipInPathGraph(Node n) {
|
||||
@@ -1520,16 +1520,17 @@ private EdgeKind caseOrDefaultEdge() {
|
||||
private int countNumberOfBranchesUsingParameter(SwitchInstruction switch, ParameterNode p) {
|
||||
exists(Ssa::SourceVariable sv |
|
||||
parameterNodeHasSourceVariable(p, sv) and
|
||||
// Count the number of cases that use the parameter. We do this by finding the phi node
|
||||
// that merges the uses/defs of the parameter. There might be multiple such phi nodes, so
|
||||
// we pick the one with the highest edge count.
|
||||
// Count the number of cases that use the parameter.
|
||||
result =
|
||||
max(SsaPhiNode phi |
|
||||
switch.getSuccessor(caseOrDefaultEdge()).getBlock().dominanceFrontier() =
|
||||
phi.getBasicBlock() and
|
||||
phi.getSourceVariable() = sv
|
||||
|
|
||||
strictcount(phi.getAnInput())
|
||||
strictcount(IRBlock caseblock |
|
||||
exists(IRBlock useblock |
|
||||
switch.getSuccessor(caseOrDefaultEdge()).getBlock() = caseblock and
|
||||
caseblock.dominates(useblock)
|
||||
|
|
||||
exists(Ssa::UseImpl use | use.hasIndexInBlock(useblock, _, sv))
|
||||
or
|
||||
exists(Ssa::DefImpl def | def.hasIndexInBlock(useblock, _, sv))
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -1631,9 +1632,7 @@ private Instruction getAnInstruction(Node n) {
|
||||
not n instanceof InstructionNode and
|
||||
result = n.asOperand().getUse()
|
||||
or
|
||||
result = n.(SsaPhiNode).getPhiNode().getBasicBlock().getFirstInstruction()
|
||||
or
|
||||
result = n.(SsaPhiInputNode).getBasicBlock().getFirstInstruction()
|
||||
result = n.(SsaSynthNode).getBasicBlock().getFirstInstruction()
|
||||
or
|
||||
n.(IndirectInstruction).hasInstructionAndIndirectionIndex(result, _)
|
||||
or
|
||||
@@ -1765,14 +1764,14 @@ module IteratorFlow {
|
||||
* Note: Unlike `def.getAnUltimateDefinition()` this predicate also
|
||||
* traverses back through iterator increment and decrement operations.
|
||||
*/
|
||||
private Ssa::Def getAnUltimateDefinition(Ssa::Def def) {
|
||||
private Ssa::Definition getAnUltimateDefinition(Ssa::Definition def) {
|
||||
result = def.getAnUltimateDefinition()
|
||||
or
|
||||
exists(IRBlock bb, int i, IteratorCrementCall crementCall, Ssa::SourceVariable sv |
|
||||
crementCall = def.getValue().asInstruction().(StoreInstruction).getSourceValue() and
|
||||
sv = def.getSourceVariable() and
|
||||
bb.getInstruction(i) = crementCall and
|
||||
Ssa::ssaDefReachesReadExt(sv, result.asDef(), bb, i)
|
||||
Ssa::ssaDefReachesRead(sv, result, bb, i)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1800,13 +1799,13 @@ module IteratorFlow {
|
||||
GetsIteratorCall beginCall, Instruction writeToDeref
|
||||
) {
|
||||
exists(
|
||||
StoreInstruction beginStore, IRBlock bbStar, int iStar, Ssa::Def def,
|
||||
IteratorPointerDereferenceCall starCall, Ssa::Def ultimate, Operand address
|
||||
StoreInstruction beginStore, IRBlock bbStar, int iStar, Ssa::Definition def,
|
||||
IteratorPointerDereferenceCall starCall, Ssa::Definition ultimate, Operand address
|
||||
|
|
||||
isIteratorWrite(writeToDeref, address) and
|
||||
operandForFullyConvertedCall(address, starCall) and
|
||||
bbStar.getInstruction(iStar) = starCall and
|
||||
Ssa::ssaDefReachesReadExt(_, def.asDef(), bbStar, iStar) and
|
||||
Ssa::ssaDefReachesRead(_, def, bbStar, iStar) and
|
||||
ultimate = getAnUltimateDefinition*(def) and
|
||||
beginStore = ultimate.getValue().asInstruction() and
|
||||
operandForFullyConvertedCall(beginStore.getSourceValueOperand(), beginCall)
|
||||
@@ -1835,45 +1834,15 @@ module IteratorFlow {
|
||||
|
||||
private module IteratorSsa = SsaImpl::Make<Location, SsaInput>;
|
||||
|
||||
cached
|
||||
private newtype TSsaDef =
|
||||
TDef(IteratorSsa::DefinitionExt def) or
|
||||
TPhi(PhiNode phi)
|
||||
|
||||
abstract private class SsaDef extends TSsaDef {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { none() }
|
||||
|
||||
/** Gets the underlying non-phi definition or use. */
|
||||
IteratorSsa::DefinitionExt asDef() { none() }
|
||||
|
||||
/** Gets the underlying phi node. */
|
||||
PhiNode asPhi() { none() }
|
||||
|
||||
/** Gets the location of this element. */
|
||||
abstract Location getLocation();
|
||||
}
|
||||
|
||||
private class Def extends TDef, SsaDef {
|
||||
IteratorSsa::DefinitionExt def;
|
||||
|
||||
Def() { this = TDef(def) }
|
||||
|
||||
final override IteratorSsa::DefinitionExt asDef() { result = def }
|
||||
|
||||
private class Def extends IteratorSsa::DefinitionExt {
|
||||
final override Location getLocation() { result = this.getImpl().getLocation() }
|
||||
|
||||
/** Gets the variable written to by this definition. */
|
||||
final SourceVariable getSourceVariable() { result = def.getSourceVariable() }
|
||||
|
||||
override string toString() { result = def.toString() }
|
||||
|
||||
/**
|
||||
* Holds if this definition (or use) has index `index` in block `block`,
|
||||
* and is a definition (or use) of the variable `sv`.
|
||||
*/
|
||||
predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) {
|
||||
def.definesAt(sv, block, index, _)
|
||||
super.definesAt(sv, block, index, _)
|
||||
}
|
||||
|
||||
private Ssa::DefImpl getImpl() {
|
||||
@@ -1890,20 +1859,6 @@ module IteratorFlow {
|
||||
int getIndirectionIndex() { result = this.getImpl().getIndirectionIndex() }
|
||||
}
|
||||
|
||||
private class Phi extends TPhi, SsaDef {
|
||||
PhiNode phi;
|
||||
|
||||
Phi() { this = TPhi(phi) }
|
||||
|
||||
final override PhiNode asPhi() { result = phi }
|
||||
|
||||
final override Location getLocation() { result = phi.getBasicBlock().getLocation() }
|
||||
|
||||
override string toString() { result = phi.toString() }
|
||||
|
||||
SsaIteratorNode getNode() { result.getIteratorFlowNode() = phi }
|
||||
}
|
||||
|
||||
private class PhiNode extends IteratorSsa::DefinitionExt {
|
||||
PhiNode() {
|
||||
this instanceof IteratorSsa::PhiNode or
|
||||
|
||||
@@ -27,7 +27,7 @@ import ExprNodes
|
||||
* - `VariableNode`, which is used to model flow through global variables.
|
||||
* - `PostUpdateNodeImpl`, which is used to model the state of an object after
|
||||
* an update after a number of loads.
|
||||
* - `SsaPhiNode`, which represents phi nodes as computed by the shared SSA
|
||||
* - `SsaSynthNode`, which represents synthesized nodes as computed by the shared SSA
|
||||
* library.
|
||||
* - `RawIndirectOperand`, which represents the value of `operand` after
|
||||
* loading the address a number of times.
|
||||
@@ -47,8 +47,7 @@ private newtype TIRDataFlowNode =
|
||||
or
|
||||
Ssa::isModifiableByCall(operand, indirectionIndex)
|
||||
} or
|
||||
TSsaPhiInputNode(Ssa::PhiNode phi, IRBlock input) { phi.hasInputFromBlock(_, _, _, _, input) } or
|
||||
TSsaPhiNode(Ssa::PhiNode phi) or
|
||||
TSsaSynthNode(Ssa::SynthNode n) or
|
||||
TSsaIteratorNode(IteratorFlow::IteratorFlowNode n) or
|
||||
TRawIndirectOperand0(Node0Impl node, int indirectionIndex) {
|
||||
Ssa::hasRawIndirectOperand(node.asOperand(), indirectionIndex)
|
||||
@@ -184,10 +183,11 @@ class Node extends TIRDataFlowNode {
|
||||
or
|
||||
this.asOperand().getUse() = block.getInstruction(i)
|
||||
or
|
||||
this.(SsaPhiNode).getPhiNode().getBasicBlock() = block and i = -1
|
||||
or
|
||||
this.(SsaPhiInputNode).getBlock() = block and
|
||||
i = block.getInstructionCount()
|
||||
exists(Ssa::SynthNode ssaNode |
|
||||
this.(SsaSynthNode).getSynthNode() = ssaNode and
|
||||
ssaNode.getBasicBlock() = block and
|
||||
ssaNode.getIndex() = i
|
||||
)
|
||||
or
|
||||
this.(RawIndirectOperand).getOperand().getUse() = block.getInstruction(i)
|
||||
or
|
||||
@@ -313,13 +313,79 @@ class Node extends TIRDataFlowNode {
|
||||
* `n.asExpr() instanceof IncrementOperation` since the result of evaluating
|
||||
* the expression `x++` is passed to `sink`.
|
||||
*/
|
||||
Expr asDefinition() {
|
||||
exists(StoreInstruction store |
|
||||
Expr asDefinition() { result = this.asDefinition(_) }
|
||||
|
||||
/**
|
||||
* Gets the definition associated with this node, if any.
|
||||
*
|
||||
* For example, consider the following example
|
||||
* ```cpp
|
||||
* int x = 42; // 1
|
||||
* x = 34; // 2
|
||||
* ++x; // 3
|
||||
* x++; // 4
|
||||
* x += 1; // 5
|
||||
* int y = x += 2; // 6
|
||||
* ```
|
||||
* - For (1) the result is `42`.
|
||||
* - For (2) the result is `x = 34`.
|
||||
* - For (3) the result is `++x`.
|
||||
* - For (4) the result is `x++`.
|
||||
* - For (5) the result is `x += 1`.
|
||||
* - For (6) there are two results:
|
||||
* - For the definition generated by `x += 2` the result is `x += 2`
|
||||
* - For the definition generated by `int y = ...` the result is
|
||||
* also `x += 2`.
|
||||
*
|
||||
* For assignments, `node.asDefinition(_)` and `node.asExpr()` will both exist
|
||||
* for the same dataflow node. However, for expression such as `x++` that
|
||||
* both write to `x` and read the current value of `x`, `node.asDefinition(_)`
|
||||
* will give the node corresponding to the value after the increment, and
|
||||
* `node.asExpr()` will give the node corresponding to the value before the
|
||||
* increment. For an example of this, consider the following:
|
||||
*
|
||||
* ```cpp
|
||||
* sink(x++);
|
||||
* ```
|
||||
* in the above program, there will not be flow from a node `n` such that
|
||||
* `n.asDefinition(_) instanceof IncrementOperation` to the argument of `sink`
|
||||
* since the value passed to `sink` is the value before to the increment.
|
||||
* However, there will be dataflow from a node `n` such that
|
||||
* `n.asExpr() instanceof IncrementOperation` since the result of evaluating
|
||||
* the expression `x++` is passed to `sink`.
|
||||
*
|
||||
* If `uncertain = false` then the definition is guaranteed to overwrite
|
||||
* the entire buffer pointed to by the destination address of the definition.
|
||||
* Otherwise, `uncertain = true`.
|
||||
*
|
||||
* For example, the write `int x; x = 42;` is guaranteed to overwrite all the
|
||||
* bytes allocated to `x`, while the assignment `int p[10]; p[3] = 42;` has
|
||||
* `uncertain = true` since the write will not overwrite the entire buffer
|
||||
* pointed to by `p`.
|
||||
*/
|
||||
Expr asDefinition(boolean uncertain) {
|
||||
exists(StoreInstruction store, Ssa::Definition def |
|
||||
store = this.asInstruction() and
|
||||
result = asDefinitionImpl(store)
|
||||
result = asDefinitionImpl(store) and
|
||||
Ssa::defToNode(this, def, _) and
|
||||
if def.isCertain() then uncertain = false else uncertain = true
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the definition associated with this node, if this node is a certain definition.
|
||||
*
|
||||
* See `Node.asDefinition/1` for a description of certain and uncertain definitions.
|
||||
*/
|
||||
Expr asCertainDefinition() { result = this.asDefinition(false) }
|
||||
|
||||
/**
|
||||
* Gets the definition associated with this node, if this node is an uncertain definition.
|
||||
*
|
||||
* See `Node.asDefinition/1` for a description of certain and uncertain definitions.
|
||||
*/
|
||||
Expr asUncertainDefinition() { result = this.asDefinition(true) }
|
||||
|
||||
/**
|
||||
* Gets the indirect definition at a given indirection corresponding to this
|
||||
* node, if any.
|
||||
@@ -620,117 +686,30 @@ class PostFieldUpdateNode extends PostUpdateNodeImpl {
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* A phi node produced by the shared SSA library, viewed as a node in a data flow graph.
|
||||
* A synthesized SSA node produced by the shared SSA library, viewed as a node
|
||||
* in a data flow graph.
|
||||
*/
|
||||
class SsaPhiNode extends Node, TSsaPhiNode {
|
||||
Ssa::PhiNode phi;
|
||||
class SsaSynthNode extends Node, TSsaSynthNode {
|
||||
Ssa::SynthNode node;
|
||||
|
||||
SsaPhiNode() { this = TSsaPhiNode(phi) }
|
||||
SsaSynthNode() { this = TSsaSynthNode(node) }
|
||||
|
||||
/** Gets the phi node associated with this node. */
|
||||
Ssa::PhiNode getPhiNode() { result = phi }
|
||||
/** Gets the synthesized SSA node associated with this node. */
|
||||
Ssa::SynthNode getSynthNode() { result = node }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() {
|
||||
result.asSourceCallable() = this.getFunction()
|
||||
}
|
||||
|
||||
override Declaration getFunction() { result = phi.getBasicBlock().getEnclosingFunction() }
|
||||
override Declaration getFunction() { result = node.getBasicBlock().getEnclosingFunction() }
|
||||
|
||||
override DataFlowType getType() {
|
||||
exists(Ssa::SourceVariable sv |
|
||||
this.getPhiNode().definesAt(sv, _, _, _) and
|
||||
result = sv.getType()
|
||||
)
|
||||
}
|
||||
override DataFlowType getType() { result = node.getSourceVariable().getType() }
|
||||
|
||||
override predicate isGLValue() { phi.getSourceVariable().isGLValue() }
|
||||
override predicate isGLValue() { node.getSourceVariable().isGLValue() }
|
||||
|
||||
final override Location getLocationImpl() { result = phi.getBasicBlock().getLocation() }
|
||||
final override Location getLocationImpl() { result = node.getLocation() }
|
||||
|
||||
override string toStringImpl() { result = phi.toString() }
|
||||
|
||||
/**
|
||||
* Gets a node that is used as input to this phi node.
|
||||
* `fromBackEdge` is true if data flows along a back-edge,
|
||||
* and `false` otherwise.
|
||||
*/
|
||||
cached
|
||||
final Node getAnInput(boolean fromBackEdge) {
|
||||
result.(SsaPhiInputNode).getPhiNode() = phi and
|
||||
exists(IRBlock bPhi, IRBlock bResult |
|
||||
bPhi = phi.getBasicBlock() and bResult = result.getBasicBlock()
|
||||
|
|
||||
if bPhi.dominates(bResult) then fromBackEdge = true else fromBackEdge = false
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a node that is used as input to this phi node. */
|
||||
final Node getAnInput() { result = this.getAnInput(_) }
|
||||
|
||||
/** Gets the source variable underlying this phi node. */
|
||||
Ssa::SourceVariable getSourceVariable() { result = phi.getSourceVariable() }
|
||||
|
||||
/**
|
||||
* Holds if this phi node is a phi-read node.
|
||||
*
|
||||
* Phi-read nodes are like normal phi nodes, but they are inserted based
|
||||
* on reads instead of writes.
|
||||
*/
|
||||
predicate isPhiRead() { phi.isPhiRead() }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* A node that is used as an input to a phi node.
|
||||
*
|
||||
* This class exists to allow more powerful barrier guards. Consider this
|
||||
* example:
|
||||
*
|
||||
* ```cpp
|
||||
* int x = source();
|
||||
* if(!safe(x)) {
|
||||
* x = clear();
|
||||
* }
|
||||
* // phi node for x here
|
||||
* sink(x);
|
||||
* ```
|
||||
*
|
||||
* At the phi node for `x` it is neither the case that `x` is dominated by
|
||||
* `safe(x)`, or is the case that the phi is dominated by a clearing of `x`.
|
||||
*
|
||||
* By inserting a "phi input" node as the last entry in the basic block that
|
||||
* defines the inputs to the phi we can conclude that each of those inputs are
|
||||
* safe to pass to `sink`.
|
||||
*/
|
||||
class SsaPhiInputNode extends Node, TSsaPhiInputNode {
|
||||
Ssa::PhiNode phi;
|
||||
IRBlock block;
|
||||
|
||||
SsaPhiInputNode() { this = TSsaPhiInputNode(phi, block) }
|
||||
|
||||
/** Gets the phi node associated with this node. */
|
||||
Ssa::PhiNode getPhiNode() { result = phi }
|
||||
|
||||
/** Gets the basic block in which this input originates. */
|
||||
IRBlock getBlock() { result = block }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() {
|
||||
result.asSourceCallable() = this.getFunction()
|
||||
}
|
||||
|
||||
override Declaration getFunction() { result = phi.getBasicBlock().getEnclosingFunction() }
|
||||
|
||||
override DataFlowType getType() { result = this.getSourceVariable().getType() }
|
||||
|
||||
override predicate isGLValue() { phi.getSourceVariable().isGLValue() }
|
||||
|
||||
final override Location getLocationImpl() { result = block.getLastInstruction().getLocation() }
|
||||
|
||||
override string toStringImpl() { result = "Phi input" }
|
||||
|
||||
/** Gets the source variable underlying this phi node. */
|
||||
Ssa::SourceVariable getSourceVariable() { result = phi.getSourceVariable() }
|
||||
override string toStringImpl() { result = node.toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -842,18 +821,11 @@ class InitialGlobalValue extends Node, TInitialGlobalValue {
|
||||
result.asSourceCallable() = this.getFunction()
|
||||
}
|
||||
|
||||
override Declaration getFunction() { result = globalDef.getIRFunction().getFunction() }
|
||||
override Declaration getFunction() { result = globalDef.getFunction() }
|
||||
|
||||
final override predicate isGLValue() { globalDef.getIndirectionIndex() = 0 }
|
||||
|
||||
override DataFlowType getType() {
|
||||
exists(DataFlowType type |
|
||||
type = globalDef.getUnderlyingType() and
|
||||
if this.isGLValue()
|
||||
then result = type
|
||||
else result = getTypeImpl(type, globalDef.getIndirectionIndex() - 1)
|
||||
)
|
||||
}
|
||||
override DataFlowType getType() { result = globalDef.getUnderlyingType() }
|
||||
|
||||
final override Location getLocationImpl() { result = globalDef.getLocation() }
|
||||
|
||||
@@ -1312,10 +1284,10 @@ class UninitializedNode extends Node {
|
||||
LocalVariable v;
|
||||
|
||||
UninitializedNode() {
|
||||
exists(Ssa::Def def, Ssa::SourceVariable sv |
|
||||
exists(Ssa::Definition def, Ssa::SourceVariable sv |
|
||||
def.getIndirectionIndex() = 0 and
|
||||
def.getValue().asInstruction() instanceof UninitializedInstruction and
|
||||
Ssa::defToNode(this, def, sv, _, _, _) and
|
||||
Ssa::defToNode(this, def, sv) and
|
||||
v = sv.getBaseVariable().(Ssa::BaseIRVariable).getIRVariable().getAst()
|
||||
)
|
||||
}
|
||||
@@ -1740,6 +1712,21 @@ predicate hasInstructionAndIndex(
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
/**
|
||||
* Holds if `n` has a local flow step that goes through a back-edge.
|
||||
*/
|
||||
cached
|
||||
predicate flowsToBackEdge(Node n) {
|
||||
exists(Node succ, IRBlock bb1, IRBlock bb2 |
|
||||
Ssa::ssaFlow(n, succ) and
|
||||
bb1 = n.getBasicBlock() and
|
||||
bb2 = succ.getBasicBlock() and
|
||||
bb1 != bb2 and
|
||||
bb2.dominates(bb1) and
|
||||
bb1.getASuccessor+() = bb2
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data flows from `nodeFrom` to `nodeTo` in exactly one local
|
||||
* (intra-procedural) step. This relation is only used for local dataflow
|
||||
@@ -1828,15 +1815,9 @@ private module Cached {
|
||||
cached
|
||||
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
|
||||
(
|
||||
// Post update node -> Node flow
|
||||
Ssa::postUpdateFlow(nodeFrom, nodeTo)
|
||||
or
|
||||
// Def-use/Use-use flow
|
||||
Ssa::ssaFlow(nodeFrom, nodeTo)
|
||||
or
|
||||
// Phi input -> Phi
|
||||
nodeFrom.(SsaPhiInputNode).getPhiNode() = nodeTo.(SsaPhiNode).getPhiNode()
|
||||
or
|
||||
IteratorFlow::localFlowStep(nodeFrom, nodeTo)
|
||||
or
|
||||
// Operand -> Instruction flow
|
||||
@@ -1851,9 +1832,6 @@ private module Cached {
|
||||
not iFrom = Ssa::getIRRepresentationOfOperand(opTo)
|
||||
)
|
||||
or
|
||||
// Phi node -> Node flow
|
||||
Ssa::fromPhiNode(nodeFrom, nodeTo)
|
||||
or
|
||||
// Indirect operand -> (indirect) instruction flow
|
||||
indirectionOperandFlow(nodeFrom, nodeTo)
|
||||
or
|
||||
@@ -2297,22 +2275,6 @@ class ContentSet instanceof Content {
|
||||
}
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate guardControlsPhiInput(
|
||||
IRGuardCondition g, boolean branch, Ssa::Definition def, IRBlock input, Ssa::PhiNode phi
|
||||
) {
|
||||
phi.hasInputFromBlock(def, _, _, _, input) and
|
||||
(
|
||||
g.controls(input, branch)
|
||||
or
|
||||
exists(EdgeKind kind |
|
||||
g.getBlock() = input and
|
||||
kind = getConditionalEdge(branch) and
|
||||
input.getSuccessor(kind) = phi.getBasicBlock()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
|
||||
*
|
||||
@@ -2344,6 +2306,10 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate guardChecksNode(IRGuardCondition g, Node n, boolean branch) {
|
||||
guardChecks(g, n.asOperand().getDef().getConvertedResultExpression(), branch)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an expression node that is safely guarded by the given guard check.
|
||||
*
|
||||
@@ -2384,14 +2350,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
IRGuardCondition g, boolean branch, Ssa::DefinitionExt def, IRBlock input, Ssa::PhiNode phi
|
||||
|
|
||||
guardChecks(g, def.getARead().asOperand().getDef().getConvertedResultExpression(), branch) and
|
||||
guardControlsPhiInput(g, branch, def, pragma[only_bind_into](input),
|
||||
pragma[only_bind_into](phi)) and
|
||||
result = TSsaPhiInputNode(phi, input)
|
||||
)
|
||||
result = Ssa::BarrierGuard<guardChecksNode/3>::getABarrierNode()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2440,6 +2399,13 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate guardChecksIndirectNode(
|
||||
IRGuardCondition g, Node n, boolean branch, int indirectionIndex
|
||||
) {
|
||||
guardChecks(g, n.asIndirectOperand(indirectionIndex).getDef().getConvertedResultExpression(),
|
||||
branch)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an indirect expression node with indirection index `indirectionIndex` that is
|
||||
* safely guarded by the given guard check.
|
||||
@@ -2482,16 +2448,8 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
IRGuardCondition g, boolean branch, Ssa::DefinitionExt def, IRBlock input, Ssa::PhiNode phi
|
||||
|
|
||||
guardChecks(g,
|
||||
def.getARead().asIndirectOperand(indirectionIndex).getDef().getConvertedResultExpression(),
|
||||
branch) and
|
||||
guardControlsPhiInput(g, branch, def, pragma[only_bind_into](input),
|
||||
pragma[only_bind_into](phi)) and
|
||||
result = TSsaPhiInputNode(phi, input)
|
||||
)
|
||||
result =
|
||||
Ssa::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2500,14 +2458,6 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
*/
|
||||
signature predicate instructionGuardChecksSig(IRGuardCondition g, Instruction instr, boolean branch);
|
||||
|
||||
private EdgeKind getConditionalEdge(boolean branch) {
|
||||
branch = true and
|
||||
result instanceof TrueEdge
|
||||
or
|
||||
branch = false and
|
||||
result instanceof FalseEdge
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a set of barrier nodes for a guard that validates an instruction.
|
||||
*
|
||||
@@ -2524,6 +2474,10 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
|
||||
)
|
||||
}
|
||||
|
||||
private predicate guardChecksNode(IRGuardCondition g, Node n, boolean branch) {
|
||||
instructionGuardChecks(g, n.asOperand().getDef(), branch)
|
||||
}
|
||||
|
||||
/** Gets a node that is safely guarded by the given guard check. */
|
||||
Node getABarrierNode() {
|
||||
exists(IRGuardCondition g, ValueNumber value, boolean edge |
|
||||
@@ -2532,14 +2486,7 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
IRGuardCondition g, boolean branch, Ssa::DefinitionExt def, IRBlock input, Ssa::PhiNode phi
|
||||
|
|
||||
instructionGuardChecks(g, def.getARead().asOperand().getDef(), branch) and
|
||||
guardControlsPhiInput(g, branch, def, pragma[only_bind_into](input),
|
||||
pragma[only_bind_into](phi)) and
|
||||
result = TSsaPhiInputNode(phi, input)
|
||||
)
|
||||
result = Ssa::BarrierGuard<guardChecksNode/3>::getABarrierNode()
|
||||
}
|
||||
|
||||
bindingset[value, n]
|
||||
@@ -2551,6 +2498,12 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
|
||||
)
|
||||
}
|
||||
|
||||
private predicate guardChecksIndirectNode(
|
||||
IRGuardCondition g, Node n, boolean branch, int indirectionIndex
|
||||
) {
|
||||
instructionGuardChecks(g, n.asIndirectOperand(indirectionIndex).getDef(), branch)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an indirect node with indirection index `indirectionIndex` that is
|
||||
* safely guarded by the given guard check.
|
||||
@@ -2562,14 +2515,8 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
exists(
|
||||
IRGuardCondition g, boolean branch, Ssa::DefinitionExt def, IRBlock input, Ssa::PhiNode phi
|
||||
|
|
||||
instructionGuardChecks(g, def.getARead().asIndirectOperand(indirectionIndex).getDef(), branch) and
|
||||
guardControlsPhiInput(g, branch, def, pragma[only_bind_into](input),
|
||||
pragma[only_bind_into](phi)) and
|
||||
result = TSsaPhiInputNode(phi, input)
|
||||
)
|
||||
result =
|
||||
Ssa::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ private import codeql.ssa.Ssa as SsaImplCommon
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import DataFlowUtil
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
private import semmle.code.cpp.controlflow.IRGuards as IRGuards
|
||||
private import semmle.code.cpp.models.interfaces.Allocation as Alloc
|
||||
private import semmle.code.cpp.models.interfaces.DataFlow as DataFlow
|
||||
private import semmle.code.cpp.models.interfaces.Taint as Taint
|
||||
@@ -225,10 +226,16 @@ abstract class DefImpl extends TDefImpl {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this definition is guaranteed to totally overwrite the
|
||||
* destination buffer.
|
||||
*/
|
||||
abstract predicate isCertain();
|
||||
|
||||
/** Gets the value written to the destination variable by this definition. */
|
||||
abstract Node0Impl getValue();
|
||||
|
||||
/** Gets the operand that represents the address of this definition, if any. */
|
||||
Operand getAddressOperand() { none() }
|
||||
}
|
||||
|
||||
@@ -458,6 +465,17 @@ private predicate finalParameterNodeHasParameterAndIndex(
|
||||
n.getIndirectionIndex() = indirectionIndex
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasReturnPosition(IRFunction f, IRBlock block, int index) {
|
||||
exists(Instruction return |
|
||||
return instanceof ReturnInstruction or
|
||||
return instanceof UnreachedInstruction
|
||||
|
|
||||
block.getInstruction(index) = return and
|
||||
return.getEnclosingIRFunction() = f
|
||||
)
|
||||
}
|
||||
|
||||
class FinalParameterUse extends UseImpl, TFinalParameterUse {
|
||||
Parameter p;
|
||||
|
||||
@@ -486,12 +504,9 @@ class FinalParameterUse extends UseImpl, TFinalParameterUse {
|
||||
// `UnreachedInstruction`. If that's the case this predicate will
|
||||
// return multiple results. I don't think this is detrimental to
|
||||
// performance, however.
|
||||
exists(Instruction return |
|
||||
return instanceof ReturnInstruction or
|
||||
return instanceof UnreachedInstruction
|
||||
|
|
||||
block.getInstruction(index) = return and
|
||||
return.getEnclosingFunction() = p.getFunction()
|
||||
exists(IRFunction f |
|
||||
hasReturnPosition(f, block, index) and
|
||||
f.getFunction() = p.getFunction()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -581,13 +596,7 @@ class GlobalUse extends UseImpl, TGlobalUse {
|
||||
// globals at any exit so that we can flow out of non-returning functions.
|
||||
// Obviously this isn't correct as we can't actually flow but the global flow
|
||||
// requires this if we want to flow into children.
|
||||
exists(Instruction return |
|
||||
return instanceof ReturnInstruction or
|
||||
return instanceof UnreachedInstruction
|
||||
|
|
||||
block.getInstruction(index) = return and
|
||||
return.getEnclosingIRFunction() = f
|
||||
)
|
||||
hasReturnPosition(f, block, index)
|
||||
}
|
||||
|
||||
override BaseSourceVariable getBaseSourceVariable() {
|
||||
@@ -663,21 +672,6 @@ class GlobalDefImpl extends DefImpl, TGlobalDefImpl {
|
||||
override Location getLocation() { result = f.getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is a definition or access at index `i1` in basic block `bb1`
|
||||
* and the next subsequent read is at index `i2` in basic block `bb2`.
|
||||
*/
|
||||
predicate adjacentDefRead(IRBlock bb1, int i1, SourceVariable sv, IRBlock bb2, int i2) {
|
||||
adjacentDefReadExt(_, sv, bb1, i1, bb2, i2)
|
||||
}
|
||||
|
||||
predicate useToNode(IRBlock bb, int i, SourceVariable sv, Node nodeTo) {
|
||||
exists(UseImpl use |
|
||||
use.hasIndexInBlock(bb, i, sv) and
|
||||
nodeTo = use.getNode()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
predicate outNodeHasAddressAndIndex(
|
||||
IndirectArgumentOutNode out, Operand address, int indirectionIndex
|
||||
@@ -691,32 +685,17 @@ predicate outNodeHasAddressAndIndex(
|
||||
*
|
||||
* Holds if `node` is the node that corresponds to the definition of `def`.
|
||||
*/
|
||||
predicate defToNode(Node node, Def def, SourceVariable sv, IRBlock bb, int i, boolean uncertain) {
|
||||
def.hasIndexInBlock(bb, i, sv) and
|
||||
(
|
||||
nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex())
|
||||
or
|
||||
nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex())
|
||||
or
|
||||
node.(InitialGlobalValue).getGlobalDef() = def
|
||||
) and
|
||||
if def.isCertain() then uncertain = false else uncertain = true
|
||||
predicate defToNode(Node node, Definition def, SourceVariable sv) {
|
||||
def.getSourceVariable() = sv and
|
||||
defToNode(node, def)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Holds if `node` is the node that corresponds to the definition or use at
|
||||
* index `i` in block `bb` of `sv`.
|
||||
*
|
||||
* `uncertain` is `true` if this is an uncertain definition.
|
||||
*/
|
||||
predicate nodeToDefOrUse(Node node, SourceVariable sv, IRBlock bb, int i, boolean uncertain) {
|
||||
defToNode(node, _, sv, bb, i, uncertain)
|
||||
private predicate defToNode(Node node, Definition def) {
|
||||
nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex())
|
||||
or
|
||||
// Node -> Use
|
||||
useToNode(bb, i, sv, node) and
|
||||
uncertain = false
|
||||
nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex())
|
||||
or
|
||||
node.(InitialGlobalValue).getGlobalDef() = def
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -724,10 +703,7 @@ predicate nodeToDefOrUse(Node node, SourceVariable sv, IRBlock bb, int i, boolea
|
||||
* only holds when there is no use-use relation out of `nTo`.
|
||||
*/
|
||||
private predicate indirectConversionFlowStep(Node nFrom, Node nTo) {
|
||||
not exists(SourceVariable sv, IRBlock bb2, int i2 |
|
||||
useToNode(bb2, i2, sv, nTo) and
|
||||
adjacentDefRead(bb2, i2, sv, _, _)
|
||||
) and
|
||||
not ssaFlowImpl(nTo, _) and
|
||||
exists(Operand op1, Operand op2, int indirectionIndex, Instruction instr |
|
||||
hasOperandAndIndex(nFrom, op1, pragma[only_bind_into](indirectionIndex)) and
|
||||
hasOperandAndIndex(nTo, op2, pragma[only_bind_into](indirectionIndex)) and
|
||||
@@ -736,50 +712,6 @@ private predicate indirectConversionFlowStep(Node nFrom, Node nTo) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` is a phi input node that should receive flow from the
|
||||
* definition to (or use of) `sv` at `(bb1, i1)`.
|
||||
*/
|
||||
private predicate phiToNode(SsaPhiInputNode node, SourceVariable sv, IRBlock bb1, int i1) {
|
||||
exists(PhiNode phi, IRBlock input |
|
||||
phi.hasInputFromBlock(_, sv, bb1, i1, input) and
|
||||
node.getPhiNode() = phi and
|
||||
node.getBlock() = input
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there should be flow from `nodeFrom` to `nodeTo` because
|
||||
* `nodeFrom` is a definition or use of `sv` at index `i1` at basic
|
||||
* block `bb1`.
|
||||
*
|
||||
* `uncertain` is `true` if `(bb1, i1)` is a definition, and that definition
|
||||
* is _not_ guaranteed to overwrite the entire allocation.
|
||||
*/
|
||||
private predicate ssaFlowImpl(
|
||||
IRBlock bb1, int i1, SourceVariable sv, Node nodeFrom, Node nodeTo, boolean uncertain
|
||||
) {
|
||||
nodeToDefOrUse(nodeFrom, sv, bb1, i1, uncertain) and
|
||||
(
|
||||
exists(IRBlock bb2, int i2 |
|
||||
adjacentDefRead(bb1, i1, sv, bb2, i2) and
|
||||
useToNode(bb2, i2, sv, nodeTo)
|
||||
)
|
||||
or
|
||||
phiToNode(nodeTo, sv, bb1, i1)
|
||||
) and
|
||||
nodeFrom != nodeTo
|
||||
}
|
||||
|
||||
/** Gets a node that represents the prior definition of `node`. */
|
||||
private Node getAPriorDefinition(DefinitionExt next) {
|
||||
exists(IRBlock bb, int i, SourceVariable sv |
|
||||
lastRefRedefExt(_, pragma[only_bind_into](sv), pragma[only_bind_into](bb),
|
||||
pragma[only_bind_into](i), _, next) and
|
||||
nodeToDefOrUse(result, sv, bb, i, _)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate inOut(FIO::FunctionInput input, FIO::FunctionOutput output) {
|
||||
exists(int indirectionIndex |
|
||||
input.isQualifierObject(indirectionIndex) and
|
||||
@@ -826,21 +758,6 @@ private predicate modeledFlowBarrier(Node n) {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if there is def-use or use-use flow from `nodeFrom` to `nodeTo`. */
|
||||
predicate ssaFlow(Node nodeFrom, Node nodeTo) {
|
||||
exists(Node nFrom, boolean uncertain, IRBlock bb, int i, SourceVariable sv |
|
||||
ssaFlowImpl(bb, i, sv, nFrom, nodeTo, uncertain) and
|
||||
not modeledFlowBarrier(nFrom) and
|
||||
nodeFrom != nodeTo
|
||||
|
|
||||
if uncertain = true
|
||||
then
|
||||
nodeFrom =
|
||||
[nFrom, getAPriorDefinition(any(DefinitionExt next | next.definesAt(sv, bb, i, _)))]
|
||||
else nodeFrom = nFrom
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isArgumentOfCallableInstruction(DataFlowCall call, Instruction instr) {
|
||||
isArgumentOfCallableOperand(call, unique( | | getAUse(instr)))
|
||||
}
|
||||
@@ -897,22 +814,15 @@ private predicate postUpdateNodeToFirstUse(PostUpdateNode pun, Node n) {
|
||||
// So this predicate recurses back along conversions and `PointerArithmetic`
|
||||
// instructions to find the first use that has provides use-use flow, and
|
||||
// uses that target as the target of the `nodeFrom`.
|
||||
exists(Node adjusted, IRBlock bb1, int i1, SourceVariable sv |
|
||||
exists(Node adjusted |
|
||||
indirectConversionFlowStep*(adjusted, pun.getPreUpdateNode()) and
|
||||
useToNode(bb1, i1, sv, adjusted)
|
||||
|
|
||||
exists(IRBlock bb2, int i2 |
|
||||
adjacentDefRead(bb1, i1, sv, bb2, i2) and
|
||||
useToNode(bb2, i2, sv, n)
|
||||
)
|
||||
or
|
||||
phiToNode(n, sv, bb1, i1)
|
||||
ssaFlowImpl(adjusted, n)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate stepUntilNotInCall(DataFlowCall call, Node n1, Node n2) {
|
||||
isArgumentOfCallable(call, n1) and
|
||||
exists(Node mid | ssaFlowImpl(_, _, _, n1, mid, _) |
|
||||
exists(Node mid | ssaFlowImpl(n1, mid) |
|
||||
isArgumentOfCallable(call, mid) and
|
||||
stepUntilNotInCall(call, mid, n2)
|
||||
or
|
||||
@@ -944,7 +854,7 @@ private predicate isArgumentOfSameCall(DataFlowCall call, Node n1, Node n2) {
|
||||
* similarly we want flow from the second argument of `write_first_argument` to `x`
|
||||
* on the next line.
|
||||
*/
|
||||
predicate postUpdateFlow(PostUpdateNode pun, Node nodeTo) {
|
||||
private predicate postUpdateFlow(PostUpdateNode pun, Node nodeTo) {
|
||||
exists(Node preUpdate, Node mid |
|
||||
preUpdate = pun.getPreUpdateNode() and
|
||||
postUpdateNodeToFirstUse(pun, mid)
|
||||
@@ -959,21 +869,6 @@ predicate postUpdateFlow(PostUpdateNode pun, Node nodeTo) {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `nodeTo` receives flow from the phi node `nodeFrom`. */
|
||||
predicate fromPhiNode(SsaPhiNode nodeFrom, Node nodeTo) {
|
||||
exists(PhiNode phi, SourceVariable sv, IRBlock bb1, int i1 |
|
||||
phi = nodeFrom.getPhiNode() and
|
||||
phi.definesAt(sv, bb1, i1, _)
|
||||
|
|
||||
exists(IRBlock bb2, int i2 |
|
||||
adjacentDefRead(bb1, i1, sv, bb2, i2) and
|
||||
useToNode(bb2, i2, sv, nodeTo)
|
||||
)
|
||||
or
|
||||
phiToNode(nodeTo, sv, bb1, i1)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate baseSourceVariableIsGlobal(
|
||||
BaseIRVariable base, GlobalLikeVariable global, IRFunction func
|
||||
) {
|
||||
@@ -1015,11 +910,6 @@ private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
exists(UseImpl use | use.hasIndexInBlock(bb, i, v) |
|
||||
if use.isCertain() then certain = true else certain = false
|
||||
)
|
||||
or
|
||||
exists(GlobalUse global |
|
||||
global.hasIndexInBlock(bb, i, v) and
|
||||
certain = true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1028,42 +918,14 @@ private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
*/
|
||||
cached
|
||||
module SsaCached {
|
||||
/**
|
||||
* Holds if `def` is accessed at index `i1` in basic block `bb1` (either a read
|
||||
* or a write), `def` is read at index `i2` in basic block `bb2`, and there is a
|
||||
* path between them without any read of `def`.
|
||||
*/
|
||||
cached
|
||||
predicate adjacentDefReadExt(
|
||||
DefinitionExt def, SourceVariable sv, IRBlock bb1, int i1, IRBlock bb2, int i2
|
||||
) {
|
||||
SsaImpl::adjacentDefReadExt(def, sv, bb1, i1, bb2, i2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the node at index `i` in `bb` is a last reference to SSA definition
|
||||
* `def`. The reference is last because it can reach another write `next`,
|
||||
* without passing through another read or write.
|
||||
*
|
||||
* The path from node `i` in `bb` to `next` goes via basic block `input`,
|
||||
* which is either a predecessor of the basic block of `next`, or `input` =
|
||||
* `bb` in case `next` occurs in basic block `bb`.
|
||||
*/
|
||||
cached
|
||||
predicate lastRefRedefExt(
|
||||
DefinitionExt def, SourceVariable sv, IRBlock bb, int i, IRBlock input, DefinitionExt next
|
||||
) {
|
||||
SsaImpl::lastRefRedefExt(def, sv, bb, i, input, next)
|
||||
predicate ssaDefReachesRead(SourceVariable v, Definition def, IRBlock bb, int i) {
|
||||
SsaImpl::ssaDefReachesRead(v, def, bb, i)
|
||||
}
|
||||
|
||||
cached
|
||||
Definition phiHasInputFromBlockExt(PhiNode phi, IRBlock bb) {
|
||||
SsaImpl::phiHasInputFromBlockExt(phi, result, bb)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate ssaDefReachesReadExt(SourceVariable v, DefinitionExt def, IRBlock bb, int i) {
|
||||
SsaImpl::ssaDefReachesReadExt(v, def, bb, i)
|
||||
predicate phiHasInputFromBlock(PhiNode phi, Definition inp, IRBlock bb) {
|
||||
SsaImpl::phiHasInputFromBlock(phi, inp, bb)
|
||||
}
|
||||
|
||||
predicate variableRead = SsaInput::variableRead/4;
|
||||
@@ -1071,221 +933,229 @@ module SsaCached {
|
||||
predicate variableWrite = SsaInput::variableWrite/4;
|
||||
}
|
||||
|
||||
cached
|
||||
private newtype TSsaDef =
|
||||
TDef(DefinitionExt def) or
|
||||
TPhi(PhiNode phi)
|
||||
|
||||
abstract private class SsaDef extends TSsaDef {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { none() }
|
||||
|
||||
/** Gets the underlying non-phi definition or use. */
|
||||
DefinitionExt asDef() { none() }
|
||||
|
||||
/** Gets the underlying phi node. */
|
||||
PhiNode asPhi() { none() }
|
||||
|
||||
/** Gets the location of this element. */
|
||||
abstract Location getLocation();
|
||||
}
|
||||
|
||||
abstract class Def extends SsaDef, TDef {
|
||||
DefinitionExt def;
|
||||
|
||||
Def() { this = TDef(def) }
|
||||
|
||||
final override DefinitionExt asDef() { result = def }
|
||||
|
||||
/** Gets the source variable underlying this SSA definition. */
|
||||
final SourceVariable getSourceVariable() { result = def.getSourceVariable() }
|
||||
|
||||
override string toString() { result = def.toString() }
|
||||
|
||||
/**
|
||||
* Holds if this definition (or use) has index `index` in block `block`,
|
||||
* and is a definition (or use) of the variable `sv`.
|
||||
*/
|
||||
predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) {
|
||||
def.definesAt(sv, block, index, _)
|
||||
}
|
||||
|
||||
/** Gets the value written by this definition, if any. */
|
||||
Node0Impl getValue() { none() }
|
||||
|
||||
/**
|
||||
* Holds if this definition is guaranteed to overwrite the entire
|
||||
* destination's allocation.
|
||||
*/
|
||||
abstract predicate isCertain();
|
||||
|
||||
/** Gets the address operand written to by this definition. */
|
||||
Operand getAddressOperand() { none() }
|
||||
|
||||
/** Gets the address written to by this definition. */
|
||||
final Instruction getAddress() { result = this.getAddressOperand().getDef() }
|
||||
|
||||
/** Gets the indirection index of this definition. */
|
||||
abstract int getIndirectionIndex();
|
||||
|
||||
/**
|
||||
* Gets the indirection level that this definition is writing to.
|
||||
* For instance, `x = y` is a definition of `x` at indirection level 1 and
|
||||
* `*x = y` is a definition of `x` at indirection level 2.
|
||||
*/
|
||||
abstract int getIndirection();
|
||||
|
||||
/**
|
||||
* Gets a definition that ultimately defines this SSA definition and is not
|
||||
* itself a phi node.
|
||||
*/
|
||||
Def getAnUltimateDefinition() { result.asDef() = def.getAnUltimateDefinition() }
|
||||
}
|
||||
|
||||
private predicate isGlobal(DefinitionExt def, GlobalDefImpl global) {
|
||||
/** Gets the `DefImpl` corresponding to `def`. */
|
||||
private DefImpl getDefImpl(SsaImpl::Definition def) {
|
||||
exists(SourceVariable sv, IRBlock bb, int i |
|
||||
def.definesAt(sv, bb, i, _) and
|
||||
global.hasIndexInBlock(bb, i, sv)
|
||||
def.definesAt(sv, bb, i) and
|
||||
result.hasIndexInBlock(bb, i, sv)
|
||||
)
|
||||
}
|
||||
|
||||
private class NonGlobalDef extends Def {
|
||||
NonGlobalDef() { not isGlobal(def, _) }
|
||||
class GlobalDef extends Definition {
|
||||
GlobalDefImpl impl;
|
||||
|
||||
final override Location getLocation() { result = this.getImpl().getLocation() }
|
||||
|
||||
private DefImpl getImpl() {
|
||||
exists(SourceVariable sv, IRBlock bb, int i |
|
||||
this.hasIndexInBlock(bb, i, sv) and
|
||||
result.hasIndexInBlock(bb, i, sv)
|
||||
)
|
||||
}
|
||||
|
||||
override Node0Impl getValue() { result = this.getImpl().getValue() }
|
||||
|
||||
override predicate isCertain() { this.getImpl().isCertain() }
|
||||
|
||||
override Operand getAddressOperand() { result = this.getImpl().getAddressOperand() }
|
||||
|
||||
override int getIndirectionIndex() { result = this.getImpl().getIndirectionIndex() }
|
||||
|
||||
override int getIndirection() { result = this.getImpl().getIndirection() }
|
||||
}
|
||||
|
||||
class GlobalDef extends Def {
|
||||
GlobalDefImpl global;
|
||||
|
||||
GlobalDef() { isGlobal(def, global) }
|
||||
|
||||
/** Gets a textual representation of this definition. */
|
||||
override string toString() { result = global.toString() }
|
||||
|
||||
final override Location getLocation() { result = global.getLocation() }
|
||||
GlobalDef() { impl = getDefImpl(this) }
|
||||
|
||||
/**
|
||||
* Gets the type of this definition after specifiers have been deeply stripped
|
||||
* and typedefs have been resolved.
|
||||
* Gets the global (or `static` local) variable written to by this SSA
|
||||
* definition.
|
||||
*/
|
||||
DataFlowType getUnspecifiedType() { result = global.getUnspecifiedType() }
|
||||
|
||||
/**
|
||||
* Gets the type of this definition, after typedefs have been resolved.
|
||||
*/
|
||||
DataFlowType getUnderlyingType() { result = global.getUnderlyingType() }
|
||||
|
||||
/** Gets the `IRFunction` whose body is evaluated after this definition. */
|
||||
IRFunction getIRFunction() { result = global.getIRFunction() }
|
||||
|
||||
/** Gets the global variable associated with this definition. */
|
||||
GlobalLikeVariable getVariable() { result = global.getVariable() }
|
||||
|
||||
override predicate isCertain() { any() }
|
||||
|
||||
final override int getIndirectionIndex() { result = global.getIndirectionIndex() }
|
||||
|
||||
final override int getIndirection() { result = global.getIndirection() }
|
||||
}
|
||||
|
||||
class Phi extends TPhi, SsaDef {
|
||||
PhiNode phi;
|
||||
|
||||
Phi() { this = TPhi(phi) }
|
||||
|
||||
final override PhiNode asPhi() { result = phi }
|
||||
|
||||
final override Location getLocation() { result = phi.getBasicBlock().getLocation() }
|
||||
|
||||
override string toString() { result = phi.toString() }
|
||||
|
||||
SsaPhiInputNode getNode(IRBlock block) { result.getPhiNode() = phi and result.getBlock() = block }
|
||||
|
||||
predicate hasInputFromBlock(Definition inp, IRBlock bb) { inp = phiHasInputFromBlockExt(phi, bb) }
|
||||
|
||||
final Definition getAnInput() { this.hasInputFromBlock(result, _) }
|
||||
GlobalLikeVariable getVariable() { result = impl.getVariable() }
|
||||
}
|
||||
|
||||
private module SsaImpl = SsaImplCommon::Make<Location, SsaInput>;
|
||||
|
||||
private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationInputSig {
|
||||
private import codeql.util.Void
|
||||
|
||||
class Expr extends Instruction {
|
||||
Expr() {
|
||||
exists(IRBlock bb, int i |
|
||||
variableRead(bb, i, _, true) and
|
||||
this = bb.getInstruction(i)
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { bb.getInstruction(i) = this }
|
||||
}
|
||||
|
||||
Expr getARead(SsaImpl::Definition def) {
|
||||
exists(SourceVariable v, IRBlock bb, int i |
|
||||
ssaDefReachesRead(v, def, bb, i) and
|
||||
variableRead(bb, i, v, true) and
|
||||
result.hasCfgNode(bb, i)
|
||||
)
|
||||
}
|
||||
|
||||
predicate ssaDefAssigns(SsaImpl::WriteDefinition def, Expr value) { none() }
|
||||
|
||||
class Parameter extends Void {
|
||||
Location getLocation() { none() }
|
||||
}
|
||||
|
||||
predicate ssaDefInitializesParam(SsaImpl::WriteDefinition def, Parameter p) { none() }
|
||||
|
||||
predicate allowFlowIntoUncertainDef(SsaImpl::UncertainWriteDefinition def) { any() }
|
||||
|
||||
private EdgeKind getConditionalEdge(boolean branch) {
|
||||
branch = true and
|
||||
result instanceof TrueEdge
|
||||
or
|
||||
branch = false and
|
||||
result instanceof FalseEdge
|
||||
}
|
||||
|
||||
class Guard instanceof IRGuards::IRGuardCondition {
|
||||
string toString() { result = super.toString() }
|
||||
|
||||
predicate controlsBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
|
||||
exists(EdgeKind kind |
|
||||
super.getBlock() = bb1 and
|
||||
kind = getConditionalEdge(branch) and
|
||||
bb1.getSuccessor(kind) = bb2
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
predicate guardControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
|
||||
guard.(IRGuards::IRGuardCondition).controls(bb, branch)
|
||||
}
|
||||
}
|
||||
|
||||
private module DataFlowIntegrationImpl = SsaImpl::DataFlowIntegration<DataFlowIntegrationInput>;
|
||||
|
||||
class SynthNode extends DataFlowIntegrationImpl::SsaNode {
|
||||
SynthNode() { not this.asDefinition() instanceof SsaImpl::WriteDefinition }
|
||||
}
|
||||
|
||||
signature predicate guardChecksNodeSig(IRGuards::IRGuardCondition g, Node e, boolean branch);
|
||||
|
||||
signature predicate guardChecksNodeSig(
|
||||
IRGuards::IRGuardCondition g, Node e, boolean branch, int indirectionIndex
|
||||
);
|
||||
|
||||
module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
|
||||
private predicate ssaDefReachesCertainUse(Definition def, UseImpl use) {
|
||||
exists(SourceVariable v, IRBlock bb, int i |
|
||||
use.hasIndexInBlock(bb, i, v) and
|
||||
variableRead(bb, i, v, true) and
|
||||
ssaDefReachesRead(v, def, bb, i)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate guardChecks(
|
||||
DataFlowIntegrationInput::Guard g, SsaImpl::Definition def, boolean branch, int indirectionIndex
|
||||
) {
|
||||
exists(UseImpl use |
|
||||
guardChecksNode(g, use.getNode(), branch, indirectionIndex) and
|
||||
ssaDefReachesCertainUse(def, use)
|
||||
)
|
||||
}
|
||||
|
||||
Node getABarrierNode(int indirectionIndex) {
|
||||
// Only get the SynthNodes from the shared implementation, as the ExprNodes cannot
|
||||
// be matched on SourceVariable.
|
||||
result.(SsaSynthNode).getSynthNode() =
|
||||
DataFlowIntegrationImpl::BarrierGuardDefWithState<int, guardChecks/4>::getABarrierNode(indirectionIndex)
|
||||
or
|
||||
// Calculate the guarded UseImpls corresponding to ExprNodes directly.
|
||||
exists(DataFlowIntegrationInput::Guard g, boolean branch, Definition def, IRBlock bb |
|
||||
guardChecks(g, def, branch, indirectionIndex) and
|
||||
exists(UseImpl use |
|
||||
ssaDefReachesCertainUse(def, use) and
|
||||
use.getBlock() = bb and
|
||||
DataFlowIntegrationInput::guardControlsBlock(g, bb, branch) and
|
||||
result = use.getNode()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module BarrierGuard<guardChecksNodeSig/3 guardChecksNode> {
|
||||
private predicate guardChecksNode(
|
||||
IRGuards::IRGuardCondition g, Node e, boolean branch, int indirectionIndex
|
||||
) {
|
||||
guardChecksNode(g, e, branch) and indirectionIndex = 0
|
||||
}
|
||||
|
||||
Node getABarrierNode() {
|
||||
result = BarrierGuardWithIntParam<guardChecksNode/4>::getABarrierNode(0)
|
||||
}
|
||||
}
|
||||
|
||||
bindingset[result, v]
|
||||
pragma[inline_late]
|
||||
DataFlowIntegrationImpl::Node fromDfNode(Node n, SourceVariable v) {
|
||||
result = n.(SsaSynthNode).getSynthNode()
|
||||
or
|
||||
exists(UseImpl use, IRBlock bb, int i |
|
||||
result.(DataFlowIntegrationImpl::ExprNode).getExpr().hasCfgNode(bb, i) and
|
||||
use.hasIndexInBlock(bb, i, v) and
|
||||
use.isCertain() and
|
||||
use.getNode() = n
|
||||
)
|
||||
or
|
||||
defToNode(n, result.(DataFlowIntegrationImpl::SsaDefinitionNode).getDefinition())
|
||||
}
|
||||
|
||||
private predicate ssaFlowImpl(Node nodeFrom, Node nodeTo) {
|
||||
exists(SourceVariable v |
|
||||
nodeFrom != nodeTo and
|
||||
DataFlowIntegrationImpl::localFlowStep(v, fromDfNode(nodeFrom, v), fromDfNode(nodeTo, v), _)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if there is def-use or use-use flow from `nodeFrom` to `nodeTo`. */
|
||||
predicate ssaFlow(Node nodeFrom, Node nodeTo) {
|
||||
postUpdateFlow(nodeFrom, nodeTo)
|
||||
or
|
||||
ssaFlowImpl(nodeFrom, nodeTo) and
|
||||
not modeledFlowBarrier(nodeFrom)
|
||||
}
|
||||
|
||||
/**
|
||||
* An static single assignment (SSA) phi node.
|
||||
*
|
||||
* This is either a normal phi node or a phi-read node.
|
||||
*/
|
||||
class PhiNode extends SsaImpl::DefinitionExt {
|
||||
PhiNode() {
|
||||
this instanceof SsaImpl::PhiNode or
|
||||
this instanceof SsaImpl::PhiReadNode
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this phi node is a phi-read node.
|
||||
*
|
||||
* Phi-read nodes are like normal phi nodes, but they are inserted based
|
||||
* on reads instead of writes.
|
||||
*/
|
||||
predicate isPhiRead() { this instanceof SsaImpl::PhiReadNode }
|
||||
|
||||
/**
|
||||
* Holds if the node at index `i` in `bb` is a last reference to SSA
|
||||
* definition `def` of `sv`. The reference is last because it can reach
|
||||
* this phi node, without passing through another read or write.
|
||||
*
|
||||
* The path from node `i` in `bb` to this phi node goes via basic block
|
||||
* `input`, which is either a predecessor of the basic block of this phi
|
||||
* node, or `input` = `bb` in case this phi node occurs in basic block `bb`.
|
||||
*/
|
||||
predicate hasInputFromBlock(DefinitionExt def, SourceVariable sv, IRBlock bb, int i, IRBlock input) {
|
||||
SsaCached::lastRefRedefExt(def, sv, bb, i, input, this)
|
||||
}
|
||||
|
||||
class PhiNode extends Definition instanceof SsaImpl::PhiNode {
|
||||
/** Gets a definition that is an input to this phi node. */
|
||||
final Definition getAnInput() { this.hasInputFromBlock(result, _, _, _, _) }
|
||||
final Definition getAnInput() { phiHasInputFromBlock(this, result, _) }
|
||||
}
|
||||
|
||||
/** An static single assignment (SSA) definition. */
|
||||
class DefinitionExt extends SsaImpl::DefinitionExt {
|
||||
class Definition extends SsaImpl::Definition {
|
||||
// TODO: Include prior definitions of uncertain writes or rename predicate
|
||||
// i.e. the disjunct `SsaImpl::uncertainWriteDefinitionInput(this, result)`
|
||||
private Definition getAPhiInputOrPriorDefinition() { result = this.(PhiNode).getAnInput() }
|
||||
|
||||
/**
|
||||
* Gets a definition that ultimately defines this SSA definition and is
|
||||
* not itself a phi node.
|
||||
*/
|
||||
final DefinitionExt getAnUltimateDefinition() {
|
||||
final Definition getAnUltimateDefinition() {
|
||||
result = this.getAPhiInputOrPriorDefinition*() and
|
||||
not result instanceof PhiNode
|
||||
}
|
||||
|
||||
/** Gets a node that represents a read of this SSA definition. */
|
||||
pragma[nomagic]
|
||||
Node getARead() {
|
||||
exists(SourceVariable sv, IRBlock bb, int i | SsaCached::ssaDefReachesReadExt(sv, this, bb, i) |
|
||||
useToNode(bb, i, sv, result)
|
||||
or
|
||||
phiToNode(result, sv, bb, i)
|
||||
)
|
||||
}
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
Node0Impl getValue() { result = getDefImpl(this).getValue() }
|
||||
|
||||
/** Gets the indirection index of this definition. */
|
||||
int getIndirectionIndex() { result = getDefImpl(this).getIndirectionIndex() }
|
||||
|
||||
/** Gets the indirection of this definition. */
|
||||
int getIndirection() { result = getDefImpl(this).getIndirection() }
|
||||
|
||||
/**
|
||||
* Holds if this definition is guaranteed to totally overwrite the buffer
|
||||
* being written to.
|
||||
*/
|
||||
predicate isCertain() { getDefImpl(this).isCertain() }
|
||||
|
||||
/**
|
||||
* Gets the enclosing declaration of this definition.
|
||||
*
|
||||
* Note that this may be a variable when this definition defines a global, or
|
||||
* a static local, variable.
|
||||
*/
|
||||
Declaration getFunction() { result = getDefImpl(this).getBlock().getEnclosingFunction() }
|
||||
|
||||
/** Gets the underlying type of the variable being defined by this definition. */
|
||||
Type getUnderlyingType() { result = this.getSourceVariable().getType() }
|
||||
|
||||
/** Gets the unspecified type of the variable being defined by this definition. */
|
||||
Type getUnspecifiedType() { result = this.getUnderlyingType().getUnspecifiedType() }
|
||||
}
|
||||
|
||||
class Definition = SsaImpl::Definition;
|
||||
|
||||
import SsaCached
|
||||
|
||||
@@ -630,10 +630,18 @@ private module Cached {
|
||||
Operand operand, int indirectionIndex, Operand operandRepr, int indirectionIndexRepr
|
||||
) {
|
||||
indirectionIndex = [1 .. countIndirectionsForCppType(getLanguageType(operand))] and
|
||||
exists(Instruction load |
|
||||
isDereference(load, operand, false) and
|
||||
operandRepr = unique( | | getAUse(load)) and
|
||||
indirectionIndexRepr = indirectionIndex - 1
|
||||
(
|
||||
exists(Instruction load |
|
||||
isDereference(load, operand, false) and
|
||||
operandRepr = unique( | | getAUse(load)) and
|
||||
indirectionIndexRepr = indirectionIndex - 1
|
||||
)
|
||||
or
|
||||
exists(CopyValueInstruction copy |
|
||||
copy.getSourceValueOperand() = operand and
|
||||
operandRepr = unique( | | getAUse(copy)) and
|
||||
indirectionIndexRepr = indirectionIndex
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -649,11 +657,19 @@ private module Cached {
|
||||
Instruction instr, int indirectionIndex, Instruction instrRepr, int indirectionIndexRepr
|
||||
) {
|
||||
indirectionIndex = [1 .. countIndirectionsForCppType(getResultLanguageType(instr))] and
|
||||
exists(Instruction load, Operand address |
|
||||
address = unique( | | getAUse(instr)) and
|
||||
isDereference(load, address, false) and
|
||||
instrRepr = load and
|
||||
indirectionIndexRepr = indirectionIndex - 1
|
||||
(
|
||||
exists(Instruction load, Operand address |
|
||||
address = unique( | | getAUse(instr)) and
|
||||
isDereference(load, address, false) and
|
||||
instrRepr = load and
|
||||
indirectionIndexRepr = indirectionIndex - 1
|
||||
)
|
||||
or
|
||||
exists(CopyValueInstruction copy |
|
||||
copy.getSourceValueOperand() = unique( | | getAUse(instr)) and
|
||||
instrRepr = copy and
|
||||
indirectionIndexRepr = indirectionIndex
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -327,9 +327,7 @@ private module Config implements ProductFlow::StateConfigSig {
|
||||
|
||||
predicate isBarrierIn1(DataFlow::Node node) { isSourcePair(node, _, _, _) }
|
||||
|
||||
predicate isBarrierOut2(DataFlow::Node node) {
|
||||
node = any(DataFlow::SsaPhiNode phi).getAnInput(true)
|
||||
}
|
||||
predicate isBarrierOut2(DataFlow::Node node) { DataFlow::flowsToBackEdge(node) }
|
||||
}
|
||||
|
||||
private module AllocToInvalidPointerFlow = ProductFlow::GlobalWithState<Config>;
|
||||
|
||||
@@ -203,9 +203,7 @@ private module InvalidPointerToDerefConfig implements DataFlow::StateConfigSig {
|
||||
|
||||
predicate isSink(DataFlow::Node sink, FlowState pai) { none() }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
node = any(DataFlow::SsaPhiNode phi | not phi.isPhiRead()).getAnInput(true)
|
||||
}
|
||||
predicate isBarrier(DataFlow::Node node) { DataFlow::flowsToBackEdge(node) }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node, FlowState pai) {
|
||||
// `node = getABarrierNode(pai)` ensures that node < pai, so this node is safe to dereference.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.3.4
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.3.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -12,7 +12,11 @@
|
||||
import cpp
|
||||
|
||||
predicate allowedTypedefs(TypedefType t) {
|
||||
t.getName() = ["I64", "U64", "I32", "U32", "I16", "U16", "I8", "U8", "F64", "F32"]
|
||||
t.getName() =
|
||||
[
|
||||
"I64", "U64", "I32", "U32", "I16", "U16", "I8", "U8", "F64", "F32", "int64_t", "uint64_t",
|
||||
"int32_t", "uint32_t", "int16_t", "uint16_t", "int8_t", "uint8_t"
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,6 +50,8 @@ from Declaration d, Type usedType
|
||||
where
|
||||
usedType = getAUsedType*(getAnImmediateUsedType(d)) and
|
||||
problematic(usedType) and
|
||||
// Allow uses of boolean types where defined by the language.
|
||||
not usedType instanceof BoolType and
|
||||
// Ignore violations for which we do not have a valid location.
|
||||
not d.getLocation() instanceof UnknownLocation
|
||||
select d,
|
||||
|
||||
@@ -208,8 +208,7 @@ class LoopWithAlloca extends Stmt {
|
||||
this.conditionRequiresInequality(va, _, _) and
|
||||
DataFlow::localFlow(result, DataFlow::exprNode(va)) and
|
||||
// Phi nodes will be preceded by nodes that represent actual definitions
|
||||
not result instanceof DataFlow::SsaPhiNode and
|
||||
not result instanceof DataFlow::SsaPhiInputNode and
|
||||
not result instanceof DataFlow::SsaSynthNode and
|
||||
// A source is outside the loop if it's not inside the loop
|
||||
not exists(Expr e | e = getExpr(result) | this = getAnEnclosingLoopOfExpr(e))
|
||||
)
|
||||
|
||||
20
cpp/ql/src/Metrics/Internal/IncludeResolutionStatus.ql
Normal file
20
cpp/ql/src/Metrics/Internal/IncludeResolutionStatus.ql
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @name Include file resolution status
|
||||
* @description Counts unresolved and resolved #includes.
|
||||
* This query is for internal use only and may change without notice.
|
||||
* @kind table
|
||||
* @id cpp/include-resolution-status
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
/**
|
||||
* A cannot open file error.
|
||||
*
|
||||
* Typically this is due to a missing include.
|
||||
*/
|
||||
class CannotOpenFileError extends CompilerError {
|
||||
CannotOpenFileError() { this.hasTag(["cannot_open_file", "cannot_open_file_reason"]) }
|
||||
}
|
||||
|
||||
select count(CannotOpenFileError e) as failed_includes, count(Include i) as successful_includes
|
||||
@@ -49,11 +49,17 @@ predicate interestingConcatenation(DataFlow::Node incoming, DataFlow::Node outgo
|
||||
call.getTarget() = op and
|
||||
op.hasQualifiedName("std", "operator+") and
|
||||
op.getType().(UserType).hasQualifiedName("std", "basic_string") and
|
||||
incoming.asIndirectArgument() = call.getArgument(1) and // left operand
|
||||
incoming.asIndirectArgument() = call.getArgument(1) and // right operand
|
||||
call = outgoing.asInstruction().getUnconvertedResultExpression()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A state will represent the most recent concatenation that occurred in the data flow.
|
||||
* - `TConcatState` if the concetenation has not yet occurred.
|
||||
* - `TExecState(incoming, outgoing)`, representing the concatenation of data from `incoming`
|
||||
* into result `outgoing`.
|
||||
*/
|
||||
newtype TState =
|
||||
TConcatState() or
|
||||
TExecState(DataFlow::Node incoming, DataFlow::Node outgoing) {
|
||||
@@ -74,7 +80,9 @@ class ExecState extends TExecState {
|
||||
|
||||
DataFlow::Node getOutgoingNode() { result = outgoing }
|
||||
|
||||
/** Holds if this is a possible `ExecState` for `sink`. */
|
||||
/**
|
||||
* Holds if this is a possible `ExecState` at `sink`, that is, if `outgoing` flows to `sink`.
|
||||
*/
|
||||
predicate isFeasibleForSink(DataFlow::Node sink) { ExecState::flow(outgoing, sink) }
|
||||
|
||||
string toString() { result = "ExecState" }
|
||||
@@ -110,6 +118,12 @@ module ExecStateConfig implements DataFlow::ConfigSig {
|
||||
|
||||
module ExecState = TaintTracking::Global<ExecStateConfig>;
|
||||
|
||||
/**
|
||||
* A full `TaintTracking` configuration from source to concatenation to sink, using a flow
|
||||
* state to remember the concatenation. It's important that we track flow to the sink even though
|
||||
* as soon as we reach the concatenation we know it will get there (due to the check of
|
||||
* `isFeasibleForSink`), because this way we get a complete flow path.
|
||||
*/
|
||||
module ExecTaintConfig implements DataFlow::StateConfigSig {
|
||||
class FlowState = TState;
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ module Config implements DataFlow::ConfigSig {
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
isSink(node) and node.asExpr().getUnspecifiedType() instanceof ArithmeticType
|
||||
or
|
||||
node.asInstruction().(StoreInstruction).getResultType() instanceof ArithmeticType
|
||||
node.asCertainDefinition().getUnspecifiedType() instanceof ArithmeticType
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ module Config implements DataFlow::ConfigSig {
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
isSink(node) and node.asExpr().getUnspecifiedType() instanceof ArithmeticType
|
||||
or
|
||||
node.asInstruction().(StoreInstruction).getResultType() instanceof ArithmeticType
|
||||
node.asCertainDefinition().getUnspecifiedType() instanceof ArithmeticType
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
* buffer.
|
||||
* @kind problem
|
||||
* @id cpp/overflow-buffer
|
||||
* @problem.severity recommendation
|
||||
* @problem.severity warning
|
||||
* @security-severity 9.3
|
||||
* @precision medium
|
||||
* @tags security
|
||||
* external/cwe/cwe-119
|
||||
* external/cwe/cwe-121
|
||||
|
||||
@@ -212,9 +212,7 @@ module StringSizeConfig implements ProductFlow::StateConfigSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate isBarrierOut2(DataFlow::Node node) {
|
||||
node = any(DataFlow::SsaPhiNode phi).getAnInput(true)
|
||||
}
|
||||
predicate isBarrierOut2(DataFlow::Node node) { DataFlow::flowsToBackEdge(node) }
|
||||
|
||||
predicate isAdditionalFlowStep2(
|
||||
DataFlow::Node node1, FlowState2 state1, DataFlow::Node node2, FlowState2 state2
|
||||
|
||||
@@ -42,7 +42,7 @@ module Config implements DataFlow::ConfigSig {
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
isSink(node) and isArithmeticNonCharType(node.asExpr().getUnspecifiedType())
|
||||
or
|
||||
isArithmeticNonCharType(node.asInstruction().(StoreInstruction).getResultType())
|
||||
isArithmeticNonCharType(node.asCertainDefinition().getUnspecifiedType())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ private module Config implements DataFlow::ConfigSig {
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
isSink(node) and node.asExpr().getUnspecifiedType() instanceof ArithmeticType
|
||||
or
|
||||
node.asInstruction().(StoreInstruction).getResultType() instanceof ArithmeticType
|
||||
node.asCertainDefinition().getUnspecifiedType() instanceof ArithmeticType
|
||||
or
|
||||
mayAddNullTerminator(_, node.asIndirectExpr())
|
||||
}
|
||||
|
||||
@@ -75,9 +75,11 @@ module Config implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) { isSink(sink, _, _) }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
exists(StoreInstruction store | store = node.asInstruction() |
|
||||
exists(StoreInstruction store, Expr e |
|
||||
store = node.asInstruction() and e = node.asCertainDefinition()
|
||||
|
|
||||
// Block flow to "likely small expressions"
|
||||
bounded(store.getSourceValue().getUnconvertedResultExpression())
|
||||
bounded(e)
|
||||
or
|
||||
// Block flow to "small types"
|
||||
store.getResultType().getUnspecifiedType().(IntegralType).getSize() <= 1
|
||||
|
||||
4
cpp/ql/src/change-notes/2025-02-20-overflow-buffer.md
Normal file
4
cpp/ql/src/change-notes/2025-02-20-overflow-buffer.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The query "Call to memory access function may overflow buffer" (`cpp/overflow-buffer`) has been added to the security-extended query suite. The query detects a range of buffer overflow and underflow issues.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Due to changes in libraries the query "Static array access may cause overflow" (`cpp/static-buffer-overflow`) will no longer report cases where multiple fields of a struct or class are written with a single `memset` or similar operation.
|
||||
4
cpp/ql/src/change-notes/2025-03-11-basic-int-types.md
Normal file
4
cpp/ql/src/change-notes/2025-03-11-basic-int-types.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The query "Use of basic integral type" (`cpp/jpl-c/basic-int-types`) no longer produces alerts for the standard fixed width integer types (`int8_t`, `uint8_t`, etc.), and the `_Bool` and `bool` types.
|
||||
3
cpp/ql/src/change-notes/released/1.3.4.md
Normal file
3
cpp/ql/src/change-notes/released/1.3.4.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.3.4
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.3.3
|
||||
lastReleaseVersion: 1.3.4
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 1.3.4-dev
|
||||
version: 1.3.5-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -44,6 +44,7 @@ edges
|
||||
| test.cpp:143:18:143:21 | asdf | test.cpp:134:25:134:27 | arr | provenance | |
|
||||
| test.cpp:143:18:143:21 | asdf | test.cpp:143:18:143:21 | asdf | provenance | |
|
||||
| test.cpp:146:26:146:26 | *p | test.cpp:147:4:147:9 | -- ... | provenance | |
|
||||
| test.cpp:146:26:146:26 | *p | test.cpp:147:4:147:9 | -- ... | provenance | |
|
||||
| test.cpp:154:7:154:9 | definition of buf | test.cpp:156:12:156:18 | ... + ... | provenance | Config |
|
||||
| test.cpp:156:12:156:14 | buf | test.cpp:156:12:156:18 | ... + ... | provenance | Config |
|
||||
| test.cpp:156:12:156:18 | ... + ... | test.cpp:156:12:156:18 | ... + ... | provenance | |
|
||||
@@ -154,6 +155,7 @@ nodes
|
||||
| test.cpp:143:18:143:21 | asdf | semmle.label | asdf |
|
||||
| test.cpp:146:26:146:26 | *p | semmle.label | *p |
|
||||
| test.cpp:147:4:147:9 | -- ... | semmle.label | -- ... |
|
||||
| test.cpp:147:4:147:9 | -- ... | semmle.label | -- ... |
|
||||
| test.cpp:154:7:154:9 | definition of buf | semmle.label | definition of buf |
|
||||
| test.cpp:156:12:156:14 | buf | semmle.label | buf |
|
||||
| test.cpp:156:12:156:18 | ... + ... | semmle.label | ... + ... |
|
||||
@@ -224,6 +226,8 @@ subpaths
|
||||
| test.cpp:136:9:136:16 | PointerAdd: ... += ... | test.cpp:142:10:142:13 | definition of asdf | test.cpp:138:13:138:15 | arr | This pointer arithmetic may have an off-by-2 error allowing it to overrun $@ at this $@. | test.cpp:142:10:142:13 | asdf | asdf | test.cpp:138:12:138:15 | Load: * ... | read |
|
||||
| test.cpp:136:9:136:16 | PointerAdd: ... += ... | test.cpp:143:18:143:21 | asdf | test.cpp:138:13:138:15 | arr | This pointer arithmetic may have an off-by-2 error allowing it to overrun $@ at this $@. | test.cpp:142:10:142:13 | asdf | asdf | test.cpp:138:12:138:15 | Load: * ... | read |
|
||||
| test.cpp:156:12:156:18 | PointerAdd: ... + ... | test.cpp:154:7:154:9 | definition of buf | test.cpp:147:4:147:9 | -- ... | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:154:7:154:9 | buf | buf | test.cpp:147:3:147:13 | Store: ... = ... | write |
|
||||
| test.cpp:156:12:156:18 | PointerAdd: ... + ... | test.cpp:154:7:154:9 | definition of buf | test.cpp:147:4:147:9 | -- ... | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:154:7:154:9 | buf | buf | test.cpp:147:3:147:13 | Store: ... = ... | write |
|
||||
| test.cpp:156:12:156:18 | PointerAdd: ... + ... | test.cpp:156:12:156:14 | buf | test.cpp:147:4:147:9 | -- ... | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:154:7:154:9 | buf | buf | test.cpp:147:3:147:13 | Store: ... = ... | write |
|
||||
| test.cpp:156:12:156:18 | PointerAdd: ... + ... | test.cpp:156:12:156:14 | buf | test.cpp:147:4:147:9 | -- ... | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:154:7:154:9 | buf | buf | test.cpp:147:3:147:13 | Store: ... = ... | write |
|
||||
| test.cpp:221:5:221:11 | PointerAdd: access to array | test.cpp:217:19:217:24 | definition of buffer | test.cpp:221:5:221:11 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:217:19:217:24 | buffer | buffer | test.cpp:221:5:221:15 | Store: ... = ... | write |
|
||||
| test.cpp:221:5:221:11 | PointerAdd: access to array | test.cpp:218:23:218:28 | buffer | test.cpp:221:5:221:11 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:217:19:217:24 | buffer | buffer | test.cpp:221:5:221:15 | Store: ... = ... | write |
|
||||
|
||||
@@ -31,8 +31,6 @@
|
||||
| example.c:17:21:17:21 | 0 | example.c:17:21:17:21 | 0 |
|
||||
| example.c:19:6:19:6 | *b | example.c:15:37:15:37 | *b |
|
||||
| example.c:19:6:19:6 | *b [post update] | example.c:15:37:15:37 | *b |
|
||||
| example.c:19:6:19:6 | *b [post update] | example.c:19:6:19:6 | *b |
|
||||
| example.c:19:6:19:6 | b [post update] | example.c:19:6:19:6 | b |
|
||||
| example.c:24:2:24:7 | *coords | example.c:26:18:26:24 | *& ... |
|
||||
| example.c:24:2:24:7 | *coords [post update] | example.c:26:18:26:24 | *& ... |
|
||||
| example.c:24:2:24:7 | coords | example.c:26:18:26:24 | & ... |
|
||||
@@ -53,11 +51,9 @@
|
||||
| example.c:26:18:26:24 | *& ... | example.c:26:2:26:7 | *coords |
|
||||
| example.c:26:18:26:24 | getX output argument | example.c:26:2:26:7 | *coords |
|
||||
| example.c:26:18:26:24 | pointer to getX output argument | example.c:26:2:26:7 | coords |
|
||||
| example.c:26:19:26:24 | *coords | example.c:26:18:26:24 | *& ... |
|
||||
| example.c:26:19:26:24 | coords | example.c:26:18:26:24 | & ... |
|
||||
| example.c:28:22:28:25 | & ... | example.c:28:14:28:25 | & ... |
|
||||
| example.c:28:22:28:25 | *& ... | example.c:28:14:28:25 | *& ... |
|
||||
| example.c:28:23:28:25 | *pos | example.c:28:22:28:25 | *& ... |
|
||||
| example.c:28:23:28:25 | pos | example.c:28:22:28:25 | & ... |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:6:12:6:17 | call to source |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:7:8:7:9 | t1 |
|
||||
@@ -69,34 +65,34 @@
|
||||
| test.cpp:8:8:8:9 | t1 | test.cpp:9:8:9:9 | t1 |
|
||||
| test.cpp:9:8:9:9 | t1 | test.cpp:11:7:11:8 | t1 |
|
||||
| test.cpp:9:8:9:9 | t1 | test.cpp:11:7:11:8 | t1 |
|
||||
| test.cpp:10:8:10:9 | t2 | test.cpp:11:7:11:8 | Phi input |
|
||||
| test.cpp:10:8:10:9 | t2 | test.cpp:11:7:11:8 | Phi input |
|
||||
| test.cpp:10:8:10:9 | t2 | test.cpp:11:7:11:8 | [input] SSA phi read(t2) |
|
||||
| test.cpp:10:8:10:9 | t2 | test.cpp:11:7:11:8 | [input] SSA phi(*t2) |
|
||||
| test.cpp:10:8:10:9 | t2 | test.cpp:13:10:13:11 | t2 |
|
||||
| test.cpp:11:7:11:8 | Phi input | test.cpp:15:3:15:6 | SSA phi read(t2) |
|
||||
| test.cpp:11:7:11:8 | Phi input | test.cpp:15:3:15:6 | SSA phi(*t2) |
|
||||
| test.cpp:11:7:11:8 | [input] SSA phi read(t2) | test.cpp:15:3:15:6 | SSA phi read(t2) |
|
||||
| test.cpp:11:7:11:8 | [input] SSA phi(*t2) | test.cpp:15:3:15:6 | SSA phi(*t2) |
|
||||
| test.cpp:11:7:11:8 | t1 | test.cpp:21:8:21:9 | t1 |
|
||||
| test.cpp:12:5:12:10 | ... = ... | test.cpp:13:10:13:11 | t2 |
|
||||
| test.cpp:12:10:12:10 | 0 | test.cpp:12:5:12:10 | ... = ... |
|
||||
| test.cpp:13:5:13:8 | Phi input | test.cpp:15:3:15:6 | SSA phi read(t2) |
|
||||
| test.cpp:13:5:13:8 | Phi input | test.cpp:15:3:15:6 | SSA phi(*t2) |
|
||||
| test.cpp:13:10:13:11 | t2 | test.cpp:13:5:13:8 | Phi input |
|
||||
| test.cpp:13:10:13:11 | t2 | test.cpp:13:5:13:8 | Phi input |
|
||||
| test.cpp:13:5:13:8 | [input] SSA phi read(t2) | test.cpp:15:3:15:6 | SSA phi read(t2) |
|
||||
| test.cpp:13:5:13:8 | [input] SSA phi(*t2) | test.cpp:15:3:15:6 | SSA phi(*t2) |
|
||||
| test.cpp:13:10:13:11 | t2 | test.cpp:13:5:13:8 | [input] SSA phi read(t2) |
|
||||
| test.cpp:13:10:13:11 | t2 | test.cpp:13:5:13:8 | [input] SSA phi(*t2) |
|
||||
| test.cpp:15:3:15:6 | SSA phi read(t2) | test.cpp:15:8:15:9 | t2 |
|
||||
| test.cpp:15:3:15:6 | SSA phi(*t2) | test.cpp:15:8:15:9 | t2 |
|
||||
| test.cpp:15:8:15:9 | t2 | test.cpp:23:15:23:16 | Phi input |
|
||||
| test.cpp:15:8:15:9 | t2 | test.cpp:23:15:23:16 | Phi input |
|
||||
| test.cpp:15:8:15:9 | t2 | test.cpp:23:15:23:16 | [input] SSA phi read(*t2) |
|
||||
| test.cpp:15:8:15:9 | t2 | test.cpp:23:15:23:16 | [input] SSA phi read(t2) |
|
||||
| test.cpp:17:3:17:8 | ... = ... | test.cpp:21:8:21:9 | t1 |
|
||||
| test.cpp:17:8:17:8 | 0 | test.cpp:17:3:17:8 | ... = ... |
|
||||
| test.cpp:21:8:21:9 | t1 | test.cpp:23:15:23:16 | Phi input |
|
||||
| test.cpp:21:8:21:9 | t1 | test.cpp:23:15:23:16 | Phi input |
|
||||
| test.cpp:21:8:21:9 | t1 | test.cpp:23:15:23:16 | [input] SSA phi read(t1) |
|
||||
| test.cpp:21:8:21:9 | t1 | test.cpp:23:15:23:16 | [input] SSA phi(*t1) |
|
||||
| test.cpp:23:15:23:16 | 0 | test.cpp:23:15:23:16 | 0 |
|
||||
| test.cpp:23:15:23:16 | 0 | test.cpp:23:15:23:16 | Phi input |
|
||||
| test.cpp:23:15:23:16 | Phi input | test.cpp:23:19:23:19 | SSA phi read(*t2) |
|
||||
| test.cpp:23:15:23:16 | Phi input | test.cpp:23:19:23:19 | SSA phi read(i) |
|
||||
| test.cpp:23:15:23:16 | Phi input | test.cpp:23:19:23:19 | SSA phi read(t1) |
|
||||
| test.cpp:23:15:23:16 | Phi input | test.cpp:23:19:23:19 | SSA phi read(t2) |
|
||||
| test.cpp:23:15:23:16 | Phi input | test.cpp:23:19:23:19 | SSA phi(*i) |
|
||||
| test.cpp:23:15:23:16 | Phi input | test.cpp:23:19:23:19 | SSA phi(*t1) |
|
||||
| test.cpp:23:15:23:16 | 0 | test.cpp:23:15:23:16 | [input] SSA phi(*i) |
|
||||
| test.cpp:23:15:23:16 | [input] SSA phi read(*t2) | test.cpp:23:19:23:19 | SSA phi read(*t2) |
|
||||
| test.cpp:23:15:23:16 | [input] SSA phi read(i) | test.cpp:23:19:23:19 | SSA phi read(i) |
|
||||
| test.cpp:23:15:23:16 | [input] SSA phi read(t1) | test.cpp:23:19:23:19 | SSA phi read(t1) |
|
||||
| test.cpp:23:15:23:16 | [input] SSA phi read(t2) | test.cpp:23:19:23:19 | SSA phi read(t2) |
|
||||
| test.cpp:23:15:23:16 | [input] SSA phi(*i) | test.cpp:23:19:23:19 | SSA phi(*i) |
|
||||
| test.cpp:23:15:23:16 | [input] SSA phi(*t1) | test.cpp:23:19:23:19 | SSA phi(*t1) |
|
||||
| test.cpp:23:19:23:19 | SSA phi read(*t2) | test.cpp:24:10:24:11 | t2 |
|
||||
| test.cpp:23:19:23:19 | SSA phi read(i) | test.cpp:23:19:23:19 | i |
|
||||
| test.cpp:23:19:23:19 | SSA phi read(t1) | test.cpp:23:23:23:24 | t1 |
|
||||
@@ -105,25 +101,25 @@
|
||||
| test.cpp:23:19:23:19 | SSA phi(*t1) | test.cpp:23:23:23:24 | t1 |
|
||||
| test.cpp:23:19:23:19 | i | test.cpp:23:27:23:27 | i |
|
||||
| test.cpp:23:19:23:19 | i | test.cpp:23:27:23:27 | i |
|
||||
| test.cpp:23:23:23:24 | t1 | test.cpp:23:27:23:29 | Phi input |
|
||||
| test.cpp:23:23:23:24 | t1 | test.cpp:23:27:23:29 | [input] SSA phi read(t1) |
|
||||
| test.cpp:23:23:23:24 | t1 | test.cpp:26:8:26:9 | t1 |
|
||||
| test.cpp:23:23:23:24 | t1 | test.cpp:26:8:26:9 | t1 |
|
||||
| test.cpp:23:27:23:27 | *i | test.cpp:23:27:23:27 | *i |
|
||||
| test.cpp:23:27:23:27 | *i | test.cpp:23:27:23:27 | i |
|
||||
| test.cpp:23:27:23:27 | i | test.cpp:23:27:23:27 | i |
|
||||
| test.cpp:23:27:23:27 | i | test.cpp:23:27:23:27 | i |
|
||||
| test.cpp:23:27:23:27 | i | test.cpp:23:27:23:29 | Phi input |
|
||||
| test.cpp:23:27:23:27 | i | test.cpp:23:27:23:29 | [input] SSA phi read(i) |
|
||||
| test.cpp:23:27:23:29 | ... ++ | test.cpp:23:27:23:29 | ... ++ |
|
||||
| test.cpp:23:27:23:29 | ... ++ | test.cpp:23:27:23:29 | Phi input |
|
||||
| test.cpp:23:27:23:29 | Phi input | test.cpp:23:19:23:19 | SSA phi read(*t2) |
|
||||
| test.cpp:23:27:23:29 | Phi input | test.cpp:23:19:23:19 | SSA phi read(i) |
|
||||
| test.cpp:23:27:23:29 | Phi input | test.cpp:23:19:23:19 | SSA phi read(t1) |
|
||||
| test.cpp:23:27:23:29 | Phi input | test.cpp:23:19:23:19 | SSA phi read(t2) |
|
||||
| test.cpp:23:27:23:29 | Phi input | test.cpp:23:19:23:19 | SSA phi(*i) |
|
||||
| test.cpp:23:27:23:29 | Phi input | test.cpp:23:19:23:19 | SSA phi(*t1) |
|
||||
| test.cpp:24:5:24:11 | ... = ... | test.cpp:23:27:23:29 | Phi input |
|
||||
| test.cpp:24:10:24:11 | t2 | test.cpp:23:27:23:29 | Phi input |
|
||||
| test.cpp:24:10:24:11 | t2 | test.cpp:23:27:23:29 | Phi input |
|
||||
| test.cpp:23:27:23:29 | ... ++ | test.cpp:23:27:23:29 | [input] SSA phi(*i) |
|
||||
| test.cpp:23:27:23:29 | [input] SSA phi read(*t2) | test.cpp:23:19:23:19 | SSA phi read(*t2) |
|
||||
| test.cpp:23:27:23:29 | [input] SSA phi read(i) | test.cpp:23:19:23:19 | SSA phi read(i) |
|
||||
| test.cpp:23:27:23:29 | [input] SSA phi read(t1) | test.cpp:23:19:23:19 | SSA phi read(t1) |
|
||||
| test.cpp:23:27:23:29 | [input] SSA phi read(t2) | test.cpp:23:19:23:19 | SSA phi read(t2) |
|
||||
| test.cpp:23:27:23:29 | [input] SSA phi(*i) | test.cpp:23:19:23:19 | SSA phi(*i) |
|
||||
| test.cpp:23:27:23:29 | [input] SSA phi(*t1) | test.cpp:23:19:23:19 | SSA phi(*t1) |
|
||||
| test.cpp:24:5:24:11 | ... = ... | test.cpp:23:27:23:29 | [input] SSA phi(*t1) |
|
||||
| test.cpp:24:10:24:11 | t2 | test.cpp:23:27:23:29 | [input] SSA phi read(*t2) |
|
||||
| test.cpp:24:10:24:11 | t2 | test.cpp:23:27:23:29 | [input] SSA phi read(t2) |
|
||||
| test.cpp:24:10:24:11 | t2 | test.cpp:24:5:24:11 | ... = ... |
|
||||
| test.cpp:382:48:382:54 | source1 | test.cpp:384:16:384:23 | *& ... |
|
||||
| test.cpp:383:12:383:13 | 0 | test.cpp:383:12:383:13 | 0 |
|
||||
@@ -134,7 +130,6 @@
|
||||
| test.cpp:384:10:384:13 | *& ... | test.cpp:384:10:384:13 | *& ... |
|
||||
| test.cpp:384:10:384:13 | memcpy output argument | test.cpp:385:8:385:10 | tmp |
|
||||
| test.cpp:384:10:384:13 | pointer to memcpy output argument | test.cpp:385:8:385:10 | tmp |
|
||||
| test.cpp:384:11:384:13 | *tmp | test.cpp:384:10:384:13 | *& ... |
|
||||
| test.cpp:384:11:384:13 | tmp | test.cpp:384:10:384:13 | & ... |
|
||||
| test.cpp:384:16:384:23 | & ... | test.cpp:384:16:384:23 | & ... |
|
||||
| test.cpp:384:16:384:23 | *& ... | test.cpp:384:3:384:8 | **call to memcpy |
|
||||
@@ -143,7 +138,6 @@
|
||||
| test.cpp:384:16:384:23 | *& ... | test.cpp:384:16:384:23 | *& ... |
|
||||
| test.cpp:384:16:384:23 | **& ... | test.cpp:384:3:384:8 | **call to memcpy |
|
||||
| test.cpp:384:16:384:23 | **& ... | test.cpp:384:10:384:13 | memcpy output argument |
|
||||
| test.cpp:384:17:384:23 | *source1 | test.cpp:384:16:384:23 | *& ... |
|
||||
| test.cpp:384:17:384:23 | source1 | test.cpp:384:16:384:23 | & ... |
|
||||
| test.cpp:388:53:388:59 | source1 | test.cpp:391:16:391:23 | *& ... |
|
||||
| test.cpp:388:66:388:66 | b | test.cpp:393:7:393:7 | b |
|
||||
@@ -153,7 +147,6 @@
|
||||
| test.cpp:390:18:390:21 | & ... | test.cpp:391:10:391:13 | & ... |
|
||||
| test.cpp:390:18:390:21 | *& ... | test.cpp:390:18:390:21 | *& ... |
|
||||
| test.cpp:390:18:390:21 | *& ... | test.cpp:391:10:391:13 | *& ... |
|
||||
| test.cpp:390:19:390:21 | *tmp | test.cpp:390:18:390:21 | *& ... |
|
||||
| test.cpp:390:19:390:21 | tmp | test.cpp:390:18:390:21 | & ... |
|
||||
| test.cpp:391:10:391:13 | & ... | test.cpp:391:3:391:8 | call to memcpy |
|
||||
| test.cpp:391:10:391:13 | & ... | test.cpp:391:10:391:13 | & ... |
|
||||
@@ -161,7 +154,6 @@
|
||||
| test.cpp:391:10:391:13 | *& ... | test.cpp:391:10:391:13 | *& ... |
|
||||
| test.cpp:391:10:391:13 | memcpy output argument | test.cpp:392:8:392:10 | tmp |
|
||||
| test.cpp:391:10:391:13 | pointer to memcpy output argument | test.cpp:392:8:392:10 | tmp |
|
||||
| test.cpp:391:11:391:13 | *tmp | test.cpp:391:10:391:13 | *& ... |
|
||||
| test.cpp:391:11:391:13 | tmp | test.cpp:391:10:391:13 | & ... |
|
||||
| test.cpp:391:16:391:23 | & ... | test.cpp:391:16:391:23 | & ... |
|
||||
| test.cpp:391:16:391:23 | *& ... | test.cpp:391:3:391:8 | **call to memcpy |
|
||||
@@ -170,7 +162,6 @@
|
||||
| test.cpp:391:16:391:23 | *& ... | test.cpp:391:16:391:23 | *& ... |
|
||||
| test.cpp:391:16:391:23 | **& ... | test.cpp:391:3:391:8 | **call to memcpy |
|
||||
| test.cpp:391:16:391:23 | **& ... | test.cpp:391:10:391:13 | memcpy output argument |
|
||||
| test.cpp:391:17:391:23 | *source1 | test.cpp:391:16:391:23 | *& ... |
|
||||
| test.cpp:391:17:391:23 | source1 | test.cpp:391:16:391:23 | & ... |
|
||||
| test.cpp:392:8:392:10 | tmp | test.cpp:394:10:394:12 | tmp |
|
||||
| test.cpp:392:8:392:10 | tmp | test.cpp:394:10:394:12 | tmp |
|
||||
@@ -196,8 +187,6 @@
|
||||
| test.cpp:488:24:488:30 | content | test.cpp:488:21:488:30 | content |
|
||||
| test.cpp:489:20:489:20 | *s | test.cpp:487:67:487:67 | *s |
|
||||
| test.cpp:489:20:489:20 | *s [post update] | test.cpp:487:67:487:67 | *s |
|
||||
| test.cpp:489:20:489:20 | *s [post update] | test.cpp:489:20:489:20 | *s |
|
||||
| test.cpp:489:20:489:20 | s [post update] | test.cpp:489:20:489:20 | s |
|
||||
| test.cpp:489:23:489:29 | *content | test.cpp:489:23:489:29 | *content |
|
||||
| test.cpp:489:23:489:29 | *content | test.cpp:490:8:490:17 | * ... |
|
||||
| test.cpp:489:23:489:29 | content | test.cpp:489:23:489:29 | content |
|
||||
@@ -209,5 +198,4 @@
|
||||
| test.cpp:1087:3:1087:3 | a [post update] | test.cpp:1088:8:1088:9 | & ... |
|
||||
| test.cpp:1087:15:1087:21 | 0 | test.cpp:1087:3:1087:21 | ... = ... |
|
||||
| test.cpp:1087:15:1087:21 | *0 | test.cpp:1087:3:1087:21 | *... = ... |
|
||||
| test.cpp:1088:9:1088:9 | *a | test.cpp:1088:8:1088:9 | *& ... |
|
||||
| test.cpp:1088:9:1088:9 | a | test.cpp:1088:8:1088:9 | & ... |
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
| test.cpp:3:8:3:8 | C<1> | 0 | int | test.cpp:5:25:5:25 | 1 |
|
||||
| test.cpp:3:8:3:8 | C<2> | 0 | int | file://:0:0:0:0 | 2 |
|
||||
| test.cpp:3:8:3:8 | C<x> | 0 | int | file://:0:0:0:0 | x |
|
||||
| test.cpp:10:8:10:8 | D<T, X> | 0 | <none> | test.cpp:9:19:9:19 | T |
|
||||
| test.cpp:10:8:10:8 | D<T, X> | 1 | T | file://:0:0:0:0 | X |
|
||||
| test.cpp:10:8:10:8 | D<int, 2> | 0 | <none> | file://:0:0:0:0 | int |
|
||||
| test.cpp:10:8:10:8 | D<int, 2> | 1 | int | test.cpp:12:8:12:8 | 2 |
|
||||
| test.cpp:10:8:10:8 | D<long, 2L> | 0 | <none> | file://:0:0:0:0 | long |
|
||||
| test.cpp:10:8:10:8 | D<long, 2L> | 1 | long | file://:0:0:0:0 | 2 |
|
||||
| test.cpp:16:8:16:8 | E<T, X> | 0 | <none> | test.cpp:15:19:15:19 | T |
|
||||
| test.cpp:16:8:16:8 | E<T, X> | 1 | T * | file://:0:0:0:0 | X |
|
||||
| test.cpp:16:8:16:8 | E<int, (int *)nullptr> | 0 | <none> | file://:0:0:0:0 | int |
|
||||
| test.cpp:16:8:16:8 | E<int, (int *)nullptr> | 1 | int * | file://:0:0:0:0 | 0 |
|
||||
| test.cpp:3:8:3:8 | C<1> | 0 | int | test.cpp:5:25:5:25 | 1 | 1 |
|
||||
| test.cpp:3:8:3:8 | C<2> | 0 | int | file://:0:0:0:0 | 2 | 2 |
|
||||
| test.cpp:3:8:3:8 | C<x> | 0 | int | file://:0:0:0:0 | x | x |
|
||||
| test.cpp:10:8:10:8 | D<T, X> | 0 | <none> | test.cpp:9:19:9:19 | T | <none> |
|
||||
| test.cpp:10:8:10:8 | D<T, X> | 1 | T | file://:0:0:0:0 | X | X |
|
||||
| test.cpp:10:8:10:8 | D<int, 2> | 0 | <none> | file://:0:0:0:0 | int | <none> |
|
||||
| test.cpp:10:8:10:8 | D<int, 2> | 1 | int | test.cpp:12:8:12:8 | 2 | 2 |
|
||||
| test.cpp:10:8:10:8 | D<long, 2L> | 0 | <none> | file://:0:0:0:0 | long | <none> |
|
||||
| test.cpp:10:8:10:8 | D<long, 2L> | 1 | long | file://:0:0:0:0 | 2 | 2 |
|
||||
| test.cpp:16:8:16:8 | E<T, X> | 0 | <none> | test.cpp:15:19:15:19 | T | <none> |
|
||||
| test.cpp:16:8:16:8 | E<T, X> | 1 | T * | file://:0:0:0:0 | X | X |
|
||||
| test.cpp:16:8:16:8 | E<int, (int *)nullptr> | 0 | <none> | file://:0:0:0:0 | int | <none> |
|
||||
| test.cpp:16:8:16:8 | E<int, (int *)nullptr> | 1 | int * | file://:0:0:0:0 | 0 | 0 |
|
||||
|
||||
@@ -9,6 +9,16 @@ string maybeGetTemplateArgumentKind(Declaration d, int i) {
|
||||
i = [0 .. d.getNumberOfTemplateArguments()]
|
||||
}
|
||||
|
||||
string maybeGetTemplateArgumentValue(Declaration d, int i) {
|
||||
(
|
||||
if exists(d.getTemplateArgument(i).(Expr).getValue())
|
||||
then result = d.getTemplateArgument(i).(Expr).getValue()
|
||||
else result = "<none>"
|
||||
) and
|
||||
i = [0 .. d.getNumberOfTemplateArguments()]
|
||||
}
|
||||
|
||||
from Declaration d, int i
|
||||
where i >= 0 and i < d.getNumberOfTemplateArguments()
|
||||
select d, i, maybeGetTemplateArgumentKind(d, i), d.getTemplateArgument(i)
|
||||
select d, i, maybeGetTemplateArgumentKind(d, i), d.getTemplateArgument(i),
|
||||
maybeGetTemplateArgumentValue(d, i)
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
| test.c:6:26:6:26 | x | x uses the basic integral type unsigned char rather than a typedef with size and signedness. |
|
||||
| test.c:7:20:7:20 | x | x uses the basic integral type unsigned char rather than a typedef with size and signedness. |
|
||||
| test.c:10:16:10:20 | test7 | test7 uses the basic integral type unsigned char rather than a typedef with size and signedness. |
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
edges
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:62:25:62:46 | ... = ... | provenance | |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:69:21:69:40 | ... = ... | provenance | |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | *data | provenance | |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:62:25:62:46 | ... = ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | *data | provenance | |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:69:21:69:40 | ... = ... | CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | *data | provenance | |
|
||||
nodes
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:55:27:55:38 | fgets output argument | semmle.label | fgets output argument |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:62:25:62:46 | ... = ... | semmle.label | ... = ... |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:69:21:69:40 | ... = ... | semmle.label | ... = ... |
|
||||
| CWE23_Relative_Path_Traversal__char_console_fopen_11.cpp:77:23:77:26 | *data | semmle.label | *data |
|
||||
subpaths
|
||||
#select
|
||||
|
||||
@@ -7,68 +7,88 @@ edges
|
||||
| test.cpp:47:21:47:26 | *call to getenv | test.cpp:50:35:50:43 | *envCflags | provenance | |
|
||||
| test.cpp:50:11:50:17 | sprintf output argument | test.cpp:51:10:51:16 | *command | provenance | |
|
||||
| test.cpp:50:35:50:43 | *envCflags | test.cpp:50:11:50:17 | sprintf output argument | provenance | Config |
|
||||
| test.cpp:62:9:62:16 | fread output argument | test.cpp:64:20:64:27 | *filename | provenance | |
|
||||
| test.cpp:64:11:64:17 | strncat output argument | test.cpp:65:10:65:16 | *command | provenance | |
|
||||
| test.cpp:64:20:64:27 | *filename | test.cpp:64:11:64:17 | strncat output argument | provenance | Config |
|
||||
| test.cpp:82:9:82:16 | fread output argument | test.cpp:84:20:84:27 | *filename | provenance | |
|
||||
| test.cpp:84:11:84:17 | strncat output argument | test.cpp:85:32:85:38 | *command | provenance | |
|
||||
| test.cpp:84:20:84:27 | *filename | test.cpp:84:11:84:17 | strncat output argument | provenance | Config |
|
||||
| test.cpp:91:9:91:16 | fread output argument | test.cpp:93:17:93:24 | *filename | provenance | |
|
||||
| test.cpp:93:11:93:14 | strncat output argument | test.cpp:94:45:94:48 | *path | provenance | |
|
||||
| test.cpp:93:17:93:24 | *filename | test.cpp:93:11:93:14 | strncat output argument | provenance | Config |
|
||||
| test.cpp:106:20:106:38 | *call to getenv | test.cpp:107:33:107:36 | *path | provenance | TaintFunction |
|
||||
| test.cpp:107:31:107:31 | call to operator+ | test.cpp:107:31:107:31 | call to operator+ | provenance | |
|
||||
| test.cpp:107:31:107:31 | call to operator+ | test.cpp:108:18:108:22 | *call to c_str | provenance | TaintFunction |
|
||||
| test.cpp:107:33:107:36 | *path | test.cpp:107:31:107:31 | call to operator+ | provenance | Config |
|
||||
| test.cpp:113:20:113:38 | *call to getenv | test.cpp:114:19:114:22 | *path | provenance | TaintFunction |
|
||||
| test.cpp:114:10:114:23 | call to operator+ | test.cpp:114:25:114:29 | *call to c_str | provenance | TaintFunction |
|
||||
| test.cpp:114:10:114:23 | call to operator+ | test.cpp:114:25:114:29 | *call to c_str | provenance | TaintFunction |
|
||||
| test.cpp:114:17:114:17 | call to operator+ | test.cpp:114:10:114:23 | call to operator+ | provenance | |
|
||||
| test.cpp:114:19:114:22 | *path | test.cpp:114:10:114:23 | call to operator+ | provenance | Config |
|
||||
| test.cpp:114:19:114:22 | *path | test.cpp:114:17:114:17 | call to operator+ | provenance | Config |
|
||||
| test.cpp:119:20:119:38 | *call to getenv | test.cpp:120:19:120:22 | *path | provenance | TaintFunction |
|
||||
| test.cpp:120:17:120:17 | call to operator+ | test.cpp:120:10:120:30 | *call to data | provenance | TaintFunction |
|
||||
| test.cpp:120:19:120:22 | *path | test.cpp:120:17:120:17 | call to operator+ | provenance | Config |
|
||||
| test.cpp:140:9:140:11 | fread output argument | test.cpp:142:31:142:33 | *str | provenance | |
|
||||
| test.cpp:142:11:142:17 | sprintf output argument | test.cpp:143:10:143:16 | *command | provenance | |
|
||||
| test.cpp:142:31:142:33 | *str | test.cpp:142:11:142:17 | sprintf output argument | provenance | Config |
|
||||
| test.cpp:174:9:174:16 | fread output argument | test.cpp:177:20:177:27 | *filename | provenance | |
|
||||
| test.cpp:174:9:174:16 | fread output argument | test.cpp:180:22:180:29 | *filename | provenance | |
|
||||
| test.cpp:177:13:177:17 | strncat output argument | test.cpp:178:22:178:26 | *flags | provenance | |
|
||||
| test.cpp:177:13:177:17 | strncat output argument | test.cpp:178:22:178:26 | *flags | provenance | |
|
||||
| test.cpp:177:20:177:27 | *filename | test.cpp:177:13:177:17 | strncat output argument | provenance | Config |
|
||||
| test.cpp:177:20:177:27 | *filename | test.cpp:177:13:177:17 | strncat output argument | provenance | TaintFunction |
|
||||
| test.cpp:178:13:178:19 | strncat output argument | test.cpp:183:32:183:38 | *command | provenance | |
|
||||
| test.cpp:178:13:178:19 | strncat output argument | test.cpp:183:32:183:38 | *command | provenance | |
|
||||
| test.cpp:178:22:178:26 | *flags | test.cpp:178:13:178:19 | strncat output argument | provenance | Config |
|
||||
| test.cpp:178:22:178:26 | *flags | test.cpp:178:13:178:19 | strncat output argument | provenance | TaintFunction |
|
||||
| test.cpp:180:13:180:19 | strncat output argument | test.cpp:183:32:183:38 | *command | provenance | |
|
||||
| test.cpp:180:22:180:29 | *filename | test.cpp:180:13:180:19 | strncat output argument | provenance | Config |
|
||||
| test.cpp:186:47:186:54 | *filename | test.cpp:187:18:187:25 | *filename | provenance | |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | *flags | provenance | |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | *flags | provenance | |
|
||||
| test.cpp:187:18:187:25 | *filename | test.cpp:187:11:187:15 | strncat output argument | provenance | Config |
|
||||
| test.cpp:187:18:187:25 | *filename | test.cpp:187:11:187:15 | strncat output argument | provenance | TaintFunction |
|
||||
| test.cpp:188:11:188:17 | strncat output argument | test.cpp:186:19:186:25 | *command | provenance | |
|
||||
| test.cpp:188:11:188:17 | strncat output argument | test.cpp:186:19:186:25 | *command | provenance | |
|
||||
| test.cpp:188:11:188:17 | strncat output argument | test.cpp:186:19:186:25 | *command [Return] | provenance | |
|
||||
| test.cpp:188:11:188:17 | strncat output argument | test.cpp:186:19:186:25 | *command [Return] | provenance | |
|
||||
| test.cpp:188:20:188:24 | *flags | test.cpp:188:11:188:17 | strncat output argument | provenance | Config |
|
||||
| test.cpp:188:20:188:24 | *flags | test.cpp:188:11:188:17 | strncat output argument | provenance | TaintFunction |
|
||||
| test.cpp:194:9:194:16 | fread output argument | test.cpp:196:26:196:33 | *filename | provenance | |
|
||||
| test.cpp:196:10:196:16 | concat output argument | test.cpp:198:32:198:38 | *command | provenance | |
|
||||
| test.cpp:196:10:196:16 | concat output argument | test.cpp:198:32:198:38 | *command | provenance | |
|
||||
| test.cpp:196:26:196:33 | *filename | test.cpp:186:47:186:54 | *filename | provenance | |
|
||||
| test.cpp:196:26:196:33 | *filename | test.cpp:196:10:196:16 | concat output argument | provenance | Config |
|
||||
| test.cpp:196:26:196:33 | *filename | test.cpp:196:10:196:16 | concat output argument | provenance | TaintFunction |
|
||||
| test.cpp:218:9:218:16 | fread output argument | test.cpp:220:19:220:26 | *filename | provenance | |
|
||||
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:220:10:220:16 | strncat output argument | provenance | TaintFunction |
|
||||
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:220:10:220:16 | strncat output argument | provenance | TaintFunction |
|
||||
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command | provenance | |
|
||||
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command | provenance | |
|
||||
| test.cpp:220:19:220:26 | *filename | test.cpp:220:10:220:16 | strncat output argument | provenance | Config |
|
||||
| test.cpp:220:19:220:26 | *filename | test.cpp:220:10:220:16 | strncat output argument | provenance | Config |
|
||||
| test.cpp:220:19:220:26 | *filename | test.cpp:220:19:220:26 | *filename | provenance | |
|
||||
| test.cpp:63:9:63:16 | fread output argument | test.cpp:65:20:65:27 | *filename | provenance | |
|
||||
| test.cpp:65:11:65:17 | strncat output argument | test.cpp:66:10:66:16 | *command | provenance | |
|
||||
| test.cpp:65:20:65:27 | *filename | test.cpp:65:11:65:17 | strncat output argument | provenance | Config |
|
||||
| test.cpp:83:9:83:16 | fread output argument | test.cpp:85:20:85:27 | *filename | provenance | |
|
||||
| test.cpp:85:11:85:17 | strncat output argument | test.cpp:86:32:86:38 | *command | provenance | |
|
||||
| test.cpp:85:20:85:27 | *filename | test.cpp:85:11:85:17 | strncat output argument | provenance | Config |
|
||||
| test.cpp:92:9:92:16 | fread output argument | test.cpp:94:17:94:24 | *filename | provenance | |
|
||||
| test.cpp:94:11:94:14 | strncat output argument | test.cpp:95:45:95:48 | *path | provenance | |
|
||||
| test.cpp:94:17:94:24 | *filename | test.cpp:94:11:94:14 | strncat output argument | provenance | Config |
|
||||
| test.cpp:107:20:107:38 | *call to getenv | test.cpp:108:33:108:36 | *path | provenance | TaintFunction |
|
||||
| test.cpp:108:31:108:31 | call to operator+ | test.cpp:108:31:108:31 | call to operator+ | provenance | |
|
||||
| test.cpp:108:31:108:31 | call to operator+ | test.cpp:109:18:109:22 | *call to c_str | provenance | TaintFunction |
|
||||
| test.cpp:108:33:108:36 | *path | test.cpp:108:31:108:31 | call to operator+ | provenance | Config |
|
||||
| test.cpp:114:20:114:38 | *call to getenv | test.cpp:115:19:115:22 | *path | provenance | TaintFunction |
|
||||
| test.cpp:115:10:115:23 | call to operator+ | test.cpp:115:25:115:29 | *call to c_str | provenance | TaintFunction |
|
||||
| test.cpp:115:10:115:23 | call to operator+ | test.cpp:115:25:115:29 | *call to c_str | provenance | TaintFunction |
|
||||
| test.cpp:115:17:115:17 | call to operator+ | test.cpp:115:10:115:23 | call to operator+ | provenance | |
|
||||
| test.cpp:115:19:115:22 | *path | test.cpp:115:10:115:23 | call to operator+ | provenance | Config |
|
||||
| test.cpp:115:19:115:22 | *path | test.cpp:115:17:115:17 | call to operator+ | provenance | Config |
|
||||
| test.cpp:120:20:120:38 | *call to getenv | test.cpp:121:19:121:22 | *path | provenance | TaintFunction |
|
||||
| test.cpp:121:17:121:17 | call to operator+ | test.cpp:121:10:121:30 | *call to data | provenance | TaintFunction |
|
||||
| test.cpp:121:19:121:22 | *path | test.cpp:121:17:121:17 | call to operator+ | provenance | Config |
|
||||
| test.cpp:141:9:141:11 | fread output argument | test.cpp:143:31:143:33 | *str | provenance | |
|
||||
| test.cpp:143:11:143:17 | sprintf output argument | test.cpp:144:10:144:16 | *command | provenance | |
|
||||
| test.cpp:143:31:143:33 | *str | test.cpp:143:11:143:17 | sprintf output argument | provenance | Config |
|
||||
| test.cpp:175:9:175:16 | fread output argument | test.cpp:178:20:178:27 | *filename | provenance | |
|
||||
| test.cpp:175:9:175:16 | fread output argument | test.cpp:181:22:181:29 | *filename | provenance | |
|
||||
| test.cpp:178:13:178:17 | strncat output argument | test.cpp:179:22:179:26 | *flags | provenance | |
|
||||
| test.cpp:178:13:178:17 | strncat output argument | test.cpp:179:22:179:26 | *flags | provenance | |
|
||||
| test.cpp:178:20:178:27 | *filename | test.cpp:178:13:178:17 | strncat output argument | provenance | Config |
|
||||
| test.cpp:178:20:178:27 | *filename | test.cpp:178:13:178:17 | strncat output argument | provenance | TaintFunction |
|
||||
| test.cpp:179:13:179:19 | strncat output argument | test.cpp:184:32:184:38 | *command | provenance | |
|
||||
| test.cpp:179:13:179:19 | strncat output argument | test.cpp:184:32:184:38 | *command | provenance | |
|
||||
| test.cpp:179:22:179:26 | *flags | test.cpp:179:13:179:19 | strncat output argument | provenance | Config |
|
||||
| test.cpp:179:22:179:26 | *flags | test.cpp:179:13:179:19 | strncat output argument | provenance | TaintFunction |
|
||||
| test.cpp:181:13:181:19 | strncat output argument | test.cpp:184:32:184:38 | *command | provenance | |
|
||||
| test.cpp:181:22:181:29 | *filename | test.cpp:181:13:181:19 | strncat output argument | provenance | Config |
|
||||
| test.cpp:187:47:187:54 | *filename | test.cpp:188:18:188:25 | *filename | provenance | |
|
||||
| test.cpp:188:11:188:15 | strncat output argument | test.cpp:189:20:189:24 | *flags | provenance | |
|
||||
| test.cpp:188:11:188:15 | strncat output argument | test.cpp:189:20:189:24 | *flags | provenance | |
|
||||
| test.cpp:188:18:188:25 | *filename | test.cpp:188:11:188:15 | strncat output argument | provenance | Config |
|
||||
| test.cpp:188:18:188:25 | *filename | test.cpp:188:11:188:15 | strncat output argument | provenance | TaintFunction |
|
||||
| test.cpp:189:11:189:17 | strncat output argument | test.cpp:187:19:187:25 | *command | provenance | |
|
||||
| test.cpp:189:11:189:17 | strncat output argument | test.cpp:187:19:187:25 | *command | provenance | |
|
||||
| test.cpp:189:11:189:17 | strncat output argument | test.cpp:187:19:187:25 | *command [Return] | provenance | |
|
||||
| test.cpp:189:11:189:17 | strncat output argument | test.cpp:187:19:187:25 | *command [Return] | provenance | |
|
||||
| test.cpp:189:20:189:24 | *flags | test.cpp:189:11:189:17 | strncat output argument | provenance | Config |
|
||||
| test.cpp:189:20:189:24 | *flags | test.cpp:189:11:189:17 | strncat output argument | provenance | TaintFunction |
|
||||
| test.cpp:195:9:195:16 | fread output argument | test.cpp:197:26:197:33 | *filename | provenance | |
|
||||
| test.cpp:197:10:197:16 | concat output argument | test.cpp:199:32:199:38 | *command | provenance | |
|
||||
| test.cpp:197:10:197:16 | concat output argument | test.cpp:199:32:199:38 | *command | provenance | |
|
||||
| test.cpp:197:26:197:33 | *filename | test.cpp:187:47:187:54 | *filename | provenance | |
|
||||
| test.cpp:197:26:197:33 | *filename | test.cpp:197:10:197:16 | concat output argument | provenance | Config |
|
||||
| test.cpp:197:26:197:33 | *filename | test.cpp:197:10:197:16 | concat output argument | provenance | TaintFunction |
|
||||
| test.cpp:219:9:219:16 | fread output argument | test.cpp:221:19:221:26 | *filename | provenance | |
|
||||
| test.cpp:221:10:221:16 | strncat output argument | test.cpp:221:10:221:16 | strncat output argument | provenance | TaintFunction |
|
||||
| test.cpp:221:10:221:16 | strncat output argument | test.cpp:221:10:221:16 | strncat output argument | provenance | TaintFunction |
|
||||
| test.cpp:221:10:221:16 | strncat output argument | test.cpp:223:32:223:38 | *command | provenance | |
|
||||
| test.cpp:221:10:221:16 | strncat output argument | test.cpp:223:32:223:38 | *command | provenance | |
|
||||
| test.cpp:221:19:221:26 | *filename | test.cpp:221:10:221:16 | strncat output argument | provenance | Config |
|
||||
| test.cpp:221:19:221:26 | *filename | test.cpp:221:10:221:16 | strncat output argument | provenance | Config |
|
||||
| test.cpp:221:19:221:26 | *filename | test.cpp:221:19:221:26 | *filename | provenance | |
|
||||
| test.cpp:231:11:231:16 | strncat output argument | test.cpp:232:11:232:16 | strncat output argument | provenance | TaintFunction |
|
||||
| test.cpp:231:19:231:33 | *call to getenv | test.cpp:231:11:231:16 | strncat output argument | provenance | Config |
|
||||
| test.cpp:232:11:232:16 | strncat output argument | test.cpp:233:11:233:16 | strncat output argument | provenance | TaintFunction |
|
||||
| test.cpp:232:11:232:16 | strncat output argument | test.cpp:233:11:233:16 | strncat output argument | provenance | TaintFunction |
|
||||
| test.cpp:232:19:232:33 | *call to getenv | test.cpp:232:11:232:16 | strncat output argument | provenance | Config |
|
||||
| test.cpp:233:11:233:16 | strncat output argument | test.cpp:234:10:234:15 | *buffer | provenance | |
|
||||
| test.cpp:233:11:233:16 | strncat output argument | test.cpp:234:10:234:15 | *buffer | provenance | |
|
||||
| test.cpp:242:11:242:17 | sprintf output argument | test.cpp:247:5:247:11 | *buffer1 | provenance | |
|
||||
| test.cpp:242:11:242:17 | sprintf output argument | test.cpp:247:5:247:11 | *buffer1 | provenance | |
|
||||
| test.cpp:243:5:243:10 | *call to getenv | test.cpp:242:11:242:17 | sprintf output argument | provenance | TaintFunction |
|
||||
| test.cpp:244:5:244:10 | *call to getenv | test.cpp:242:11:242:17 | sprintf output argument | provenance | Config |
|
||||
| test.cpp:244:5:244:10 | *call to getenv | test.cpp:242:11:242:17 | sprintf output argument | provenance | TaintFunction |
|
||||
| test.cpp:245:11:245:17 | sprintf output argument | test.cpp:249:10:249:16 | *buffer2 | provenance | |
|
||||
| test.cpp:245:11:245:17 | sprintf output argument | test.cpp:249:10:249:16 | *buffer2 | provenance | |
|
||||
| test.cpp:245:11:245:17 | sprintf output argument | test.cpp:249:10:249:16 | *buffer2 | provenance | |
|
||||
| test.cpp:247:5:247:11 | *buffer1 | test.cpp:245:11:245:17 | sprintf output argument | provenance | Config |
|
||||
| test.cpp:247:5:247:11 | *buffer1 | test.cpp:245:11:245:17 | sprintf output argument | provenance | TaintFunction |
|
||||
| test.cpp:248:5:248:10 | *call to getenv | test.cpp:245:11:245:17 | sprintf output argument | provenance | Config |
|
||||
| test.cpp:259:13:259:18 | strncat output argument | test.cpp:261:10:261:15 | *buffer | provenance | |
|
||||
| test.cpp:259:21:259:35 | *call to getenv | test.cpp:259:13:259:18 | strncat output argument | provenance | Config |
|
||||
nodes
|
||||
| test.cpp:15:27:15:30 | **argv | semmle.label | **argv |
|
||||
| test.cpp:16:20:16:26 | *access to array | semmle.label | *access to array |
|
||||
@@ -80,98 +100,130 @@ nodes
|
||||
| test.cpp:50:11:50:17 | sprintf output argument | semmle.label | sprintf output argument |
|
||||
| test.cpp:50:35:50:43 | *envCflags | semmle.label | *envCflags |
|
||||
| test.cpp:51:10:51:16 | *command | semmle.label | *command |
|
||||
| test.cpp:62:9:62:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:64:11:64:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:64:20:64:27 | *filename | semmle.label | *filename |
|
||||
| test.cpp:65:10:65:16 | *command | semmle.label | *command |
|
||||
| test.cpp:82:9:82:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:84:11:84:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:84:20:84:27 | *filename | semmle.label | *filename |
|
||||
| test.cpp:85:32:85:38 | *command | semmle.label | *command |
|
||||
| test.cpp:91:9:91:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:93:11:93:14 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:93:17:93:24 | *filename | semmle.label | *filename |
|
||||
| test.cpp:94:45:94:48 | *path | semmle.label | *path |
|
||||
| test.cpp:106:20:106:38 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:107:31:107:31 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:107:31:107:31 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:107:33:107:36 | *path | semmle.label | *path |
|
||||
| test.cpp:108:18:108:22 | *call to c_str | semmle.label | *call to c_str |
|
||||
| test.cpp:113:20:113:38 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:114:10:114:23 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:114:10:114:23 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:114:17:114:17 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:114:19:114:22 | *path | semmle.label | *path |
|
||||
| test.cpp:114:25:114:29 | *call to c_str | semmle.label | *call to c_str |
|
||||
| test.cpp:114:25:114:29 | *call to c_str | semmle.label | *call to c_str |
|
||||
| test.cpp:119:20:119:38 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:120:10:120:30 | *call to data | semmle.label | *call to data |
|
||||
| test.cpp:120:17:120:17 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:120:19:120:22 | *path | semmle.label | *path |
|
||||
| test.cpp:140:9:140:11 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:142:11:142:17 | sprintf output argument | semmle.label | sprintf output argument |
|
||||
| test.cpp:142:31:142:33 | *str | semmle.label | *str |
|
||||
| test.cpp:143:10:143:16 | *command | semmle.label | *command |
|
||||
| test.cpp:174:9:174:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:177:13:177:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:177:13:177:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:177:20:177:27 | *filename | semmle.label | *filename |
|
||||
| test.cpp:178:13:178:19 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:178:13:178:19 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:178:22:178:26 | *flags | semmle.label | *flags |
|
||||
| test.cpp:178:22:178:26 | *flags | semmle.label | *flags |
|
||||
| test.cpp:180:13:180:19 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:180:22:180:29 | *filename | semmle.label | *filename |
|
||||
| test.cpp:183:32:183:38 | *command | semmle.label | *command |
|
||||
| test.cpp:183:32:183:38 | *command | semmle.label | *command |
|
||||
| test.cpp:183:32:183:38 | *command | semmle.label | *command |
|
||||
| test.cpp:186:19:186:25 | *command | semmle.label | *command |
|
||||
| test.cpp:186:19:186:25 | *command | semmle.label | *command |
|
||||
| test.cpp:186:19:186:25 | *command [Return] | semmle.label | *command [Return] |
|
||||
| test.cpp:186:19:186:25 | *command [Return] | semmle.label | *command [Return] |
|
||||
| test.cpp:186:47:186:54 | *filename | semmle.label | *filename |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:187:18:187:25 | *filename | semmle.label | *filename |
|
||||
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:188:20:188:24 | *flags | semmle.label | *flags |
|
||||
| test.cpp:188:20:188:24 | *flags | semmle.label | *flags |
|
||||
| test.cpp:194:9:194:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:196:10:196:16 | concat output argument | semmle.label | concat output argument |
|
||||
| test.cpp:196:10:196:16 | concat output argument | semmle.label | concat output argument |
|
||||
| test.cpp:196:26:196:33 | *filename | semmle.label | *filename |
|
||||
| test.cpp:198:32:198:38 | *command | semmle.label | *command |
|
||||
| test.cpp:198:32:198:38 | *command | semmle.label | *command |
|
||||
| test.cpp:218:9:218:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:220:10:220:16 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:220:10:220:16 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:220:10:220:16 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:220:10:220:16 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:220:19:220:26 | *filename | semmle.label | *filename |
|
||||
| test.cpp:220:19:220:26 | *filename | semmle.label | *filename |
|
||||
| test.cpp:222:32:222:38 | *command | semmle.label | *command |
|
||||
| test.cpp:222:32:222:38 | *command | semmle.label | *command |
|
||||
| test.cpp:63:9:63:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:65:11:65:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:65:20:65:27 | *filename | semmle.label | *filename |
|
||||
| test.cpp:66:10:66:16 | *command | semmle.label | *command |
|
||||
| test.cpp:83:9:83:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:85:11:85:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:85:20:85:27 | *filename | semmle.label | *filename |
|
||||
| test.cpp:86:32:86:38 | *command | semmle.label | *command |
|
||||
| test.cpp:92:9:92:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:94:11:94:14 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:94:17:94:24 | *filename | semmle.label | *filename |
|
||||
| test.cpp:95:45:95:48 | *path | semmle.label | *path |
|
||||
| test.cpp:107:20:107:38 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:108:31:108:31 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:108:31:108:31 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:108:33:108:36 | *path | semmle.label | *path |
|
||||
| test.cpp:109:18:109:22 | *call to c_str | semmle.label | *call to c_str |
|
||||
| test.cpp:114:20:114:38 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:115:10:115:23 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:115:10:115:23 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:115:17:115:17 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:115:19:115:22 | *path | semmle.label | *path |
|
||||
| test.cpp:115:25:115:29 | *call to c_str | semmle.label | *call to c_str |
|
||||
| test.cpp:115:25:115:29 | *call to c_str | semmle.label | *call to c_str |
|
||||
| test.cpp:120:20:120:38 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:121:10:121:30 | *call to data | semmle.label | *call to data |
|
||||
| test.cpp:121:17:121:17 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:121:19:121:22 | *path | semmle.label | *path |
|
||||
| test.cpp:141:9:141:11 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:143:11:143:17 | sprintf output argument | semmle.label | sprintf output argument |
|
||||
| test.cpp:143:31:143:33 | *str | semmle.label | *str |
|
||||
| test.cpp:144:10:144:16 | *command | semmle.label | *command |
|
||||
| test.cpp:175:9:175:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:178:13:178:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:178:13:178:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:178:20:178:27 | *filename | semmle.label | *filename |
|
||||
| test.cpp:179:13:179:19 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:179:13:179:19 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:179:22:179:26 | *flags | semmle.label | *flags |
|
||||
| test.cpp:179:22:179:26 | *flags | semmle.label | *flags |
|
||||
| test.cpp:181:13:181:19 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:181:22:181:29 | *filename | semmle.label | *filename |
|
||||
| test.cpp:184:32:184:38 | *command | semmle.label | *command |
|
||||
| test.cpp:184:32:184:38 | *command | semmle.label | *command |
|
||||
| test.cpp:184:32:184:38 | *command | semmle.label | *command |
|
||||
| test.cpp:187:19:187:25 | *command | semmle.label | *command |
|
||||
| test.cpp:187:19:187:25 | *command | semmle.label | *command |
|
||||
| test.cpp:187:19:187:25 | *command [Return] | semmle.label | *command [Return] |
|
||||
| test.cpp:187:19:187:25 | *command [Return] | semmle.label | *command [Return] |
|
||||
| test.cpp:187:47:187:54 | *filename | semmle.label | *filename |
|
||||
| test.cpp:188:11:188:15 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:188:11:188:15 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:188:18:188:25 | *filename | semmle.label | *filename |
|
||||
| test.cpp:189:11:189:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:189:11:189:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:189:20:189:24 | *flags | semmle.label | *flags |
|
||||
| test.cpp:189:20:189:24 | *flags | semmle.label | *flags |
|
||||
| test.cpp:195:9:195:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:197:10:197:16 | concat output argument | semmle.label | concat output argument |
|
||||
| test.cpp:197:10:197:16 | concat output argument | semmle.label | concat output argument |
|
||||
| test.cpp:197:26:197:33 | *filename | semmle.label | *filename |
|
||||
| test.cpp:199:32:199:38 | *command | semmle.label | *command |
|
||||
| test.cpp:199:32:199:38 | *command | semmle.label | *command |
|
||||
| test.cpp:219:9:219:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:221:10:221:16 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:221:10:221:16 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:221:10:221:16 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:221:10:221:16 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:221:19:221:26 | *filename | semmle.label | *filename |
|
||||
| test.cpp:221:19:221:26 | *filename | semmle.label | *filename |
|
||||
| test.cpp:223:32:223:38 | *command | semmle.label | *command |
|
||||
| test.cpp:223:32:223:38 | *command | semmle.label | *command |
|
||||
| test.cpp:231:11:231:16 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:231:19:231:33 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:232:11:232:16 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:232:11:232:16 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:232:19:232:33 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:233:11:233:16 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:233:11:233:16 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:234:10:234:15 | *buffer | semmle.label | *buffer |
|
||||
| test.cpp:234:10:234:15 | *buffer | semmle.label | *buffer |
|
||||
| test.cpp:242:11:242:17 | sprintf output argument | semmle.label | sprintf output argument |
|
||||
| test.cpp:242:11:242:17 | sprintf output argument | semmle.label | sprintf output argument |
|
||||
| test.cpp:243:5:243:10 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:244:5:244:10 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:245:11:245:17 | sprintf output argument | semmle.label | sprintf output argument |
|
||||
| test.cpp:245:11:245:17 | sprintf output argument | semmle.label | sprintf output argument |
|
||||
| test.cpp:245:11:245:17 | sprintf output argument | semmle.label | sprintf output argument |
|
||||
| test.cpp:247:5:247:11 | *buffer1 | semmle.label | *buffer1 |
|
||||
| test.cpp:247:5:247:11 | *buffer1 | semmle.label | *buffer1 |
|
||||
| test.cpp:248:5:248:10 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:249:10:249:16 | *buffer2 | semmle.label | *buffer2 |
|
||||
| test.cpp:249:10:249:16 | *buffer2 | semmle.label | *buffer2 |
|
||||
| test.cpp:249:10:249:16 | *buffer2 | semmle.label | *buffer2 |
|
||||
| test.cpp:259:13:259:18 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:259:21:259:35 | *call to getenv | semmle.label | *call to getenv |
|
||||
| test.cpp:261:10:261:15 | *buffer | semmle.label | *buffer |
|
||||
subpaths
|
||||
| test.cpp:196:26:196:33 | *filename | test.cpp:186:47:186:54 | *filename | test.cpp:186:19:186:25 | *command | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:26:196:33 | *filename | test.cpp:186:47:186:54 | *filename | test.cpp:186:19:186:25 | *command | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:26:196:33 | *filename | test.cpp:186:47:186:54 | *filename | test.cpp:186:19:186:25 | *command [Return] | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:26:196:33 | *filename | test.cpp:186:47:186:54 | *filename | test.cpp:186:19:186:25 | *command [Return] | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:197:26:197:33 | *filename | test.cpp:187:47:187:54 | *filename | test.cpp:187:19:187:25 | *command | test.cpp:197:10:197:16 | concat output argument |
|
||||
| test.cpp:197:26:197:33 | *filename | test.cpp:187:47:187:54 | *filename | test.cpp:187:19:187:25 | *command | test.cpp:197:10:197:16 | concat output argument |
|
||||
| test.cpp:197:26:197:33 | *filename | test.cpp:187:47:187:54 | *filename | test.cpp:187:19:187:25 | *command [Return] | test.cpp:197:10:197:16 | concat output argument |
|
||||
| test.cpp:197:26:197:33 | *filename | test.cpp:187:47:187:54 | *filename | test.cpp:187:19:187:25 | *command [Return] | test.cpp:197:10:197:16 | concat output argument |
|
||||
#select
|
||||
| test.cpp:23:12:23:19 | command1 | test.cpp:15:27:15:30 | **argv | test.cpp:23:12:23:19 | *command1 | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:15:27:15:30 | **argv | user input (a command-line argument) | test.cpp:22:13:22:20 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:51:10:51:16 | command | test.cpp:47:21:47:26 | *call to getenv | test.cpp:51:10:51:16 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:47:21:47:26 | *call to getenv | user input (an environment variable) | test.cpp:50:11:50:17 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:65:10:65:16 | command | test.cpp:62:9:62:16 | fread output argument | test.cpp:65:10:65:16 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:62:9:62:16 | fread output argument | user input (string read by fread) | test.cpp:64:11:64:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:85:32:85:38 | command | test.cpp:82:9:82:16 | fread output argument | test.cpp:85:32:85:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:82:9:82:16 | fread output argument | user input (string read by fread) | test.cpp:84:11:84:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:94:45:94:48 | path | test.cpp:91:9:91:16 | fread output argument | test.cpp:94:45:94:48 | *path | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:91:9:91:16 | fread output argument | user input (string read by fread) | test.cpp:93:11:93:14 | strncat output argument | strncat output argument |
|
||||
| test.cpp:108:18:108:22 | call to c_str | test.cpp:106:20:106:38 | *call to getenv | test.cpp:108:18:108:22 | *call to c_str | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:106:20:106:38 | *call to getenv | user input (an environment variable) | test.cpp:107:31:107:31 | call to operator+ | call to operator+ |
|
||||
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:38 | *call to getenv | test.cpp:114:25:114:29 | *call to c_str | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:38 | *call to getenv | user input (an environment variable) | test.cpp:114:10:114:23 | call to operator+ | call to operator+ |
|
||||
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:38 | *call to getenv | test.cpp:114:25:114:29 | *call to c_str | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:38 | *call to getenv | user input (an environment variable) | test.cpp:114:17:114:17 | call to operator+ | call to operator+ |
|
||||
| test.cpp:120:25:120:28 | call to data | test.cpp:119:20:119:38 | *call to getenv | test.cpp:120:10:120:30 | *call to data | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:119:20:119:38 | *call to getenv | user input (an environment variable) | test.cpp:120:17:120:17 | call to operator+ | call to operator+ |
|
||||
| test.cpp:143:10:143:16 | command | test.cpp:140:9:140:11 | fread output argument | test.cpp:143:10:143:16 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:140:9:140:11 | fread output argument | user input (string read by fread) | test.cpp:142:11:142:17 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (string read by fread) | test.cpp:177:13:177:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (string read by fread) | test.cpp:178:13:178:19 | strncat output argument | strncat output argument |
|
||||
| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (string read by fread) | test.cpp:180:13:180:19 | strncat output argument | strncat output argument |
|
||||
| test.cpp:198:32:198:38 | command | test.cpp:194:9:194:16 | fread output argument | test.cpp:198:32:198:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:194:9:194:16 | fread output argument | user input (string read by fread) | test.cpp:187:11:187:15 | strncat output argument | strncat output argument |
|
||||
| test.cpp:198:32:198:38 | command | test.cpp:194:9:194:16 | fread output argument | test.cpp:198:32:198:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:194:9:194:16 | fread output argument | user input (string read by fread) | test.cpp:188:11:188:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:222:32:222:38 | command | test.cpp:218:9:218:16 | fread output argument | test.cpp:222:32:222:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:218:9:218:16 | fread output argument | user input (string read by fread) | test.cpp:220:10:220:16 | strncat output argument | strncat output argument |
|
||||
| test.cpp:222:32:222:38 | command | test.cpp:218:9:218:16 | fread output argument | test.cpp:222:32:222:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:218:9:218:16 | fread output argument | user input (string read by fread) | test.cpp:220:10:220:16 | strncat output argument | strncat output argument |
|
||||
| test.cpp:66:10:66:16 | command | test.cpp:63:9:63:16 | fread output argument | test.cpp:66:10:66:16 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:63:9:63:16 | fread output argument | user input (string read by fread) | test.cpp:65:11:65:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:86:32:86:38 | command | test.cpp:83:9:83:16 | fread output argument | test.cpp:86:32:86:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:83:9:83:16 | fread output argument | user input (string read by fread) | test.cpp:85:11:85:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:95:45:95:48 | path | test.cpp:92:9:92:16 | fread output argument | test.cpp:95:45:95:48 | *path | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:92:9:92:16 | fread output argument | user input (string read by fread) | test.cpp:94:11:94:14 | strncat output argument | strncat output argument |
|
||||
| test.cpp:109:18:109:22 | call to c_str | test.cpp:107:20:107:38 | *call to getenv | test.cpp:109:18:109:22 | *call to c_str | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:107:20:107:38 | *call to getenv | user input (an environment variable) | test.cpp:108:31:108:31 | call to operator+ | call to operator+ |
|
||||
| test.cpp:115:25:115:29 | call to c_str | test.cpp:114:20:114:38 | *call to getenv | test.cpp:115:25:115:29 | *call to c_str | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:114:20:114:38 | *call to getenv | user input (an environment variable) | test.cpp:115:10:115:23 | call to operator+ | call to operator+ |
|
||||
| test.cpp:115:25:115:29 | call to c_str | test.cpp:114:20:114:38 | *call to getenv | test.cpp:115:25:115:29 | *call to c_str | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:114:20:114:38 | *call to getenv | user input (an environment variable) | test.cpp:115:17:115:17 | call to operator+ | call to operator+ |
|
||||
| test.cpp:121:25:121:28 | call to data | test.cpp:120:20:120:38 | *call to getenv | test.cpp:121:10:121:30 | *call to data | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:120:20:120:38 | *call to getenv | user input (an environment variable) | test.cpp:121:17:121:17 | call to operator+ | call to operator+ |
|
||||
| test.cpp:144:10:144:16 | command | test.cpp:141:9:141:11 | fread output argument | test.cpp:144:10:144:16 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:141:9:141:11 | fread output argument | user input (string read by fread) | test.cpp:143:11:143:17 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:184:32:184:38 | command | test.cpp:175:9:175:16 | fread output argument | test.cpp:184:32:184:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:175:9:175:16 | fread output argument | user input (string read by fread) | test.cpp:178:13:178:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:184:32:184:38 | command | test.cpp:175:9:175:16 | fread output argument | test.cpp:184:32:184:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:175:9:175:16 | fread output argument | user input (string read by fread) | test.cpp:179:13:179:19 | strncat output argument | strncat output argument |
|
||||
| test.cpp:184:32:184:38 | command | test.cpp:175:9:175:16 | fread output argument | test.cpp:184:32:184:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:175:9:175:16 | fread output argument | user input (string read by fread) | test.cpp:181:13:181:19 | strncat output argument | strncat output argument |
|
||||
| test.cpp:199:32:199:38 | command | test.cpp:195:9:195:16 | fread output argument | test.cpp:199:32:199:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:195:9:195:16 | fread output argument | user input (string read by fread) | test.cpp:188:11:188:15 | strncat output argument | strncat output argument |
|
||||
| test.cpp:199:32:199:38 | command | test.cpp:195:9:195:16 | fread output argument | test.cpp:199:32:199:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:195:9:195:16 | fread output argument | user input (string read by fread) | test.cpp:189:11:189:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:223:32:223:38 | command | test.cpp:219:9:219:16 | fread output argument | test.cpp:223:32:223:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:219:9:219:16 | fread output argument | user input (string read by fread) | test.cpp:221:10:221:16 | strncat output argument | strncat output argument |
|
||||
| test.cpp:223:32:223:38 | command | test.cpp:219:9:219:16 | fread output argument | test.cpp:223:32:223:38 | *command | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:219:9:219:16 | fread output argument | user input (string read by fread) | test.cpp:221:10:221:16 | strncat output argument | strncat output argument |
|
||||
| test.cpp:234:10:234:15 | buffer | test.cpp:231:19:231:33 | *call to getenv | test.cpp:234:10:234:15 | *buffer | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:231:19:231:33 | *call to getenv | user input (an environment variable) | test.cpp:231:11:231:16 | strncat output argument | strncat output argument |
|
||||
| test.cpp:234:10:234:15 | buffer | test.cpp:232:19:232:33 | *call to getenv | test.cpp:234:10:234:15 | *buffer | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:232:19:232:33 | *call to getenv | user input (an environment variable) | test.cpp:232:11:232:16 | strncat output argument | strncat output argument |
|
||||
| test.cpp:249:10:249:16 | buffer2 | test.cpp:243:5:243:10 | *call to getenv | test.cpp:249:10:249:16 | *buffer2 | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:243:5:243:10 | *call to getenv | user input (an environment variable) | test.cpp:245:11:245:17 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:249:10:249:16 | buffer2 | test.cpp:244:5:244:10 | *call to getenv | test.cpp:249:10:249:16 | *buffer2 | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:244:5:244:10 | *call to getenv | user input (an environment variable) | test.cpp:242:11:242:17 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:249:10:249:16 | buffer2 | test.cpp:244:5:244:10 | *call to getenv | test.cpp:249:10:249:16 | *buffer2 | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:244:5:244:10 | *call to getenv | user input (an environment variable) | test.cpp:245:11:245:17 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:249:10:249:16 | buffer2 | test.cpp:248:5:248:10 | *call to getenv | test.cpp:249:10:249:16 | *buffer2 | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:248:5:248:10 | *call to getenv | user input (an environment variable) | test.cpp:245:11:245:17 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:261:10:261:15 | buffer | test.cpp:259:21:259:35 | *call to getenv | test.cpp:261:10:261:15 | *buffer | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:259:21:259:35 | *call to getenv | user input (an environment variable) | test.cpp:259:13:259:18 | strncat output argument | strncat output argument |
|
||||
|
||||
@@ -14,7 +14,7 @@ extern void encodeShellString(char *shellStr, int maxChars, const char* cStr);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
char *userName = argv[2];
|
||||
|
||||
|
||||
{
|
||||
// BAD: a string from the user is injected directly into
|
||||
// a command.
|
||||
@@ -23,10 +23,10 @@ int main(int argc, char** argv) {
|
||||
system(command1);
|
||||
}
|
||||
|
||||
{
|
||||
{
|
||||
// GOOD: the user string is encoded by a library routine.
|
||||
char userNameQuoted[1000] = {0};
|
||||
encodeShellString(userNameQuoted, 1000, userName);
|
||||
encodeShellString(userNameQuoted, 1000, userName);
|
||||
char command2[1000] = {0};
|
||||
sprintf(command2, "userinfo -v %s", userNameQuoted);
|
||||
system(command2);
|
||||
@@ -36,16 +36,16 @@ int main(int argc, char** argv) {
|
||||
void test2(char* arg2) {
|
||||
// GOOD?: the user string is the *first* part of the command, like $CC in many environments
|
||||
char *envCC = getenv("CC");
|
||||
|
||||
|
||||
char command[1000];
|
||||
sprintf("%s %s", envCC, arg2);
|
||||
sprintf(command, "%s %s", envCC, arg2);
|
||||
system(command);
|
||||
}
|
||||
|
||||
void test3(char* arg1) {
|
||||
// GOOD?: the user string is a `$CFLAGS` environment variable
|
||||
char *envCflags = getenv("CFLAGS");
|
||||
|
||||
|
||||
char command[1000];
|
||||
sprintf(command, "%s %s", arg1, envCflags);
|
||||
system(command);
|
||||
@@ -54,6 +54,7 @@ void test3(char* arg1) {
|
||||
typedef unsigned long size_t;
|
||||
typedef void FILE;
|
||||
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
|
||||
char *strncpy(char *s1, const char *s2, size_t n);
|
||||
char *strncat(char *s1, const char *s2, size_t n);
|
||||
|
||||
void test4(FILE *f) {
|
||||
@@ -160,7 +161,7 @@ void test15(FILE *f) {
|
||||
fread(temp, 1, 10, f);
|
||||
|
||||
int x = atoi(temp);
|
||||
|
||||
|
||||
char temp2[10];
|
||||
sprintf(temp2, "%d", x);
|
||||
sprintf(command, "tail -n %s foo.log", temp2);
|
||||
@@ -222,4 +223,42 @@ void test19(FILE *f) {
|
||||
execl("/bin/sh", "sh", "-c", command);
|
||||
}
|
||||
|
||||
void test20() {
|
||||
// BAD: the user strings `var_b`, `var_c` are injected directly into a command
|
||||
char buffer[1024 * 4];
|
||||
|
||||
strncpy(buffer, getenv("var_a"), 1024);
|
||||
strncat(buffer, getenv("var_b"), 1024);
|
||||
strncat(buffer, getenv("var_c"), 1024);
|
||||
strncat(buffer, " ", 1024);
|
||||
system(buffer);
|
||||
}
|
||||
|
||||
void test21() {
|
||||
// BAD: the user strings `var_b`, `var_c` are injected directly into a command
|
||||
char buffer1[1024];
|
||||
char buffer2[1024];
|
||||
|
||||
sprintf(buffer1, "%s %s",
|
||||
getenv("var_a"),
|
||||
getenv("var_b"));
|
||||
sprintf(buffer2, "%s %s %s",
|
||||
" ",
|
||||
buffer1,
|
||||
getenv("var_c"));
|
||||
system(buffer2);
|
||||
}
|
||||
|
||||
void test22() {
|
||||
// BAD: the user strings `var_a` are injected directly into a command
|
||||
char buffer[1024 * 11];
|
||||
int i;
|
||||
|
||||
strncpy(buffer, "command ", 1024);
|
||||
for (i = 0; i < 10; i++) {
|
||||
strncat(buffer, getenv("var_a"), 1024);
|
||||
}
|
||||
system(buffer);
|
||||
}
|
||||
|
||||
// open question: do we want to report certain sources even when they're the start of the string?
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
| tests.cpp:45:9:45:14 | call to memcpy | This 'memcpy' operation accesses 32 bytes but the $@ is only 16 bytes. | tests.cpp:32:10:32:18 | charFirst | destination buffer |
|
||||
| tests.cpp:60:9:60:14 | call to memcpy | This 'memcpy' operation accesses 32 bytes but the $@ is only 16 bytes. | tests.cpp:32:10:32:18 | charFirst | destination buffer |
|
||||
| tests.cpp:171:9:171:14 | call to memcpy | This 'memcpy' operation accesses 100 bytes but the $@ is only 50 bytes. | tests.cpp:164:20:164:25 | call to malloc | destination buffer |
|
||||
| tests.cpp:172:9:172:19 | access to array | This array indexing operation accesses byte offset 99 but the $@ is only 50 bytes. | tests.cpp:164:20:164:25 | call to malloc | array |
|
||||
| tests.cpp:192:9:192:14 | call to memcpy | This 'memcpy' operation accesses 100 bytes but the $@ is only 50 bytes. | tests.cpp:181:10:181:22 | dataBadBuffer | destination buffer |
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
| tests.cpp:45:51:45:72 | sizeof(<expr>) | Potential buffer-overflow: 'charFirst' has size 16 not 32. |
|
||||
| tests.cpp:60:52:60:74 | sizeof(<expr>) | Potential buffer-overflow: 'charFirst' has size 16 not 32. |
|
||||
|
||||
@@ -42,7 +42,7 @@ void CWE121_Stack_Based_Buffer_Overflow__char_type_overrun_memcpy_01_bad()
|
||||
/* Print the initial block pointed to by structCharVoid.voidSecond */
|
||||
printLine((char *)structCharVoid.voidSecond);
|
||||
/* FLAW: Use the sizeof(structCharVoid) which will overwrite the pointer voidSecond */
|
||||
memcpy(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid));
|
||||
memcpy(structCharVoid.charFirst, SRC_STR, sizeof(structCharVoid)); // [NOT DETECTED]
|
||||
structCharVoid.charFirst[(sizeof(structCharVoid.charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */
|
||||
printLine((char *)structCharVoid.charFirst);
|
||||
printLine((char *)structCharVoid.voidSecond);
|
||||
@@ -57,7 +57,7 @@ void CWE122_Heap_Based_Buffer_Overflow__char_type_overrun_memcpy_01_bad()
|
||||
/* Print the initial block pointed to by structCharVoid->voidSecond */
|
||||
printLine((char *)structCharVoid->voidSecond);
|
||||
/* FLAW: Use the sizeof(*structCharVoid) which will overwrite the pointer y */
|
||||
memcpy(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid));
|
||||
memcpy(structCharVoid->charFirst, SRC_STR, sizeof(*structCharVoid)); // [NOT DETECTED]
|
||||
structCharVoid->charFirst[(sizeof(structCharVoid->charFirst)/sizeof(char))-1] = '\0'; /* null terminate the string */
|
||||
printLine((char *)structCharVoid->charFirst);
|
||||
printLine((char *)structCharVoid->voidSecond);
|
||||
@@ -292,7 +292,7 @@ namespace CWE122_Heap_Based_Buffer_Overflow__cpp_CWE193_wchar_t_ncpy_01
|
||||
delete [] data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void goodG2B()
|
||||
{
|
||||
wchar_t * data;
|
||||
@@ -459,7 +459,7 @@ void CWE122_Heap_Based_Buffer_Overflow__cpp_CWE805_wchar_t_ncpy_01_bad()
|
||||
#ifdef _WIN32
|
||||
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format, ...);
|
||||
#define SNPRINTF _snwprintf
|
||||
#else
|
||||
#else
|
||||
int snprintf(char *s, size_t n, const char *format, ...);
|
||||
int swprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, ...);
|
||||
//#define SNPRINTF snprintf --- original code; using snprintf appears to be a mistake in samate?
|
||||
@@ -485,14 +485,14 @@ void CWE122_Heap_Based_Buffer_Overflow__cpp_CWE805_wchar_t_snprintf_01_bad()
|
||||
}
|
||||
|
||||
/* classes used in some test cases as a custom type */
|
||||
class TwoIntsClass
|
||||
class TwoIntsClass
|
||||
{
|
||||
public: // Needed to access variables from label files
|
||||
int intOne;
|
||||
int intTwo;
|
||||
};
|
||||
|
||||
class OneIntClass
|
||||
class OneIntClass
|
||||
{
|
||||
public: // Needed to access variables from label files
|
||||
int intOne;
|
||||
@@ -636,7 +636,7 @@ void CWE122_Heap_Based_Buffer_Overflow__cpp_CWE805_wchar_t_snprintf_31_bad()
|
||||
|
||||
int rand(void);
|
||||
|
||||
int globalReturnsTrueOrFalse()
|
||||
int globalReturnsTrueOrFalse()
|
||||
{
|
||||
return (rand() % 2);
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
| tests.cpp:1055:2:1055:8 | call to strncpy | This 'call to strncpy' operation is limited to 131 bytes but the destination is only 128 bytes. |
|
||||
| tests.cpp:1057:2:1057:8 | call to strncpy | This 'call to strncpy' operation is limited to 131 bytes but the destination is only 64 bytes. |
|
||||
| var_size_struct.cpp:73:3:73:9 | call to strncpy | This 'call to strncpy' operation is limited to 1025 bytes but the destination is only 1024 bytes. |
|
||||
| var_size_struct.cpp:103:3:103:9 | call to strncpy | This 'call to strncpy' operation is limited to 129 bytes but the destination is only 128 bytes. |
|
||||
|
||||
@@ -17,69 +17,81 @@
|
||||
| tests.cpp:285:3:285:8 | call to memset | This 'memset' operation accesses 128 bytes but the $@ is only 64 bytes. | tests.cpp:283:12:283:23 | new[] | destination buffer |
|
||||
| tests.cpp:292:3:292:8 | call to memset | This 'memset' operation accesses 11 bytes but the $@ is only 10 bytes. | tests.cpp:289:8:289:12 | array | destination buffer |
|
||||
| tests.cpp:310:2:310:7 | call to memset | This 'memset' operation accesses 21 bytes but the $@ is only 20 bytes. | tests.cpp:301:10:301:14 | myVar | destination buffer |
|
||||
| tests.cpp:312:2:312:7 | call to memset | This 'memset' operation accesses 17 bytes but the $@ is only 16 bytes. | tests.cpp:298:7:298:12 | buffer | destination buffer |
|
||||
| tests.cpp:314:2:314:7 | call to memset | This 'memset' operation accesses 8 bytes but the $@ is only 4 bytes. | tests.cpp:299:6:299:10 | field | destination buffer |
|
||||
| tests.cpp:346:2:346:14 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:349:2:349:14 | access to array | This array indexing operation accesses byte offset 10 but the $@ is only 10 bytes. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:350:17:350:29 | access to array | This array indexing operation accesses byte offset 10 but the $@ is only 10 bytes. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:352:2:352:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:355:2:355:13 | access to array | This array indexing operation accesses byte offset 43 but the $@ is only 40 bytes. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:356:16:356:27 | access to array | This array indexing operation accesses byte offset 43 but the $@ is only 40 bytes. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:358:2:358:16 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:344:11:344:21 | structArray | array |
|
||||
| tests.cpp:361:2:361:16 | access to array | This array indexing operation accesses byte offset 219 but the $@ is only 200 bytes. | tests.cpp:344:11:344:21 | structArray | array |
|
||||
| tests.cpp:362:25:362:39 | access to array | This array indexing operation accesses byte offset 219 but the $@ is only 200 bytes. | tests.cpp:344:11:344:21 | structArray | array |
|
||||
| tests.cpp:365:23:365:34 | access to array | This array indexing operation accesses byte offset 43 but the $@ is only 40 bytes. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:373:3:373:13 | access to array | This array indexing operation accesses byte offset 101 but the $@ is only 100 bytes. | tests.cpp:368:47:368:52 | call to malloc | array |
|
||||
| tests.cpp:376:3:376:13 | access to array | This array indexing operation accesses byte offset 101 but the $@ is only 101 bytes. | tests.cpp:369:47:369:52 | call to malloc | array |
|
||||
| tests.cpp:446:3:446:24 | access to array | This array indexing operation accesses a negative index -3 on the $@. | tests.cpp:444:7:444:14 | intArray | array |
|
||||
| tests.cpp:454:3:454:11 | access to array | This array indexing operation accesses a negative index -21 on the $@. | tests.cpp:450:7:450:11 | multi | array |
|
||||
| tests.cpp:456:3:456:11 | access to array | This array indexing operation accesses a negative index -21 on the $@. | tests.cpp:450:7:450:11 | multi | array |
|
||||
| tests.cpp:459:3:459:11 | access to array | This array indexing operation accesses byte offset 639 but the $@ is only 400 bytes. | tests.cpp:450:7:450:11 | multi | array |
|
||||
| tests.cpp:461:3:461:11 | access to array | This array indexing operation accesses byte offset 639 but the $@ is only 400 bytes. | tests.cpp:450:7:450:11 | multi | array |
|
||||
| tests.cpp:476:2:476:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:469:7:469:12 | buffer | array |
|
||||
| tests.cpp:477:2:477:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:469:7:469:12 | buffer | array |
|
||||
| tests.cpp:481:2:481:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:469:7:469:12 | buffer | array |
|
||||
| tests.cpp:487:2:487:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:473:21:473:26 | call to malloc | array |
|
||||
| tests.cpp:491:2:491:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:474:21:474:26 | call to malloc | array |
|
||||
| tests.cpp:519:3:519:8 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 10 bytes. | tests.cpp:502:15:502:20 | call to malloc | destination buffer |
|
||||
| tests.cpp:519:3:519:8 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 10 bytes. | tests.cpp:510:16:510:21 | call to malloc | destination buffer |
|
||||
| tests.cpp:541:6:541:10 | call to fread | This 'fread' operation may access 101 bytes but the $@ is only 100 bytes. | tests.cpp:532:7:532:16 | charBuffer | destination buffer |
|
||||
| tests.cpp:546:6:546:10 | call to fread | This 'fread' operation may access 400 bytes but the $@ is only 100 bytes. | tests.cpp:532:7:532:16 | charBuffer | destination buffer |
|
||||
| tests.cpp:569:6:569:15 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:565:7:565:12 | buffer | array |
|
||||
| tests.cpp:577:7:577:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:565:7:565:12 | buffer | array |
|
||||
| tests.cpp:637:6:637:15 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:633:7:633:12 | buffer | array |
|
||||
| tests.cpp:645:7:645:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:633:7:633:12 | buffer | array |
|
||||
| tests.cpp:708:3:708:8 | call to memset | This 'memset' operation accesses 24 bytes but the $@ is only 8 bytes. | tests.cpp:693:16:693:16 | c | destination buffer |
|
||||
| tests.cpp:712:3:712:8 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:693:16:693:16 | c | destination buffer |
|
||||
| tests.cpp:716:3:716:8 | call to memset | This 'memset' operation accesses 24 bytes but the $@ is only 16 bytes. | tests.cpp:692:16:692:16 | b | destination buffer |
|
||||
| tests.cpp:727:2:727:7 | call to memset | This 'memset' operation accesses 24 bytes but the $@ is only 8 bytes. | tests.cpp:693:16:693:16 | c | destination buffer |
|
||||
| tests.cpp:753:5:753:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:735:20:735:22 | b_1 | destination buffer |
|
||||
| tests.cpp:756:5:756:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:735:20:735:22 | b_1 | destination buffer |
|
||||
| tests.cpp:760:5:760:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:736:20:736:22 | c_1 | destination buffer |
|
||||
| tests.cpp:761:5:761:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 8 bytes. | tests.cpp:736:20:736:22 | c_1 | destination buffer |
|
||||
| tests.cpp:763:5:763:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:736:20:736:22 | c_1 | destination buffer |
|
||||
| tests.cpp:764:5:764:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 8 bytes. | tests.cpp:736:20:736:22 | c_1 | destination buffer |
|
||||
| tests.cpp:774:5:774:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:740:20:740:22 | b_2 | destination buffer |
|
||||
| tests.cpp:777:5:777:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:740:20:740:22 | b_2 | destination buffer |
|
||||
| tests.cpp:795:5:795:10 | call to memset | This 'memset' operation accesses 8 bytes but the $@ is only 4 bytes. | tests.cpp:790:16:790:16 | b | destination buffer |
|
||||
| tests.cpp:822:5:822:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 16 bytes. | tests.cpp:801:16:801:16 | b | destination buffer |
|
||||
| tests.cpp:825:5:825:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 16 bytes. | tests.cpp:801:16:801:16 | b | destination buffer |
|
||||
| tests.cpp:827:5:827:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 16 bytes. | tests.cpp:801:16:801:16 | b | destination buffer |
|
||||
| tests.cpp:830:5:830:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 12 bytes. | tests.cpp:802:16:802:16 | c | destination buffer |
|
||||
| tests.cpp:831:5:831:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:802:16:802:16 | c | destination buffer |
|
||||
| tests.cpp:833:5:833:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 12 bytes. | tests.cpp:802:16:802:16 | c | destination buffer |
|
||||
| tests.cpp:835:5:835:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 12 bytes. | tests.cpp:802:16:802:16 | c | destination buffer |
|
||||
| tests.cpp:846:5:846:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 8 bytes. | tests.cpp:807:16:807:16 | x | destination buffer |
|
||||
| tests.cpp:847:5:847:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:807:16:807:16 | x | destination buffer |
|
||||
| tests.cpp:848:5:848:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 8 bytes. | tests.cpp:807:16:807:16 | x | destination buffer |
|
||||
| tests.cpp:849:5:849:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 8 bytes. | tests.cpp:807:16:807:16 | x | destination buffer |
|
||||
| tests.cpp:851:5:851:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 8 bytes. | tests.cpp:807:16:807:16 | x | destination buffer |
|
||||
| tests.cpp:862:5:862:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
|
||||
| tests.cpp:863:5:863:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
|
||||
| tests.cpp:864:5:864:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
|
||||
| tests.cpp:865:5:865:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
|
||||
| tests.cpp:866:5:866:10 | call to memset | This 'memset' operation accesses 8 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
|
||||
| tests.cpp:867:5:867:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 4 bytes. | tests.cpp:812:12:812:12 | u | destination buffer |
|
||||
| tests.cpp:348:2:348:14 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:351:2:351:14 | access to array | This array indexing operation accesses byte offset 10 but the $@ is only 10 bytes. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:352:17:352:29 | access to array | This array indexing operation accesses byte offset 10 but the $@ is only 10 bytes. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:354:2:354:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:357:2:357:13 | access to array | This array indexing operation accesses byte offset 43 but the $@ is only 40 bytes. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:358:16:358:27 | access to array | This array indexing operation accesses byte offset 43 but the $@ is only 40 bytes. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:360:2:360:16 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:344:11:344:21 | structArray | array |
|
||||
| tests.cpp:363:2:363:16 | access to array | This array indexing operation accesses byte offset 219 but the $@ is only 200 bytes. | tests.cpp:344:11:344:21 | structArray | array |
|
||||
| tests.cpp:364:25:364:39 | access to array | This array indexing operation accesses byte offset 219 but the $@ is only 200 bytes. | tests.cpp:344:11:344:21 | structArray | array |
|
||||
| tests.cpp:367:23:367:34 | access to array | This array indexing operation accesses byte offset 43 but the $@ is only 40 bytes. | tests.cpp:343:6:343:13 | intArray | array |
|
||||
| tests.cpp:369:2:369:13 | access to array | This array indexing operation accesses a negative index -2 on the $@. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:370:2:370:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:374:2:374:13 | access to array | This array indexing operation accesses byte offset 10 but the $@ is only 10 bytes. | tests.cpp:342:7:342:15 | charArray | array |
|
||||
| tests.cpp:394:3:394:13 | access to array | This array indexing operation accesses byte offset 101 but the $@ is only 100 bytes. | tests.cpp:389:47:389:52 | call to malloc | array |
|
||||
| tests.cpp:397:3:397:13 | access to array | This array indexing operation accesses byte offset 101 but the $@ is only 101 bytes. | tests.cpp:390:47:390:52 | call to malloc | array |
|
||||
| tests.cpp:467:3:467:24 | access to array | This array indexing operation accesses a negative index -3 on the $@. | tests.cpp:465:7:465:14 | intArray | array |
|
||||
| tests.cpp:475:3:475:11 | access to array | This array indexing operation accesses a negative index -21 on the $@. | tests.cpp:471:7:471:11 | multi | array |
|
||||
| tests.cpp:477:3:477:11 | access to array | This array indexing operation accesses a negative index -21 on the $@. | tests.cpp:471:7:471:11 | multi | array |
|
||||
| tests.cpp:480:3:480:11 | access to array | This array indexing operation accesses byte offset 639 but the $@ is only 400 bytes. | tests.cpp:471:7:471:11 | multi | array |
|
||||
| tests.cpp:482:3:482:11 | access to array | This array indexing operation accesses byte offset 639 but the $@ is only 400 bytes. | tests.cpp:471:7:471:11 | multi | array |
|
||||
| tests.cpp:497:2:497:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:490:7:490:12 | buffer | array |
|
||||
| tests.cpp:498:2:498:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:490:7:490:12 | buffer | array |
|
||||
| tests.cpp:502:2:502:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:490:7:490:12 | buffer | array |
|
||||
| tests.cpp:508:2:508:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:494:21:494:26 | call to malloc | array |
|
||||
| tests.cpp:512:2:512:7 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:495:21:495:26 | call to malloc | array |
|
||||
| tests.cpp:540:3:540:8 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 10 bytes. | tests.cpp:523:15:523:20 | call to malloc | destination buffer |
|
||||
| tests.cpp:540:3:540:8 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 10 bytes. | tests.cpp:531:16:531:21 | call to malloc | destination buffer |
|
||||
| tests.cpp:562:6:562:10 | call to fread | This 'fread' operation may access 101 bytes but the $@ is only 100 bytes. | tests.cpp:553:7:553:16 | charBuffer | destination buffer |
|
||||
| tests.cpp:567:6:567:10 | call to fread | This 'fread' operation may access 400 bytes but the $@ is only 100 bytes. | tests.cpp:553:7:553:16 | charBuffer | destination buffer |
|
||||
| tests.cpp:590:6:590:15 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:586:7:586:12 | buffer | array |
|
||||
| tests.cpp:598:7:598:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:586:7:586:12 | buffer | array |
|
||||
| tests.cpp:658:6:658:15 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:654:7:654:12 | buffer | array |
|
||||
| tests.cpp:666:7:666:13 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:654:7:654:12 | buffer | array |
|
||||
| tests.cpp:729:3:729:8 | call to memset | This 'memset' operation accesses 24 bytes but the $@ is only 8 bytes. | tests.cpp:714:16:714:16 | c | destination buffer |
|
||||
| tests.cpp:733:3:733:8 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:714:16:714:16 | c | destination buffer |
|
||||
| tests.cpp:737:3:737:8 | call to memset | This 'memset' operation accesses 24 bytes but the $@ is only 16 bytes. | tests.cpp:713:16:713:16 | b | destination buffer |
|
||||
| tests.cpp:748:2:748:7 | call to memset | This 'memset' operation accesses 24 bytes but the $@ is only 8 bytes. | tests.cpp:714:16:714:16 | c | destination buffer |
|
||||
| tests.cpp:774:5:774:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:756:20:756:22 | b_1 | destination buffer |
|
||||
| tests.cpp:777:5:777:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:756:20:756:22 | b_1 | destination buffer |
|
||||
| tests.cpp:781:5:781:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:757:20:757:22 | c_1 | destination buffer |
|
||||
| tests.cpp:782:5:782:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 8 bytes. | tests.cpp:757:20:757:22 | c_1 | destination buffer |
|
||||
| tests.cpp:784:5:784:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:757:20:757:22 | c_1 | destination buffer |
|
||||
| tests.cpp:785:5:785:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 8 bytes. | tests.cpp:757:20:757:22 | c_1 | destination buffer |
|
||||
| tests.cpp:795:5:795:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:761:20:761:22 | b_2 | destination buffer |
|
||||
| tests.cpp:798:5:798:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:761:20:761:22 | b_2 | destination buffer |
|
||||
| tests.cpp:816:5:816:10 | call to memset | This 'memset' operation accesses 8 bytes but the $@ is only 4 bytes. | tests.cpp:811:16:811:16 | b | destination buffer |
|
||||
| tests.cpp:843:5:843:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 16 bytes. | tests.cpp:822:16:822:16 | b | destination buffer |
|
||||
| tests.cpp:846:5:846:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 16 bytes. | tests.cpp:822:16:822:16 | b | destination buffer |
|
||||
| tests.cpp:848:5:848:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 16 bytes. | tests.cpp:822:16:822:16 | b | destination buffer |
|
||||
| tests.cpp:851:5:851:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 12 bytes. | tests.cpp:823:16:823:16 | c | destination buffer |
|
||||
| tests.cpp:852:5:852:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 12 bytes. | tests.cpp:823:16:823:16 | c | destination buffer |
|
||||
| tests.cpp:854:5:854:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 12 bytes. | tests.cpp:823:16:823:16 | c | destination buffer |
|
||||
| tests.cpp:856:5:856:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 12 bytes. | tests.cpp:823:16:823:16 | c | destination buffer |
|
||||
| tests.cpp:867:5:867:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 8 bytes. | tests.cpp:828:16:828:16 | x | destination buffer |
|
||||
| tests.cpp:868:5:868:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 8 bytes. | tests.cpp:828:16:828:16 | x | destination buffer |
|
||||
| tests.cpp:869:5:869:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 8 bytes. | tests.cpp:828:16:828:16 | x | destination buffer |
|
||||
| tests.cpp:870:5:870:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 8 bytes. | tests.cpp:828:16:828:16 | x | destination buffer |
|
||||
| tests.cpp:872:5:872:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 8 bytes. | tests.cpp:828:16:828:16 | x | destination buffer |
|
||||
| tests.cpp:883:5:883:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 4 bytes. | tests.cpp:833:12:833:12 | u | destination buffer |
|
||||
| tests.cpp:884:5:884:10 | call to memset | This 'memset' operation accesses 16 bytes but the $@ is only 4 bytes. | tests.cpp:833:12:833:12 | u | destination buffer |
|
||||
| tests.cpp:885:5:885:10 | call to memset | This 'memset' operation accesses 12 bytes but the $@ is only 4 bytes. | tests.cpp:833:12:833:12 | u | destination buffer |
|
||||
| tests.cpp:886:5:886:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 4 bytes. | tests.cpp:833:12:833:12 | u | destination buffer |
|
||||
| tests.cpp:887:5:887:10 | call to memset | This 'memset' operation accesses 8 bytes but the $@ is only 4 bytes. | tests.cpp:833:12:833:12 | u | destination buffer |
|
||||
| tests.cpp:888:5:888:10 | call to memset | This 'memset' operation accesses 20 bytes but the $@ is only 4 bytes. | tests.cpp:833:12:833:12 | u | destination buffer |
|
||||
| tests.cpp:984:2:984:9 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:981:6:981:8 | arr | array |
|
||||
| tests.cpp:989:2:989:9 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:981:6:981:8 | arr | array |
|
||||
| tests.cpp:994:2:994:9 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:981:6:981:8 | arr | array |
|
||||
| tests.cpp:1001:2:1001:9 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:981:6:981:8 | arr | array |
|
||||
| tests.cpp:1009:2:1009:9 | access to array | This array indexing operation accesses a negative index -1 on the $@. | tests.cpp:981:6:981:8 | arr | array |
|
||||
| tests.cpp:1031:2:1031:7 | call to memset | This 'memset' operation accesses 130 bytes but the $@ is only 120 bytes. | tests.cpp:1020:12:1020:15 | arr1 | destination buffer |
|
||||
| tests.cpp:1050:2:1050:7 | call to memset | This 'memset' operation accesses 132 bytes but the $@ is only 128 bytes. | tests.cpp:1037:8:1037:14 | buffer1 | destination buffer |
|
||||
| tests.cpp:1052:2:1052:7 | call to memset | This 'memset' operation accesses 132 bytes but the $@ is only 64 bytes. | tests.cpp:1041:8:1041:14 | buffer2 | destination buffer |
|
||||
| tests.cpp:1055:2:1055:8 | call to strncpy | This 'strncpy' operation may access 131 bytes but the $@ is only 128 bytes. | tests.cpp:1037:8:1037:14 | buffer1 | destination buffer |
|
||||
| tests.cpp:1057:2:1057:8 | call to strncpy | This 'strncpy' operation may access 131 bytes but the $@ is only 64 bytes. | tests.cpp:1041:8:1041:14 | buffer2 | destination buffer |
|
||||
| tests_restrict.c:12:2:12:7 | call to memcpy | This 'memcpy' operation accesses 2 bytes but the $@ is only 1 byte. | tests_restrict.c:7:6:7:13 | smallbuf | source buffer |
|
||||
| unions.cpp:26:2:26:7 | call to memset | This 'memset' operation accesses 200 bytes but the $@ is only 100 bytes. | unions.cpp:21:10:21:11 | mu | destination buffer |
|
||||
| unions.cpp:30:2:30:7 | call to memset | This 'memset' operation accesses 200 bytes but the $@ is only 100 bytes. | unions.cpp:15:7:15:11 | small | destination buffer |
|
||||
@@ -88,5 +100,4 @@
|
||||
| var_size_struct.cpp:73:3:73:9 | call to strncpy | This 'strncpy' operation may access 1025 bytes but the $@ is only 1024 bytes. | var_size_struct.cpp:63:8:63:11 | data | destination buffer |
|
||||
| var_size_struct.cpp:87:3:87:19 | access to array | This array indexing operation accesses byte offset 67 but the $@ is only 64 bytes. | var_size_struct.cpp:78:7:78:14 | elements | array |
|
||||
| var_size_struct.cpp:99:3:99:8 | call to memset | This 'memset' operation accesses 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer |
|
||||
| var_size_struct.cpp:101:3:101:8 | call to memset | This 'memset' operation accesses 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer |
|
||||
| var_size_struct.cpp:103:3:103:9 | call to strncpy | This 'strncpy' operation may access 129 bytes but the $@ is only 128 bytes. | var_size_struct.cpp:92:8:92:10 | str | destination buffer |
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
| tests.cpp:163:3:163:11 | access to array | Potential buffer-overflow: counter 'k' <= 100 but 'buffer' has 100 elements. |
|
||||
| tests.cpp:164:8:164:16 | access to array | Potential buffer-overflow: counter 'k' <= 100 but 'buffer' has 100 elements. |
|
||||
| tests.cpp:245:42:245:42 | 6 | Potential buffer-overflow: 'global_array_5' has size 5 not 6. |
|
||||
| tests.cpp:349:2:349:14 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' may be accessed here. |
|
||||
| tests.cpp:350:17:350:29 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' may be accessed here. |
|
||||
| tests.cpp:351:2:351:14 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' may be accessed here. |
|
||||
| tests.cpp:352:17:352:29 | access to array | Potential buffer-overflow: 'charArray' has size 10 but 'charArray[10]' may be accessed here. |
|
||||
| tests.cpp:1055:26:1055:39 | ... - ... | Potential buffer-overflow: 'buffer1' has size 128 not 131. |
|
||||
| tests.cpp:1057:26:1057:39 | ... - ... | Potential buffer-overflow: 'buffer2' has size 64 not 131. |
|
||||
| var_size_struct.cpp:103:39:103:41 | 129 | Potential buffer-overflow: 'str' has size 128 not 129. |
|
||||
|
||||
@@ -27,26 +27,26 @@ edges
|
||||
| main.cpp:9:29:9:32 | *argv | tests_restrict.c:15:41:15:44 | *argv | provenance | |
|
||||
| main.cpp:9:29:9:32 | tests_restrict_main output argument | main.cpp:10:20:10:23 | **argv | provenance | |
|
||||
| main.cpp:9:29:9:32 | tests_restrict_main output argument | main.cpp:10:20:10:23 | *argv | provenance | |
|
||||
| main.cpp:10:20:10:23 | **argv | tests.cpp:872:32:872:35 | **argv | provenance | |
|
||||
| main.cpp:10:20:10:23 | *argv | tests.cpp:872:32:872:35 | *argv | provenance | |
|
||||
| main.cpp:10:20:10:23 | **argv | tests.cpp:1060:32:1060:35 | **argv | provenance | |
|
||||
| main.cpp:10:20:10:23 | *argv | tests.cpp:1060:32:1060:35 | *argv | provenance | |
|
||||
| overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:23:45:23:48 | **argv | provenance | |
|
||||
| overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:23:45:23:48 | *argv | provenance | |
|
||||
| test_buffer_overrun.cpp:32:46:32:49 | **argv | test_buffer_overrun.cpp:32:46:32:49 | **argv | provenance | |
|
||||
| test_buffer_overrun.cpp:32:46:32:49 | **argv | test_buffer_overrun.cpp:32:46:32:49 | *argv | provenance | |
|
||||
| test_buffer_overrun.cpp:32:46:32:49 | *argv | test_buffer_overrun.cpp:32:46:32:49 | *argv | provenance | |
|
||||
| tests.cpp:613:19:613:24 | *source | tests.cpp:615:17:615:22 | *source | provenance | |
|
||||
| tests.cpp:622:19:622:24 | *source | tests.cpp:625:2:625:16 | *... = ... | provenance | |
|
||||
| tests.cpp:625:2:625:2 | *s [post update] [*home] | tests.cpp:628:14:628:14 | *s [*home] | provenance | |
|
||||
| tests.cpp:625:2:625:16 | *... = ... | tests.cpp:625:2:625:2 | *s [post update] [*home] | provenance | |
|
||||
| tests.cpp:628:14:628:14 | *s [*home] | tests.cpp:628:14:628:19 | *home | provenance | |
|
||||
| tests.cpp:628:14:628:14 | *s [*home] | tests.cpp:628:16:628:19 | *home | provenance | |
|
||||
| tests.cpp:628:16:628:19 | *home | tests.cpp:628:14:628:19 | *home | provenance | |
|
||||
| tests.cpp:872:32:872:35 | **argv | tests.cpp:897:9:897:15 | *access to array | provenance | |
|
||||
| tests.cpp:872:32:872:35 | **argv | tests.cpp:898:9:898:15 | *access to array | provenance | |
|
||||
| tests.cpp:872:32:872:35 | *argv | tests.cpp:897:9:897:15 | *access to array | provenance | |
|
||||
| tests.cpp:872:32:872:35 | *argv | tests.cpp:898:9:898:15 | *access to array | provenance | |
|
||||
| tests.cpp:897:9:897:15 | *access to array | tests.cpp:613:19:613:24 | *source | provenance | |
|
||||
| tests.cpp:898:9:898:15 | *access to array | tests.cpp:622:19:622:24 | *source | provenance | |
|
||||
| tests.cpp:634:19:634:24 | *source | tests.cpp:636:17:636:22 | *source | provenance | |
|
||||
| tests.cpp:643:19:643:24 | *source | tests.cpp:646:2:646:16 | *... = ... | provenance | |
|
||||
| tests.cpp:646:2:646:2 | *s [post update] [*home] | tests.cpp:649:14:649:14 | *s [*home] | provenance | |
|
||||
| tests.cpp:646:2:646:16 | *... = ... | tests.cpp:646:2:646:2 | *s [post update] [*home] | provenance | |
|
||||
| tests.cpp:649:14:649:14 | *s [*home] | tests.cpp:649:14:649:19 | *home | provenance | |
|
||||
| tests.cpp:649:14:649:14 | *s [*home] | tests.cpp:649:16:649:19 | *home | provenance | |
|
||||
| tests.cpp:649:16:649:19 | *home | tests.cpp:649:14:649:19 | *home | provenance | |
|
||||
| tests.cpp:1060:32:1060:35 | **argv | tests.cpp:1085:9:1085:15 | *access to array | provenance | |
|
||||
| tests.cpp:1060:32:1060:35 | **argv | tests.cpp:1086:9:1086:15 | *access to array | provenance | |
|
||||
| tests.cpp:1060:32:1060:35 | *argv | tests.cpp:1085:9:1085:15 | *access to array | provenance | |
|
||||
| tests.cpp:1060:32:1060:35 | *argv | tests.cpp:1086:9:1086:15 | *access to array | provenance | |
|
||||
| tests.cpp:1085:9:1085:15 | *access to array | tests.cpp:634:19:634:24 | *source | provenance | |
|
||||
| tests.cpp:1086:9:1086:15 | *access to array | tests.cpp:643:19:643:24 | *source | provenance | |
|
||||
| tests_restrict.c:15:41:15:44 | **argv | tests_restrict.c:15:41:15:44 | **argv | provenance | |
|
||||
| tests_restrict.c:15:41:15:44 | *argv | tests_restrict.c:15:41:15:44 | *argv | provenance | |
|
||||
nodes
|
||||
@@ -72,18 +72,18 @@ nodes
|
||||
| test_buffer_overrun.cpp:32:46:32:49 | *argv | semmle.label | *argv |
|
||||
| test_buffer_overrun.cpp:32:46:32:49 | *argv | semmle.label | *argv |
|
||||
| test_buffer_overrun.cpp:32:46:32:49 | *argv | semmle.label | *argv |
|
||||
| tests.cpp:613:19:613:24 | *source | semmle.label | *source |
|
||||
| tests.cpp:615:17:615:22 | *source | semmle.label | *source |
|
||||
| tests.cpp:622:19:622:24 | *source | semmle.label | *source |
|
||||
| tests.cpp:625:2:625:2 | *s [post update] [*home] | semmle.label | *s [post update] [*home] |
|
||||
| tests.cpp:625:2:625:16 | *... = ... | semmle.label | *... = ... |
|
||||
| tests.cpp:628:14:628:14 | *s [*home] | semmle.label | *s [*home] |
|
||||
| tests.cpp:628:14:628:19 | *home | semmle.label | *home |
|
||||
| tests.cpp:628:16:628:19 | *home | semmle.label | *home |
|
||||
| tests.cpp:872:32:872:35 | **argv | semmle.label | **argv |
|
||||
| tests.cpp:872:32:872:35 | *argv | semmle.label | *argv |
|
||||
| tests.cpp:897:9:897:15 | *access to array | semmle.label | *access to array |
|
||||
| tests.cpp:898:9:898:15 | *access to array | semmle.label | *access to array |
|
||||
| tests.cpp:634:19:634:24 | *source | semmle.label | *source |
|
||||
| tests.cpp:636:17:636:22 | *source | semmle.label | *source |
|
||||
| tests.cpp:643:19:643:24 | *source | semmle.label | *source |
|
||||
| tests.cpp:646:2:646:2 | *s [post update] [*home] | semmle.label | *s [post update] [*home] |
|
||||
| tests.cpp:646:2:646:16 | *... = ... | semmle.label | *... = ... |
|
||||
| tests.cpp:649:14:649:14 | *s [*home] | semmle.label | *s [*home] |
|
||||
| tests.cpp:649:14:649:19 | *home | semmle.label | *home |
|
||||
| tests.cpp:649:16:649:19 | *home | semmle.label | *home |
|
||||
| tests.cpp:1060:32:1060:35 | **argv | semmle.label | **argv |
|
||||
| tests.cpp:1060:32:1060:35 | *argv | semmle.label | *argv |
|
||||
| tests.cpp:1085:9:1085:15 | *access to array | semmle.label | *access to array |
|
||||
| tests.cpp:1086:9:1086:15 | *access to array | semmle.label | *access to array |
|
||||
| tests_restrict.c:15:41:15:44 | **argv | semmle.label | **argv |
|
||||
| tests_restrict.c:15:41:15:44 | **argv | semmle.label | **argv |
|
||||
| tests_restrict.c:15:41:15:44 | *argv | semmle.label | *argv |
|
||||
@@ -97,5 +97,5 @@ subpaths
|
||||
| main.cpp:9:29:9:32 | **argv | tests_restrict.c:15:41:15:44 | **argv | tests_restrict.c:15:41:15:44 | **argv | main.cpp:9:29:9:32 | tests_restrict_main output argument |
|
||||
| main.cpp:9:29:9:32 | *argv | tests_restrict.c:15:41:15:44 | *argv | tests_restrict.c:15:41:15:44 | *argv | main.cpp:9:29:9:32 | tests_restrict_main output argument |
|
||||
#select
|
||||
| tests.cpp:615:2:615:7 | call to strcpy | main.cpp:6:27:6:30 | **argv | tests.cpp:615:17:615:22 | *source | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | **argv | a command-line argument |
|
||||
| tests.cpp:628:2:628:7 | call to strcpy | main.cpp:6:27:6:30 | **argv | tests.cpp:628:14:628:19 | *home | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | **argv | a command-line argument |
|
||||
| tests.cpp:636:2:636:7 | call to strcpy | main.cpp:6:27:6:30 | **argv | tests.cpp:636:17:636:22 | *source | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | **argv | a command-line argument |
|
||||
| tests.cpp:649:2:649:7 | call to strcpy | main.cpp:6:27:6:30 | **argv | tests.cpp:649:14:649:19 | *home | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | **argv | a command-line argument |
|
||||
|
||||
@@ -18,7 +18,7 @@ void test1()
|
||||
{
|
||||
char smallbuffer[10];
|
||||
char bigbuffer[20];
|
||||
|
||||
|
||||
memcpy(bigbuffer, smallbuffer, sizeof(smallbuffer)); // GOOD
|
||||
memcpy(bigbuffer, smallbuffer, sizeof(bigbuffer)); // BAD: over-read
|
||||
memcpy(smallbuffer, bigbuffer, sizeof(smallbuffer)); // GOOD
|
||||
@@ -29,7 +29,7 @@ void test2()
|
||||
{
|
||||
char *smallbuffer = (char *)malloc(sizeof(char) * 10);
|
||||
char *bigbuffer = (char *)malloc(sizeof(char) * 20);
|
||||
|
||||
|
||||
memcpy(bigbuffer, smallbuffer, sizeof(smallbuffer)); // GOOD
|
||||
memcpy(bigbuffer, smallbuffer, sizeof(bigbuffer)); // BAD: over-read [NOT DETECTED]
|
||||
memcpy(smallbuffer, bigbuffer, sizeof(smallbuffer)); // GOOD
|
||||
@@ -59,7 +59,7 @@ void test4(int unbounded)
|
||||
{
|
||||
int bounded = 100;
|
||||
char buffer1[100], buffer2[100];
|
||||
|
||||
|
||||
memmove(buffer1, buffer2, bounded); // GOOD
|
||||
memmove(buffer1, buffer2, unbounded); // BAD: may over-write [NOT DETECTED]
|
||||
}
|
||||
@@ -107,11 +107,11 @@ void test6(bool cond)
|
||||
a = -1;
|
||||
buffer[a] = 'x'; // BAD: under-write [NOT DETECTED]
|
||||
ch = buffer[a]; // BAD: under-read [NOT DETECTED]
|
||||
|
||||
|
||||
b = 0;
|
||||
buffer[b] = 'x'; // GOOD
|
||||
ch = buffer[b]; // GOOD
|
||||
|
||||
|
||||
c = 100;
|
||||
buffer[c] = 'x'; // BAD: over-write [NOT DETECTED]
|
||||
ch = buffer[c]; // BAD: over-read [NOT DETECTED]
|
||||
@@ -120,7 +120,7 @@ void test6(bool cond)
|
||||
d = 1000;
|
||||
buffer[d] = 'x'; // BAD: over-write [NOT DETECTED]
|
||||
ch = buffer[d]; // BAD: over-read [NOT DETECTED]
|
||||
|
||||
|
||||
e = 1000;
|
||||
e = 0;
|
||||
buffer[e] = 'x'; // GOOD
|
||||
@@ -130,12 +130,12 @@ void test6(bool cond)
|
||||
if (cond) {f = 1000;}
|
||||
buffer[f] = 'x'; // BAD: may over-write [NOT DETECTED]
|
||||
ch = buffer[f]; // BAD: may over-read [NOT DETECTED]
|
||||
|
||||
|
||||
g = 1000;
|
||||
if (cond) {g = 0;}
|
||||
buffer[g] = 'x'; // BAD: may over-write [NOT DETECTED]
|
||||
ch = buffer[g]; // BAD: may over-read [NOT DETECTED]
|
||||
|
||||
|
||||
h = 1000;
|
||||
if (cond)
|
||||
{
|
||||
@@ -151,13 +151,13 @@ void test6(bool cond)
|
||||
buffer[i] = 'x'; // GOOD
|
||||
ch = buffer[i]; // GOOD
|
||||
}
|
||||
|
||||
|
||||
for (j = -1; j < 100; j++)
|
||||
{
|
||||
buffer[j] = 'x'; // BAD: under-write [NOT DETECTED]
|
||||
ch = buffer[j]; // BAD: under-read [NOT DETECTED]
|
||||
}
|
||||
|
||||
|
||||
for (k = 0; k <= 100; k++)
|
||||
{
|
||||
buffer[k] = 'x'; // BAD: over-write
|
||||
@@ -187,7 +187,7 @@ void test8(int unbounded)
|
||||
{
|
||||
buffer[i] = 0; // GOOD
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < v2; i++)
|
||||
{
|
||||
buffer[i] = 0; // BAD: over-write [NOT DETECTED]
|
||||
@@ -226,7 +226,7 @@ void test9(int param)
|
||||
memset(buffer3, 0, 33); // BAD: overrun write of buffer3
|
||||
memset(buffer4, 0, 32); // GOOD
|
||||
memset(buffer4, 0, 33); // BAD: overrun write of buffer4 (buffer3)
|
||||
|
||||
|
||||
memcmp(buffer1, buffer2, 32); // GOOD
|
||||
memcmp(buffer1, buffer2, 33); // BAD: overrun read of buffer1, buffer2
|
||||
}
|
||||
@@ -274,7 +274,7 @@ void test11()
|
||||
memset(string, 0, 14); // GOOD
|
||||
memset(string, 0, 15); // BAD: overrun write of string
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
char *buffer = new char[128];
|
||||
|
||||
@@ -284,7 +284,7 @@ void test11()
|
||||
|
||||
memset(buffer, 0, 128); // BAD: overrun write of buffer
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
char array[10] = "123";
|
||||
|
||||
@@ -309,7 +309,7 @@ void test12()
|
||||
memset(&myVar, 0, sizeof(myVar)); // GOOD
|
||||
memset(&myVar, 0, sizeof(myVar) + 1); // BAD: overrun write of myVar
|
||||
memset(myVar.buffer, 0, 16); // GOOD
|
||||
memset(myVar.buffer, 0, 17); // BAD: overrun write of myVar.buffer
|
||||
memset(myVar.buffer, 0, 17); // DUBIOUS: overrun write of myVar.buffer, but not out of myVar itself [NOT DETECTED]
|
||||
memset(&(myVar.field), 0, sizeof(int)); // GOOD
|
||||
memset(&(myVar.field), 0, sizeof(int) * 2); // BAD: overrun write of myVar.field
|
||||
|
||||
@@ -317,7 +317,7 @@ void test12()
|
||||
memset(buf + 8, 0, 9); // BAD: overrun write of buf [NOT DETECTED]
|
||||
memset(dbuf + 8, 0, 8); // GOOD
|
||||
memset(dbuf + 8, 0, 9); // BAD: overrun write of dbuf [NOT DETECTED]
|
||||
|
||||
|
||||
{
|
||||
myStruct *myPtr1 = &myVar;
|
||||
myStruct *myPtr2;
|
||||
@@ -331,17 +331,19 @@ void test12()
|
||||
|
||||
{
|
||||
void *myPtr3 = (void *)(&myVar);
|
||||
|
||||
|
||||
memset(myPtr3, 0, sizeof(myStruct)); // GOOD
|
||||
memset(myPtr3, 0, sizeof(myStruct) + 1); // BAD: overrun write of myVar
|
||||
}
|
||||
}
|
||||
|
||||
void test13()
|
||||
void test13(char *argArray)
|
||||
{
|
||||
char charArray[10];
|
||||
int intArray[10];
|
||||
myStruct structArray[10];
|
||||
char *ptrArray = charArray;
|
||||
char *ptrArrayOffset = charArray + 1;
|
||||
|
||||
charArray[-1] = 1; // BAD: underrun write
|
||||
charArray[0] = 1; // GOOD
|
||||
@@ -363,7 +365,26 @@ void test13()
|
||||
|
||||
charArray[9] = (char)intArray[9]; // GOOD
|
||||
charArray[9] = (char)intArray[10]; // BAD: overrun read
|
||||
|
||||
|
||||
ptrArray[-2] = 1; // BAD: underrun write
|
||||
ptrArray[-1] = 1; // BAD: underrun write
|
||||
ptrArray[0] = 1; // GOOD
|
||||
ptrArray[8] = 1; // GOOD
|
||||
ptrArray[9] = 1; // GOOD
|
||||
ptrArray[10] = 1; // BAD: overrun write
|
||||
|
||||
ptrArrayOffset[-2] = 1; // BAD: underrun write [NOT DETECTED]
|
||||
ptrArrayOffset[-1] = 1; // GOOD (there is room for this)
|
||||
ptrArrayOffset[0] = 1; // GOOD
|
||||
ptrArrayOffset[8] = 1; // GOOD
|
||||
ptrArrayOffset[9] = 1; // BAD: overrun write [NOT DETECTED]
|
||||
ptrArrayOffset[10] = 1; // BAD: overrun write [NOT DETECTED]
|
||||
|
||||
argArray[-1] = 1; // BAD: underrun write [NOT DETECTED]
|
||||
argArray[0] = 1; // GOOD
|
||||
argArray[1] = 1; // GOOD (we can't tell the length of this array)
|
||||
argArray[999] = 1; // GOOD (we can't tell the length of this array)
|
||||
|
||||
{
|
||||
unsigned short *buffer1 = (unsigned short *)malloc(sizeof(short) * 50);
|
||||
unsigned short *buffer2 = (unsigned short *)malloc(101); // 50.5 shorts
|
||||
@@ -442,13 +463,13 @@ void test17(long long *longArray)
|
||||
|
||||
{
|
||||
int intArray[5];
|
||||
|
||||
|
||||
((char *)intArray)[-3] = 0; // BAD: underrun write
|
||||
}
|
||||
|
||||
{
|
||||
int multi[10][10];
|
||||
|
||||
|
||||
multi[5][5] = 0; // GOOD
|
||||
|
||||
multi[-5][5] = 0; // BAD: underrun write [INCORRECT MESSAGE]
|
||||
@@ -511,7 +532,7 @@ void test19(bool b)
|
||||
p2 = (char *)malloc(20);
|
||||
p3 = (char *)malloc(20);
|
||||
}
|
||||
|
||||
|
||||
// ...
|
||||
|
||||
if (b)
|
||||
@@ -663,7 +684,7 @@ void test27(){
|
||||
char buffer[MAX_SIZE];
|
||||
|
||||
strncpy(dest, src, 8); // GOOD, strncpy will not read past null terminator of source
|
||||
|
||||
|
||||
if(IND < MAX_SIZE){
|
||||
buffer[IND] = 0; // GOOD: out of bounds, but inaccessible code
|
||||
}
|
||||
@@ -739,7 +760,7 @@ struct AnonUnionInStruct
|
||||
unsigned int a_2;
|
||||
unsigned int b_2;
|
||||
};
|
||||
};
|
||||
};
|
||||
unsigned int d;
|
||||
|
||||
void test37() {
|
||||
@@ -869,6 +890,173 @@ struct S2 {
|
||||
}
|
||||
};
|
||||
|
||||
typedef int MyArray[10];
|
||||
|
||||
typedef struct _MyArrayArray {
|
||||
struct {
|
||||
int as[10];
|
||||
} bs[10];
|
||||
|
||||
union {
|
||||
int i;
|
||||
char cs[4];
|
||||
} ds[10];
|
||||
|
||||
struct {
|
||||
MyArray xs;
|
||||
} ys[10];
|
||||
} MyArrayArray;
|
||||
|
||||
void test26() {
|
||||
MyArrayArray maa;
|
||||
|
||||
maa.bs[0].as[-1] = 0; // BAD: underrun write [NOT DETECTED]
|
||||
maa.bs[0].as[0] = 0; // GOOD
|
||||
maa.bs[0].as[99] = 0; // GOOD (overflows into bs[9])
|
||||
maa.bs[0].as[100] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
maa.bs[1].as[-1] = 0; // GOOD (underflows into bs[0])
|
||||
maa.bs[1].as[0] = 0; // GOOD
|
||||
maa.bs[1].as[99] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
maa.bs[1].as[100] = 0; // BAD: overrun write[ NOT DETECTED]
|
||||
|
||||
maa.ds[0].i = 0; // GOOD
|
||||
maa.ds[9].i = 0; // GOOD
|
||||
maa.ds[10].i = 0; // BAD: overrun write [NOT DETECTED]
|
||||
maa.ds[0].cs[0] = 0; // GOOD
|
||||
maa.ds[0].cs[3] = 0; // GOOD
|
||||
maa.ds[0].cs[4] = 0; // GOOD (overflows into vs[1])
|
||||
maa.ds[0].cs[39] = 0; // GOOD (overflows into vs[9])
|
||||
maa.ds[0].cs[40] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
maa.ds[9].cs[0] = 0; // GOOD
|
||||
maa.ds[9].cs[3] = 0; // GOOD
|
||||
maa.ds[9].cs[4] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
|
||||
maa.ys[0].xs[-1] = 0; // BAD: underrun write [NOT DETECTED]
|
||||
maa.ys[0].xs[0] = 0; // GOOD
|
||||
maa.ys[0].xs[99] = 0; // GOOD (overflows into bs[9])
|
||||
maa.ys[0].xs[100] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
maa.ys[1].xs[-1] = 0; // GOOD (underflows into ys[0])
|
||||
maa.ys[1].xs[0] = 0; // GOOD
|
||||
maa.ys[1].xs[99] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
maa.ys[1].xs[100] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
|
||||
char zs[2][2];
|
||||
zs[0][-1] = 0; // BAD: underrun write [NOT DETECTED]
|
||||
zs[0][0] = 0; // GOOD
|
||||
zs[0][1] = 0; // GOOD
|
||||
zs[0][2] = 0; // GOOD
|
||||
zs[0][3] = 0; // GOOD
|
||||
zs[0][4] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
zs[1][-3] = 0; // BAD: underrun write [NOT DETECTED]
|
||||
zs[1][-2] = 0; // GOOD
|
||||
zs[1][-1] = 0; // GOOD
|
||||
zs[1][0] = 0; // GOOD
|
||||
zs[1][1] = 0; // GOOD
|
||||
zs[1][2] = 0; // BAD: overrun write [NOT DETECTED]
|
||||
}
|
||||
|
||||
struct Array10 {
|
||||
int values[10];
|
||||
};
|
||||
|
||||
void test27(size_t s) {
|
||||
Array10 arr;
|
||||
|
||||
if (s < sizeof(arr.values[10])) { // GOOD (harmless)
|
||||
// ...
|
||||
}
|
||||
|
||||
if (s < offsetof(Array10, values[10])) { // GOOD (harmless)
|
||||
// ...
|
||||
}
|
||||
|
||||
if (s < &(arr.values[10]) - &(arr.values[0])) { // GOOD (harmless)
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
bool cond();
|
||||
|
||||
void test28() {
|
||||
int arr[10];
|
||||
|
||||
int *ptr1 = arr;
|
||||
ptr1[-1] = 0; // BAD: underrun write
|
||||
ptr1++;
|
||||
ptr1[-1] = 0; // GOOD
|
||||
|
||||
int *ptr2 = arr;
|
||||
ptr2[-1] = 0; // BAD: underrun write
|
||||
*ptr2++;
|
||||
ptr2[-1] = 0; // GOOD
|
||||
|
||||
int *ptr3 = arr;
|
||||
ptr3[-1] = 0; // BAD: underrun write
|
||||
if (cond()) {
|
||||
ptr3++;
|
||||
}
|
||||
ptr3[-1] = 0; // GOOD (depending what cond() does)
|
||||
|
||||
int *ptr4 = arr;
|
||||
ptr4[-1] = 0; // BAD: underrun write
|
||||
while (true) {
|
||||
ptr4++;
|
||||
if (cond()) break;
|
||||
}
|
||||
ptr4[-1] = 0; // GOOD
|
||||
|
||||
int *ptr5 = arr;
|
||||
ptr5[-1] = 0; // BAD: underrun write
|
||||
while (true) {
|
||||
if (cond()) ptr5++;
|
||||
if (cond()) break;
|
||||
}
|
||||
ptr5[-1] = 0; // GOOD (depending what cond() does)
|
||||
}
|
||||
|
||||
typedef int myInt29;
|
||||
typedef myInt29 myArray29[10];
|
||||
struct _myStruct29 {
|
||||
myArray29 arr1;
|
||||
myInt29 arr2[20];
|
||||
};
|
||||
typedef _myStruct29 myStruct29;
|
||||
|
||||
void test29() {
|
||||
myStruct29 *ptr;
|
||||
|
||||
memset(ptr->arr1, 0, sizeof(ptr->arr1) + sizeof(ptr->arr2)); // GOOD (overwrites arr1, arr2)
|
||||
memset(&(ptr->arr1[0]), 0, sizeof(ptr->arr1) + sizeof(ptr->arr2)); // GOOD (overwrites arr1, arr2)
|
||||
|
||||
memset(ptr->arr1, 0, sizeof(ptr->arr1) + sizeof(ptr->arr2) + 10); // BAD
|
||||
}
|
||||
|
||||
struct UnionStruct {
|
||||
int a;
|
||||
union {
|
||||
char buffer1[64];
|
||||
int b;
|
||||
};
|
||||
union {
|
||||
char buffer2[64];
|
||||
int c;
|
||||
};
|
||||
};
|
||||
|
||||
void test30() {
|
||||
UnionStruct us;
|
||||
|
||||
memset(us.buffer1, 0, sizeof(us.buffer1)); // GOOD
|
||||
memset(us.buffer1, 0, sizeof(us)); // BAD
|
||||
memset(us.buffer2, 0, sizeof(us.buffer2)); // GOOD
|
||||
memset(us.buffer2, 0, sizeof(us)); // BAD
|
||||
|
||||
strncpy(us.buffer1, "", sizeof(us.buffer1) - 1); // GOOD
|
||||
strncpy(us.buffer1, "", sizeof(us) - 1); // BAD
|
||||
strncpy(us.buffer2, "", sizeof(us.buffer2) - 1); // GOOD
|
||||
strncpy(us.buffer2, "", sizeof(us) - 1); // BAD
|
||||
}
|
||||
|
||||
int tests_main(int argc, char *argv[])
|
||||
{
|
||||
long long arr17[19];
|
||||
@@ -896,6 +1084,11 @@ int tests_main(int argc, char *argv[])
|
||||
test23();
|
||||
test24(argv[0]);
|
||||
test25(argv[0]);
|
||||
test26();
|
||||
test27(argc);
|
||||
test28();
|
||||
test29();
|
||||
test30();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -96,9 +96,9 @@ void testNotVarStruct1() {
|
||||
notVarStruct1 *nvs1 = (notVarStruct1 *)malloc(sizeof(notVarStruct1) * 2);
|
||||
|
||||
memset(nvs1->str, 0, 128); // GOOD
|
||||
memset(nvs1->str, 0, 129); // BAD: buffer overflow
|
||||
memset(nvs1->str, 0, 129); // DUBIOUS: buffer overflow (overflows nvs1->str but not nvs1 overall)
|
||||
memset(nvs1[1].str, 0, 128); // GOOD
|
||||
memset(nvs1[1].str, 0, 129); // BAD: buffer overflow
|
||||
memset(nvs1[1].str, 0, 129); // BAD: buffer overflow [NOT DETECTED]
|
||||
strncpy(nvs1->str, "Hello, world!", 128); // GOOD
|
||||
strncpy(nvs1->str, "Hello, world!", 129); // BAD
|
||||
}
|
||||
|
||||
@@ -16,6 +16,17 @@
|
||||
| tests.c:136:2:136:8 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes. |
|
||||
| tests.c:186:3:186:9 | call to sprintf | This 'call to sprintf' operation requires 9 bytes but the destination is only 2 bytes. |
|
||||
| tests.c:189:3:189:9 | call to sprintf | This 'call to sprintf' operation requires 3 bytes but the destination is only 2 bytes. |
|
||||
| unions.c:26:2:26:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 16 bytes. |
|
||||
| unions.c:27:2:27:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 16 bytes. |
|
||||
| unions.c:26:2:26:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 15 bytes. |
|
||||
| unions.c:27:2:27:7 | call to strcpy | This 'call to strcpy' operation requires 21 bytes but the destination is only 15 bytes. |
|
||||
| var_size_struct.cpp:22:3:22:8 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 9 bytes. |
|
||||
| varbuffer.c:15:5:15:10 | call to strcpy | This 'call to strcpy' operation requires 2 bytes but the destination is only 1 bytes. |
|
||||
| varbuffer.c:16:5:16:10 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 1 bytes. |
|
||||
| varbuffer.c:23:5:23:10 | call to strcpy | This 'call to strcpy' operation requires 12 bytes but the destination is only 11 bytes. |
|
||||
| varbuffer.c:24:5:24:10 | call to strcpy | This 'call to strcpy' operation requires 17 bytes but the destination is only 11 bytes. |
|
||||
| varbuffer.c:39:5:39:10 | call to strcpy | This 'call to strcpy' operation requires 3 bytes but the destination is only 2 bytes. |
|
||||
| varbuffer.c:40:5:40:10 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 2 bytes. |
|
||||
| varbuffer.c:45:5:45:10 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 2 bytes. |
|
||||
| varbuffer.c:46:5:46:10 | call to strcpy | This 'call to strcpy' operation requires 17 bytes but the destination is only 2 bytes. |
|
||||
| varbuffer.c:60:5:60:10 | call to strcpy | This 'call to strcpy' operation requires 2 bytes but the destination is only 1 bytes. |
|
||||
| varbuffer.c:61:5:61:10 | call to strcpy | This 'call to strcpy' operation requires 10 bytes but the destination is only 1 bytes. |
|
||||
| varbuffer.c:67:5:67:10 | call to strcpy | This 'call to strcpy' operation requires 17 bytes but the destination is only 11 bytes. |
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// Further test cases for CWE-120.
|
||||
|
||||
typedef unsigned long size_t;
|
||||
|
||||
typedef struct _MyVarStruct {
|
||||
size_t len;
|
||||
char buffer[1]; // variable size buffer
|
||||
} MyVarStruct;
|
||||
|
||||
void testMyVarStruct()
|
||||
{
|
||||
MyVarStruct *ptr1 = (MyVarStruct*)malloc(sizeof(MyVarStruct));
|
||||
ptr1->len = 0;
|
||||
strcpy(ptr1->buffer, ""); // GOOD
|
||||
strcpy(ptr1->buffer, "1"); // BAD: length 2, but destination only has length 1
|
||||
strcpy(ptr1->buffer, "123456789"); // BAD: length 10, but destination only has length 1
|
||||
// ...
|
||||
|
||||
MyVarStruct *ptr2 = (MyVarStruct*)malloc(sizeof(MyVarStruct) + (sizeof(char) * 10));
|
||||
ptr2->len = 10;
|
||||
strcpy(ptr2->buffer, "123456789"); // GOOD
|
||||
strcpy(ptr2->buffer, "1234567890"); // GOOD
|
||||
strcpy(ptr2->buffer, "1234567890a"); // BAD: length 12, but destination only has length 11
|
||||
strcpy(ptr2->buffer, "1234567890abcdef"); // BAD: length 17, but destination only has length 11
|
||||
// ...
|
||||
}
|
||||
|
||||
typedef struct MyFixedStruct1 {
|
||||
int len;
|
||||
char buffer[2]; // assumed to be a fixed size buffer
|
||||
} MyFixedStruct1;
|
||||
|
||||
void testMyFixedStruct()
|
||||
{
|
||||
MyFixedStruct1 *ptr1 = (MyFixedStruct1 *)malloc(sizeof(MyFixedStruct1));
|
||||
ptr1->len = 1;
|
||||
strcpy(ptr1->buffer, ""); // GOOD
|
||||
strcpy(ptr1->buffer, "1"); // GOOD
|
||||
strcpy(ptr1->buffer, "12"); // BAD: length 3, but destination only has length 2
|
||||
strcpy(ptr1->buffer, "123456789"); // BAD: length 10, but destination only has length 2
|
||||
// ...
|
||||
|
||||
MyFixedStruct1 *ptr2 = (MyFixedStruct1*)malloc(sizeof(MyFixedStruct1) + (sizeof(char) * 10));
|
||||
ptr2->len = 11;
|
||||
strcpy(ptr2->buffer, "123456789"); // BAD / DUBIOUS: length 10, but destination only has length 2
|
||||
strcpy(ptr2->buffer, "1234567890abcdef"); // BAD: length 17, but destination only has length 2
|
||||
// ...
|
||||
}
|
||||
|
||||
typedef struct _MyFixedStruct2 {
|
||||
char buffer[1]; // fixed size buffer
|
||||
size_t len;
|
||||
} MyFixedStruct2;
|
||||
|
||||
void testMyFixedStruct2()
|
||||
{
|
||||
MyFixedStruct2 *ptr1 = (MyFixedStruct2 *)malloc(sizeof(MyFixedStruct2));
|
||||
ptr1->len = 1;
|
||||
strcpy(ptr1->buffer, ""); // GOOD
|
||||
strcpy(ptr1->buffer, "1"); // BAD: length 2, but destination only has length 1
|
||||
strcpy(ptr1->buffer, "123456789"); // BAD: length 10, but destination only has length 1
|
||||
// ...
|
||||
|
||||
MyFixedStruct2 *ptr2 = (MyFixedStruct2*)malloc(sizeof(MyFixedStruct2) + (sizeof(char) * 10));
|
||||
ptr2->len = 11;
|
||||
strcpy(ptr2->buffer, "123456789"); // BAD: length 10, but destination only has length 1 [NOT DETECTED]
|
||||
strcpy(ptr2->buffer, "1234567890abcdef"); // BAD: length 17, but destination only has length 1
|
||||
// ...
|
||||
}
|
||||
@@ -1,12 +1,21 @@
|
||||
edges
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:100:13:100:60 | ... = ... | provenance | |
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | provenance | |
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:100:13:100:60 | ... = ... | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | provenance | |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:37:21:37:43 | ... = ... | provenance | |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:44:17:44:37 | ... = ... | provenance | |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | *data | provenance | |
|
||||
| char_console_fprintf_01_bad.c:37:21:37:43 | ... = ... | char_console_fprintf_01_bad.c:49:21:49:24 | *data | provenance | |
|
||||
| char_console_fprintf_01_bad.c:44:17:44:37 | ... = ... | char_console_fprintf_01_bad.c:49:21:49:24 | *data | provenance | |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | provenance | |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | *data | provenance | TaintFunction |
|
||||
nodes
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | semmle.label | recv output argument |
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:100:13:100:60 | ... = ... | semmle.label | ... = ... |
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | *data | semmle.label | *data |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | semmle.label | fgets output argument |
|
||||
| char_console_fprintf_01_bad.c:37:21:37:43 | ... = ... | semmle.label | ... = ... |
|
||||
| char_console_fprintf_01_bad.c:44:17:44:37 | ... = ... | semmle.label | ... = ... |
|
||||
| char_console_fprintf_01_bad.c:49:21:49:24 | *data | semmle.label | *data |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | semmle.label | *call to getenv |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | *call to getenv | semmle.label | *call to getenv |
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
edges
|
||||
| consts.cpp:24:7:24:9 | **gv1 | consts.cpp:24:7:24:9 | **gv1 | provenance | |
|
||||
| consts.cpp:24:7:24:9 | **gv1 | consts.cpp:25:2:25:4 | *a | provenance | |
|
||||
| consts.cpp:24:7:24:9 | **gv1 | consts.cpp:30:9:30:14 | *access to array | provenance | |
|
||||
| consts.cpp:24:7:24:9 | **gv1 | consts.cpp:123:2:123:12 | *... = ... | provenance | |
|
||||
| consts.cpp:25:2:25:4 | *a | consts.cpp:26:2:26:4 | *b | provenance | |
|
||||
| consts.cpp:26:2:26:4 | *b | consts.cpp:24:7:24:9 | **gv1 | provenance | |
|
||||
| consts.cpp:29:7:29:25 | **nonConstFuncToArray | consts.cpp:126:9:126:30 | *call to nonConstFuncToArray | provenance | |
|
||||
| consts.cpp:30:9:30:14 | *access to array | consts.cpp:29:7:29:25 | **nonConstFuncToArray | provenance | |
|
||||
| consts.cpp:85:7:85:8 | gets output argument | consts.cpp:86:9:86:10 | *v1 | provenance | |
|
||||
@@ -25,8 +28,7 @@ edges
|
||||
| consts.cpp:106:13:106:19 | *call to varFunc | consts.cpp:107:9:107:10 | *v5 | provenance | |
|
||||
| consts.cpp:111:2:111:15 | *... = ... | consts.cpp:112:9:112:10 | *v6 | provenance | |
|
||||
| consts.cpp:111:7:111:13 | *call to varFunc | consts.cpp:111:2:111:15 | *... = ... | provenance | |
|
||||
| consts.cpp:115:17:115:18 | *v1 | consts.cpp:116:9:116:13 | *access to array | provenance | |
|
||||
| consts.cpp:115:17:115:18 | *v1 | consts.cpp:120:2:120:11 | *... = ... | provenance | |
|
||||
| consts.cpp:115:17:115:18 | *v1 | consts.cpp:115:21:115:22 | *v2 | provenance | |
|
||||
| consts.cpp:115:21:115:22 | *v2 | consts.cpp:116:9:116:13 | *access to array | provenance | |
|
||||
| consts.cpp:115:21:115:22 | *v2 | consts.cpp:120:2:120:11 | *... = ... | provenance | |
|
||||
| consts.cpp:120:2:120:11 | *... = ... | consts.cpp:121:9:121:10 | *v8 | provenance | |
|
||||
@@ -36,6 +38,8 @@ edges
|
||||
| consts.cpp:144:16:144:18 | readStringRef output argument | consts.cpp:145:9:145:11 | *v12 | provenance | |
|
||||
nodes
|
||||
| consts.cpp:24:7:24:9 | **gv1 | semmle.label | **gv1 |
|
||||
| consts.cpp:25:2:25:4 | *a | semmle.label | *a |
|
||||
| consts.cpp:26:2:26:4 | *b | semmle.label | *b |
|
||||
| consts.cpp:29:7:29:25 | **nonConstFuncToArray | semmle.label | **nonConstFuncToArray |
|
||||
| consts.cpp:30:9:30:14 | *access to array | semmle.label | *access to array |
|
||||
| consts.cpp:85:7:85:8 | gets output argument | semmle.label | gets output argument |
|
||||
|
||||
@@ -27,6 +27,10 @@ edges
|
||||
| test.cpp:53:5:53:23 | ... = ... | test.cpp:51:33:51:35 | *end | provenance | |
|
||||
| test.cpp:53:12:53:23 | ... + ... | test.cpp:53:5:53:23 | ... = ... | provenance | |
|
||||
| test.cpp:60:34:60:37 | mk_array output argument | test.cpp:67:9:67:14 | ... = ... | provenance | Config |
|
||||
| test.cpp:60:34:60:37 | mk_array output argument | test.cpp:67:9:67:14 | ... = ... | provenance | Config |
|
||||
| test.cpp:66:37:66:39 | *++ ... | test.cpp:67:9:67:14 | ... = ... | provenance | |
|
||||
| test.cpp:66:37:66:39 | *++ ... | test.cpp:67:9:67:14 | ... = ... | provenance | |
|
||||
| test.cpp:67:9:67:14 | ... = ... | test.cpp:66:37:66:39 | *++ ... | provenance | |
|
||||
| test.cpp:205:15:205:33 | call to malloc | test.cpp:205:15:205:33 | call to malloc | provenance | |
|
||||
| test.cpp:205:15:205:33 | call to malloc | test.cpp:206:17:206:23 | ... + ... | provenance | Config |
|
||||
| test.cpp:206:17:206:23 | ... + ... | test.cpp:206:17:206:23 | ... + ... | provenance | |
|
||||
@@ -47,6 +51,11 @@ edges
|
||||
| test.cpp:271:14:271:21 | ... + ... | test.cpp:271:14:271:21 | ... + ... | provenance | |
|
||||
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... | provenance | Config |
|
||||
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... | provenance | Config |
|
||||
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... | provenance | Config |
|
||||
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... | provenance | Config |
|
||||
| test.cpp:272:31:272:33 | *... ++ | test.cpp:274:5:274:10 | ... = ... | provenance | |
|
||||
| test.cpp:272:31:272:33 | *... ++ | test.cpp:274:5:274:10 | ... = ... | provenance | |
|
||||
| test.cpp:274:5:274:10 | ... = ... | test.cpp:272:31:272:33 | *... ++ | provenance | |
|
||||
| test.cpp:355:14:355:27 | new[] | test.cpp:355:14:355:27 | new[] | provenance | |
|
||||
| test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:23 | ... + ... | provenance | Config |
|
||||
| test.cpp:356:15:356:23 | ... + ... | test.cpp:356:15:356:23 | ... + ... | provenance | |
|
||||
@@ -114,9 +123,18 @@ edges
|
||||
| test.cpp:794:5:794:24 | ... = ... | test.cpp:792:60:792:62 | *end | provenance | |
|
||||
| test.cpp:794:12:794:24 | ... + ... | test.cpp:794:5:794:24 | ... = ... | provenance | |
|
||||
| test.cpp:800:40:800:43 | mk_array_no_field_flow output argument | test.cpp:807:7:807:12 | ... = ... | provenance | Config |
|
||||
| test.cpp:800:40:800:43 | mk_array_no_field_flow output argument | test.cpp:807:7:807:12 | ... = ... | provenance | Config |
|
||||
| test.cpp:806:35:806:37 | *++ ... | test.cpp:807:7:807:12 | ... = ... | provenance | |
|
||||
| test.cpp:806:35:806:37 | *++ ... | test.cpp:807:7:807:12 | ... = ... | provenance | |
|
||||
| test.cpp:807:7:807:12 | ... = ... | test.cpp:806:35:806:37 | *++ ... | provenance | |
|
||||
| test.cpp:815:52:815:54 | end | test.cpp:815:52:815:54 | end | provenance | |
|
||||
| test.cpp:815:52:815:54 | end | test.cpp:821:7:821:12 | ... = ... | provenance | Config |
|
||||
| test.cpp:815:52:815:54 | end | test.cpp:821:7:821:12 | ... = ... | provenance | Config |
|
||||
| test.cpp:815:52:815:54 | end | test.cpp:821:7:821:12 | ... = ... | provenance | Config |
|
||||
| test.cpp:815:52:815:54 | end | test.cpp:821:7:821:12 | ... = ... | provenance | Config |
|
||||
| test.cpp:820:35:820:37 | *++ ... | test.cpp:821:7:821:12 | ... = ... | provenance | |
|
||||
| test.cpp:820:35:820:37 | *++ ... | test.cpp:821:7:821:12 | ... = ... | provenance | |
|
||||
| test.cpp:821:7:821:12 | ... = ... | test.cpp:820:35:820:37 | *++ ... | provenance | |
|
||||
| test.cpp:832:40:832:43 | mk_array_no_field_flow output argument | test.cpp:833:37:833:39 | end | provenance | |
|
||||
| test.cpp:833:37:833:39 | end | test.cpp:815:52:815:54 | end | provenance | |
|
||||
| test.cpp:841:18:841:35 | call to malloc | test.cpp:841:18:841:35 | call to malloc | provenance | |
|
||||
@@ -157,6 +175,8 @@ nodes
|
||||
| test.cpp:53:5: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:66:37:66:39 | *++ ... | semmle.label | *++ ... |
|
||||
| test.cpp:67:9:67:14 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:67:9:67:14 | ... = ... | 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 |
|
||||
@@ -174,6 +194,8 @@ nodes
|
||||
| test.cpp:270:13:270:24 | new[] | semmle.label | new[] |
|
||||
| test.cpp:271:14:271:21 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:271:14:271:21 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:272:31:272:33 | *... ++ | semmle.label | *... ++ |
|
||||
| test.cpp:274:5:274:10 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:274:5:274:10 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:355:14:355:27 | new[] | semmle.label | new[] |
|
||||
| test.cpp:355:14:355:27 | new[] | semmle.label | new[] |
|
||||
@@ -240,9 +262,13 @@ nodes
|
||||
| test.cpp:794:5: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:806:35:806:37 | *++ ... | semmle.label | *++ ... |
|
||||
| test.cpp:807:7:807:12 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:807:7:807:12 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:815:52:815:54 | end | semmle.label | end |
|
||||
| test.cpp:815:52:815:54 | end | semmle.label | end |
|
||||
| test.cpp:820:35:820:37 | *++ ... | semmle.label | *++ ... |
|
||||
| test.cpp:821:7:821:12 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:821:7:821:12 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:832:40:832:43 | mk_array_no_field_flow output argument | semmle.label | mk_array_no_field_flow output argument |
|
||||
| test.cpp:833:37:833:39 | end | semmle.label | end |
|
||||
|
||||
@@ -16,7 +16,8 @@ edges
|
||||
| test3.cpp:138:24:138:32 | password1 | test3.cpp:138:21:138:22 | call to id | provenance | |
|
||||
| test3.cpp:144:16:144:29 | call to get_global_str | test3.cpp:144:16:144:29 | call to get_global_str | provenance | |
|
||||
| test3.cpp:144:16:144:29 | call to get_global_str | test3.cpp:146:15:146:18 | data | provenance | |
|
||||
| test3.cpp:157:19:157:26 | password | test3.cpp:159:15:159:20 | *buffer | provenance | TaintFunction |
|
||||
| test3.cpp:157:19:157:26 | password | test3.cpp:158:3:158:16 | ... = ... | provenance | TaintFunction |
|
||||
| test3.cpp:158:3:158:16 | ... = ... | test3.cpp:159:15:159:20 | *buffer | provenance | |
|
||||
| test3.cpp:270:16:270:23 | password | test3.cpp:272:15:272:18 | *data | provenance | DataFlowFunction |
|
||||
| test3.cpp:278:20:278:23 | data | test3.cpp:280:14:280:17 | data | provenance | |
|
||||
| test3.cpp:283:20:283:23 | data | test3.cpp:285:14:285:17 | data | provenance | |
|
||||
@@ -70,6 +71,7 @@ nodes
|
||||
| test3.cpp:144:16:144:29 | call to get_global_str | semmle.label | call to get_global_str |
|
||||
| test3.cpp:146:15:146:18 | data | semmle.label | data |
|
||||
| test3.cpp:157:19:157:26 | password | semmle.label | password |
|
||||
| test3.cpp:158:3:158:16 | ... = ... | semmle.label | ... = ... |
|
||||
| test3.cpp:159:15:159:20 | *buffer | semmle.label | *buffer |
|
||||
| test3.cpp:173:15:173:22 | password | semmle.label | password |
|
||||
| test3.cpp:181:15:181:22 | password | semmle.label | password |
|
||||
|
||||
@@ -42,5 +42,5 @@ MySql.Data.MySqlClient,48,,,,,,,,,,,,48,,,,,,,,,,
|
||||
Newtonsoft.Json,,,91,,,,,,,,,,,,,,,,,,,73,18
|
||||
ServiceStack,194,,7,27,,,,,75,,,,92,,,,,,,,,7,
|
||||
SourceGenerators,,,5,,,,,,,,,,,,,,,,,,,,5
|
||||
System,54,47,12221,,6,5,5,,,4,1,,33,2,,6,15,17,4,3,,5921,6300
|
||||
System,54,47,12241,,6,5,5,,,4,1,,33,2,,6,15,17,4,3,,5941,6300
|
||||
Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,,,,,,,,
|
||||
|
||||
|
@@ -8,7 +8,7 @@ C# framework & library support
|
||||
|
||||
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting`
|
||||
`ServiceStack <https://servicestack.net/>`_,"``ServiceStack.*``, ``ServiceStack``",,7,194,
|
||||
System,"``System.*``, ``System``",47,12221,54,5
|
||||
System,"``System.*``, ``System``",47,12241,54,5
|
||||
Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.AspNetCore.Components``, ``Microsoft.AspNetCore.Http``, ``Microsoft.AspNetCore.Mvc``, ``Microsoft.AspNetCore.WebUtilities``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.DotNet.Build.Tasks``, ``Microsoft.DotNet.PlatformAbstractions``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.JSInterop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.VisualBasic``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",60,2272,152,4
|
||||
Totals,,107,14500,400,9
|
||||
Totals,,107,14520,400,9
|
||||
|
||||
|
||||
@@ -1,14 +1,30 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Semmle.Util;
|
||||
using Semmle.Util.Logging;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
public class DependabotProxy : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents configurations for package registries.
|
||||
/// </summary>
|
||||
public struct RegistryConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of package registry.
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
/// <summary>
|
||||
/// The URL of the package registry.
|
||||
/// </summary>
|
||||
public string URL { get; set; }
|
||||
}
|
||||
|
||||
private readonly string host;
|
||||
private readonly string port;
|
||||
|
||||
@@ -17,6 +33,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// </summary>
|
||||
internal string Address { get; }
|
||||
/// <summary>
|
||||
/// The URLs of package registries that are configured for the proxy.
|
||||
/// </summary>
|
||||
internal HashSet<string> RegistryURLs { get; }
|
||||
/// <summary>
|
||||
/// The path to the temporary file where the certificate is stored.
|
||||
/// </summary>
|
||||
internal string? CertificatePath { get; private set; }
|
||||
@@ -67,6 +87,39 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
result.Certificate = X509Certificate2.CreateFromPem(cert);
|
||||
}
|
||||
|
||||
// Try to obtain the list of private registry URLs.
|
||||
var registryURLs = Environment.GetEnvironmentVariable(EnvironmentVariableNames.ProxyURLs);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(registryURLs))
|
||||
{
|
||||
try
|
||||
{
|
||||
// The value of the environment variable should be a JSON array of objects, such as:
|
||||
// [ { "type": "nuget_feed", "url": "https://nuget.pkg.github.com/org/index.json" } ]
|
||||
var array = JsonConvert.DeserializeObject<List<RegistryConfig>>(registryURLs);
|
||||
if (array != null)
|
||||
{
|
||||
foreach (RegistryConfig config in array)
|
||||
{
|
||||
// The array contains all configured private registries, not just ones for C#.
|
||||
// We ignore the non-C# ones here.
|
||||
if (!config.Type.Equals("nuget_feed"))
|
||||
{
|
||||
logger.LogDebug($"Ignoring registry at '{config.URL}' since it is not of type 'nuget_feed'.");
|
||||
continue;
|
||||
}
|
||||
|
||||
logger.LogInfo($"Found private registry at '{config.URL}'");
|
||||
result.RegistryURLs.Add(config.URL);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
logger.LogError($"Unable to parse '{EnvironmentVariableNames.ProxyURLs}': {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -75,6 +128,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.Address = $"http://{this.host}:{this.port}";
|
||||
this.RegistryURLs = new HashSet<string>();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using System.Text;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using Semmle.Util;
|
||||
@@ -67,6 +67,19 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
args += $" --configfile \"{restoreSettings.PathToNugetConfig}\"";
|
||||
}
|
||||
|
||||
// Add package sources. If any are present, they override all sources specified in
|
||||
// the configuration file(s).
|
||||
if (restoreSettings.Sources != null)
|
||||
{
|
||||
var feedArgs = new StringBuilder();
|
||||
foreach (string source in restoreSettings.Sources)
|
||||
{
|
||||
feedArgs.Append($" -s {source}");
|
||||
}
|
||||
|
||||
args += feedArgs.ToString();
|
||||
}
|
||||
|
||||
if (restoreSettings.ForceReevaluation)
|
||||
{
|
||||
args += " --force";
|
||||
|
||||
@@ -89,5 +89,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// Contains the certificate used by the Dependabot proxy.
|
||||
/// </summary>
|
||||
public const string ProxyCertificate = "CODEQL_PROXY_CA_CERTIFICATE";
|
||||
|
||||
/// <summary>
|
||||
/// Contains the URLs of private nuget registries as a JSON array.
|
||||
/// </summary>
|
||||
public const string ProxyURLs = "CODEQL_PROXY_URLS";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
IList<string> GetNugetFeedsFromFolder(string folderPath);
|
||||
}
|
||||
|
||||
public record class RestoreSettings(string File, string PackageDirectory, bool ForceDotnetRefAssemblyFetching, string? PathToNugetConfig = null, bool ForceReevaluation = false, bool TargetWindows = false);
|
||||
public record class RestoreSettings(string File, string PackageDirectory, bool ForceDotnetRefAssemblyFetching, IList<string>? Sources = null, string? PathToNugetConfig = null, bool ForceReevaluation = false, bool TargetWindows = false);
|
||||
|
||||
public partial record class RestoreResult(bool Success, IList<string> Output)
|
||||
{
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
if (checkNugetFeedResponsiveness && !CheckFeeds(out explicitFeeds))
|
||||
{
|
||||
// todo: we could also check the reachability of the inherited nuget feeds, but to use those in the fallback we would need to handle authentication too.
|
||||
var unresponsiveMissingPackageLocation = DownloadMissingPackagesFromSpecificFeeds(explicitFeeds);
|
||||
var unresponsiveMissingPackageLocation = DownloadMissingPackagesFromSpecificFeeds([], explicitFeeds);
|
||||
return unresponsiveMissingPackageLocation is null
|
||||
? []
|
||||
: [unresponsiveMissingPackageLocation];
|
||||
@@ -156,7 +156,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
|
||||
var restoredProjects = RestoreSolutions(out var container);
|
||||
var projects = fileProvider.Projects.Except(restoredProjects);
|
||||
RestoreProjects(projects, out var containers);
|
||||
RestoreProjects(projects, explicitFeeds, out var containers);
|
||||
|
||||
var dependencies = containers.Flatten(container);
|
||||
|
||||
@@ -166,11 +166,11 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
.ToList();
|
||||
assemblyLookupLocations.UnionWith(paths.Select(p => new AssemblyLookupLocation(p)));
|
||||
|
||||
LogAllUnusedPackages(dependencies);
|
||||
var usedPackageNames = GetAllUsedPackageDirNames(dependencies);
|
||||
|
||||
var missingPackageLocation = checkNugetFeedResponsiveness
|
||||
? DownloadMissingPackagesFromSpecificFeeds(explicitFeeds)
|
||||
: DownloadMissingPackages();
|
||||
? DownloadMissingPackagesFromSpecificFeeds(usedPackageNames, explicitFeeds)
|
||||
: DownloadMissingPackages(usedPackageNames);
|
||||
|
||||
if (missingPackageLocation is not null)
|
||||
{
|
||||
@@ -260,8 +260,24 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// Populates dependencies with the relative paths to the assets files generated by the restore.
|
||||
/// </summary>
|
||||
/// <param name="projects">A list of paths to project files.</param>
|
||||
private void RestoreProjects(IEnumerable<string> projects, out ConcurrentBag<DependencyContainer> dependencies)
|
||||
private void RestoreProjects(IEnumerable<string> projects, HashSet<string>? configuredSources, out ConcurrentBag<DependencyContainer> dependencies)
|
||||
{
|
||||
// Conservatively, we only set this to a non-null value if a Dependabot proxy is enabled.
|
||||
// This ensures that we continue to get the old behaviour where feeds are taken from
|
||||
// `nuget.config` files instead of the command-line arguments.
|
||||
HashSet<string>? sources = null;
|
||||
|
||||
if (this.dependabotProxy != null)
|
||||
{
|
||||
// If the Dependabot proxy is configured, then our main goal is to make `dotnet` aware
|
||||
// of the private registry feeds. However, since providing them as command-line arguments
|
||||
// to `dotnet` ignores other feeds that may be configured, we also need to add the feeds
|
||||
// we have discovered from analysing `nuget.config` files.
|
||||
sources = configuredSources ?? new();
|
||||
sources.Add(PublicNugetOrgFeed);
|
||||
this.dependabotProxy?.RegistryURLs.ForEach(url => sources.Add(url));
|
||||
}
|
||||
|
||||
var successCount = 0;
|
||||
var nugetSourceFailures = 0;
|
||||
ConcurrentBag<DependencyContainer> collectedDependencies = [];
|
||||
@@ -276,7 +292,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
foreach (var project in projectGroup)
|
||||
{
|
||||
logger.LogInfo($"Restoring project {project}...");
|
||||
var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, TargetWindows: isWindows));
|
||||
var res = dotnet.Restore(new(project, PackageDirectory.DirInfo.FullName, ForceDotnetRefAssemblyFetching: true, sources?.ToList(), TargetWindows: isWindows));
|
||||
assets.AddDependenciesRange(res.AssetsFilePaths);
|
||||
lock (sync)
|
||||
{
|
||||
@@ -297,21 +313,21 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
compilationInfoContainer.CompilationInfos.Add(("Failed project restore with package source error", nugetSourceFailures.ToString()));
|
||||
}
|
||||
|
||||
private AssemblyLookupLocation? DownloadMissingPackagesFromSpecificFeeds(HashSet<string>? feedsFromNugetConfigs)
|
||||
private AssemblyLookupLocation? DownloadMissingPackagesFromSpecificFeeds(IEnumerable<string> usedPackageNames, HashSet<string>? feedsFromNugetConfigs)
|
||||
{
|
||||
var reachableFallbackFeeds = GetReachableFallbackNugetFeeds(feedsFromNugetConfigs);
|
||||
if (reachableFallbackFeeds.Count > 0)
|
||||
{
|
||||
return DownloadMissingPackages(fallbackNugetFeeds: reachableFallbackFeeds);
|
||||
return DownloadMissingPackages(usedPackageNames, fallbackNugetFeeds: reachableFallbackFeeds);
|
||||
}
|
||||
|
||||
logger.LogWarning("Skipping download of missing packages from specific feeds as no fallback Nuget feeds are reachable.");
|
||||
return null;
|
||||
}
|
||||
|
||||
private AssemblyLookupLocation? DownloadMissingPackages(IEnumerable<string>? fallbackNugetFeeds = null)
|
||||
private AssemblyLookupLocation? DownloadMissingPackages(IEnumerable<string> usedPackageNames, IEnumerable<string>? fallbackNugetFeeds = null)
|
||||
{
|
||||
var alreadyDownloadedPackages = GetRestoredPackageDirectoryNames(PackageDirectory.DirInfo);
|
||||
var alreadyDownloadedPackages = usedPackageNames.Select(p => p.ToLowerInvariant());
|
||||
var alreadyDownloadedLegacyPackages = GetRestoredLegacyPackageNames();
|
||||
|
||||
var notYetDownloadedPackages = new HashSet<PackageReference>(fileContent.AllPackages);
|
||||
@@ -418,17 +434,23 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
return nugetConfig;
|
||||
}
|
||||
|
||||
private void LogAllUnusedPackages(DependencyContainer dependencies)
|
||||
private IEnumerable<string> GetAllUsedPackageDirNames(DependencyContainer dependencies)
|
||||
{
|
||||
var allPackageDirectories = GetAllPackageDirectories();
|
||||
|
||||
logger.LogInfo($"Restored {allPackageDirectories.Count} packages");
|
||||
logger.LogInfo($"Found {dependencies.Packages.Count} packages in project.assets.json files");
|
||||
|
||||
allPackageDirectories
|
||||
.Where(package => !dependencies.Packages.Contains(package))
|
||||
var usage = allPackageDirectories.Select(package => (package, isUsed: dependencies.Packages.Contains(package)));
|
||||
|
||||
usage
|
||||
.Where(package => !package.isUsed)
|
||||
.Order()
|
||||
.ForEach(package => logger.LogDebug($"Unused package: {package}"));
|
||||
.ForEach(package => logger.LogDebug($"Unused package: {package.package}"));
|
||||
|
||||
return usage
|
||||
.Where(package => package.isUsed)
|
||||
.Select(package => package.package);
|
||||
}
|
||||
|
||||
private ICollection<string> GetAllPackageDirectories()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user