ElwigData: Check zip file integrity
All checks were successful
Test / Run tests (push) Successful in 1m59s

This commit is contained in:
2025-08-06 12:31:19 +02:00
parent 73fe4531cc
commit d3157e4d48
5 changed files with 21 additions and 5 deletions

View File

@@ -240,9 +240,9 @@ namespace Elwig {
} }
} }
public static void ReplaceDatabase(string filename) { public static async Task ReplaceDatabase(string filename) {
try { 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); MessageBox.Show("Das Ersetzen war erfolgreich!\n\nBitte starten Sie Elwig neu!", "Datenbank ersetzen", MessageBoxButton.OK, MessageBoxImage.Information);
ForceShutdown = true; ForceShutdown = true;
Current.Shutdown(); Current.Shutdown();

View File

@@ -35,6 +35,7 @@
<PackageReference Include="RazorLight" Version="2.3.1" /> <PackageReference Include="RazorLight" Version="2.3.1" />
<PackageReference Include="ScottPlot.WPF" Version="5.0.55" /> <PackageReference Include="ScottPlot.WPF" Version="5.0.55" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.0" /> <PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.0" />
<PackageReference Include="System.IO.Hashing" Version="9.0.8" />
<PackageReference Include="System.IO.Ports" Version="9.0.8" /> <PackageReference Include="System.IO.Ports" Version="9.0.8" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.8" /> <PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.8" />
</ItemGroup> </ItemGroup>

View File

@@ -75,6 +75,7 @@ namespace Elwig.Helpers.Export {
foreach (var filename in filenames) { foreach (var filename in filenames) {
// TODO read encrypted files // TODO read encrypted files
using var zip = ZipFile.Open(filename, ZipArchiveMode.Read); using var zip = ZipFile.Open(filename, ZipArchiveMode.Read);
await zip.CheckIntegrity();
var version = zip.GetEntry("version"); var version = zip.GetEntry("version");
using (var reader = new StreamReader(version!.Open(), Utils.UTF8)) { using (var reader = new StreamReader(version!.Open(), Utils.UTF8)) {
@@ -370,11 +371,12 @@ namespace Elwig.Helpers.Export {
}.Export(filename); }.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 oldName = Path.ChangeExtension(App.Config.DatabaseFile, ".old.sqlite3");
var newName = Path.ChangeExtension(App.Config.DatabaseFile, ".new.sqlite3"); var newName = Path.ChangeExtension(App.Config.DatabaseFile, ".new.sqlite3");
try { try {
using (var zip = ZipFile.Open(filename, ZipArchiveMode.Read)) { using (var zip = ZipFile.Open(filename, ZipArchiveMode.Read)) {
await zip.CheckIntegrity();
var db = zip.GetEntry("database.sqlite3")!; var db = zip.GetEntry("database.sqlite3")!;
db.ExtractToFile(newName, true); db.ExtractToFile(newName, true);
} }

View File

@@ -1,5 +1,7 @@
using System; using System;
using System.IO; using System.IO;
using System.IO.Compression;
using System.IO.Hashing;
using System.Net.Http; using System.Net.Http;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
@@ -95,5 +97,16 @@ namespace Elwig.Helpers {
await download.CopyToAsync(destination, 81920, relativeProgress, cancellationToken); await download.CopyToAsync(destination, 81920, relativeProgress, cancellationToken);
progress.Report(100.0); 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}'");
}
}
} }
} }

View File

@@ -266,8 +266,8 @@ namespace Elwig.Windows {
if (res != MessageBoxResult.OK) if (res != MessageBoxResult.OK)
return; return;
await App.MainDispatcher.BeginInvoke(() => { await App.MainDispatcher.BeginInvoke(async () => {
App.ReplaceDatabase(filename); await App.ReplaceDatabase(filename);
}); });
} catch (HttpRequestException exc) { } catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Datenbank herunterladen", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Datenbank herunterladen", MessageBoxButton.OK, MessageBoxImage.Error);