FTDISerialDevice: simplify adaptArray() length formula and fix crash bug

The old iterative method of calculating realLength was pretty clumsy
and slow.

Additionally, it failed to consider an incomplete FTDI header.  This
shouldn't happen, but it was seen in the dirty real world:

 java.lang.ArrayIndexOutOfBoundsException: src.length=65 srcPos=2 dst.length=61 dstPos=0 length=62
   at java.lang.System.arraycopy(Native Method)
   at com.felhr.usbserial.FTDISerialDevice.copyData(FTDISerialDevice.java:527)
   at com.felhr.usbserial.FTDISerialDevice.adaptArray(FTDISerialDevice.java:508)
   at com.felhr.usbserial.UsbSerialDevice$WorkerThread.doRun(UsbSerialDevice.java:359)
   at com.felhr.usbserial.AbstractWorkerThread.run(AbstractWorkerThread.java:21)

The same bug would manifest in copyData() due to a badly implemented
length check.

Fixes https://github.com/XCSoar/XCSoar/issues/1032
pull/356/head
Max Kellermann 2022-09-02 22:47:30 +02:00
rodzic b35bc77c2c
commit aa8de4ed93
1 zmienionych plików z 5 dodań i 9 usunięć

Wyświetl plik

@ -495,15 +495,11 @@ public class FTDISerialDevice extends UsbSerialDevice
int length = ftdiData.length;
if(length > 64)
{
int n = 1;
int p = 64;
// Precalculate length without FTDI headers
while(p < length)
{
n++;
p = n*64;
}
int realLength = length - n*2;
int realLength = (length / 64) * 62;
if (length % 64 > 2)
realLength += length % 64 - 2;
byte[] data = new byte[realLength];
copyData(ftdiData, data);
return data;
@ -529,7 +525,7 @@ public class FTDISerialDevice extends UsbSerialDevice
dstPos += 62;
}
int remaining = src.length - srcPos + 2;
if (remaining > 0)
if (remaining > 2)
{
System.arraycopy(src, srcPos, dst, dstPos, remaining - 2);
}