mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Exception stack trace analysis: support negative index/length reported from arraycopy
GitOrigin-RevId: a1d20d0865cdeb5d7413fca5c379243b1ff343c8
This commit is contained in:
committed by
intellij-monorepo-bot
parent
64a4cc2be6
commit
bf6805099c
@@ -129,6 +129,11 @@ public class DataflowExceptionAnalysisProvider implements ExceptionAnalysisProvi
|
||||
else if (info instanceof ArithmeticExceptionInfo) {
|
||||
return fromArithmeticException(anchor);
|
||||
}
|
||||
else if (info instanceof ArrayCopyIndexOutOfBoundsExceptionInfo) {
|
||||
if (anchor instanceof PsiExpression) {
|
||||
return Analysis.create(DfTypes.intValue(((ArrayCopyIndexOutOfBoundsExceptionInfo)info).getValue()), (PsiExpression)anchor);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+21
@@ -288,6 +288,27 @@ public class DataflowExceptionAnalysisProviderTest extends LightJavaCodeInsightT
|
||||
" void callee(String x, String y, String z) {}\n" +
|
||||
"}");
|
||||
}
|
||||
|
||||
public void testArrayCopySource() {
|
||||
doTest("java.lang.ArrayIndexOutOfBoundsException: arraycopy: source index -1 out of bounds for int[10]\n" +
|
||||
"\tat java.base/java.lang.System.arraycopy(Native Method)",
|
||||
"Find why 'src' could be -1",
|
||||
"class Test {static void test(int[] data, int src, int dst, int len) { System.arraycopy(data, src, data, dst, len); }}");
|
||||
}
|
||||
|
||||
public void testArrayCopyDest() {
|
||||
doTest("java.lang.ArrayIndexOutOfBoundsException: arraycopy: destination index -1 out of bounds for int[10]\n" +
|
||||
"\tat java.base/java.lang.System.arraycopy(Native Method)",
|
||||
"Find why 'dst' could be -1",
|
||||
"class Test {static void test(int[] data, int src, int dst, int len) { System.arraycopy(data, src, data, dst, len); }}");
|
||||
}
|
||||
|
||||
public void testArrayCopyLength() {
|
||||
doTest("java.lang.ArrayIndexOutOfBoundsException: arraycopy: length -1 is negative\n" +
|
||||
"\tat java.base/java.lang.System.arraycopy(Native Method)",
|
||||
"Find why 'len' could be -1",
|
||||
"class Test {static void test(int[] data, int src, int dst, int len) { System.arraycopy(data, src, data, dst, len); }}");
|
||||
}
|
||||
|
||||
private void doTest(@NotNull String exceptionLine,
|
||||
@Nullable("If no action is expected") String expectedActionTitle,
|
||||
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.execution.filters;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ArrayCopyIndexOutOfBoundsExceptionInfo extends ExceptionInfo {
|
||||
private static final String SOURCE_INDEX_PREFIX = "source index ";
|
||||
private static final String DESTINATION_INDEX_PREFIX = "destination index ";
|
||||
private static final String COMMON_PREFIX = "arraycopy: ";
|
||||
private static final String LENGTH_PREFIX = "length ";
|
||||
private final int myValue;
|
||||
private final int myParameter;
|
||||
|
||||
public ArrayCopyIndexOutOfBoundsExceptionInfo(int offset, String message, int value, int parameter) {
|
||||
super(offset, "java.lang.ArrayIndexOutOfBoundsException", message);
|
||||
myValue = value;
|
||||
myParameter = parameter;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable PsiElement matchSpecificExceptionElement(@NotNull PsiElement element) {
|
||||
if (!(element instanceof PsiIdentifier)) return null;
|
||||
if (!element.textMatches("arraycopy")) return null;
|
||||
PsiElement ref = element.getParent();
|
||||
if (!(ref instanceof PsiReferenceExpression)) return null;
|
||||
PsiMethodCallExpression call = ObjectUtils.tryCast(ref.getParent(), PsiMethodCallExpression.class);
|
||||
if (call == null) return null;
|
||||
PsiExpression[] args = call.getArgumentList().getExpressions();
|
||||
if (args.length != 5) return null;
|
||||
PsiMethod method = call.resolveMethod();
|
||||
if (method == null) return null;
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass == null || !"java.lang.System".equals(containingClass.getQualifiedName())) return null;
|
||||
return args[myParameter];
|
||||
}
|
||||
|
||||
public static ExceptionInfo tryCreate(int offset, String message) {
|
||||
if (!message.startsWith(COMMON_PREFIX)) return null;
|
||||
int parameter;
|
||||
int indexOffset = COMMON_PREFIX.length();
|
||||
if (message.startsWith(SOURCE_INDEX_PREFIX, COMMON_PREFIX.length())) {
|
||||
parameter = 1;
|
||||
indexOffset += SOURCE_INDEX_PREFIX.length();
|
||||
}
|
||||
else if (message.startsWith(DESTINATION_INDEX_PREFIX, COMMON_PREFIX.length())) {
|
||||
parameter = 3;
|
||||
indexOffset += DESTINATION_INDEX_PREFIX.length();
|
||||
}
|
||||
else if (message.startsWith(LENGTH_PREFIX, COMMON_PREFIX.length())) {
|
||||
parameter = 4;
|
||||
indexOffset += LENGTH_PREFIX.length();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
int indexEndOffset = message.indexOf(' ', indexOffset);
|
||||
if (indexEndOffset == -1) return null;
|
||||
String indexStr = message.substring(indexOffset, indexEndOffset);
|
||||
int index;
|
||||
try {
|
||||
index = Integer.parseInt(indexStr);
|
||||
}
|
||||
catch (NumberFormatException ignored) {
|
||||
return null;
|
||||
}
|
||||
return new ArrayCopyIndexOutOfBoundsExceptionInfo(offset, message, index, parameter);
|
||||
}
|
||||
}
|
||||
+8
@@ -24,6 +24,14 @@ public class ArrayIndexOutOfBoundsExceptionInfo extends ExceptionInfo {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExceptionInfo consumeStackLine(String line) {
|
||||
if (line.contains("java.lang.System.arraycopy")) {
|
||||
return ArrayCopyIndexOutOfBoundsExceptionInfo.tryCreate(getClassNameOffset(), getExceptionMessage());
|
||||
}
|
||||
return super.consumeStackLine(line);
|
||||
}
|
||||
|
||||
public @Nullable Integer getIndex() {
|
||||
return myIndex;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user