fix(rar): unsupported rar archives are marked as such

solid, encrypted, and multi-volumes rar4 archives are not supported

closes #147
This commit is contained in:
Gauthier Roebroeck 2020-05-02 22:20:22 +08:00
parent d275506eac
commit 6c0ebbeee1
8 changed files with 24 additions and 13 deletions

View File

@ -1,6 +1,7 @@
package org.gotson.komga.domain.model
class MediaNotReadyException : Exception()
class MediaUnsupportedException(message: String) : Exception(message)
class ImageConversionException(message: String) : Exception(message)
class DirectoryNotFoundException(message: String) : Exception(message)
class DuplicateNameException(message: String) : Exception(message)

View File

@ -5,6 +5,7 @@ import org.gotson.komga.domain.model.Book
import org.gotson.komga.domain.model.BookPage
import org.gotson.komga.domain.model.Media
import org.gotson.komga.domain.model.MediaNotReadyException
import org.gotson.komga.domain.model.MediaUnsupportedException
import org.gotson.komga.infrastructure.image.ImageConverter
import org.gotson.komga.infrastructure.mediacontainer.ContentDetector
import org.gotson.komga.infrastructure.mediacontainer.MediaContainerExtractor
@ -36,6 +37,8 @@ class BookAnalyzer(
val entries = try {
supportedMediaTypes.getValue(mediaType).getEntries(book.path())
} catch (ex: MediaUnsupportedException) {
return Media(mediaType = mediaType, status = Media.Status.UNSUPPORTED, comment = ex.message)
} catch (ex: Exception) {
logger.error(ex) { "Error while analyzing book: $book" }
return Media(mediaType = mediaType, status = Media.Status.ERROR, comment = ex.message)

View File

@ -1,10 +1,14 @@
package org.gotson.komga.infrastructure.mediacontainer
import org.gotson.komga.domain.model.MediaContainerEntry
import org.gotson.komga.domain.model.MediaUnsupportedException
import java.nio.file.Path
interface MediaContainerExtractor {
fun mediaTypes(): List<String>
@Throws(MediaUnsupportedException::class)
fun getEntries(path: Path): List<MediaContainerEntry>
fun getEntryStream(path: Path, entryName: String): ByteArray
}

View File

@ -4,6 +4,7 @@ import com.github.junrar.Archive
import mu.KotlinLogging
import net.greypanther.natsort.CaseInsensitiveSimpleNaturalComparator
import org.gotson.komga.domain.model.MediaContainerEntry
import org.gotson.komga.domain.model.MediaUnsupportedException
import org.springframework.stereotype.Service
import java.nio.file.Files
import java.nio.file.Path
@ -22,6 +23,9 @@ class RarExtractor(
override fun getEntries(path: Path): List<MediaContainerEntry> =
Archive(Files.newInputStream(path)).use { rar ->
if (rar.mainHeader.isEncrypted) throw MediaUnsupportedException("Encrypted RAR archives are not supported")
if (rar.mainHeader.isSolid) throw MediaUnsupportedException("Solid RAR archives are not supported")
if (rar.mainHeader.isMultiVolume) throw MediaUnsupportedException("Multi-Volume RAR archives are not supported")
rar.fileHeaders
.filter { !it.isDirectory }
.map {
@ -38,6 +42,6 @@ class RarExtractor(
override fun getEntryStream(path: Path, entryName: String): ByteArray =
Archive(Files.newInputStream(path)).use { rar ->
val header = rar.fileHeaders.find { it.fileNameString == entryName }
rar.getInputStream(header).readBytes()
rar.getInputStream(header).readBytes()
}
}

View File

@ -21,30 +21,30 @@ class BookAnalyzerTest(
@Autowired private val bookAnalyzer: BookAnalyzer
) {
@ParameterizedTest
@ValueSource(strings = [
"rar4.rar", "rar4-solid.rar"
])
fun `given rar4 archive when analyzing then media status is READY`(fileName: String) {
val file = ClassPathResource("archives/$fileName")
@Test
fun `given rar4 archive when analyzing then media status is READY`() {
val file = ClassPathResource("archives/rar4.rar")
val book = Book("book", file.url, LocalDateTime.now())
val media = bookAnalyzer.analyze(book)
assertThat(media.mediaType).isEqualTo("application/x-rar-compressed; version=4")
assertThat(media.status).isEqualTo(Media.Status.READY)
assertThat(media.pages).hasSize(1)
assertThat(media.pages).hasSize(3)
}
@Test
fun `given rar4 encrypted archive when analyzing then media status is ERROR`() {
val file = ClassPathResource("archives/rar4-encrypted.rar")
@ParameterizedTest
@ValueSource(strings = [
"rar4-solid.rar", "rar4-encrypted.rar"
])
fun `given rar4 solid or encrypted archive when analyzing then media status is UNSUPPORTED`(fileName: String) {
val file = ClassPathResource("archives/rar4-solid.rar")
val book = Book("book", file.url, LocalDateTime.now())
val media = bookAnalyzer.analyze(book)
assertThat(media.mediaType).isEqualTo("application/x-rar-compressed; version=4")
assertThat(media.status).isEqualTo(Media.Status.ERROR)
assertThat(media.status).isEqualTo(Media.Status.UNSUPPORTED)
}
@ParameterizedTest
@ -112,5 +112,4 @@ class BookAnalyzerTest(
assertThat(media.status).isEqualTo(Media.Status.READY)
assertThat(media.pages).hasSize(1)
}
}