Mercurial > hg4j
changeset 41:858d1b2458cb
Check integrity for bundle changelog. Sort nodeids when calculating hash
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 14 Jan 2011 04:14:08 +0100 |
parents | 21e26da142fa |
children | 92c3d0920d58 |
files | design.txt src/com/tmate/hgkit/ll/DigestHelper.java src/com/tmate/hgkit/ll/HgBundle.java src/com/tmate/hgkit/ll/Nodeid.java |
diffstat | 4 files changed, 28 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/design.txt Fri Jan 14 03:37:06 2011 +0100 +++ b/design.txt Fri Jan 14 04:14:08 2011 +0100 @@ -37,6 +37,9 @@ Changeset to get index (local revision number) RevisionWalker (on manifest) and WorkingCopyWalker (io.File) talking to ? and/or dirstate RevlogStream - Inflater. Perhaps, InflaterStream instead? +Implement use of fncache (use names from it - perhaps, would help for Mac issues Alex mentioned) along with 'digest'-ing long file names + + Status operation from GUI - guess, usually on a file/subfolder, hence API should allow for starting path (unlike cmdline, seems useless to implement include/exclide patterns - GUI users hardly enter them, ever)
--- a/src/com/tmate/hgkit/ll/DigestHelper.java Fri Jan 14 03:37:06 2011 +0100 +++ b/src/com/tmate/hgkit/ll/DigestHelper.java Fri Jan 14 04:14:08 2011 +0100 @@ -9,6 +9,7 @@ import java.security.NoSuchAlgorithmException; /** + * TODO sha1_binary to give array for Nodeid.equalsTo * * @author artem */ @@ -30,16 +31,27 @@ return sha1; } - // XXX perhaps, digest functions should throw an exception, as it's caller responsibility to deal with eof, etc + + public String 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) { MessageDigest alg = getSHA1(); - alg.update(nodeidParent1); - alg.update(nodeidParent2); + if ((nodeidParent1[0] & 0x00FF) < (nodeidParent2[0] & 0x00FF)) { + alg.update(nodeidParent1); + alg.update(nodeidParent2); + } else { + alg.update(nodeidParent2); + alg.update(nodeidParent1); + } byte[] digest = alg.digest(data); assert digest.length == 20; return toHexString(digest, 0, 20); } + // 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 { MessageDigest alg = getSHA1(); byte[] buf = new byte[1024];
--- a/src/com/tmate/hgkit/ll/HgBundle.java Fri Jan 14 03:37:06 2011 +0100 +++ b/src/com/tmate/hgkit/ll/HgBundle.java Fri Jan 14 04:14:08 2011 +0100 @@ -28,6 +28,7 @@ public void changes(HgRepository hgRepo) throws IOException { DataAccess da = accessProvider.create(bundleFile); + DigestHelper dh = new DigestHelper(); try { List<GroupElement> changelogGroup = readGroup(da); if (changelogGroup.isEmpty()) { @@ -46,6 +47,9 @@ for (GroupElement ge : changelogGroup) { 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); Changeset cs = Changeset.parse(csetContent, 0, csetContent.length); cs.dump(); baseRevContent = csetContent;
--- a/src/com/tmate/hgkit/ll/Nodeid.java Fri Jan 14 03:37:06 2011 +0100 +++ b/src/com/tmate/hgkit/ll/Nodeid.java Fri Jan 14 04:14:08 2011 +0100 @@ -75,6 +75,12 @@ return true; } + // primary purpose is to give DigestHelper access to internal structure. Despite it's friends-only (package visibility), it's still makes sense to + // return a copy, to avoid any accidental modification (same reason field is not made visible, nor any callback, e.g. Output.write(byte[]) was introduced) + /*package-local*/byte[] cloneData() { + return binaryData.clone(); + } + // primary difference with cons is handling of NULL id (this method returns constant) // always makes a copy of an array passed public static Nodeid fromBinary(byte[] binaryRepresentation, int offset) {