Include the original file instead of a patch if the patch is larger than the original file.

This saves processing and disk space, as there is no point in applying a patch when the original file is smaller and can be included in its entirety.
This commit is contained in:
CalDescent 2021-10-24 12:02:09 +01:00
parent 8dd4d71d75
commit 04aabe0921
4 changed files with 46 additions and 11 deletions

View File

@ -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());

View File

@ -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();

View File

@ -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.

View File

@ -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.