mirror of
https://github.com/github/codeql.git
synced 2026-01-17 00:14:51 +01:00
Flow from a definition by reference of a field into its object was working inconsistently and in a very syntax-dependent way. For a function `f` receiving a reference, `f(a->x)` could propagate data back to `a` via the _reverse read_ mechanism in the shared data-flow library, but for a function `g` receiving a pointer, `g(&a->x)` would not work. And `f((*a).x)` would not work either. In all cases, the issue was that the shared data-flow library propagates data backwards between `PostUpdateNode`s only, but there is no `PostUpdateNode` for `a->x` in `g(&a->x)`. This pull request inserts such post-update nodes where appropriate and links them to their neighbors. In this exapmle, flow back from the output parameter of `g` passes first to the `PostUpdateNode` of `&`, then to the (new) `PostUpdateNode` of `a->x`, and finally, as a _reverse read_ with the appropriate field projection, to `a`.
50 lines
1.2 KiB
C++
50 lines
1.2 KiB
C++
void sink(void *o);
|
|
void *user_input(void);
|
|
|
|
namespace qualifiers {
|
|
|
|
struct Inner {
|
|
void *a;
|
|
|
|
void setA(void *value) { this->a = value; }
|
|
};
|
|
|
|
void pointerSetA(Inner *inner, void *value) { inner->a = value; }
|
|
void referenceSetA(Inner &inner, void *value) { inner.a = value; }
|
|
|
|
struct Outer {
|
|
Inner *inner;
|
|
|
|
Inner *getInner() { return inner; }
|
|
};
|
|
|
|
void assignToGetter(Outer outer) {
|
|
outer.getInner()->a = user_input();
|
|
sink(outer.inner->a); // flow [NOT DETECTED by IR]
|
|
}
|
|
|
|
void getterArgument1(Outer outer) {
|
|
outer.getInner()->setA(user_input());
|
|
sink(outer.inner->a); // flow [NOT DETECTED by IR]
|
|
}
|
|
|
|
void getterArgument2(Outer outer) {
|
|
pointerSetA(outer.getInner(), user_input());
|
|
sink(outer.inner->a); // flow [NOT DETECTED by IR]
|
|
}
|
|
|
|
void getterArgument2Ref(Outer outer) {
|
|
referenceSetA(*outer.getInner(), user_input());
|
|
sink(outer.inner->a); // flow [NOT DETECTED by IR]
|
|
}
|
|
|
|
void assignToGetterStar(Outer outer) {
|
|
(*outer.getInner()).a = user_input();
|
|
sink(outer.inner->a); // flow [NOT DETECTED by IR]
|
|
}
|
|
|
|
void assignToGetterAmp(Outer outer) {
|
|
(&outer)->getInner()->a = user_input();
|
|
sink(outer.inner->a); // flow [NOT DETECTED by IR]
|
|
}
|
|
} |