diff --git a/src/main/java/org/qortal/arbitrary/patch/UnifiedDiffPatch.java b/src/main/java/org/qortal/arbitrary/patch/UnifiedDiffPatch.java index ae24f03b..16b9464f 100644 --- a/src/main/java/org/qortal/arbitrary/patch/UnifiedDiffPatch.java +++ b/src/main/java/org/qortal/arbitrary/patch/UnifiedDiffPatch.java @@ -91,7 +91,8 @@ public class UnifiedDiffPatch { } /** - * Validate the patch to ensure it works correctly + * Validate the patch at the "destination" path to ensure + * it works correctly and is smaller than the original file * * @return true if valid, false if invalid * @throws IOException @@ -110,8 +111,13 @@ public class UnifiedDiffPatch { byte[] inputDigest = Crypto.digest(after.toFile()); byte[] outputDigest = Crypto.digest(tempPath.toFile()); if (Arrays.equals(inputDigest, outputDigest)) { - // Patch is valid - return true; + // Patch is valid, but we might want to reject if it's larger than the original file + long originalSize = Files.size(after); + long patchSize = Files.size(destination); + if (patchSize < originalSize) { + // Patch file is smaller than the original file size, so treat it as valid + return true; + } } else { LOGGER.info("Checksum mismatch when verifying patch for file {}", destination.toString()); diff --git a/src/test/java/org/qortal/test/arbitrary/ArbitraryDataMergeTests.java b/src/test/java/org/qortal/test/arbitrary/ArbitraryDataMergeTests.java index 7a607e21..5d0af2e8 100644 --- a/src/test/java/org/qortal/test/arbitrary/ArbitraryDataMergeTests.java +++ b/src/test/java/org/qortal/test/arbitrary/ArbitraryDataMergeTests.java @@ -68,23 +68,26 @@ public class ArbitraryDataMergeTests extends Common { Crypto.digest(Paths.get(patchPath.toString(), "dir1", "dir2", "lorem5.txt").toFile()) )); - // Ensure that the patch files differ from the second path (except for lorem3, which is missing) + // Ensure that the patch files 1, 4, and 5 differ from the second path assertFalse(Arrays.equals( Crypto.digest(Paths.get(path2.toString(), "lorem1.txt").toFile()), Crypto.digest(Paths.get(patchPath.toString(), "lorem1.txt").toFile()) )); - assertFalse(Arrays.equals( - Crypto.digest(Paths.get(path2.toString(), "lorem2.txt").toFile()), - Crypto.digest(Paths.get(patchPath.toString(), "lorem2.txt").toFile()) - )); assertFalse(Arrays.equals( Crypto.digest(Paths.get(path2.toString(), "dir1", "lorem4.txt").toFile()), Crypto.digest(Paths.get(patchPath.toString(), "dir1", "lorem4.txt").toFile()) )); - assertFalse(Arrays.equals( + + // Files 2 and 5 should match the original files, because their contents were + // too small to create a patch file smaller than to original file + assertArrayEquals( + Crypto.digest(Paths.get(path2.toString(), "lorem2.txt").toFile()), + Crypto.digest(Paths.get(patchPath.toString(), "lorem2.txt").toFile()) + ); + assertArrayEquals( Crypto.digest(Paths.get(path2.toString(), "dir1", "dir2", "lorem5.txt").toFile()), Crypto.digest(Paths.get(patchPath.toString(), "dir1", "dir2", "lorem5.txt").toFile()) - )); + ); // Now merge the patch with the original path ArbitraryDataMerge merge = new ArbitraryDataMerge(path1, patchPath); @@ -227,6 +230,8 @@ public class ArbitraryDataMergeTests extends Common { // Write a random string to the first file BufferedWriter file1Writer = new BufferedWriter(new FileWriter(file1)); String initialString = this.generateRandomString(1024); + // Add a newline every 50 chars + initialString = initialString.replaceAll("(.{50})", "$1\n"); file1Writer.write(initialString); file1Writer.newLine(); file1Writer.close(); @@ -289,6 +294,10 @@ public class ArbitraryDataMergeTests extends Common { // Write a random string to the first file BufferedWriter file1Writer = new BufferedWriter(new FileWriter(file1)); String initialString = this.generateRandomString(1024); + // Add a newline every 50 chars + initialString = initialString.replaceAll("(.{50})", "$1\n"); + // Remove newline at end of string + initialString = initialString.stripTrailing(); file1Writer.write(initialString); // No newline file1Writer.close(); @@ -354,6 +363,8 @@ public class ArbitraryDataMergeTests extends Common { // Write a random string to the first file BufferedWriter file1Writer = new BufferedWriter(new FileWriter(file1)); String initialString = this.generateRandomString(110 * 1024); + // Add a newline every 50 chars + initialString = initialString.replaceAll("(.{50})", "$1\n"); file1Writer.write(initialString); file1Writer.newLine(); file1Writer.close(); diff --git a/src/test/resources/arbitrary/demo1/lorem1.txt b/src/test/resources/arbitrary/demo1/lorem1.txt index 4f006a88..5721466c 100644 --- a/src/test/resources/arbitrary/demo1/lorem1.txt +++ b/src/test/resources/arbitrary/demo1/lorem1.txt @@ -1 +1,10 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. +Ut ligula felis, imperdiet nec placerat at, placerat +quis diam. Praesent a ultricies lacus. +Aenean luctus blandit dui. Quisque vel augue +diam. Nulla libero libero, condimentum sed +accumsan eu, elementum sit amet turpis. +In semper risus ac libero lobortis, +ut consectetur urna euismod. +Donec ut erat quis mi eleifend tincidunt +aliquet vitae lacus. diff --git a/src/test/resources/arbitrary/demo2/lorem1.txt b/src/test/resources/arbitrary/demo2/lorem1.txt index febb7414..4df35553 100644 --- a/src/test/resources/arbitrary/demo2/lorem1.txt +++ b/src/test/resources/arbitrary/demo2/lorem1.txt @@ -1 +1,10 @@ -Lorem ipsum dolor sit amet, adipiscing elit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. +Ut ligula felis, imperdiet nec placerat at, placerat +quis diam. Praesent a ultricies lacus. +Aenean luctus blandit dui. Quisque vel augue +diam. Nulla libero libero; condimentum sed +accumsan eu, elementum sit amet turpis. +In semper risus ac libero lobortis, +ut consectetur urna euismod. +Donec ut erat quis mi eleifend tincidunt +aliquet vitae lacus.