import org.apache.commons.lang3.mutable.Mutable; import org.apache.commons.lang3.mutable.MutableObject; class MutableTest { String taint() { return "tainted"; } void sink(Object o) {} void test() throws Exception { MutableObject tainted = new MutableObject<>(taint()); MutableObject taintSet = new MutableObject<>("clean"); MutableObject taintCleared = new MutableObject<>(taint()); taintSet.setValue(taint()); taintCleared.setValue("clean"); Mutable taintedAlias = tainted; Mutable taintSetAlias = taintSet; Mutable taintClearedAlias = taintCleared; sink(tainted.getValue()); // $hasValueFlow sink(taintedAlias.getValue()); // $hasValueFlow sink(taintSet.getValue()); // $hasValueFlow sink(taintSetAlias.getValue()); // $hasValueFlow // These two cases don't work currently because synthetic fields are always weakly updated, // so no taint clearing takes place. sink(taintCleared.getValue()); // $SPURIOUS: hasValueFlow sink(taintClearedAlias.getValue()); // $SPURIOUS: hasValueFlow } }