We now generate an adler32 checksum for each patched file and verify at load time that they match.

Mismatch won't crash, but will emit a big warning..
This commit is contained in:
Christian 2013-07-08 13:19:14 -04:00
parent 94315253b1
commit e64c07a109
3 changed files with 24 additions and 2 deletions

View file

@ -6,12 +6,14 @@ public class ClassPatch {
public final String targetClassName;
public final boolean existsAtTarget;
public final byte[] patch;
public ClassPatch(String name, String sourceClassName, String targetClassName, boolean existsAtTarget, byte[] patch)
public final int inputChecksum;
public ClassPatch(String name, String sourceClassName, String targetClassName, boolean existsAtTarget, int inputChecksum, byte[] patch)
{
this.name = name;
this.sourceClassName = sourceClassName;
this.targetClassName = targetClassName;
this.existsAtTarget = existsAtTarget;
this.inputChecksum = inputChecksum;
this.patch = patch;
}

View file

@ -26,6 +26,7 @@ import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ListMultimap;
import com.google.common.hash.Hashing;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
@ -80,6 +81,14 @@ public class ClassPatchManager {
{
FMLLog.warning("Patcher expecting empty class data file for %s, but received non-empty", patch.targetClassName);
}
else
{
int inputChecksum = Hashing.adler32().hashBytes(inputData).asInt();
if (patch.inputChecksum != inputChecksum)
{
FMLLog.severe("There is a binary discrepency between the expected input class %s (%s) and the actual class. Checksum on disk is %x, in patch %x. Things are probably about to go very wrong. Did you put something into the jar file?", mappedName, name, inputChecksum, patch.inputChecksum);
}
}
synchronized (patcher)
{
try
@ -181,10 +190,15 @@ public class ClassPatchManager {
String sourceClassName = input.readUTF();
String targetClassName = input.readUTF();
boolean exists = input.readBoolean();
int inputChecksum = 0;
if (exists)
{
inputChecksum = input.readInt();
}
int patchLength = input.readInt();
byte[] patchBytes = new byte[patchLength];
input.readFully(patchBytes);
return new ClassPatch(name, sourceClassName, targetClassName, exists, patchBytes);
return new ClassPatch(name, sourceClassName, targetClassName, exists, inputChecksum, patchBytes);
}
}

View file

@ -13,6 +13,7 @@ import java.util.logging.Logger;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.hash.Hashing;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
@ -64,6 +65,7 @@ public class GenDiffSet {
byte[] diff = delta.compute(vanillaBytes, patchedBytes);
ByteArrayDataOutput diffOut = ByteStreams.newDataOutput(diff.length + 50);
// Original name
diffOut.writeUTF(name);
@ -73,6 +75,10 @@ public class GenDiffSet {
diffOut.writeUTF(targetClassName);
// exists at original
diffOut.writeBoolean(entry != null);
if (entry != null)
{
diffOut.writeInt(Hashing.adler32().hashBytes(vanillaBytes).asInt());
}
// length of patch
diffOut.writeInt(diff.length);
// patch