How to determine array size in Java bytecode (FindBugs)

I would like to know about the size of the allocated array by looking at the bytecode if this information is known at compile time, of course.

Background: I want to write a FindBugs detector (which looks at compiled bytecode) and report some cases of array allocation. To filter out false positives, I am not interested in "small" arrays, but only those whose size is not available at compile time or more than a custom threshold.

Since the source code for FindBugs is not too documented, I'm looking for some tips on how to get started - maybe there is already a tool that does something similar that I could look at.

+4
source share
2 answers

It may seem complicated. My knowledge is incomplete, but you have at least three kinds of instructions to look for (NEWARRAY, ANEWARRAY and MULTIANEWARRAY). Looking at the previous instruction (or in the case of MULTIANEWARRAY, n of the previous instructions) it gets a size that, even if it was a constant, can be loaded using BIPUSH, SIPUSH or LDC (anything else?) Depending on the size. As you noticed, if a class is the result of a calculation, you can track instructions back indefinitely.

If I remember correctly, FindBugs uses BCEL internally, but I never dug there to understand how smart they are. If each of these groups has corresponding mailing lists, they might be better off to ask - they will probably at least find out if anyone has been along the way before.

+2
source

Well, if they are distributed based on a constant, you can check the constant that was pressed just before the distribution. For instance:

class ArraySize { private static final int smallsize = 10; private static final int largesize = 1000; public static void main(String[] args) { int[] small = new int[smallsize]; int[] big = new int[largesize]; } } 

gives a bytecode:

 Compiled from "ArraySize.java" class ArraySize extends java.lang.Object{ ArraySize(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: bipush 10 2: newarray int 4: astore_1 5: sipush 1000 8: newarray int 10: astore_2 11: return } 
+5
source

Source: https://habr.com/ru/post/1286227/


All Articles