changeset 42:92c3d0920d58

Real integrity check, with exception. DigestHelper refactored to accomodate new needs
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 14 Jan 2011 04:29:03 +0100
parents 858d1b2458cb
children 1b26247d7367
files src/com/tmate/hgkit/console/Cat.java src/com/tmate/hgkit/ll/DigestHelper.java src/com/tmate/hgkit/ll/HgBundle.java
diffstat 3 files changed, 35 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/com/tmate/hgkit/console/Cat.java	Fri Jan 14 04:14:08 2011 +0100
+++ b/src/com/tmate/hgkit/console/Cat.java	Fri Jan 14 04:29:03 2011 +0100
@@ -43,7 +43,7 @@
 					byte[] parent1 = new byte[20];
 					byte[] parent2 = new byte[20];
 					fn.parents(i, parentRevisions, parent1, parent2);
-					System.out.println(dh.sha1(parent1, parent2, content));
+					System.out.println(dh.sha1(parent1, parent2, content).asHexString());
 				}
 			} else {
 				System.out.println(">>>Not found!");
--- a/src/com/tmate/hgkit/ll/DigestHelper.java	Fri Jan 14 04:14:08 2011 +0100
+++ b/src/com/tmate/hgkit/ll/DigestHelper.java	Fri Jan 14 04:29:03 2011 +0100
@@ -9,12 +9,18 @@
 import java.security.NoSuchAlgorithmException;
 
 /**
- * TODO sha1_binary to give array for Nodeid.equalsTo 
- *
+ * <pre>
+ * DigestHelper dh;
+ * dh.sha1(...).asHexString();
+ *  or 
+ * dh = dh.sha1(...);
+ * nodeid.equalsTo(dh.asBinary());
+ * </pre>
  * @author artem
  */
 public class DigestHelper {
 	private MessageDigest sha1;
+	private byte[] digest;
 
 	public DigestHelper() {
 	}
@@ -32,12 +38,12 @@
 	}
 
 
-	public String sha1(Nodeid nodeid1, Nodeid nodeid2, byte[] data) {
+	public DigestHelper sha1(Nodeid nodeid1, Nodeid nodeid2, byte[] data) {
 		return sha1(nodeid1.cloneData(), nodeid2.cloneData(), data);
 	}
 
 	//  sha1_digest(min(p1,p2) ++ max(p1,p2) ++ final_text)
-	public String sha1(byte[] nodeidParent1, byte[] nodeidParent2, byte[] data) {
+	public DigestHelper sha1(byte[] nodeidParent1, byte[] nodeidParent2, byte[] data) {
 		MessageDigest alg = getSHA1();
 		if ((nodeidParent1[0] & 0x00FF) < (nodeidParent2[0] & 0x00FF)) { 
 			alg.update(nodeidParent1);
@@ -46,21 +52,36 @@
 			alg.update(nodeidParent2);
 			alg.update(nodeidParent1);
 		}
-		byte[] digest = alg.digest(data);
+		digest = alg.digest(data);
 		assert digest.length == 20;
-		return toHexString(digest, 0, 20);
+		return this;
+	}
+	
+	public String asHexString() {
+		if (digest == null) {
+			throw new IllegalStateException("Shall init with sha1() call first");
+		}
+		return toHexString(digest, 0, digest.length);
+	}
+	
+	// by reference, be careful not to modify (or #clone() if needed)
+	public byte[] asBinary() {
+		if (digest == null) {
+			throw new IllegalStateException("Shall init with sha1() call first");
+		}
+		return digest; 
 	}
 
 	// XXX perhaps, digest functions should throw an exception, as it's caller responsibility to deal with eof, etc
-	public byte[] sha1(InputStream is /*ByteBuffer*/) throws IOException {
+	public DigestHelper sha1(InputStream is /*ByteBuffer*/) throws IOException {
 		MessageDigest alg = getSHA1();
 		byte[] buf = new byte[1024];
 		int c;
 		while ((c = is.read(buf)) != -1) {
 			alg.update(buf, 0, c);
 		}
-		byte[] digest = alg.digest();
-		return digest;
+		digest = alg.digest();
+		return this;
 	}
 
 	public static String toHexString(byte[] data, final int offset, final int count) {
--- a/src/com/tmate/hgkit/ll/HgBundle.java	Fri Jan 14 04:14:08 2011 +0100
+++ b/src/com/tmate/hgkit/ll/HgBundle.java	Fri Jan 14 04:29:03 2011 +0100
@@ -48,8 +48,10 @@
 				int resultLen = 10000; // XXX calculate based on baseRevContent.length and ge.patches
 				byte[] csetContent = RevlogStream.apply(baseRevContent, resultLen, ge.patches);
 				// wiki suggests sha1_digest(min(p1,p2) ++ max(p1,p2) ++ final_text),
-				String digest = dh.sha1(ge.firstParent(), ge.secondParent(), csetContent); // XXX ge may give me access to byte[] content of nodeid directly, perhaps, I don't need DH to be friend of Nodeid?
-				System.out.println("Node: " + ge.node() + ", digest: " + digest);
+				dh = dh.sha1(ge.firstParent(), ge.secondParent(), csetContent); // XXX ge may give me access to byte[] content of nodeid directly, perhaps, I don't need DH to be friend of Nodeid?
+				if (!ge.node().equalsTo(dh.asBinary())) {
+					throw new IllegalStateException("Integrity check failed on " + bundleFile + ", node:" + ge.node());
+				}
 				Changeset cs = Changeset.parse(csetContent, 0, csetContent.length);
 				cs.dump();
 				baseRevContent = csetContent;