Skip to content

Commit 7856083

Browse files
committed
C++: Add a test distilled from real code
Author: @rvermeulen. The consistency warnings go away because `sink` is defined with a body in this file.
1 parent bdce247 commit 7856083

File tree

7 files changed

+151
-4
lines changed

7 files changed

+151
-4
lines changed

cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
uniqueEnclosingCallable
22
uniqueType
33
uniqueNodeLocation
4-
| D.cpp:1:17:1:17 | o | Node should have one location but has 4. |
5-
| arrays.cpp:1:17:1:17 | o | Node should have one location but has 4. |
6-
| by_reference.cpp:1:17:1:17 | o | Node should have one location but has 4. |
74
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
85
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
96
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
107
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
11-
| qualifiers.cpp:1:17:1:17 | o | Node should have one location but has 4. |
128
missingLocation
139
| Nodes without location: 4 |
1410
uniqueNodeToString

cpp/ql/test/library-tests/dataflow/fields/flow-diff.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,6 @@
4444
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:38:23:38:23 | a | AST only |
4545
| qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:43:23:43:23 | a | AST only |
4646
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:48:23:48:23 | a | AST only |
47+
| realistic.cpp:53:55:53:64 | call to user_input | realistic.cpp:61:47:61:55 | bufferLen | AST only |
4748
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:33:25:33:25 | a | AST only |
4849
| struct_init.c:40:20:40:29 | call to user_input | struct_init.c:15:12:15:12 | a | AST only |

cpp/ql/test/library-tests/dataflow/fields/partial-definition-diff.expected

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,32 @@
344344
| qualifiers.cpp:48:10:48:14 | outer | AST only |
345345
| qualifiers.cpp:48:16:48:20 | inner | AST only |
346346
| qualifiers.cpp:48:23:48:23 | a | AST only |
347+
| realistic.cpp:26:5:26:10 | offset | AST only |
348+
| realistic.cpp:42:20:42:20 | o | AST only |
349+
| realistic.cpp:49:9:49:11 | foo | AST only |
350+
| realistic.cpp:49:20:49:22 | baz | AST only |
351+
| realistic.cpp:53:9:53:11 | foo | AST only |
352+
| realistic.cpp:53:9:53:18 | access to array | AST only |
353+
| realistic.cpp:53:20:53:22 | baz | AST only |
354+
| realistic.cpp:53:25:53:33 | userInput | AST only |
355+
| realistic.cpp:53:35:53:43 | bufferLen | AST only |
356+
| realistic.cpp:54:16:54:18 | foo | AST only |
357+
| realistic.cpp:54:16:54:25 | access to array | AST only |
358+
| realistic.cpp:54:27:54:29 | baz | AST only |
359+
| realistic.cpp:54:32:54:40 | userInput | AST only |
360+
| realistic.cpp:54:42:54:47 | buffer | AST only |
361+
| realistic.cpp:60:16:60:18 | dst | AST only |
362+
| realistic.cpp:61:21:61:23 | foo | AST only |
363+
| realistic.cpp:61:21:61:30 | access to array | AST only |
364+
| realistic.cpp:61:32:61:34 | baz | AST only |
365+
| realistic.cpp:61:37:61:45 | userInput | AST only |
366+
| realistic.cpp:61:47:61:55 | bufferLen | AST only |
367+
| realistic.cpp:65:21:65:23 | foo | AST only |
368+
| realistic.cpp:65:21:65:30 | access to array | AST only |
369+
| realistic.cpp:65:32:65:34 | baz | AST only |
370+
| realistic.cpp:65:37:65:45 | userInput | AST only |
371+
| realistic.cpp:65:47:65:52 | buffer | AST only |
372+
| realistic.cpp:66:21:66:23 | dst | AST only |
347373
| simple.cpp:20:24:20:25 | a_ | AST only |
348374
| simple.cpp:21:24:21:25 | b_ | AST only |
349375
| simple.cpp:28:10:28:10 | f | AST only |

cpp/ql/test/library-tests/dataflow/fields/partial-definition-ir.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
| qualifiers.cpp:9:30:9:33 | this |
4040
| qualifiers.cpp:12:49:12:53 | inner |
4141
| qualifiers.cpp:13:51:13:55 | inner |
42+
| realistic.cpp:49:9:49:18 | access to array |
4243
| simple.cpp:20:24:20:25 | this |
4344
| simple.cpp:21:24:21:25 | this |
4445
| simple.cpp:65:5:65:5 | a |

cpp/ql/test/library-tests/dataflow/fields/partial-definition.expected

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,33 @@
385385
| qualifiers.cpp:48:10:48:14 | outer |
386386
| qualifiers.cpp:48:16:48:20 | inner |
387387
| qualifiers.cpp:48:23:48:23 | a |
388+
| realistic.cpp:26:5:26:10 | offset |
389+
| realistic.cpp:42:20:42:20 | o |
390+
| realistic.cpp:49:9:49:11 | foo |
391+
| realistic.cpp:49:9:49:18 | access to array |
392+
| realistic.cpp:49:20:49:22 | baz |
393+
| realistic.cpp:53:9:53:11 | foo |
394+
| realistic.cpp:53:9:53:18 | access to array |
395+
| realistic.cpp:53:20:53:22 | baz |
396+
| realistic.cpp:53:25:53:33 | userInput |
397+
| realistic.cpp:53:35:53:43 | bufferLen |
398+
| realistic.cpp:54:16:54:18 | foo |
399+
| realistic.cpp:54:16:54:25 | access to array |
400+
| realistic.cpp:54:27:54:29 | baz |
401+
| realistic.cpp:54:32:54:40 | userInput |
402+
| realistic.cpp:54:42:54:47 | buffer |
403+
| realistic.cpp:60:16:60:18 | dst |
404+
| realistic.cpp:61:21:61:23 | foo |
405+
| realistic.cpp:61:21:61:30 | access to array |
406+
| realistic.cpp:61:32:61:34 | baz |
407+
| realistic.cpp:61:37:61:45 | userInput |
408+
| realistic.cpp:61:47:61:55 | bufferLen |
409+
| realistic.cpp:65:21:65:23 | foo |
410+
| realistic.cpp:65:21:65:30 | access to array |
411+
| realistic.cpp:65:32:65:34 | baz |
412+
| realistic.cpp:65:37:65:45 | userInput |
413+
| realistic.cpp:65:47:65:52 | buffer |
414+
| realistic.cpp:66:21:66:23 | dst |
388415
| simple.cpp:20:24:20:25 | a_ |
389416
| simple.cpp:20:24:20:25 | this |
390417
| simple.cpp:21:24:21:25 | b_ |

cpp/ql/test/library-tests/dataflow/fields/path-flow.expected

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,18 @@ edges
354354
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:47:5:47:42 | ... = ... |
355355
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | qualifiers.cpp:48:16:48:20 | inner [a] |
356356
| qualifiers.cpp:48:16:48:20 | inner [a] | qualifiers.cpp:48:23:48:23 | a |
357+
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, ... (4)] | realistic.cpp:61:21:61:23 | foo [bar, baz, ... (4)] |
358+
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, ... (3)] | realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, ... (3)] |
359+
| realistic.cpp:53:9:53:66 | ... = ... | realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] |
360+
| realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, ... (3)] | realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, ... (4)] |
361+
| realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] | realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, ... (3)] |
362+
| realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] | realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] |
363+
| realistic.cpp:53:55:53:64 | call to user_input | realistic.cpp:53:9:53:66 | ... = ... |
364+
| realistic.cpp:61:21:61:23 | foo [bar, baz, ... (4)] | realistic.cpp:61:25:61:27 | bar [baz, userInput, ... (3)] |
365+
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] | realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] |
366+
| realistic.cpp:61:25:61:27 | bar [baz, userInput, ... (3)] | realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] |
367+
| realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | realistic.cpp:61:37:61:45 | userInput [bufferLen] |
368+
| realistic.cpp:61:37:61:45 | userInput [bufferLen] | realistic.cpp:61:47:61:55 | bufferLen |
357369
| simple.cpp:26:15:26:15 | f [a_] | simple.cpp:28:10:28:10 | f [a_] |
358370
| simple.cpp:26:15:26:15 | f [b_] | simple.cpp:29:10:29:10 | f [b_] |
359371
| simple.cpp:28:10:28:10 | f [a_] | simple.cpp:28:12:28:12 | call to a |
@@ -802,6 +814,19 @@ nodes
802814
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | semmle.label | outer [inner, a] |
803815
| qualifiers.cpp:48:16:48:20 | inner [a] | semmle.label | inner [a] |
804816
| qualifiers.cpp:48:23:48:23 | a | semmle.label | a |
817+
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, ... (4)] | semmle.label | foo [post update] [bar, baz, ... (4)] |
818+
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, ... (3)] | semmle.label | access to array [post update] [baz, userInput, ... (3)] |
819+
| realistic.cpp:53:9:53:66 | ... = ... | semmle.label | ... = ... |
820+
| realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, ... (3)] | semmle.label | bar [inner post update] [baz, userInput, ... (3)] |
821+
| realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] | semmle.label | baz [post update] [userInput, bufferLen] |
822+
| realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] | semmle.label | userInput [post update] [bufferLen] |
823+
| realistic.cpp:53:55:53:64 | call to user_input | semmle.label | call to user_input |
824+
| realistic.cpp:61:21:61:23 | foo [bar, baz, ... (4)] | semmle.label | foo [bar, baz, ... (4)] |
825+
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] | semmle.label | access to array [baz, userInput, ... (3)] |
826+
| realistic.cpp:61:25:61:27 | bar [baz, userInput, ... (3)] | semmle.label | bar [baz, userInput, ... (3)] |
827+
| realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | semmle.label | baz [userInput, bufferLen] |
828+
| realistic.cpp:61:37:61:45 | userInput [bufferLen] | semmle.label | userInput [bufferLen] |
829+
| realistic.cpp:61:47:61:55 | bufferLen | semmle.label | bufferLen |
805830
| simple.cpp:26:15:26:15 | f [a_] | semmle.label | f [a_] |
806831
| simple.cpp:26:15:26:15 | f [b_] | semmle.label | f [b_] |
807832
| simple.cpp:28:10:28:10 | f [a_] | semmle.label | f [a_] |
@@ -935,6 +960,7 @@ nodes
935960
| qualifiers.cpp:38:23:38:23 | a | qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:38:23:38:23 | a | a flows from $@ | qualifiers.cpp:37:38:37:47 | call to user_input | call to user_input |
936961
| qualifiers.cpp:43:23:43:23 | a | qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:43:23:43:23 | a | a flows from $@ | qualifiers.cpp:42:29:42:38 | call to user_input | call to user_input |
937962
| qualifiers.cpp:48:23:48:23 | a | qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:48:23:48:23 | a | a flows from $@ | qualifiers.cpp:47:31:47:40 | call to user_input | call to user_input |
963+
| realistic.cpp:61:47:61:55 | bufferLen | realistic.cpp:53:55:53:64 | call to user_input | realistic.cpp:61:47:61:55 | bufferLen | bufferLen flows from $@ | realistic.cpp:53:55:53:64 | call to user_input | call to user_input |
938964
| simple.cpp:28:12:28:12 | call to a | simple.cpp:39:12:39:21 | call to user_input | simple.cpp:28:12:28:12 | call to a | call to a flows from $@ | simple.cpp:39:12:39:21 | call to user_input | call to user_input |
939965
| simple.cpp:28:12:28:12 | call to a | simple.cpp:41:12:41:21 | call to user_input | simple.cpp:28:12:28:12 | call to a | call to a flows from $@ | simple.cpp:41:12:41:21 | call to user_input | call to user_input |
940966
| simple.cpp:29:12:29:12 | call to b | simple.cpp:40:12:40:21 | call to user_input | simple.cpp:29:12:29:12 | call to b | call to b flows from $@ | simple.cpp:40:12:40:21 | call to user_input | call to user_input |
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
typedef unsigned char u8;
2+
typedef unsigned long size_t;
3+
struct UserInput {
4+
size_t bufferLen;
5+
u8 buffer[256];
6+
};
7+
struct Baz {
8+
int foo;
9+
struct UserInput userInput;
10+
};
11+
struct Bar {
12+
u8* foo;
13+
struct Baz * baz;
14+
};
15+
struct Foo {
16+
struct Bar bar[128];
17+
};
18+
void printf(const char *fmt, ...) {
19+
return;
20+
}
21+
void * malloc(size_t size) {
22+
static unsigned char buffer[0x1000];
23+
static unsigned int offset;
24+
if (size + offset >= sizeof(buffer)) return nullptr;
25+
void* m = (void*)&buffer[offset];
26+
offset += size;
27+
return m;
28+
}
29+
void * memcpy ( void * destination, const void * source, size_t num ) {
30+
u8* d = (u8*)destination;
31+
u8* s = (u8*)source;
32+
u8* e = d + num;
33+
while(d != e) {
34+
*d++ = *s++;
35+
}
36+
return destination;
37+
}
38+
void *user_input(void) {
39+
return (void*)"\x0a\x00\x00\x00\x00\x00\x00\x00The quick brown fox jumps over the lazy dog";
40+
}
41+
void sink(void *o) {
42+
printf("%p\n", o);
43+
}
44+
#define MAX_BAZ 3
45+
int main(int argc, char** argv) {
46+
char dst[256];
47+
struct Foo foo;
48+
for (int i = 0; i < MAX_BAZ; i++) {
49+
foo.bar[i].baz = (struct Baz*)malloc(sizeof(struct Baz));
50+
}
51+
int i = 0;
52+
while(i < MAX_BAZ) {
53+
foo.bar[i].baz->userInput.bufferLen = (size_t)user_input();
54+
memcpy(foo.bar[i].baz->userInput.buffer, user_input(), sizeof(foo.bar[i].baz->userInput.buffer));
55+
if(foo.bar[i].baz->userInput.bufferLen > sizeof(foo.bar[i].baz->userInput.buffer))
56+
{
57+
printf("The user-supplied input 0x%lx is larger than the buffer 0x%lx!\n", foo.bar[i].baz->userInput.bufferLen, sizeof(foo.bar[i].baz->userInput.buffer));
58+
return -1;
59+
}
60+
memcpy(dst, foo.bar[i].baz->userInput.buffer, foo.bar[i].baz->userInput.bufferLen);
61+
sink((void*)foo.bar[i].baz->userInput.bufferLen); // $ast $f-:ir
62+
// There is no flow to the following two `sink` calls because the
63+
// source is the _pointer_ returned by `user_input` rather than the
64+
// _data_ to which it points.
65+
sink((void*)foo.bar[i].baz->userInput.buffer); // $f-:ast,ir
66+
sink((void*)dst); // $f-:ast,ir
67+
i++;
68+
}
69+
return 0;
70+
}

0 commit comments

Comments
 (0)