From c625f61bfc2192861ca5cf7808f143c16ddff881 Mon Sep 17 00:00:00 2001 From: Simon Barner <barner@fortiss.org> Date: Fri, 13 Oct 2023 16:59:07 +0200 Subject: [PATCH] Fix computeGitObjectHash() to compute the same object has as Git * Renamed from computeGitHash() Issue-Ref: 4310 Issue-Url: https://git.fortiss.org/af3/af3/-/issues/4310 Signed-off-by: Simon Barner <barner@fortiss.org> --- .../tooling/ext/quality/storage/.ratings | 2 +- .../ext/quality/storage/CSVFileWriter.java | 52 +++++++++++-------- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/.ratings b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/.ratings index 1af854e96..a7cf9548b 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/.ratings +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/.ratings @@ -1,2 +1,2 @@ -CSVFileWriter.java a779fce240c25aae1b72dfd11d27b74b0b21d599 RED +CSVFileWriter.java 0cae6203edc159cec0d3f68c61f4b04a3c61eecd RED ModelQualityStorageManager.java 8293f17743bdc85e2595eae99b978ed868bd029b RED diff --git a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/CSVFileWriter.java b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/CSVFileWriter.java index a779fce24..0cae6203e 100644 --- a/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/CSVFileWriter.java +++ b/org.fortiss.tooling.ext.quality/src/org/fortiss/tooling/ext/quality/storage/CSVFileWriter.java @@ -15,18 +15,14 @@ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.ext.quality.storage; -import static java.lang.Integer.toHexString; - import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.time.LocalDateTime; @@ -102,7 +98,7 @@ public class CSVFileWriter { // Add topLevelElement.doSave(new NullProgressMonitor()); Path modelFile = new File(ModelQualityStorageManager.MODEL_PROJECT_DIR, topLevelElement.getSaveableName()).toPath(); - String projectHash = computeGitHash(modelFile); + String projectHash = computeGitObjectHash(modelFile); List<String> allKeys = new ArrayList<>(); boolean createNewIndex = true; @@ -216,27 +212,39 @@ public class CSVFileWriter { } /** - * Function to generate the hash for the model in order to later on match versions of the file - * project with saved metrics (assuming both are under version control using Git). + * Return the Git object hash for the contents of the given file: + * <p> + * {@code SHA-1("blob <size>\0"+<contents>).asHexString()}. */ - private static String computeGitHash(Path filePath) + private static String computeGitObjectHash(Path filePath) throws NoSuchAlgorithmException, IOException { - String fileAsString = new String(Files.readAllBytes(Paths.get(filePath.toString()))); - MessageDigest digest = MessageDigest.getInstance("SHA-1"); - byte[] hash = digest.digest(fileAsString.getBytes(StandardCharsets.UTF_8)); - return bytesToHex(hash); - } - /** Switching from bytes to Hex notation. */ - private static String bytesToHex(byte[] hash) { - StringBuilder hexString = new StringBuilder(2 * hash.length); - for(byte b : hash) { - String hex = toHexString(0xff & b); - if(hex.length() == 1) { - hexString.append('0'); + try(BufferedReader reader = new BufferedReader(new FileReader(filePath.toString()))) { + // Read file line-wise with UNIX line endings + StringBuilder inputBuilder = new StringBuilder(); + do { + String line = reader.readLine(); + if(line == null) { + break; + } + inputBuilder.append(line); + inputBuilder.append("\n"); + } while(true); + + // Construct pre-image (input to hash function) according to Git specification + String fileContents = inputBuilder.toString(); + int n = fileContents.length(); + String preImage = "blob " + n + "\0" + fileContents; + + // Compute hash and convert it to a hex string + MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); + byte[] digest = sha1.digest(preImage.getBytes()); + + StringBuilder resultBuilder = new StringBuilder(); + for(byte b : digest) { + resultBuilder.append(String.format("%02x", b & 0xff)); } - hexString.append(hex); + return resultBuilder.toString(); } - return hexString.toString(); } } -- GitLab