@@ -636,31 +636,41 @@ private module Internal {
636
636
)
637
637
}
638
638
639
- private predicate stepExpr0(Expr succ, Expr pred) {
640
- Steps::stepOpen(pred, succ)
641
- or
642
- exists(Assignable a |
643
- a instanceof Field or
644
- a instanceof Property
645
- |
646
- succ.(AssignableRead) = a.getAnAccess() and
647
- pred = a.getAnAssignedValue() and
648
- a = any(Modifiable m | not m.isEffectivelyPublic())
649
- )
650
- }
651
-
652
- private predicate stepExpr(Expr succ, Expr pred) {
653
- stepExpr0(succ, pred) and
639
+ private predicate stepExpr(Expr pred, Expr succ) {
640
+ Steps::stepOpen(pred, succ) and
654
641
// Do not step through down casts
655
642
not downCast(succ) and
656
643
// Only step when we may learn more about the actual type
657
644
typeMayBeImprecise(succ.getType())
658
645
}
659
646
660
- private predicate stepTC(Expr succ, Expr pred) = fastTC(stepExpr/2)(succ, pred)
647
+ private class AnalyzableFieldOrProperty extends Assignable, Modifiable {
648
+ AnalyzableFieldOrProperty() {
649
+ (
650
+ this instanceof Field or
651
+ this instanceof Property
652
+ ) and
653
+ not this.isEffectivelyPublic() and
654
+ exists(this.getAnAssignedValue())
655
+ }
656
+
657
+ AssignableRead getARead() { result = this.getAnAccess() }
658
+ }
661
659
662
660
private class Source extends Expr {
663
- Source() { not stepExpr(this, _) }
661
+ Source() {
662
+ not stepExpr(_, this) and
663
+ not this = any(AnalyzableFieldOrProperty a).getARead()
664
+ }
665
+
666
+ Type getType(boolean isExact) {
667
+ result = this.getType() and
668
+ if
669
+ this instanceof ObjectCreation or
670
+ this instanceof BaseAccess
671
+ then isExact = true
672
+ else isExact = false
673
+ }
664
674
}
665
675
666
676
private class Sink extends Expr {
@@ -680,24 +690,38 @@ private module Internal {
680
690
this = any(DispatchCallImpl c).getArgument(_)
681
691
}
682
692
683
- Source getASource() { stepTC(this, result) }
693
+ pragma[nomagic]
694
+ Expr getAPred() { stepExpr*(result, this) }
695
+
696
+ pragma[nomagic]
697
+ AnalyzableFieldOrProperty getAPredRead() { this.getAPred() = result.getARead() }
684
698
}
685
699
686
- /** Holds if the expression `e` has an exact type. */
687
- private predicate hasExactType(Expr e) {
688
- e instanceof ObjectCreation or
689
- e instanceof BaseAccess
700
+ /** Gets a source type for sink expression `e`, using simple data flow. */
701
+ Type getASourceType(Sink sink, boolean isExact) {
702
+ result = sink.getAPred().(Source).getType(isExact)
703
+ or
704
+ result = sink.getAPredRead().(RelevantFieldOrProperty).getASourceType(isExact)
690
705
}
691
706
692
- /** Gets a source type for expression `e`, using simple data flow. */
693
- Type getASourceType(Sink e, boolean isExact) {
694
- exists(Source s |
695
- s = e.getASource() or
696
- s = e
697
- |
698
- result = s.getType() and
699
- if hasExactType(s) then isExact = true else isExact = false
700
- )
707
+ private class RelevantFieldOrProperty extends AnalyzableFieldOrProperty {
708
+ RelevantFieldOrProperty() {
709
+ this = any(Sink s).getAPredRead()
710
+ or
711
+ this = any(RelevantFieldOrProperty a).getAPredRead()
712
+ }
713
+
714
+ pragma[nomagic]
715
+ Expr getAPred() { stepExpr*(result, this.getAnAssignedValue()) }
716
+
717
+ pragma[nomagic]
718
+ AnalyzableFieldOrProperty getAPredRead() { this.getAPred() = result.getARead() }
719
+
720
+ Type getASourceType(boolean isExact) {
721
+ result = this.getAPred().(Source).getType(isExact)
722
+ or
723
+ result = this.getAPredRead().(RelevantFieldOrProperty).getASourceType(isExact)
724
+ }
701
725
}
702
726
}
703
727
0 commit comments