Program: 53173
Project: 53173
Buggy source:
static void relativizeOsoSymbols(FileChannel file,Path linkingDirectory) throws IOException, MachoException {
  Preconditions.checkState(linkingDirectory.isAbsolute());
  long size=file.size();
  MappedByteBuffer map=file.map(FileChannel.MapMode.READ_WRITE,0,size);
  MachoHeader header=getHeader(map);
  int symbolTableOffset=0;
  int symbolTableCount=0;
  int stringTableOffset=0;
  int stringTableSizePosition=0;
  int stringTableSize=0;
  boolean symbolTableSegmentFound=false;
  int segmentSizePosition=0;
  int segmentSize=0;
  int commandsCount=header.getCommandsCount();
  for (int i=0; i < commandsCount; i++) {
    int commandStart=map.position();
    int command=ObjectFileScrubbers.getLittleEndianInt(map);
    int commandSize=ObjectFileScrubbers.getLittleEndianInt(map);
switch (command) {
case LC_SYMTAB:
      symbolTableOffset=ObjectFileScrubbers.getLittleEndianInt(map);
    symbolTableCount=ObjectFileScrubbers.getLittleEndianInt(map);
  stringTableOffset=ObjectFileScrubbers.getLittleEndianInt(map);
stringTableSizePosition=map.position();
stringTableSize=ObjectFileScrubbers.getLittleEndianInt(map);
symbolTableSegmentFound=true;
break;
case LC_SEGMENT:
ObjectFileScrubbers.getBytes(map,16);
ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
int segmentFileOffset=ObjectFileScrubbers.getLittleEndianInt(map);
int segmentFileSizePosition=map.position();
int segmentFileSize=ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
if (segmentFileOffset + segmentFileSize == size) {
if (segmentSizePosition != 0) {
throw new MachoException("String_Node_Str");
}
segmentSizePosition=segmentFileSizePosition;
segmentSize=segmentFileSize;
}
break;
case LC_SEGMENT_64:
ObjectFileScrubbers.getBytes(map,16);
ObjectFileScrubbers.getLittleEndianLong(map);
ObjectFileScrubbers.getLittleEndianLong(map);
long segment64FileOffset=ObjectFileScrubbers.getLittleEndianLong(map);
int segment64FileSizePosition=map.position();
long segment64FileSize=ObjectFileScrubbers.getLittleEndianLong(map);
ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
if (segment64FileOffset + segment64FileSize == size) {
if (segmentSizePosition != 0) {
throw new MachoException("String_Node_Str");
}
segmentSizePosition=segment64FileSizePosition;
if (segment64FileSize > Ints.MAX_POWER_OF_TWO) {
throw new MachoException("String_Node_Str");
}
segmentSize=(int)segment64FileSize;
}
break;
}
map.position(commandStart + commandSize);
}
if (!symbolTableSegmentFound) {
throw new MachoException("String_Node_Str");
}
if (stringTableOffset + stringTableSize != size) {
throw new MachoException("String_Node_Str");
}
if (stringTableSize == 0) {
return;
}
if (segmentSizePosition == 0 || segmentSize == 0) {
throw new MachoException("String_Node_Str");
}
map.position(stringTableOffset);
if (map.get() != 0x20) {
throw new MachoException("String_Node_Str");
}
if (map.get() != 0x00) {
throw new MachoException("String_Node_Str");
}
int currentStringTableOffset=map.position();
byte[] stringTableBytes=new byte[stringTableSize];
map.position(stringTableOffset);
map.get(stringTableBytes);
ByteBuffer stringTable=ByteBuffer.wrap(stringTableBytes);
map.position(symbolTableOffset);
Map<Integer,Integer> strings=new HashMap<>();
String prefix=linkingDirectory.toString() + "String_Node_Str";
for (int i=0; i < symbolTableCount; i++) {
int stringTableIndexPosition=map.position();
int stringTableIndex=ObjectFileScrubbers.getLittleEndianInt(map);
byte type=map.get();
map.get();
ObjectFileScrubbers.getLittleEndianShort(map);
int valuePosition=map.position();
if (header.getIs64Bit()) {
ObjectFileScrubbers.getLittleEndianLong(map);
}
 else {
ObjectFileScrubbers.getLittleEndianInt(map);
}
if (stringTableIndex < 2) {
continue;
}
int position=map.position();
try {
int newStringTableIndex;
if (strings.containsKey(stringTableIndex)) {
newStringTableIndex=strings.get(stringTableIndex);
}
 else {
stringTable.position(stringTableIndex);
String string=ObjectFileScrubbers.getAsciiString(stringTable);
if (type == N_OSO) {
string=MoreStrings.stripPrefix(string,prefix).or(string);
map.position(valuePosition);
if (header.getIs64Bit()) {
ObjectFileScrubbers.putLittleEndianLong(map,Ints.MAX_POWER_OF_TWO);
}
 else {
ObjectFileScrubbers.putLittleEndianInt(map,Ints.MAX_POWER_OF_TWO);
}
}
map.position(currentStringTableOffset);
ObjectFileScrubbers.putAsciiString(map,string);
newStringTableIndex=currentStringTableOffset - stringTableOffset;
currentStringTableOffset=map.position();
strings.put(stringTableIndex,newStringTableIndex);
}
map.position(stringTableIndexPosition);
ObjectFileScrubbers.putLittleEndianInt(map,newStringTableIndex);
}
  finally {
map.position(position);
}
}
map.position(stringTableSizePosition);
int newStringTableSize=currentStringTableOffset - stringTableOffset;
ObjectFileScrubbers.putLittleEndianInt(map,newStringTableSize);
map.position(segmentSizePosition);
ObjectFileScrubbers.putLittleEndianInt(map,segmentSize + (newStringTableSize - stringTableSize));
file.truncate(currentStringTableOffset);
}

Fixed version (ground truth):
static void relativizeOsoSymbols(FileChannel file,Path linkingDirectory) throws IOException, MachoException {
  Preconditions.checkState(linkingDirectory.isAbsolute());
  long size=file.size();
  MappedByteBuffer map=file.map(FileChannel.MapMode.READ_WRITE,0,size);
  MachoHeader header=getHeader(map);
  int symbolTableOffset=0;
  int symbolTableCount=0;
  int stringTableOffset=0;
  int stringTableSizePosition=0;
  int stringTableSize=0;
  boolean symbolTableSegmentFound=false;
  int segmentSizePosition=0;
  int segmentSize=0;
  int commandsCount=header.getCommandsCount();
  for (int i=0; i < commandsCount; i++) {
    int commandStart=map.position();
    int command=ObjectFileScrubbers.getLittleEndianInt(map);
    int commandSize=ObjectFileScrubbers.getLittleEndianInt(map);
switch (command) {
case LC_SYMTAB:
      symbolTableOffset=ObjectFileScrubbers.getLittleEndianInt(map);
    symbolTableCount=ObjectFileScrubbers.getLittleEndianInt(map);
  stringTableOffset=ObjectFileScrubbers.getLittleEndianInt(map);
stringTableSizePosition=map.position();
stringTableSize=ObjectFileScrubbers.getLittleEndianInt(map);
symbolTableSegmentFound=true;
break;
case LC_SEGMENT:
ObjectFileScrubbers.getBytes(map,16);
ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
int segmentFileOffset=ObjectFileScrubbers.getLittleEndianInt(map);
int segmentFileSizePosition=map.position();
int segmentFileSize=ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
if (segmentFileOffset + segmentFileSize == size) {
if (segmentSizePosition != 0) {
throw new MachoException("String_Node_Str");
}
segmentSizePosition=segmentFileSizePosition;
segmentSize=segmentFileSize;
}
break;
case LC_SEGMENT_64:
ObjectFileScrubbers.getBytes(map,16);
ObjectFileScrubbers.getLittleEndianLong(map);
ObjectFileScrubbers.getLittleEndianLong(map);
long segment64FileOffset=ObjectFileScrubbers.getLittleEndianLong(map);
int segment64FileSizePosition=map.position();
long segment64FileSize=ObjectFileScrubbers.getLittleEndianLong(map);
ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
ObjectFileScrubbers.getLittleEndianInt(map);
if (segment64FileOffset + segment64FileSize == size) {
if (segmentSizePosition != 0) {
throw new MachoException("String_Node_Str");
}
segmentSizePosition=segment64FileSizePosition;
if (segment64FileSize > Ints.MAX_POWER_OF_TWO) {
throw new MachoException("String_Node_Str");
}
segmentSize=(int)segment64FileSize;
}
break;
}
map.position(commandStart + commandSize);
}
if (!symbolTableSegmentFound) {
throw new MachoException("String_Node_Str");
}
if (stringTableOffset + stringTableSize != size) {
throw new MachoException("String_Node_Str");
}
if (stringTableSize == 0) {
return;
}
if (segmentSizePosition == 0 || segmentSize == 0) {
throw new MachoException("String_Node_Str");
}
map.position(stringTableOffset);
if (map.get() != 0x20) {
throw new MachoException("String_Node_Str");
}
if (map.get() != 0x00) {
throw new MachoException("String_Node_Str");
}
int currentStringTableOffset=map.position();
byte[] stringTableBytes=new byte[stringTableSize];
map.position(stringTableOffset);
map.get(stringTableBytes);
ByteBuffer stringTable=ByteBuffer.wrap(stringTableBytes);
map.position(symbolTableOffset);
Map<Integer,Integer> strings=new HashMap<>();
String prefix=linkingDirectory.toString() + "String_Node_Str";
for (int i=0; i < symbolTableCount; i++) {
int stringTableIndexPosition=map.position();
int stringTableIndex=ObjectFileScrubbers.getLittleEndianInt(map);
byte type=map.get();
map.get();
ObjectFileScrubbers.getLittleEndianShort(map);
int valuePosition=map.position();
if (header.getIs64Bit()) {
ObjectFileScrubbers.getLittleEndianLong(map);
}
 else {
ObjectFileScrubbers.getLittleEndianInt(map);
}
if (stringTableIndex < 2) {
continue;
}
int position=map.position();
try {
int newStringTableIndex;
if (strings.containsKey(stringTableIndex)) {
newStringTableIndex=strings.get(stringTableIndex);
}
 else {
stringTable.position(stringTableIndex);
String string=ObjectFileScrubbers.getAsciiString(stringTable);
if (type == N_OSO) {
string=MoreStrings.stripPrefix(string,prefix).transform(new Function<String,String>(){
@Override public String apply(String input){
return "String_Node_Str" + input;
}
}
).or(string);
map.position(valuePosition);
if (header.getIs64Bit()) {
ObjectFileScrubbers.putLittleEndianLong(map,0);
}
 else {
ObjectFileScrubbers.putLittleEndianInt(map,0);
}
}
map.position(currentStringTableOffset);
ObjectFileScrubbers.putAsciiString(map,string);
newStringTableIndex=currentStringTableOffset - stringTableOffset;
currentStringTableOffset=map.position();
strings.put(stringTableIndex,newStringTableIndex);
}
map.position(stringTableIndexPosition);
ObjectFileScrubbers.putLittleEndianInt(map,newStringTableIndex);
}
  finally {
map.position(position);
}
}
map.position(stringTableSizePosition);
int newStringTableSize=currentStringTableOffset - stringTableOffset;
ObjectFileScrubbers.putLittleEndianInt(map,newStringTableSize);
map.position(segmentSizePosition);
ObjectFileScrubbers.putLittleEndianInt(map,segmentSize + (newStringTableSize - stringTableSize));
file.truncate(currentStringTableOffset);
}