Program: 4860
Project: 4860
Buggy source:
/** 
 * @requires buf.length==23
 * @effects exactly like Message.read(in), but buf is used as scratch forreading the header.  This is an optimization that lets you avoid repeatedly allocating 23-byte arrays.  buf may be used when this returns, but the contents are not guaranteed to contain any useful data.  
 */
static Message read(InputStream in,byte[] buf) throws BadPacketException, IOException {
  for (int i=0; i < 23; ) {
    int got;
    try {
      got=in.read(buf,i,23 - i);
    }
 catch (    InterruptedIOException e) {
      if (i == 0)       return null;
 else       throw e;
    }
    if (got == -1)     throw new IOException("String_Node_Str");
    i+=got;
  }
  byte[] guid=new byte[16];
  for (int i=0; i < 16; i++)   guid[i]=buf[i];
  byte func=buf[16];
  byte ttl=buf[17];
  byte hops=buf[18];
  int length=ByteOrder.leb2int(buf,19);
  if (length < 0 || length > SettingsManager.instance().getMaxLength())   throw new IOException("String_Node_Str" + length);
  byte[] payload=null;
  if (length != 0) {
    payload=new byte[length];
    for (int i=0; i < length; ) {
      int got=in.read(payload,i,length - i);
      if (got == -1)       throw new IOException("String_Node_Str");
      i+=got;
    }
  }
  byte softMax=SettingsManager.instance().getSoftMaxTTL();
  byte hardMax=SettingsManager.instance().getMaxTTL();
  if (hops < 0)   throw new BadPacketException("String_Node_Str");
 else   if (ttl < 0)   throw new BadPacketException("String_Node_Str");
 else   if (hops > softMax)   throw new BadPacketException("String_Node_Str");
 else   if (ttl + hops > hardMax)   throw new BadPacketException("String_Node_Str");
 else   if (ttl + hops > softMax) {
    ttl=(byte)(softMax - hops);
    Assert.that(ttl >= 0);
  }
switch (func) {
case F_PING:
    if (PARSE_GROUP_PINGS && length >= 15) {
      return new GroupPingRequest(guid,ttl,hops,payload);
    }
 else     if (length > 0)     return new PingRequest(guid,ttl,hops,payload);
  return new PingRequest(guid,ttl,hops);
case F_PING_REPLY:
return new PingReply(guid,ttl,hops,payload);
case F_QUERY:
if (length < 3) break;
return new QueryRequest(guid,ttl,hops,payload);
case F_QUERY_REPLY:
if (length < 26) break;
return new QueryReply(guid,ttl,hops,payload);
case F_PUSH:
return new PushRequest(guid,ttl,hops,payload);
case F_ROUTE_TABLE_UPDATE:
return RouteTableMessage.read(guid,ttl,hops,payload);
}
throw new BadPacketException("String_Node_Str" + func);
}

Fixed version (ground truth):
/** 
 * @requires buf.length==23
 * @effects exactly like Message.read(in), but buf is used as scratch forreading the header.  This is an optimization that lets you avoid repeatedly allocating 23-byte arrays.  buf may be used when this returns, but the contents are not guaranteed to contain any useful data.  
 */
static Message read(InputStream in,byte[] buf) throws BadPacketException, IOException {
  for (int i=0; i < 23; ) {
    int got;
    try {
      got=in.read(buf,i,23 - i);
    }
 catch (    InterruptedIOException e) {
      if (i == 0)       return null;
 else       throw e;
    }
    if (got == -1)     throw new IOException("String_Node_Str");
    i+=got;
  }
  byte[] guid=new byte[16];
  for (int i=0; i < 16; i++)   guid[i]=buf[i];
  byte func=buf[16];
  byte ttl=buf[17];
  byte hops=buf[18];
  int length=ByteOrder.leb2int(buf,19);
  if (length < 0 || length > SettingsManager.instance().getMaxLength())   throw new IOException("String_Node_Str" + length);
  byte[] payload=null;
  if (length != 0) {
    payload=new byte[length];
    for (int i=0; i < length; ) {
      int got=in.read(payload,i,length - i);
      if (got == -1)       throw new IOException("String_Node_Str");
      i+=got;
    }
  }
 else   payload=new byte[0];
  byte softMax=SettingsManager.instance().getSoftMaxTTL();
  byte hardMax=SettingsManager.instance().getMaxTTL();
  if (hops < 0)   throw new BadPacketException("String_Node_Str");
 else   if (ttl < 0)   throw new BadPacketException("String_Node_Str");
 else   if (hops > softMax)   throw new BadPacketException("String_Node_Str");
 else   if (ttl + hops > hardMax)   throw new BadPacketException("String_Node_Str");
 else   if (ttl + hops > softMax) {
    ttl=(byte)(softMax - hops);
    Assert.that(ttl >= 0);
  }
switch (func) {
case F_PING:
    if (PARSE_GROUP_PINGS && length >= 15) {
      return new GroupPingRequest(guid,ttl,hops,payload);
    }
 else     if (length > 0)     return new PingRequest(guid,ttl,hops,payload);
  return new PingRequest(guid,ttl,hops);
case F_PING_REPLY:
return new PingReply(guid,ttl,hops,payload);
case F_QUERY:
if (length < 3) break;
return new QueryRequest(guid,ttl,hops,payload);
case F_QUERY_REPLY:
if (length < 26) break;
return new QueryReply(guid,ttl,hops,payload);
case F_PUSH:
return new PushRequest(guid,ttl,hops,payload);
case F_ROUTE_TABLE_UPDATE:
return RouteTableMessage.read(guid,ttl,hops,payload);
}
throw new BadPacketException("String_Node_Str" + func);
}