mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
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.
This commit is contained in:
@@ -1,14 +1,10 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
| D.cpp:1:17:1:17 | o | Node should have one location but has 4. |
|
||||
| arrays.cpp:1:17:1:17 | o | Node should have one location but has 4. |
|
||||
| by_reference.cpp:1:17:1:17 | o | Node should have one location but has 4. |
|
||||
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
|
||||
| file://:0:0:0:0 | p#0 | Node should have one location but has 0. |
|
||||
| qualifiers.cpp:1:17:1:17 | o | Node should have one location but has 4. |
|
||||
missingLocation
|
||||
| Nodes without location: 4 |
|
||||
uniqueNodeToString
|
||||
|
||||
@@ -44,5 +44,6 @@
|
||||
| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:38:23:38:23 | a | AST only |
|
||||
| qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:43:23:43:23 | a | AST only |
|
||||
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:48:23:48:23 | a | AST only |
|
||||
| realistic.cpp:53:55:53:64 | call to user_input | realistic.cpp:61:47:61:55 | bufferLen | AST only |
|
||||
| struct_init.c:20:20:20:29 | call to user_input | struct_init.c:33:25:33:25 | a | AST only |
|
||||
| struct_init.c:40:20:40:29 | call to user_input | struct_init.c:15:12:15:12 | a | AST only |
|
||||
|
||||
@@ -344,6 +344,32 @@
|
||||
| qualifiers.cpp:48:10:48:14 | outer | AST only |
|
||||
| qualifiers.cpp:48:16:48:20 | inner | AST only |
|
||||
| qualifiers.cpp:48:23:48:23 | a | AST only |
|
||||
| realistic.cpp:26:5:26:10 | offset | AST only |
|
||||
| realistic.cpp:42:20:42:20 | o | AST only |
|
||||
| realistic.cpp:49:9:49:11 | foo | AST only |
|
||||
| realistic.cpp:49:20:49:22 | baz | AST only |
|
||||
| realistic.cpp:53:9:53:11 | foo | AST only |
|
||||
| realistic.cpp:53:9:53:18 | access to array | AST only |
|
||||
| realistic.cpp:53:20:53:22 | baz | AST only |
|
||||
| realistic.cpp:53:25:53:33 | userInput | AST only |
|
||||
| realistic.cpp:53:35:53:43 | bufferLen | AST only |
|
||||
| realistic.cpp:54:16:54:18 | foo | AST only |
|
||||
| realistic.cpp:54:16:54:25 | access to array | AST only |
|
||||
| realistic.cpp:54:27:54:29 | baz | AST only |
|
||||
| realistic.cpp:54:32:54:40 | userInput | AST only |
|
||||
| realistic.cpp:54:42:54:47 | buffer | AST only |
|
||||
| realistic.cpp:60:16:60:18 | dst | AST only |
|
||||
| realistic.cpp:61:21:61:23 | foo | AST only |
|
||||
| realistic.cpp:61:21:61:30 | access to array | AST only |
|
||||
| realistic.cpp:61:32:61:34 | baz | AST only |
|
||||
| realistic.cpp:61:37:61:45 | userInput | AST only |
|
||||
| realistic.cpp:61:47:61:55 | bufferLen | AST only |
|
||||
| realistic.cpp:65:21:65:23 | foo | AST only |
|
||||
| realistic.cpp:65:21:65:30 | access to array | AST only |
|
||||
| realistic.cpp:65:32:65:34 | baz | AST only |
|
||||
| realistic.cpp:65:37:65:45 | userInput | AST only |
|
||||
| realistic.cpp:65:47:65:52 | buffer | AST only |
|
||||
| realistic.cpp:66:21:66:23 | dst | AST only |
|
||||
| simple.cpp:20:24:20:25 | a_ | AST only |
|
||||
| simple.cpp:21:24:21:25 | b_ | AST only |
|
||||
| simple.cpp:28:10:28:10 | f | AST only |
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
| qualifiers.cpp:9:30:9:33 | this |
|
||||
| qualifiers.cpp:12:49:12:53 | inner |
|
||||
| qualifiers.cpp:13:51:13:55 | inner |
|
||||
| realistic.cpp:49:9:49:18 | access to array |
|
||||
| simple.cpp:20:24:20:25 | this |
|
||||
| simple.cpp:21:24:21:25 | this |
|
||||
| simple.cpp:65:5:65:5 | a |
|
||||
|
||||
@@ -385,6 +385,33 @@
|
||||
| qualifiers.cpp:48:10:48:14 | outer |
|
||||
| qualifiers.cpp:48:16:48:20 | inner |
|
||||
| qualifiers.cpp:48:23:48:23 | a |
|
||||
| realistic.cpp:26:5:26:10 | offset |
|
||||
| realistic.cpp:42:20:42:20 | o |
|
||||
| realistic.cpp:49:9:49:11 | foo |
|
||||
| realistic.cpp:49:9:49:18 | access to array |
|
||||
| realistic.cpp:49:20:49:22 | baz |
|
||||
| realistic.cpp:53:9:53:11 | foo |
|
||||
| realistic.cpp:53:9:53:18 | access to array |
|
||||
| realistic.cpp:53:20:53:22 | baz |
|
||||
| realistic.cpp:53:25:53:33 | userInput |
|
||||
| realistic.cpp:53:35:53:43 | bufferLen |
|
||||
| realistic.cpp:54:16:54:18 | foo |
|
||||
| realistic.cpp:54:16:54:25 | access to array |
|
||||
| realistic.cpp:54:27:54:29 | baz |
|
||||
| realistic.cpp:54:32:54:40 | userInput |
|
||||
| realistic.cpp:54:42:54:47 | buffer |
|
||||
| realistic.cpp:60:16:60:18 | dst |
|
||||
| realistic.cpp:61:21:61:23 | foo |
|
||||
| realistic.cpp:61:21:61:30 | access to array |
|
||||
| realistic.cpp:61:32:61:34 | baz |
|
||||
| realistic.cpp:61:37:61:45 | userInput |
|
||||
| realistic.cpp:61:47:61:55 | bufferLen |
|
||||
| realistic.cpp:65:21:65:23 | foo |
|
||||
| realistic.cpp:65:21:65:30 | access to array |
|
||||
| realistic.cpp:65:32:65:34 | baz |
|
||||
| realistic.cpp:65:37:65:45 | userInput |
|
||||
| realistic.cpp:65:47:65:52 | buffer |
|
||||
| realistic.cpp:66:21:66:23 | dst |
|
||||
| simple.cpp:20:24:20:25 | a_ |
|
||||
| simple.cpp:20:24:20:25 | this |
|
||||
| simple.cpp:21:24:21:25 | b_ |
|
||||
|
||||
@@ -354,6 +354,18 @@ edges
|
||||
| qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:47:5:47:42 | ... = ... |
|
||||
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | qualifiers.cpp:48:16:48:20 | inner [a] |
|
||||
| qualifiers.cpp:48:16:48:20 | inner [a] | qualifiers.cpp:48:23:48:23 | a |
|
||||
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, ... (4)] | realistic.cpp:61:21:61:23 | foo [bar, baz, ... (4)] |
|
||||
| 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)] |
|
||||
| realistic.cpp:53:9:53:66 | ... = ... | realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] |
|
||||
| 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)] |
|
||||
| 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)] |
|
||||
| realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] | realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] |
|
||||
| realistic.cpp:53:55:53:64 | call to user_input | realistic.cpp:53:9:53:66 | ... = ... |
|
||||
| realistic.cpp:61:21:61:23 | foo [bar, baz, ... (4)] | realistic.cpp:61:25:61:27 | bar [baz, userInput, ... (3)] |
|
||||
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] | realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] |
|
||||
| realistic.cpp:61:25:61:27 | bar [baz, userInput, ... (3)] | realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] |
|
||||
| realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | realistic.cpp:61:37:61:45 | userInput [bufferLen] |
|
||||
| realistic.cpp:61:37:61:45 | userInput [bufferLen] | realistic.cpp:61:47:61:55 | bufferLen |
|
||||
| simple.cpp:26:15:26:15 | f [a_] | simple.cpp:28:10:28:10 | f [a_] |
|
||||
| simple.cpp:26:15:26:15 | f [b_] | simple.cpp:29:10:29:10 | f [b_] |
|
||||
| simple.cpp:28:10:28:10 | f [a_] | simple.cpp:28:12:28:12 | call to a |
|
||||
@@ -802,6 +814,19 @@ nodes
|
||||
| qualifiers.cpp:48:10:48:14 | outer [inner, a] | semmle.label | outer [inner, a] |
|
||||
| qualifiers.cpp:48:16:48:20 | inner [a] | semmle.label | inner [a] |
|
||||
| qualifiers.cpp:48:23:48:23 | a | semmle.label | a |
|
||||
| realistic.cpp:53:9:53:11 | foo [post update] [bar, baz, ... (4)] | semmle.label | foo [post update] [bar, baz, ... (4)] |
|
||||
| realistic.cpp:53:9:53:18 | access to array [post update] [baz, userInput, ... (3)] | semmle.label | access to array [post update] [baz, userInput, ... (3)] |
|
||||
| realistic.cpp:53:9:53:66 | ... = ... | semmle.label | ... = ... |
|
||||
| realistic.cpp:53:13:53:15 | bar [inner post update] [baz, userInput, ... (3)] | semmle.label | bar [inner post update] [baz, userInput, ... (3)] |
|
||||
| realistic.cpp:53:20:53:22 | baz [post update] [userInput, bufferLen] | semmle.label | baz [post update] [userInput, bufferLen] |
|
||||
| realistic.cpp:53:25:53:33 | userInput [post update] [bufferLen] | semmle.label | userInput [post update] [bufferLen] |
|
||||
| realistic.cpp:53:55:53:64 | call to user_input | semmle.label | call to user_input |
|
||||
| realistic.cpp:61:21:61:23 | foo [bar, baz, ... (4)] | semmle.label | foo [bar, baz, ... (4)] |
|
||||
| realistic.cpp:61:21:61:30 | access to array [baz, userInput, ... (3)] | semmle.label | access to array [baz, userInput, ... (3)] |
|
||||
| realistic.cpp:61:25:61:27 | bar [baz, userInput, ... (3)] | semmle.label | bar [baz, userInput, ... (3)] |
|
||||
| realistic.cpp:61:32:61:34 | baz [userInput, bufferLen] | semmle.label | baz [userInput, bufferLen] |
|
||||
| realistic.cpp:61:37:61:45 | userInput [bufferLen] | semmle.label | userInput [bufferLen] |
|
||||
| realistic.cpp:61:47:61:55 | bufferLen | semmle.label | bufferLen |
|
||||
| simple.cpp:26:15:26:15 | f [a_] | semmle.label | f [a_] |
|
||||
| simple.cpp:26:15:26:15 | f [b_] | semmle.label | f [b_] |
|
||||
| simple.cpp:28:10:28:10 | f [a_] | semmle.label | f [a_] |
|
||||
@@ -935,6 +960,7 @@ nodes
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
|
||||
70
cpp/ql/test/library-tests/dataflow/fields/realistic.cpp
Normal file
70
cpp/ql/test/library-tests/dataflow/fields/realistic.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned long size_t;
|
||||
struct UserInput {
|
||||
size_t bufferLen;
|
||||
u8 buffer[256];
|
||||
};
|
||||
struct Baz {
|
||||
int foo;
|
||||
struct UserInput userInput;
|
||||
};
|
||||
struct Bar {
|
||||
u8* foo;
|
||||
struct Baz * baz;
|
||||
};
|
||||
struct Foo {
|
||||
struct Bar bar[128];
|
||||
};
|
||||
void printf(const char *fmt, ...) {
|
||||
return;
|
||||
}
|
||||
void * malloc(size_t size) {
|
||||
static unsigned char buffer[0x1000];
|
||||
static unsigned int offset;
|
||||
if (size + offset >= sizeof(buffer)) return nullptr;
|
||||
void* m = (void*)&buffer[offset];
|
||||
offset += size;
|
||||
return m;
|
||||
}
|
||||
void * memcpy ( void * destination, const void * source, size_t num ) {
|
||||
u8* d = (u8*)destination;
|
||||
u8* s = (u8*)source;
|
||||
u8* e = d + num;
|
||||
while(d != e) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
return destination;
|
||||
}
|
||||
void *user_input(void) {
|
||||
return (void*)"\x0a\x00\x00\x00\x00\x00\x00\x00The quick brown fox jumps over the lazy dog";
|
||||
}
|
||||
void sink(void *o) {
|
||||
printf("%p\n", o);
|
||||
}
|
||||
#define MAX_BAZ 3
|
||||
int main(int argc, char** argv) {
|
||||
char dst[256];
|
||||
struct Foo foo;
|
||||
for (int i = 0; i < MAX_BAZ; i++) {
|
||||
foo.bar[i].baz = (struct Baz*)malloc(sizeof(struct Baz));
|
||||
}
|
||||
int i = 0;
|
||||
while(i < MAX_BAZ) {
|
||||
foo.bar[i].baz->userInput.bufferLen = (size_t)user_input();
|
||||
memcpy(foo.bar[i].baz->userInput.buffer, user_input(), sizeof(foo.bar[i].baz->userInput.buffer));
|
||||
if(foo.bar[i].baz->userInput.bufferLen > sizeof(foo.bar[i].baz->userInput.buffer))
|
||||
{
|
||||
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));
|
||||
return -1;
|
||||
}
|
||||
memcpy(dst, foo.bar[i].baz->userInput.buffer, foo.bar[i].baz->userInput.bufferLen);
|
||||
sink((void*)foo.bar[i].baz->userInput.bufferLen); // $ast $f-:ir
|
||||
// There is no flow to the following two `sink` calls because the
|
||||
// source is the _pointer_ returned by `user_input` rather than the
|
||||
// _data_ to which it points.
|
||||
sink((void*)foo.bar[i].baz->userInput.buffer); // $f-:ast,ir
|
||||
sink((void*)dst); // $f-:ast,ir
|
||||
i++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user