Program: 99424
Project: 99424
Buggy source:
@Override public void run(){
  final UsbDeviceConnection deviceConnection=usbDeviceConnection;
  final UsbEndpoint usbEndpoint=inputEndpoint;
  final int maxPacketSize=inputEndpoint.getMaxPacketSize();
  final MidiInputDevice sender=MidiInputDevice.this;
  final OnMidiInputEventListener midiEventListener=MidiInputDevice.this.midiEventListener;
  final byte[] bulkReadBuffer=new byte[maxPacketSize];
  byte[] readBuffer=new byte[maxPacketSize * 2];
  int readBufferSize=0;
  byte[] read=new byte[maxPacketSize * 2];
  int length;
  int cable;
  int codeIndexNumber;
  int byte1;
  int byte2;
  int byte3;
  int i;
  int readSize;
  int unreadSize;
  final int RPN_STATUS_NONE=0;
  final int RPN_STATUS_RPN=1;
  final int RPN_STATUS_NRPN=2;
  int rpnNrpnFunction;
  int rpnNrpnValueMsb;
  int rpnNrpnValueLsb;
  int rpnStatus=RPN_STATUS_NONE;
  int rpnFunctionMsb=0x7f;
  int rpnFunctionLsb=0x7f;
  int nrpnFunctionMsb=0x7f;
  int nrpnFunctionLsb=0x7f;
  SparseIntArray rpnCacheMsb=new SparseIntArray();
  SparseIntArray rpnCacheLsb=new SparseIntArray();
  SparseIntArray nrpnCacheMsb=new SparseIntArray();
  SparseIntArray nrpnCacheLsb=new SparseIntArray();
  ReusableByteArrayOutputStream[] systemExclusive=new ReusableByteArrayOutputStream[16];
  for (i=0; i < 16; i++) {
    systemExclusive[i]=new ReusableByteArrayOutputStream();
  }
  while (!stopFlag) {
    length=deviceConnection.bulkTransfer(usbEndpoint,bulkReadBuffer,maxPacketSize,10);
synchronized (suspendSignal) {
      if (suspendFlag) {
        try {
          suspendSignal.wait(100);
        }
 catch (        InterruptedException e) {
        }
        continue;
      }
    }
    if (length <= 0) {
      continue;
    }
    System.arraycopy(bulkReadBuffer,0,readBuffer,readBufferSize,length);
    readBufferSize+=length;
    if (readBufferSize < 4) {
      continue;
    }
    readSize=readBufferSize / 4 * 4;
    System.arraycopy(readBuffer,0,read,0,readSize);
    unreadSize=readBufferSize - readSize;
    if (unreadSize > 0) {
      System.arraycopy(readBuffer,readSize,readBuffer,0,unreadSize);
      readBufferSize=unreadSize;
    }
 else {
      readBufferSize=0;
    }
    for (i=0; i < readSize; i+=4) {
      cable=(read[i] >> 4) & 0xf;
      codeIndexNumber=read[i] & 0xf;
      byte1=read[i + 1] & 0xff;
      byte2=read[i + 2] & 0xff;
      byte3=read[i + 3] & 0xff;
switch (codeIndexNumber) {
case 0:
        if (midiEventListener != null) {
          midiEventListener.onMidiMiscellaneousFunctionCodes(sender,cable,byte1,byte2,byte3);
        }
      break;
case 1:
    if (midiEventListener != null) {
      midiEventListener.onMidiCableEvents(sender,cable,byte1,byte2,byte3);
    }
  break;
case 2:
if (midiEventListener != null) {
  byte[] bytes=new byte[]{(byte)byte1,(byte)byte2};
  midiEventListener.onMidiSystemCommonMessage(sender,cable,bytes);
}
break;
case 3:
if (midiEventListener != null) {
byte[] bytes=new byte[]{(byte)byte1,(byte)byte2,(byte)byte3};
midiEventListener.onMidiSystemCommonMessage(sender,cable,bytes);
}
break;
case 4:
synchronized (systemExclusive[cable]) {
systemExclusive[cable].write(byte1);
systemExclusive[cable].write(byte2);
systemExclusive[cable].write(byte3);
}
break;
case 5:
synchronized (systemExclusive[cable]) {
systemExclusive[cable].write(byte1);
if (midiEventListener != null) {
midiEventListener.onMidiSystemExclusive(sender,cable,systemExclusive[cable].toByteArray());
}
systemExclusive[cable].reset();
}
break;
case 6:
synchronized (systemExclusive[cable]) {
systemExclusive[cable].write(byte1);
systemExclusive[cable].write(byte2);
if (midiEventListener != null) {
midiEventListener.onMidiSystemExclusive(sender,cable,systemExclusive[cable].toByteArray());
}
systemExclusive[cable].reset();
}
break;
case 7:
synchronized (systemExclusive[cable]) {
systemExclusive[cable].write(byte1);
systemExclusive[cable].write(byte2);
systemExclusive[cable].write(byte3);
if (midiEventListener != null) {
midiEventListener.onMidiSystemExclusive(sender,cable,systemExclusive[cable].toByteArray());
}
systemExclusive[cable].reset();
}
break;
case 8:
if (midiEventListener != null) {
midiEventListener.onMidiNoteOff(sender,cable,byte1 & 0xf,byte2,byte3);
}
break;
case 9:
if (midiEventListener != null) {
if (byte3 == 0x00) {
midiEventListener.onMidiNoteOff(sender,cable,byte1 & 0xf,byte2,byte3);
}
 else {
midiEventListener.onMidiNoteOn(sender,cable,byte1 & 0xf,byte2,byte3);
}
}
break;
case 10:
if (midiEventListener != null) {
midiEventListener.onMidiPolyphonicAftertouch(sender,cable,byte1 & 0xf,byte2,byte3);
}
break;
case 11:
if (midiEventListener != null) {
midiEventListener.onMidiControlChange(sender,cable,byte1 & 0xf,byte2,byte3);
}
switch (byte2) {
case 6:
{
rpnNrpnValueMsb=byte3 & 0x7f;
if (rpnStatus == RPN_STATUS_RPN) {
rpnNrpnFunction=((rpnFunctionMsb & 0x7f) << 7) | (rpnFunctionLsb & 0x7f);
rpnCacheMsb.put(rpnNrpnFunction,rpnNrpnValueMsb);
rpnNrpnValueLsb=rpnCacheLsb.get(rpnNrpnFunction,0);
if (midiEventListener != null) {
midiEventListener.onMidiRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,(rpnNrpnValueMsb << 7 | rpnNrpnValueLsb));
midiEventListener.onMidiRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,rpnNrpnValueMsb,rpnNrpnValueLsb);
}
}
 else if (rpnStatus == RPN_STATUS_NRPN) {
rpnNrpnFunction=((nrpnFunctionMsb & 0x7f) << 7) | (nrpnFunctionLsb & 0x7f);
nrpnCacheMsb.put(rpnNrpnFunction,rpnNrpnValueMsb);
rpnNrpnValueLsb=nrpnCacheLsb.get(rpnNrpnFunction,0);
if (midiEventListener != null) {
midiEventListener.onMidiNRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,(rpnNrpnValueMsb << 7 | rpnNrpnValueLsb));
midiEventListener.onMidiNRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,rpnNrpnValueMsb,rpnNrpnValueLsb);
}
}
break;
}
case 38:
{
rpnNrpnValueLsb=byte3 & 0x7f;
if (rpnStatus == RPN_STATUS_RPN) {
rpnNrpnFunction=((rpnFunctionMsb & 0x7f) << 7) | (rpnFunctionLsb & 0x7f);
rpnNrpnValueMsb=rpnCacheMsb.get(rpnNrpnFunction,0);
rpnCacheLsb.put(rpnNrpnFunction,rpnNrpnValueLsb);
if (midiEventListener != null) {
midiEventListener.onMidiRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,(rpnNrpnValueMsb << 7 | rpnNrpnValueLsb));
midiEventListener.onMidiRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,rpnNrpnValueMsb,rpnNrpnValueLsb);
}
}
 else if (rpnStatus == RPN_STATUS_NRPN) {
rpnNrpnFunction=((nrpnFunctionMsb & 0x7f) << 7) | (nrpnFunctionLsb & 0x7f);
rpnNrpnValueMsb=nrpnCacheMsb.get(rpnNrpnFunction,0);
nrpnCacheLsb.put(rpnNrpnFunction,rpnNrpnValueLsb);
if (midiEventListener != null) {
midiEventListener.onMidiNRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,(rpnNrpnValueMsb << 7 | rpnNrpnValueLsb));
midiEventListener.onMidiNRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,rpnNrpnValueMsb,rpnNrpnValueLsb);
}
}
break;
}
case 98:
{
nrpnFunctionLsb=byte3 & 0x7f;
rpnStatus=RPN_STATUS_NRPN;
break;
}
case 99:
{
nrpnFunctionMsb=byte3 & 0x7f;
rpnStatus=RPN_STATUS_NRPN;
break;
}
case 100:
{
rpnFunctionLsb=byte3 & 0x7f;
if (rpnFunctionMsb == 0x7f && rpnFunctionLsb == 0x7f) {
rpnStatus=RPN_STATUS_NONE;
}
 else {
rpnStatus=RPN_STATUS_RPN;
}
break;
}
case 101:
{
rpnFunctionMsb=byte3 & 0x7f;
if (rpnFunctionMsb == 0x7f && rpnFunctionLsb == 0x7f) {
rpnStatus=RPN_STATUS_NONE;
}
 else {
rpnStatus=RPN_STATUS_RPN;
}
break;
}
default :
break;
}
break;
case 12:
if (midiEventListener != null) {
midiEventListener.onMidiProgramChange(sender,cable,byte1 & 0xf,byte2);
}
break;
case 13:
if (midiEventListener != null) {
midiEventListener.onMidiChannelAftertouch(sender,cable,byte1 & 0xf,byte2);
}
break;
case 14:
if (midiEventListener != null) {
midiEventListener.onMidiPitchWheel(sender,cable,byte1 & 0xf,byte2 | (byte3 << 7));
}
break;
case 15:
if (midiEventListener != null) {
midiEventListener.onMidiSingleByte(sender,cable,byte1);
}
break;
default :
break;
}
}
}
}

Fixed version (ground truth):
@Override public void run(){
  final UsbDeviceConnection deviceConnection=usbDeviceConnection;
  final UsbEndpoint usbEndpoint=inputEndpoint;
  final int maxPacketSize=inputEndpoint.getMaxPacketSize();
  final MidiInputDevice sender=MidiInputDevice.this;
  final OnMidiInputEventListener midiEventListener=MidiInputDevice.this.midiEventListener;
  final byte[] bulkReadBuffer=new byte[maxPacketSize];
  byte[] readBuffer=new byte[maxPacketSize * 2];
  int readBufferSize=0;
  byte[] read=new byte[maxPacketSize * 2];
  int length;
  int cable;
  int codeIndexNumber;
  int byte1;
  int byte2;
  int byte3;
  int i;
  int readSize;
  int unreadSize;
  final int RPN_STATUS_NONE=0;
  final int RPN_STATUS_RPN=1;
  final int RPN_STATUS_NRPN=2;
  int rpnNrpnFunction;
  int rpnNrpnValueMsb;
  int rpnNrpnValueLsb;
  int rpnStatus=RPN_STATUS_NONE;
  int rpnFunctionMsb=0x7f;
  int rpnFunctionLsb=0x7f;
  int nrpnFunctionMsb=0x7f;
  int nrpnFunctionLsb=0x7f;
  SparseIntArray rpnCacheMsb=new SparseIntArray();
  SparseIntArray rpnCacheLsb=new SparseIntArray();
  SparseIntArray nrpnCacheMsb=new SparseIntArray();
  SparseIntArray nrpnCacheLsb=new SparseIntArray();
  ReusableByteArrayOutputStream[] systemExclusive=new ReusableByteArrayOutputStream[16];
  for (i=0; i < 16; i++) {
    systemExclusive[i]=new ReusableByteArrayOutputStream();
  }
  while (!stopFlag) {
    length=deviceConnection.bulkTransfer(usbEndpoint,bulkReadBuffer,maxPacketSize,10);
synchronized (suspendSignal) {
      if (suspendFlag) {
        try {
          suspendSignal.wait(100);
        }
 catch (        InterruptedException e) {
        }
        continue;
      }
    }
    if (length <= 0) {
      continue;
    }
    System.arraycopy(bulkReadBuffer,0,readBuffer,readBufferSize,length);
    readBufferSize+=length;
    if (readBufferSize < 4) {
      continue;
    }
    readSize=readBufferSize / 4 * 4;
    System.arraycopy(readBuffer,0,read,0,readSize);
    unreadSize=readBufferSize - readSize;
    if (unreadSize > 0) {
      System.arraycopy(readBuffer,readSize,readBuffer,0,unreadSize);
      readBufferSize=unreadSize;
    }
 else {
      readBufferSize=0;
    }
    for (i=0; i < readSize; i+=4) {
      cable=(read[i] >> 4) & 0xf;
      codeIndexNumber=read[i] & 0xf;
      byte1=read[i + 1] & 0xff;
      byte2=read[i + 2] & 0xff;
      byte3=read[i + 3] & 0xff;
switch (codeIndexNumber) {
case 0:
        if (midiEventListener != null) {
          midiEventListener.onMidiMiscellaneousFunctionCodes(sender,cable,byte1,byte2,byte3);
        }
      break;
case 1:
    if (midiEventListener != null) {
      midiEventListener.onMidiCableEvents(sender,cable,byte1,byte2,byte3);
    }
  break;
case 2:
if (midiEventListener != null) {
switch (byte1) {
case 0xf1:
    midiEventListener.onMidiTimeCodeQuarterFrame(sender,cable,byte2 & 0x7f);
  break;
case 0xf3:
midiEventListener.onMidiSongSelect(sender,cable,byte2 & 0x7f);
break;
}
byte[] bytes=new byte[]{(byte)byte1,(byte)byte2};
midiEventListener.onMidiSystemCommonMessage(sender,cable,bytes);
}
break;
case 3:
if (midiEventListener != null) {
switch (byte1) {
case 0xf2:
midiEventListener.onMidiSongPositionPointer(sender,cable,(byte2 & 0x7f) | ((byte3 & 0x7f) << 7));
break;
}
byte[] bytes=new byte[]{(byte)byte1,(byte)byte2,(byte)byte3};
midiEventListener.onMidiSystemCommonMessage(sender,cable,bytes);
}
break;
case 4:
synchronized (systemExclusive[cable]) {
systemExclusive[cable].write(byte1);
systemExclusive[cable].write(byte2);
systemExclusive[cable].write(byte3);
}
break;
case 5:
synchronized (systemExclusive[cable]) {
systemExclusive[cable].write(byte1);
if (midiEventListener != null) {
byte[] sysexBytes=systemExclusive[cable].toByteArray();
if (sysexBytes.length == 1) {
switch (sysexBytes[0] & 0xff) {
case 0xf6:
midiEventListener.onMidiTuneRequest(sender,cable);
break;
case 0xf8:
midiEventListener.onMidiTimingClock(sender,cable);
break;
case 0xfa:
midiEventListener.onMidiStart(sender,cable);
break;
case 0xfb:
midiEventListener.onMidiContinue(sender,cable);
break;
case 0xfc:
midiEventListener.onMidiStop(sender,cable);
break;
case 0xfe:
midiEventListener.onMidiActiveSensing(sender,cable);
break;
case 0xff:
midiEventListener.onMidiReset(sender,cable);
break;
}
}
midiEventListener.onMidiSystemExclusive(sender,cable,sysexBytes);
}
systemExclusive[cable].reset();
}
break;
case 6:
synchronized (systemExclusive[cable]) {
systemExclusive[cable].write(byte1);
systemExclusive[cable].write(byte2);
if (midiEventListener != null) {
midiEventListener.onMidiSystemExclusive(sender,cable,systemExclusive[cable].toByteArray());
}
systemExclusive[cable].reset();
}
break;
case 7:
synchronized (systemExclusive[cable]) {
systemExclusive[cable].write(byte1);
systemExclusive[cable].write(byte2);
systemExclusive[cable].write(byte3);
if (midiEventListener != null) {
midiEventListener.onMidiSystemExclusive(sender,cable,systemExclusive[cable].toByteArray());
}
systemExclusive[cable].reset();
}
break;
case 8:
if (midiEventListener != null) {
midiEventListener.onMidiNoteOff(sender,cable,byte1 & 0xf,byte2,byte3);
}
break;
case 9:
if (midiEventListener != null) {
if (byte3 == 0x00) {
midiEventListener.onMidiNoteOff(sender,cable,byte1 & 0xf,byte2,byte3);
}
 else {
midiEventListener.onMidiNoteOn(sender,cable,byte1 & 0xf,byte2,byte3);
}
}
break;
case 10:
if (midiEventListener != null) {
midiEventListener.onMidiPolyphonicAftertouch(sender,cable,byte1 & 0xf,byte2,byte3);
}
break;
case 11:
if (midiEventListener != null) {
midiEventListener.onMidiControlChange(sender,cable,byte1 & 0xf,byte2,byte3);
}
switch (byte2) {
case 6:
{
rpnNrpnValueMsb=byte3 & 0x7f;
if (rpnStatus == RPN_STATUS_RPN) {
rpnNrpnFunction=((rpnFunctionMsb & 0x7f) << 7) | (rpnFunctionLsb & 0x7f);
rpnCacheMsb.put(rpnNrpnFunction,rpnNrpnValueMsb);
rpnNrpnValueLsb=rpnCacheLsb.get(rpnNrpnFunction,0);
if (midiEventListener != null) {
midiEventListener.onMidiRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,(rpnNrpnValueMsb << 7 | rpnNrpnValueLsb));
midiEventListener.onMidiRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,rpnNrpnValueMsb,rpnNrpnValueLsb);
}
}
 else if (rpnStatus == RPN_STATUS_NRPN) {
rpnNrpnFunction=((nrpnFunctionMsb & 0x7f) << 7) | (nrpnFunctionLsb & 0x7f);
nrpnCacheMsb.put(rpnNrpnFunction,rpnNrpnValueMsb);
rpnNrpnValueLsb=nrpnCacheLsb.get(rpnNrpnFunction,0);
if (midiEventListener != null) {
midiEventListener.onMidiNRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,(rpnNrpnValueMsb << 7 | rpnNrpnValueLsb));
midiEventListener.onMidiNRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,rpnNrpnValueMsb,rpnNrpnValueLsb);
}
}
break;
}
case 38:
{
rpnNrpnValueLsb=byte3 & 0x7f;
if (rpnStatus == RPN_STATUS_RPN) {
rpnNrpnFunction=((rpnFunctionMsb & 0x7f) << 7) | (rpnFunctionLsb & 0x7f);
rpnNrpnValueMsb=rpnCacheMsb.get(rpnNrpnFunction,0);
rpnCacheLsb.put(rpnNrpnFunction,rpnNrpnValueLsb);
if (midiEventListener != null) {
midiEventListener.onMidiRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,(rpnNrpnValueMsb << 7 | rpnNrpnValueLsb));
midiEventListener.onMidiRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,rpnNrpnValueMsb,rpnNrpnValueLsb);
}
}
 else if (rpnStatus == RPN_STATUS_NRPN) {
rpnNrpnFunction=((nrpnFunctionMsb & 0x7f) << 7) | (nrpnFunctionLsb & 0x7f);
rpnNrpnValueMsb=nrpnCacheMsb.get(rpnNrpnFunction,0);
nrpnCacheLsb.put(rpnNrpnFunction,rpnNrpnValueLsb);
if (midiEventListener != null) {
midiEventListener.onMidiNRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,(rpnNrpnValueMsb << 7 | rpnNrpnValueLsb));
midiEventListener.onMidiNRPNReceived(sender,cable,byte1 & 0xf,rpnNrpnFunction,rpnNrpnValueMsb,rpnNrpnValueLsb);
}
}
break;
}
case 98:
{
nrpnFunctionLsb=byte3 & 0x7f;
rpnStatus=RPN_STATUS_NRPN;
break;
}
case 99:
{
nrpnFunctionMsb=byte3 & 0x7f;
rpnStatus=RPN_STATUS_NRPN;
break;
}
case 100:
{
rpnFunctionLsb=byte3 & 0x7f;
if (rpnFunctionMsb == 0x7f && rpnFunctionLsb == 0x7f) {
rpnStatus=RPN_STATUS_NONE;
}
 else {
rpnStatus=RPN_STATUS_RPN;
}
break;
}
case 101:
{
rpnFunctionMsb=byte3 & 0x7f;
if (rpnFunctionMsb == 0x7f && rpnFunctionLsb == 0x7f) {
rpnStatus=RPN_STATUS_NONE;
}
 else {
rpnStatus=RPN_STATUS_RPN;
}
break;
}
default :
break;
}
break;
case 12:
if (midiEventListener != null) {
midiEventListener.onMidiProgramChange(sender,cable,byte1 & 0xf,byte2);
}
break;
case 13:
if (midiEventListener != null) {
midiEventListener.onMidiChannelAftertouch(sender,cable,byte1 & 0xf,byte2);
}
break;
case 14:
if (midiEventListener != null) {
midiEventListener.onMidiPitchWheel(sender,cable,byte1 & 0xf,byte2 | (byte3 << 7));
}
break;
case 15:
if (midiEventListener != null) {
switch (byte1) {
case 0xf6:
midiEventListener.onMidiTuneRequest(sender,cable);
break;
case 0xf8:
midiEventListener.onMidiTimingClock(sender,cable);
break;
case 0xfa:
midiEventListener.onMidiStart(sender,cable);
break;
case 0xfb:
midiEventListener.onMidiContinue(sender,cable);
break;
case 0xfc:
midiEventListener.onMidiStop(sender,cable);
break;
case 0xfe:
midiEventListener.onMidiActiveSensing(sender,cable);
break;
case 0xff:
midiEventListener.onMidiReset(sender,cable);
break;
}
midiEventListener.onMidiSingleByte(sender,cable,byte1);
}
break;
default :
break;
}
}
}
}