Program: 107518
Project: 107518
Buggy source:
/** 
 * Adds an RTP header extension with a given ID and a given length to this packet. The contents of the extension are not set to anything, and the caller of this method is responsible for filling them in. This method MUST NOT be called while iterating over the extensions using  {@link #getHeaderExtensions()}, or while manipulating the state of this  {@link RawPacket}.
 * @param id the ID of the extension to add.
 * @param len the length in bytes of the extension to add.
 * @return the header extension which was added.
 */
public HeaderExtension addExtension(byte id,int len){
  if (id < 1 || id > 15 || len < 1 || len > 16) {
    throw new IllegalArgumentException("String_Node_Str" + id + "String_Node_Str"+ len);
  }
  int payloadLength=getPayloadLength();
  boolean extensionBit=getExtensionBit();
  int extHeaderOffset=FIXED_HEADER_SIZE + 4 * getCsrcCount();
  int maxRequiredLength=getLength() + (extensionBit ? 0 : EXT_HEADER_SIZE) + 1+ len+ 3;
  byte[] newBuffer;
  int newPayloadOffset;
  if (buffer.length >= maxRequiredLength) {
    newBuffer=buffer;
    if ((offset + getHeaderLength()) >= (maxRequiredLength - getPayloadLength())) {
      newPayloadOffset=getPayloadOffset();
    }
 else {
      newPayloadOffset=buffer.length - payloadLength;
      System.arraycopy(buffer,getPayloadOffset(),buffer,newPayloadOffset,payloadLength);
    }
  }
 else {
    newBuffer=new byte[maxRequiredLength];
    newPayloadOffset=newBuffer.length - payloadLength;
    System.arraycopy(buffer,getPayloadOffset(),newBuffer,newPayloadOffset,payloadLength);
  }
  int newHeaderLength=extHeaderOffset;
  int extensionBytes=0;
  if (extensionBit) {
    newHeaderLength+=4;
    HeaderExtensions hes=getHeaderExtensions();
    while (hes.hasNext()) {
      HeaderExtension he=hes.next();
      extensionBytes+=1 + he.getExtLength();
    }
    newHeaderLength+=extensionBytes;
  }
  System.arraycopy(buffer,offset,newBuffer,0,newHeaderLength);
  if (!extensionBit) {
    RTPUtils.writeShort(newBuffer,extHeaderOffset,(short)0xBEDE);
    newHeaderLength+=4;
  }
  newBuffer[newHeaderLength++]=(byte)((id & 0x0f) << 4 | (len - 1) & 0x0f);
  extensionBytes++;
  int extensionDataOffset=newHeaderLength;
  newHeaderLength+=len;
  extensionBytes+=len;
  int paddingBytes=(4 - (extensionBytes % 4)) % 4;
  for (int i=0; i < paddingBytes; i++) {
    newBuffer[newHeaderLength++]=0;
  }
  RTPUtils.writeShort(newBuffer,extHeaderOffset + 2,(short)((extensionBytes + paddingBytes) / 4));
  int newOffset=newPayloadOffset - newHeaderLength;
  if (newOffset != 0) {
    System.arraycopy(newBuffer,0,newBuffer,newOffset,newHeaderLength);
  }
  this.buffer=newBuffer;
  this.offset=newOffset;
  this.length=newHeaderLength + payloadLength;
  setExtensionBit(true);
  HeaderExtension he=getHeaderExtensions().headerExtension;
  he.setOffset(getOffset() + extensionDataOffset);
  he.setLength(len + 1);
  return he;
}

Fixed version (ground truth):
/** 
 * Adds an RTP header extension with a given ID and a given length to this packet. The contents of the extension are not set to anything, and the caller of this method is responsible for filling them in. This method MUST NOT be called while iterating over the extensions using  {@link #getHeaderExtensions()}, or while manipulating the state of this  {@link RawPacket}.
 * @param id the ID of the extension to add.
 * @param len the length in bytes of the extension to add.
 * @return the header extension which was added.
 */
public HeaderExtension addExtension(byte id,int len){
  if (id < 1 || id > 15 || len < 1 || len > 16) {
    throw new IllegalArgumentException("String_Node_Str" + id + "String_Node_Str"+ len);
  }
  int payloadLength=getPayloadLength();
  boolean extensionBit=getExtensionBit();
  int extHeaderOffset=FIXED_HEADER_SIZE + 4 * getCsrcCount();
  int maxRequiredLength=getLength() + (extensionBit ? 0 : EXT_HEADER_SIZE) + 1+ len+ 3;
  byte[] newBuffer;
  int newPayloadOffset;
  if (buffer.length >= maxRequiredLength) {
    newBuffer=buffer;
    if ((offset + getHeaderLength()) >= (maxRequiredLength - getPayloadLength())) {
      newPayloadOffset=getPayloadOffset();
    }
 else {
      newPayloadOffset=buffer.length - payloadLength;
      System.arraycopy(buffer,getPayloadOffset(),buffer,newPayloadOffset,payloadLength);
    }
  }
 else {
    newBuffer=new byte[maxRequiredLength];
    newPayloadOffset=newBuffer.length - payloadLength;
    System.arraycopy(buffer,getPayloadOffset(),newBuffer,newPayloadOffset,payloadLength);
  }
  int newHeaderLength=extHeaderOffset;
  int extensionBytes=0;
  if (extensionBit) {
    newHeaderLength+=4;
    HeaderExtensions hes=getHeaderExtensions();
    while (hes.hasNext()) {
      HeaderExtension he=hes.next();
      extensionBytes+=1 + he.getExtLength();
    }
    newHeaderLength+=extensionBytes;
  }
  System.arraycopy(buffer,offset,newBuffer,0,newHeaderLength);
  if (!extensionBit) {
    RTPUtils.writeShort(newBuffer,extHeaderOffset,(short)0xBEDE);
    newHeaderLength+=4;
  }
  newBuffer[newHeaderLength++]=(byte)((id & 0x0f) << 4 | (len - 1) & 0x0f);
  extensionBytes++;
  int extensionDataOffset=newHeaderLength - 1;
  newHeaderLength+=len;
  extensionBytes+=len;
  int paddingBytes=(4 - (extensionBytes % 4)) % 4;
  for (int i=0; i < paddingBytes; i++) {
    newBuffer[newHeaderLength++]=0;
  }
  RTPUtils.writeShort(newBuffer,extHeaderOffset + 2,(short)((extensionBytes + paddingBytes) / 4));
  int newOffset=newPayloadOffset - newHeaderLength;
  if (newOffset != 0) {
    System.arraycopy(newBuffer,0,newBuffer,newOffset,newHeaderLength);
  }
  this.buffer=newBuffer;
  this.offset=newOffset;
  this.length=newHeaderLength + payloadLength;
  setExtensionBit(true);
  HeaderExtension he=getHeaderExtensions().headerExtension;
  he.setOffset(getOffset() + extensionDataOffset);
  he.setLength(len + 1);
  return he;
}