SourceToSinkFlowInspection: support for kotlin property auto generated accessors (IDEA-282918)

GitOrigin-RevId: 818a39dcdd4988f8ad2294c3487f9f88f6e3fa7b
This commit is contained in:
Artemiy Sartakov
2021-12-02 18:03:06 +07:00
committed by intellij-monorepo-bot
parent 704b5b0f72
commit 1745c22fce
4 changed files with 63 additions and 2 deletions

View File

@@ -187,7 +187,13 @@ public class TaintAnalyzer {
}
UBlockExpression methodBody = ObjectUtils.tryCast(uMethod.getUastBody(), UBlockExpression.class);
if (methodBody == null) return TaintValue.UNTAINTED;
if (methodBody == null) {
// maybe it is a generated kotlin property getter or setter
PsiElement sourcePsi = uMethod.getSourcePsi();
if (sourcePsi == null) return TaintValue.UNTAINTED;
TaintValue taintValue = fromField(sourcePsi);
return taintValue == null ? TaintValue.UNTAINTED : taintValue;
}
MethodAnalyzer methodAnalyzer = new MethodAnalyzer();
methodBody.accept(methodAnalyzer);
List<NonMarkedElement> children = methodAnalyzer.myChildren;
@@ -244,7 +250,17 @@ public class TaintAnalyzer {
UastBinaryOperator operator = uBinary.getOperator();
if (operator != UastBinaryOperator.ASSIGN && operator != UastBinaryOperator.PLUS_ASSIGN) return false;
UResolvable leftOperand = ObjectUtils.tryCast(UastUtils.skipParenthesizedExprDown(uBinary.getLeftOperand()), UResolvable.class);
return leftOperand != null && leftOperand.resolve() == target;
if (leftOperand == null) return false;
PsiElement lhsTarget = leftOperand.resolve();
if (lhsTarget == target) return true;
// maybe it's kotlin property auto generated setter
if (!(lhsTarget instanceof PsiMethod) || ((PsiMethod)lhsTarget).getBody() != null) {
return false;
}
UElement uElement = UastContextKt.toUElement(lhsTarget);
if (uElement == null) return false;
PsiElement property = uElement.getSourcePsi();
return property == target;
}
private static @Nullable PsiType getType(@Nullable PsiElement element) {

View File

@@ -0,0 +1,19 @@
import org.checkerframework.checker.tainting.qual.*
class TestCtor {
var f: @Untainted String = ""
fun test() {
f = bar()
sink(f)
}
fun bar(): @Untainted String {
return "foo"
}
fun sink(s: @Untainted String) {
}
}

View File

@@ -0,0 +1,19 @@
import org.checkerframework.checker.tainting.qual.*
class TestCtor {
var f: String = ""
fun test() {
f = bar()
sink(<caret>f)
}
fun bar(): String {
return "foo"
}
fun sink(s: @Untainted String) {
}
}

View File

@@ -47,4 +47,11 @@ class KotlinSourceToSinkFlowTest: LightJavaCodeInsightFixtureTestCase() {
myFixture.testHighlighting("LocalInference.kt")
}
fun testKotlinPropertyPropagateFix() {
myFixture.configureByFile("Property.kt")
val propagateAction = myFixture.getAvailableIntention("Propagate safe annotation from 'getF'")!!
myFixture.launchAction(propagateAction)
myFixture.checkResultByFile("Property.after.kt")
}
}