Program: 8911
Project: 8911
Buggy source:
/** 
 * Constructs a new STR file reader using given code page. Particularly useful for batch runs, no need to read the code page all over again<br> Reads the STR file structure
 * @param codePage the code page
 * @param file the str file to read
 */
public StrFile(CharBuffer codePage,File file){
  this.codePage=codePage;
  try (RandomAccessFile rawStr=new RandomAccessFile(file,"String_Node_Str")){
    byte[] header=new byte[4];
    rawStr.read(header);
    if (!STR_HEADER_IDENTIFIER.equals(Utils.bytesToString(header))) {
      throw new RuntimeException("String_Node_Str" + STR_HEADER_IDENTIFIER + "String_Node_Str"+ header+ "String_Node_Str");
    }
    fileId=Utils.readUnsignedInteger(rawStr);
    int offsetsCount=Utils.readUnsignedInteger(rawStr);
    List<Integer> offsets=new ArrayList<>(offsetsCount);
    for (int i=0; i < offsetsCount; i++) {
      offsets.add(Utils.readUnsignedInteger(rawStr));
    }
    entries=new LinkedHashMap<>(offsetsCount);
    for (int i=0; i < offsetsCount; i++) {
      rawStr.seek(offsets.get(i) + STR_HEADER_SIZE);
      int dataLength=(int)(i < offsets.size() - 1 ? offsets.get(i + 1) - offsets.get(i) : rawStr.length() - offsets.get(i) - STR_HEADER_SIZE);
      byte[] data=new byte[dataLength];
      int dataRead=rawStr.read(data);
      if (dataRead < dataLength) {
        logger.log(Level.WARNING,"String_Node_Str",new Object[]{i,dataLength,dataRead});
      }
      String entry=decodeEntry(data);
      if (entry == null) {
        throw new RuntimeException("String_Node_Str" + i + "String_Node_Str");
      }
      entries.put(i,entry);
    }
  }
 catch (  IOException e) {
    throw new RuntimeException("String_Node_Str" + file + "String_Node_Str",e);
  }
}

Fixed version (ground truth):
/** 
 * Constructs a new STR file reader using given code page. Particularly useful for batch runs, no need to read the code page all over again<br> Reads the STR file structure
 * @param codePage the code page
 * @param file the str file to read
 */
public StrFile(CharBuffer codePage,File file){
  this.codePage=codePage;
  try (RandomAccessFile rawStr=new RandomAccessFile(file,"String_Node_Str")){
    byte[] header=new byte[4];
    rawStr.read(header);
    if (!STR_HEADER_IDENTIFIER.equals(Utils.bytesToString(header))) {
      throw new RuntimeException("String_Node_Str" + STR_HEADER_IDENTIFIER + "String_Node_Str"+ header+ "String_Node_Str");
    }
    fileId=Utils.readUnsignedInteger(rawStr);
    int offsetsCount=Utils.readUnsignedInteger(rawStr);
    List<Integer> offsets=new ArrayList<>(offsetsCount);
    for (int i=0; i < offsetsCount; i++) {
      offsets.add(Utils.readUnsignedInteger(rawStr));
    }
    List<Integer> offsetsCopy=new ArrayList<>(offsets);
    Collections.sort(offsetsCopy);
    entries=new LinkedHashMap<>(offsetsCount);
    for (int i=0; i < offsetsCount; i++) {
      rawStr.seek(offsets.get(i) + STR_HEADER_SIZE);
      int j=Collections.binarySearch(offsetsCopy,offsets.get(i));
      int dataLength=(int)(j < offsetsCopy.size() - 1 ? offsetsCopy.get(j + 1) - offsets.get(i) : rawStr.length() - offsets.get(i) - STR_HEADER_SIZE);
      byte[] data=new byte[dataLength];
      int dataRead=rawStr.read(data);
      if (dataRead < dataLength) {
        logger.log(Level.WARNING,"String_Node_Str",new Object[]{i,dataLength,dataRead});
      }
      String entry=decodeEntry(data);
      if (entry == null) {
        throw new RuntimeException("String_Node_Str" + i + "String_Node_Str");
      }
      entries.put(i,entry);
    }
  }
 catch (  IOException e) {
    throw new RuntimeException("String_Node_Str" + file + "String_Node_Str",e);
  }
}