Skip to content

Commit a38839b

Browse files
committed
C++: Include copy of IntWrapper class with two data members
1 parent ca20f17 commit a38839b

File tree

8 files changed

+481
-217
lines changed

8 files changed

+481
-217
lines changed

cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected

Lines changed: 211 additions & 93 deletions
Large diffs are not rendered by default.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace std
2+
{
3+
template <class T>
4+
constexpr void swap(T &a, T &b);
5+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include "swap.h"
2+
/*
3+
* Note: This file exists in two versions (swap1.cpp and swap2.cpp).
4+
* The only difference is that `IntWrapper` in swap1.cpp contains a single data member, and swap2.cpp
5+
* contains two data members.
6+
*/
7+
8+
int source();
9+
void sink(...);
10+
11+
namespace std
12+
{
13+
template <class T>
14+
T &&move(T &t) noexcept { return static_cast<T &&>(t); } // simplified signature (and implementation)
15+
} // namespace std
16+
17+
namespace IntWrapper
18+
{
19+
struct Class
20+
{
21+
int data1;
22+
23+
Class() = default;
24+
Class(Class &&that) { swap(that); }
25+
Class(const Class &that) : data1(that.data1) {}
26+
27+
Class &operator=(const Class &that)
28+
{
29+
auto tmp = that;
30+
swap(tmp);
31+
return *this;
32+
}
33+
34+
Class &operator=(Class &&that)
35+
{
36+
swap(that);
37+
return *this;
38+
}
39+
40+
void swap(Class &that) noexcept
41+
{
42+
using std::swap;
43+
swap(data1, that.data1);
44+
}
45+
};
46+
47+
// For ADL
48+
void swap(Class &x, Class &y)
49+
{
50+
x.swap(y);
51+
}
52+
} // namespace IntWrapper
53+
54+
void test_copy_assignment_operator()
55+
{
56+
IntWrapper::Class x;
57+
IntWrapper::Class y;
58+
x.data1 = source();
59+
60+
sink(x.data1); // tainted
61+
sink(y.data1); // clean
62+
63+
y = x;
64+
65+
sink(y.data1); // tainted [FALSE NEGATIVE in IR]
66+
sink(x.data1); // tainted
67+
68+
IntWrapper::Class z1, z2;
69+
z1.data1 = source();
70+
sink(z1.data1); // tainted
71+
72+
swap(z1, z2);
73+
74+
sink(z2.data1); // tainted
75+
sink(z1.data1); // clean [FALSE POSITIVE]
76+
}
77+
78+
void test_move_assignment_operator()
79+
{
80+
IntWrapper::Class x;
81+
IntWrapper::Class y;
82+
x.data1 = source();
83+
84+
sink(x.data1); // tainted
85+
sink(y.data1); // clean
86+
87+
y = std::move(x);
88+
89+
sink(y.data1); // tainted [FALSE NEGATIVE in IR]
90+
sink(x.data1); // tainted
91+
}
92+
93+
void test_move_constructor()
94+
{
95+
IntWrapper::Class move_from;
96+
move_from.data1 = source();
97+
98+
sink(move_from.data1); // tainted
99+
100+
IntWrapper::Class move_to(std::move(move_from));
101+
102+
sink(move_to.data1); // tainted [FALSE NEGATIVE in IR]
103+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include "swap.h"
2+
/*
3+
* Note: This file exists in two versions (swap1.cpp and swap2.cpp).
4+
* The only difference is that `IntWrapper` in swap1.cpp contains a single data member, and swap2.cpp
5+
* contains two data members.
6+
*/
7+
8+
int source();
9+
void sink(...);
10+
11+
namespace std
12+
{
13+
template <class T>
14+
T &&move(T &t) noexcept { return static_cast<T &&>(t); } // simplified signature (and implementation)
15+
} // namespace std
16+
17+
namespace IntWrapper
18+
{
19+
struct Class
20+
{
21+
int data1; int data2;
22+
23+
Class() = default;
24+
Class(Class &&that) { swap(that); }
25+
Class(const Class &that) : data1(that.data1), data2(that.data2) {}
26+
27+
Class &operator=(const Class &that)
28+
{
29+
auto tmp = that;
30+
swap(tmp);
31+
return *this;
32+
}
33+
34+
Class &operator=(Class &&that)
35+
{
36+
swap(that);
37+
return *this;
38+
}
39+
40+
void swap(Class &that) noexcept
41+
{
42+
using std::swap;
43+
swap(data1, that.data1); swap(data2, that.data2);
44+
}
45+
};
46+
47+
// For ADL
48+
void swap(Class &x, Class &y)
49+
{
50+
x.swap(y);
51+
}
52+
} // namespace IntWrapper
53+
54+
void test_copy_assignment_operator()
55+
{
56+
IntWrapper::Class x;
57+
IntWrapper::Class y;
58+
x.data1 = source();
59+
60+
sink(x.data1); // tainted
61+
sink(y.data1); // clean
62+
63+
y = x;
64+
65+
sink(y.data1); // tainted [FALSE NEGATIVE in IR]
66+
sink(x.data1); // tainted
67+
68+
IntWrapper::Class z1, z2;
69+
z1.data1 = source();
70+
sink(z1.data1); // tainted
71+
72+
swap(z1, z2);
73+
74+
sink(z2.data1); // tainted
75+
sink(z1.data1); // clean [FALSE POSITIVE]
76+
}
77+
78+
void test_move_assignment_operator()
79+
{
80+
IntWrapper::Class x;
81+
IntWrapper::Class y;
82+
x.data1 = source();
83+
84+
sink(x.data1); // tainted
85+
sink(y.data1); // clean
86+
87+
y = std::move(x);
88+
89+
sink(y.data1); // tainted [FALSE NEGATIVE in IR]
90+
sink(x.data1); // tainted
91+
}
92+
93+
void test_move_constructor()
94+
{
95+
IntWrapper::Class move_from;
96+
move_from.data1 = source();
97+
98+
sink(move_from.data1); // tainted
99+
100+
IntWrapper::Class move_to(std::move(move_from));
101+
102+
sink(move_to.data1); // tainted [FALSE NEGATIVE in IR]
103+
}

cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp

Lines changed: 3 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,9 @@ void test_memcpy(int *source) {
197197

198198
// --- std::swap ---
199199

200-
namespace std {
201-
template<class T> constexpr void swap(T& a, T& b);
202-
}
200+
#include "swap.h"
201+
202+
203203

204204
void test_swap() {
205205
int x, y;
@@ -484,96 +484,3 @@ void test_getdelim(FILE* source1) {
484484

485485
sink(line);
486486
}
487-
488-
namespace std
489-
{
490-
template <class T>
491-
T &&move(T &t) noexcept { return static_cast<T&&>(t); } // simplified signature (and implementation)
492-
}
493-
494-
namespace IntWrapper
495-
{
496-
struct Class
497-
{
498-
int data;
499-
500-
Class() = default;
501-
Class(Class&& that) { swap(that); }
502-
Class(const Class &that) : data(that.data) {}
503-
504-
Class &operator=(const Class &that)
505-
{
506-
auto tmp = that;
507-
swap(tmp);
508-
return *this;
509-
}
510-
511-
Class& operator=(Class&& that) {
512-
swap(that);
513-
return *this;
514-
}
515-
516-
void swap(Class &that) noexcept
517-
{
518-
using std::swap;
519-
swap(data, that.data);
520-
}
521-
};
522-
523-
// For ADL
524-
void swap(Class &x, Class &y) {
525-
x.swap(y);
526-
}
527-
} // namespace IntWrapper
528-
529-
530-
531-
void test_copy_assignment_operator() {
532-
IntWrapper::Class x;
533-
IntWrapper::Class y;
534-
x.data = source();
535-
536-
sink(x.data); // tainted
537-
sink(y.data); // clean
538-
539-
y = x;
540-
541-
sink(y.data); // tainted [FALSE NEGATIVE in IR]
542-
sink(x.data); // tainted
543-
544-
IntWrapper::Class z1, z2;
545-
z1.data = source();
546-
sink(z1.data); // tainted
547-
548-
swap(z1, z2);
549-
550-
sink(z2.data); // tainted
551-
sink(z1.data); // clean [FALSE POSITIVE]
552-
}
553-
554-
void test_move_assignment_operator()
555-
{
556-
IntWrapper::Class x;
557-
IntWrapper::Class y;
558-
x.data = source();
559-
560-
sink(x.data); // tainted
561-
sink(y.data); // clean
562-
563-
y = std::move(x);
564-
565-
sink(y.data); // tainted [FALSE NEGATIVE in IR]
566-
sink(x.data); // tainted
567-
}
568-
569-
void test_move_constructor()
570-
{
571-
IntWrapper::Class move_from;
572-
move_from.data = source();
573-
574-
sink(move_from.data); // tainted
575-
576-
IntWrapper::Class move_to(std::move(move_from));
577-
578-
sink(move_to.data); // tainted [FALSE NEGATIVE in IR]
579-
}

cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,34 @@
1616
| stl.cpp:125:13:125:17 | call to c_str | stl.cpp:117:10:117:15 | call to source |
1717
| stl.cpp:129:13:129:17 | call to c_str | stl.cpp:117:10:117:15 | call to source |
1818
| stl.cpp:132:13:132:17 | call to c_str | stl.cpp:117:10:117:15 | call to source |
19+
| swap1.cpp:60:12:60:16 | data1 | swap1.cpp:58:15:58:20 | call to source |
20+
| swap1.cpp:65:12:65:16 | data1 | swap1.cpp:58:15:58:20 | call to source |
21+
| swap1.cpp:66:12:66:16 | data1 | swap1.cpp:58:15:58:20 | call to source |
22+
| swap1.cpp:70:13:70:17 | data1 | swap1.cpp:69:16:69:21 | call to source |
23+
| swap1.cpp:74:13:74:17 | data1 | swap1.cpp:69:16:69:21 | call to source |
24+
| swap1.cpp:75:13:75:17 | data1 | swap1.cpp:68:27:68:28 | z2 |
25+
| swap1.cpp:75:13:75:17 | data1 | swap1.cpp:69:16:69:21 | call to source |
26+
| swap1.cpp:84:12:84:16 | data1 | swap1.cpp:82:15:82:20 | call to source |
27+
| swap1.cpp:89:12:89:16 | data1 | swap1.cpp:80:23:80:23 | x |
28+
| swap1.cpp:89:12:89:16 | data1 | swap1.cpp:82:15:82:20 | call to source |
29+
| swap1.cpp:90:12:90:16 | data1 | swap1.cpp:82:15:82:20 | call to source |
30+
| swap1.cpp:98:20:98:24 | data1 | swap1.cpp:96:23:96:28 | call to source |
31+
| swap1.cpp:102:18:102:22 | data1 | swap1.cpp:95:23:95:31 | move_from |
32+
| swap1.cpp:102:18:102:22 | data1 | swap1.cpp:96:23:96:28 | call to source |
33+
| swap2.cpp:60:12:60:16 | data1 | swap2.cpp:58:15:58:20 | call to source |
34+
| swap2.cpp:65:12:65:16 | data1 | swap2.cpp:58:15:58:20 | call to source |
35+
| swap2.cpp:66:12:66:16 | data1 | swap2.cpp:58:15:58:20 | call to source |
36+
| swap2.cpp:70:13:70:17 | data1 | swap2.cpp:69:16:69:21 | call to source |
37+
| swap2.cpp:74:13:74:17 | data1 | swap2.cpp:69:16:69:21 | call to source |
38+
| swap2.cpp:75:13:75:17 | data1 | swap2.cpp:68:27:68:28 | z2 |
39+
| swap2.cpp:75:13:75:17 | data1 | swap2.cpp:69:16:69:21 | call to source |
40+
| swap2.cpp:84:12:84:16 | data1 | swap2.cpp:82:15:82:20 | call to source |
41+
| swap2.cpp:89:12:89:16 | data1 | swap2.cpp:80:23:80:23 | x |
42+
| swap2.cpp:89:12:89:16 | data1 | swap2.cpp:82:15:82:20 | call to source |
43+
| swap2.cpp:90:12:90:16 | data1 | swap2.cpp:82:15:82:20 | call to source |
44+
| swap2.cpp:98:20:98:24 | data1 | swap2.cpp:96:23:96:28 | call to source |
45+
| swap2.cpp:102:18:102:22 | data1 | swap2.cpp:95:23:95:31 | move_from |
46+
| swap2.cpp:102:18:102:22 | data1 | swap2.cpp:96:23:96:28 | call to source |
1947
| taint.cpp:8:8:8:13 | clean1 | taint.cpp:4:27:4:33 | source1 |
2048
| taint.cpp:16:8:16:14 | source1 | taint.cpp:12:22:12:27 | call to source |
2149
| taint.cpp:17:8:17:16 | ++ ... | taint.cpp:12:22:12:27 | call to source |
@@ -70,17 +98,3 @@
7098
| taint.cpp:470:7:470:7 | x | taint.cpp:462:6:462:11 | call to source |
7199
| taint.cpp:471:7:471:7 | y | taint.cpp:462:6:462:11 | call to source |
72100
| taint.cpp:485:7:485:10 | line | taint.cpp:480:26:480:32 | source1 |
73-
| taint.cpp:536:9:536:12 | data | taint.cpp:534:11:534:16 | call to source |
74-
| taint.cpp:541:9:541:12 | data | taint.cpp:534:11:534:16 | call to source |
75-
| taint.cpp:542:9:542:12 | data | taint.cpp:534:11:534:16 | call to source |
76-
| taint.cpp:546:10:546:13 | data | taint.cpp:545:12:545:17 | call to source |
77-
| taint.cpp:550:10:550:13 | data | taint.cpp:545:12:545:17 | call to source |
78-
| taint.cpp:551:10:551:13 | data | taint.cpp:544:24:544:25 | z2 |
79-
| taint.cpp:551:10:551:13 | data | taint.cpp:545:12:545:17 | call to source |
80-
| taint.cpp:560:9:560:12 | data | taint.cpp:558:11:558:16 | call to source |
81-
| taint.cpp:565:9:565:12 | data | taint.cpp:556:20:556:20 | x |
82-
| taint.cpp:565:9:565:12 | data | taint.cpp:558:11:558:16 | call to source |
83-
| taint.cpp:566:9:566:12 | data | taint.cpp:558:11:558:16 | call to source |
84-
| taint.cpp:574:17:574:20 | data | taint.cpp:572:19:572:24 | call to source |
85-
| taint.cpp:578:15:578:18 | data | taint.cpp:571:20:571:28 | move_from |
86-
| taint.cpp:578:15:578:18 | data | taint.cpp:572:19:572:24 | call to source |

0 commit comments

Comments
 (0)