void sink(void *o); void *user_input(void); struct S { void *a; /* * Setters */ friend void nonMemberSetA(struct S *s, void *value) { s->a = value; } void setDirectly(void *value) { this->a = value; } void setIndirectly(void *value) { this->setDirectly(value); } void setThroughNonMember(void *value) { nonMemberSetA(this, value); } /* * Getters */ friend void *nonMemberGetA(const struct S *s) { return s->a; } void* getDirectly() const { return this->a; } void* getIndirectly() const { return this->getDirectly(); } void *getThroughNonMember() const { return nonMemberGetA(this); } }; void test_setDirectly() { S s; s.setDirectly(user_input()); sink(s.getDirectly()); // $ast ir } void test_setIndirectly() { S s; s.setIndirectly(user_input()); sink(s.getIndirectly()); // $ast ir } void test_setThroughNonMember() { S s; s.setThroughNonMember(user_input()); sink(s.getThroughNonMember()); // $ast ir } void test_nonMemberSetA() { S s; nonMemberSetA(&s, user_input()); sink(nonMemberGetA(&s)); // $ast,ir } //////////////////// struct Inner { void *a; }; struct Outer { Inner inner_nested, *inner_ptr; void *a; }; void taint_inner_a_ptr(Inner *inner) { inner->a = user_input(); } void taint_inner_a_ref(Inner &inner) { inner.a = user_input(); } void taint_a_ptr(void **pa) { *pa = user_input(); } void taint_a_ref(void *&pa) { pa = user_input(); } void test_outer_with_ptr(Outer *pouter) { Outer outer; taint_inner_a_ptr(&outer.inner_nested); taint_inner_a_ptr(outer.inner_ptr); taint_a_ptr(&outer.a); taint_inner_a_ptr(&pouter->inner_nested); taint_inner_a_ptr(pouter->inner_ptr); taint_a_ptr(&pouter->a); sink(outer.inner_nested.a); // $ ast,ir sink(outer.inner_ptr->a); // $ ast,ir sink(outer.a); // $ ast,ir sink(pouter->inner_nested.a); // $ ast,ir sink(pouter->inner_ptr->a); // $ast,ir sink(pouter->a); // $ ast,ir } void test_outer_with_ref(Outer *pouter) { Outer outer; taint_inner_a_ref(outer.inner_nested); taint_inner_a_ref(*outer.inner_ptr); taint_a_ref(outer.a); taint_inner_a_ref(pouter->inner_nested); taint_inner_a_ref(*pouter->inner_ptr); taint_a_ref(pouter->a); sink(outer.inner_nested.a); // $ ast,ir sink(outer.inner_ptr->a); // $ ast,ir sink(outer.a); // $ ast,ir sink(pouter->inner_nested.a); // $ ast,ir sink(pouter->inner_ptr->a); // $ ast,ir sink(pouter->a); // $ ast,ir }