mirror of
https://github.com/github/codeql.git
synced 2025-12-17 17:23:36 +01:00
This works by adding data-flow edges to skip over array expressions when reading from arrays. On the post-update side, there was already code to skip over array expressions when storing to arrays. That happens in `valueToUpdate` in `AddressFlow.qll`, which needed just a small tweak to support assignments with non-field expressions at the top-level LHS, like `*a = ...` or `a[0] = ...`. The new code in `AddressFlow.qll` is copy-pasted from `EscapesTree.qll`, and there is already a note in these files saying that they share a lot of code and must be maintained in sync.
52 lines
1010 B
C++
52 lines
1010 B
C++
void sink(void *o);
|
|
void *user_input(void);
|
|
|
|
void local_array() {
|
|
void *arr[10] = { 0 };
|
|
arr[0] = user_input();
|
|
sink(arr[0]); // $ast,ir
|
|
sink(arr[1]); // $f+:ast
|
|
sink(*arr); // $ast,ir
|
|
sink(*&arr[0]); // $ast,ir
|
|
}
|
|
|
|
void local_array_convoluted_assign() {
|
|
void *arr[10] = { 0 };
|
|
*&arr[0] = user_input();
|
|
sink(arr[0]); // $ast,ir
|
|
sink(arr[1]); // $f+:ast
|
|
}
|
|
|
|
struct inner {
|
|
void *data;
|
|
int unrelated;
|
|
};
|
|
|
|
struct middle {
|
|
inner arr[10];
|
|
inner *ptr;
|
|
};
|
|
|
|
struct outer {
|
|
middle nested;
|
|
middle *indirect;
|
|
};
|
|
|
|
void nested_array_1(outer o) {
|
|
o.nested.arr[1].data = user_input();
|
|
sink(o.nested.arr[1].data); // $ast,ir
|
|
sink(o.nested.arr[0].data); // $f+:ast
|
|
}
|
|
|
|
void nested_array_2(outer o) {
|
|
o.indirect->arr[1].data = user_input();
|
|
sink(o.indirect->arr[1].data); // $ast $f-:ir
|
|
sink(o.indirect->arr[0].data); // $f+:ast
|
|
}
|
|
|
|
void nested_array_3(outer o) {
|
|
o.indirect->ptr[1].data = user_input();
|
|
sink(o.indirect->ptr[1].data); // $f-:ast,ir
|
|
sink(o.indirect->ptr[0].data);
|
|
}
|