diff --git a/API.Benchmark/API.Benchmark.csproj b/API.Benchmark/API.Benchmark.csproj
index 5461138d5..11ef151a2 100644
--- a/API.Benchmark/API.Benchmark.csproj
+++ b/API.Benchmark/API.Benchmark.csproj
@@ -20,5 +20,11 @@
Always
+
+
+ Data
+ Always
+
+
diff --git a/API.Benchmark/ArchiveSerivceBenchmark.cs b/API.Benchmark/ArchiveSerivceBenchmark.cs
deleted file mode 100644
index 11a66d7bc..000000000
--- a/API.Benchmark/ArchiveSerivceBenchmark.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace API.Benchmark;
-
-public class ArchiveSerivceBenchmark
-{
- // Benchmark to test default GetNumberOfPages from archive
- // vs a new method where I try to open the archive and return said stream
-}
diff --git a/API.Benchmark/ArchiveServiceBenchmark.cs b/API.Benchmark/ArchiveServiceBenchmark.cs
new file mode 100644
index 000000000..d8418ee26
--- /dev/null
+++ b/API.Benchmark/ArchiveServiceBenchmark.cs
@@ -0,0 +1,54 @@
+using System;
+using System.IO.Abstractions;
+using Microsoft.Extensions.Logging.Abstractions;
+using API.Services;
+using BenchmarkDotNet.Attributes;
+using BenchmarkDotNet.Order;
+
+namespace API.Benchmark;
+
+[StopOnFirstError]
+[MemoryDiagnoser]
+[RankColumn]
+[Orderer(SummaryOrderPolicy.FastestToSlowest)]
+[SimpleJob(launchCount: 1, warmupCount: 5, targetCount: 20)]
+public class ArchiveServiceBenchmark
+{
+ private readonly ArchiveService _archiveService;
+ private readonly IDirectoryService _directoryService;
+ private readonly IImageService _imageService;
+
+ public ArchiveServiceBenchmark()
+ {
+ _directoryService = new DirectoryService(null, new FileSystem());
+ _imageService = new ImageService(null, _directoryService);
+ _archiveService = new ArchiveService(new NullLogger(), _directoryService, _imageService);
+ }
+
+ [Benchmark(Baseline = true)]
+ public void TestGetComicInfo_baseline()
+ {
+ if (_archiveService.GetComicInfo("Data/ComicInfo.zip") == null) {
+ throw new Exception("ComicInfo not found");
+ }
+ }
+
+ [Benchmark]
+ public void TestGetComicInfo_duplicate()
+ {
+ if (_archiveService.GetComicInfo("Data/ComicInfo_duplicateInfos.zip") == null) {
+ throw new Exception("ComicInfo not found");
+ }
+ }
+
+ [Benchmark]
+ public void TestGetComicInfo_outside_root()
+ {
+ if (_archiveService.GetComicInfo("Data/ComicInfo_outside_root.zip") == null) {
+ throw new Exception("ComicInfo not found");
+ }
+ }
+
+ // Benchmark to test default GetNumberOfPages from archive
+ // vs a new method where I try to open the archive and return said stream
+}
diff --git a/API.Tests/Services/ArchiveServiceTests.cs b/API.Tests/Services/ArchiveServiceTests.cs
index 7fc267869..f399cb790 100644
--- a/API.Tests/Services/ArchiveServiceTests.cs
+++ b/API.Tests/Services/ArchiveServiceTests.cs
@@ -256,17 +256,31 @@ public class ArchiveServiceTests
Assert.Equal("Junya Inoue", comicInfo.Writer);
}
- [Fact]
- public void ShouldHaveComicInfo_TopLevelFileOnly()
+ [Theory]
+ [InlineData("ComicInfo_duplicateInfos.zip")]
+ [InlineData("ComicInfo_duplicateInfos_reversed.zip")]
+ [InlineData("ComicInfo_duplicateInfos.rar")]
+ public void ShouldHaveComicInfo_TopLevelFileOnly(string filename)
{
var testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ArchiveService/ComicInfos");
- var archive = Path.Join(testDirectory, "ComicInfo_duplicateInfos.zip");
+ var archive = Path.Join(testDirectory, filename);
var comicInfo = _archiveService.GetComicInfo(archive);
Assert.NotNull(comicInfo);
Assert.Equal("BTOOOM!", comicInfo.Series);
}
+ [Fact]
+ public void ShouldHaveComicInfo_OutsideRoot()
+ {
+ var testDirectory = Path.Join(Directory.GetCurrentDirectory(), "../../../Services/Test Data/ArchiveService/ComicInfos");
+ var archive = Path.Join(testDirectory, "ComicInfo_outside_root.zip");
+
+ var comicInfo = _archiveService.GetComicInfo(archive);
+ Assert.NotNull(comicInfo);
+ Assert.Equal("BTOOOM! - Duplicate", comicInfo.Series);
+ }
+
#endregion
#region CanParseComicInfo
diff --git a/API.Tests/Services/Test Data/ArchiveService/ComicInfos/ComicInfo_duplicateInfos.rar b/API.Tests/Services/Test Data/ArchiveService/ComicInfos/ComicInfo_duplicateInfos.rar
new file mode 100644
index 000000000..9d5bab5a2
Binary files /dev/null and b/API.Tests/Services/Test Data/ArchiveService/ComicInfos/ComicInfo_duplicateInfos.rar differ
diff --git a/API.Tests/Services/Test Data/ArchiveService/ComicInfos/ComicInfo_duplicateInfos_reversed.zip b/API.Tests/Services/Test Data/ArchiveService/ComicInfos/ComicInfo_duplicateInfos_reversed.zip
new file mode 100644
index 000000000..f764a4a60
Binary files /dev/null and b/API.Tests/Services/Test Data/ArchiveService/ComicInfos/ComicInfo_duplicateInfos_reversed.zip differ
diff --git a/API.Tests/Services/Test Data/ArchiveService/ComicInfos/ComicInfo_outside_root.zip b/API.Tests/Services/Test Data/ArchiveService/ComicInfos/ComicInfo_outside_root.zip
new file mode 100644
index 000000000..9caea5bf1
Binary files /dev/null and b/API.Tests/Services/Test Data/ArchiveService/ComicInfos/ComicInfo_outside_root.zip differ
diff --git a/API/Services/ArchiveService.cs b/API/Services/ArchiveService.cs
index 12c0a4029..b370f178d 100644
--- a/API/Services/ArchiveService.cs
+++ b/API/Services/ArchiveService.cs
@@ -328,12 +328,11 @@ public class ArchiveService : IArchiveService
return false;
}
- private static bool ValidComicInfoArchiveEntry(string fullName, string name)
+ private static bool IsComicInfoArchiveEntry(string fullName, string name)
{
- var filenameWithoutExtension = Path.GetFileNameWithoutExtension(name).ToLower();
return !Tasks.Scanner.Parser.Parser.HasBlacklistedFolderInPath(fullName)
- && (fullName.Equals(ComicInfoFilename) || (string.IsNullOrEmpty(fullName) && name.Equals(ComicInfoFilename)))
- && !filenameWithoutExtension.StartsWith(Tasks.Scanner.Parser.Parser.MacOsMetadataFileStartsWith);
+ && name.Equals(ComicInfoFilename, StringComparison.OrdinalIgnoreCase)
+ && !name.StartsWith(Tasks.Scanner.Parser.Parser.MacOsMetadataFileStartsWith);
}
///
@@ -356,7 +355,8 @@ public class ArchiveService : IArchiveService
{
using var archive = ZipFile.OpenRead(archivePath);
- var entry = archive.Entries.FirstOrDefault(x => ValidComicInfoArchiveEntry(x.FullName, x.Name));
+ var entry = archive.Entries.FirstOrDefault(x => (x.FullName ?? x.Name) == ComicInfoFilename) ??
+ archive.Entries.FirstOrDefault(x => IsComicInfoArchiveEntry(x.FullName, x.Name));
if (entry != null)
{
using var stream = entry.Open();
@@ -371,8 +371,9 @@ public class ArchiveService : IArchiveService
case ArchiveLibrary.SharpCompress:
{
using var archive = ArchiveFactory.Open(archivePath);
- var entry = archive.Entries.FirstOrDefault(entry =>
- ValidComicInfoArchiveEntry(Path.GetDirectoryName(entry.Key), entry.Key));
+ var entry = archive.Entries.FirstOrDefault(entry => entry.Key == ComicInfoFilename) ??
+ archive.Entries.FirstOrDefault(entry =>
+ IsComicInfoArchiveEntry(Path.GetDirectoryName(entry.Key), entry.Key));
if (entry != null)
{