mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SourceToSinkFlowInspection: support for kotlin primary constructor parameter (IDEA-282918)
GitOrigin-RevId: 9d89e42e7d7891237b180ede447d7bd6b3e134af
This commit is contained in:
committed by
intellij-monorepo-bot
parent
83c934c331
commit
704b5b0f72
+18
-14
@@ -4,6 +4,7 @@ package com.intellij.codeInspection.sourceToSink;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import one.util.streamex.MoreCollectors;
|
||||
import one.util.streamex.StreamEx;
|
||||
@@ -73,11 +74,11 @@ public class TaintAnalyzer {
|
||||
return codeBlock == null ? TaintValue.UNTAINTED : analyze(taintValue, codeBlock, psiVariable);
|
||||
}
|
||||
|
||||
private TaintValue analyze(@NotNull TaintValue taintValue, @NotNull UBlockExpression codeBlock, @NotNull PsiVariable psiVariable) {
|
||||
private @NotNull TaintValue analyze(@NotNull TaintValue taintValue, @NotNull UBlockExpression codeBlock, @NotNull PsiVariable psiVariable) {
|
||||
class VarAnalyzer extends AbstractUastVisitor {
|
||||
private TaintValue myTaintValue;
|
||||
|
||||
VarAnalyzer(TaintValue taintValue) {
|
||||
VarAnalyzer(@NotNull TaintValue taintValue) {
|
||||
myTaintValue = taintValue;
|
||||
}
|
||||
|
||||
@@ -110,27 +111,30 @@ public class TaintAnalyzer {
|
||||
}
|
||||
|
||||
private @Nullable TaintValue fromParam(@Nullable PsiElement target) {
|
||||
PsiParameter psiParameter = ObjectUtils.tryCast(target, PsiParameter.class);
|
||||
if (psiParameter == null) return null;
|
||||
UParameter uParameter = UastContextKt.toUElement(target, UParameter.class);
|
||||
if (uParameter == null) return null;
|
||||
PsiParameter psiParameter = ObjectUtils.tryCast(uParameter.getSourcePsi(), PsiParameter.class);
|
||||
if (psiParameter == null) return null;
|
||||
UMethod uMethod = ObjectUtils.tryCast(uParameter.getUastParent(), UMethod.class);
|
||||
if (uMethod == null) return TaintValue.UNTAINTED;
|
||||
UBlockExpression uBlock = ObjectUtils.tryCast(uMethod.getUastBody(), UBlockExpression.class);
|
||||
if (uBlock == null) return TaintValue.UNTAINTED;
|
||||
// default parameter value
|
||||
UExpression uInitializer = uParameter.getUastInitializer();
|
||||
TaintValue taintValue = fromExpression(uInitializer, true);
|
||||
if (taintValue == TaintValue.TAINTED) return taintValue;
|
||||
taintValue = analyze(taintValue, uBlock, psiParameter);
|
||||
UMethod uMethod = ObjectUtils.tryCast(uParameter.getUastParent(), UMethod.class);
|
||||
if (uMethod == null) return TaintValue.UNTAINTED;
|
||||
UBlockExpression uBlock = ObjectUtils.tryCast(uMethod.getUastBody(), UBlockExpression.class);
|
||||
if (uBlock != null) taintValue = analyze(taintValue, uBlock, psiParameter);
|
||||
if (taintValue == TaintValue.TAINTED) return taintValue;
|
||||
int paramIdx = uMethod.getUastParameters().indexOf(uParameter);
|
||||
SmartList<NonMarkedElement> nonMarkedElements = new SmartList<>();
|
||||
// this might happen when we analyze kotlin primary constructor parameter
|
||||
if (uBlock == null) nonMarkedElements.addAll(findAssignments(target));
|
||||
PsiMethod psiMethod = ObjectUtils.tryCast(uMethod.getSourcePsi(), PsiMethod.class);
|
||||
// TODO: handle varargs
|
||||
if (psiMethod == null || psiMethod.isVarArgs()) return TaintValue.UNTAINTED;
|
||||
Collection<NonMarkedElement> args = findArgs(psiMethod, paramIdx);
|
||||
if (args.isEmpty()) return taintValue;
|
||||
myNonMarkedElements.addAll(args);
|
||||
if (psiMethod != null && !psiMethod.isVarArgs()) {
|
||||
int paramIdx = uMethod.getUastParameters().indexOf(uParameter);
|
||||
nonMarkedElements.addAll(findArgs(psiMethod, paramIdx));
|
||||
}
|
||||
if (nonMarkedElements.isEmpty()) return taintValue;
|
||||
myNonMarkedElements.addAll(nonMarkedElements);
|
||||
return TaintValue.UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
+1
-9
@@ -16,13 +16,9 @@ import com.intellij.openapi.wm.ToolWindowId;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.ui.content.Content;
|
||||
import com.intellij.usageView.UsageViewContentManager;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -59,11 +55,7 @@ public class PropagateFix extends LocalQuickFixAndIntentionActionOnPsiElement {
|
||||
if (reportedElement == null) return;
|
||||
TaintAnalyzer analyzer = new TaintAnalyzer();
|
||||
if (analyzer.analyze(uExpression) != TaintValue.UNKNOWN) return;
|
||||
PsiModifierListOwner target = ObjectUtils.tryCast(((UResolvable)uExpression).resolve(), PsiModifierListOwner.class);
|
||||
if (target == null) return;
|
||||
// TODO: won't work if we start from kotlin
|
||||
PsiMethod method = PsiTreeUtil.getParentOfType(reportedElement, PsiMethod.class);
|
||||
if (method == null) return;
|
||||
PsiElement target = ((UResolvable)uExpression).resolve();
|
||||
String title = JvmAnalysisBundle.message("jvm.inspections.source.unsafe.to.sink.flow.propagate.safe.toolwindow.title");
|
||||
TaintNode root = new TaintNode(null, target, reportedElement);
|
||||
if (ApplicationManager.getApplication().isHeadlessEnvironment()) {
|
||||
|
||||
Reference in New Issue
Block a user