@@ -22,6 +22,12 @@ class Bar
22
22
Bar () : f(0 , 0 ) {}
23
23
};
24
24
25
+ class Outer
26
+ {
27
+ public:
28
+ Bar inner;
29
+ };
30
+
25
31
int user_input ()
26
32
{
27
33
return 42 ;
@@ -31,31 +37,32 @@ void sink(int x)
31
37
{
32
38
}
33
39
34
- void bar (Bar &b)
40
+ void bar (Outer &b)
35
41
{
36
42
// The library correctly finds that the four `user_input` sources can make it
37
43
// to the `sink` calls, but it also finds some source/sink combinations that
38
44
// are impossible. Those false positives here are a consequence of how the
39
45
// shared data flow library overapproximates field flow. The library only
40
- // tracks the head (`f`) and the length (2) of the field access path, and
41
- // then it tracks that both `a_` and `b_` have followed `f` in _some_ access
42
- // path somewhere in the search. That makes the library conclude that there
43
- // could be flow to `b.f.a_` even when the flow was actually to `b.f.b_`.
44
- sink (b.f .a ()); // $ast=flow 55:13 $ast=flow 57:13 $f-:ir=flow
45
- sink (b.f .b ()); // $ast=flow 56:13 $ast=flow 58:13 $f-:ir=flow
46
+ // tracks the final two fields (`f` and `inner`) and the length (3) of the field
47
+ // access path, and then it tracks that both `a_` and `b_` have followed `f.inner`
48
+ // in _some_ access path somewhere in the search. That makes the library conclude
49
+ // that there could be flow to `b.inner.f.a_` even when the flow was actually to
50
+ // `b.inner.f.b_`.
51
+ sink (b.inner .f .a ()); // $ast=flow 61:19 $f+:ast=flow 62:19 $ast=flow 63:19 $f+:ast=flow 64:19 $f-:ir=flow
52
+ sink (b.inner .f .b ()); // $f+:ast=flow 61:19 $ast=flow 62:19 $f+:ast=flow 63:19 $ast=flow 64:19 $f-:ir=flow
46
53
}
47
54
48
55
void foo ()
49
56
{
50
- Bar b1;
51
- Bar b2;
52
- Bar b3;
53
- Bar b4;
57
+ Outer b1;
58
+ Outer b2;
59
+ Outer b3;
60
+ Outer b4;
54
61
55
- b1.f .setA (user_input ());
56
- b2.f .setB (user_input ());
57
- b3.f .setA (user_input ());
58
- b3.f .setB (user_input ());
62
+ b1.inner . f .setA (user_input ());
63
+ b2.inner . f .setB (user_input ());
64
+ b3.inner . f .setA (user_input ());
65
+ b3.inner . f .setB (user_input ());
59
66
60
67
// Only a() should alert
61
68
bar (b1);
0 commit comments