diff --git a/Elwig/App.xaml.cs b/Elwig/App.xaml.cs
index df7f047..c08cec3 100644
--- a/Elwig/App.xaml.cs
+++ b/Elwig/App.xaml.cs
@@ -240,9 +240,9 @@ namespace Elwig {
}
}
- public static void ReplaceDatabase(string filename) {
+ public static async Task ReplaceDatabase(string filename) {
try {
- ElwigData.ImportDatabase(filename);
+ await ElwigData.ImportDatabase(filename);
MessageBox.Show("Das Ersetzen war erfolgreich!\n\nBitte starten Sie Elwig neu!", "Datenbank ersetzen", MessageBoxButton.OK, MessageBoxImage.Information);
ForceShutdown = true;
Current.Shutdown();
diff --git a/Elwig/Elwig.csproj b/Elwig/Elwig.csproj
index 3e0aaf0..31f09d0 100644
--- a/Elwig/Elwig.csproj
+++ b/Elwig/Elwig.csproj
@@ -35,6 +35,7 @@
+
diff --git a/Elwig/Helpers/Export/ElwigData.cs b/Elwig/Helpers/Export/ElwigData.cs
index c196c43..3868be4 100644
--- a/Elwig/Helpers/Export/ElwigData.cs
+++ b/Elwig/Helpers/Export/ElwigData.cs
@@ -75,6 +75,7 @@ namespace Elwig.Helpers.Export {
foreach (var filename in filenames) {
// TODO read encrypted files
using var zip = ZipFile.Open(filename, ZipArchiveMode.Read);
+ await zip.CheckIntegrity();
var version = zip.GetEntry("version");
using (var reader = new StreamReader(version!.Open(), Utils.UTF8)) {
@@ -370,11 +371,12 @@ namespace Elwig.Helpers.Export {
}.Export(filename);
}
- public static void ImportDatabase(string filename) {
+ public static async Task ImportDatabase(string filename) {
var oldName = Path.ChangeExtension(App.Config.DatabaseFile, ".old.sqlite3");
var newName = Path.ChangeExtension(App.Config.DatabaseFile, ".new.sqlite3");
try {
using (var zip = ZipFile.Open(filename, ZipArchiveMode.Read)) {
+ await zip.CheckIntegrity();
var db = zip.GetEntry("database.sqlite3")!;
db.ExtractToFile(newName, true);
}
diff --git a/Elwig/Helpers/Extensions.cs b/Elwig/Helpers/Extensions.cs
index bae2d8c..d616225 100644
--- a/Elwig/Helpers/Extensions.cs
+++ b/Elwig/Helpers/Extensions.cs
@@ -1,5 +1,7 @@
using System;
using System.IO;
+using System.IO.Compression;
+using System.IO.Hashing;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Threading;
@@ -95,5 +97,16 @@ namespace Elwig.Helpers {
await download.CopyToAsync(destination, 81920, relativeProgress, cancellationToken);
progress.Report(100.0);
}
+
+ public static async Task CheckIntegrity(this ZipArchive zip) {
+ var crc = new Crc32();
+ foreach (var entry in zip.Entries) {
+ crc.Reset();
+ using var stream = entry.Open();
+ await crc.AppendAsync(stream);
+ if (crc.GetCurrentHashAsUInt32() != entry.Crc32)
+ throw new InvalidDataException($"CRC-32 mismatch in '{entry.FullName}'");
+ }
+ }
}
}
diff --git a/Elwig/Windows/MainWindow.xaml.cs b/Elwig/Windows/MainWindow.xaml.cs
index e5f8351..a7fef8e 100644
--- a/Elwig/Windows/MainWindow.xaml.cs
+++ b/Elwig/Windows/MainWindow.xaml.cs
@@ -266,8 +266,8 @@ namespace Elwig.Windows {
if (res != MessageBoxResult.OK)
return;
- await App.MainDispatcher.BeginInvoke(() => {
- App.ReplaceDatabase(filename);
+ await App.MainDispatcher.BeginInvoke(async () => {
+ await App.ReplaceDatabase(filename);
});
} catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Datenbank herunterladen", MessageBoxButton.OK, MessageBoxImage.Error);