Skip to content

Commit

Permalink
Merge pull request #3254 from TeamAmaze/bugfix/3035
Browse files Browse the repository at this point in the history
Exception handling for 7z entries without timestamps
  • Loading branch information
VishalNehra authored Apr 23, 2022
2 parents e0a5057 + 298e84a commit e58a26b
Show file tree
Hide file tree
Showing 13 changed files with 172 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

package com.amaze.filemanager.asynchronous.asynctasks.compress

import android.util.Log
import com.amaze.filemanager.adapters.data.CompressedObjectParcelable
import com.amaze.filemanager.file_operations.filesystem.compressed.ArchivePasswordCache
import com.amaze.filemanager.filesystem.compressed.CompressedHelper
Expand All @@ -28,7 +29,7 @@ import org.apache.commons.compress.PasswordRequiredException
import org.apache.commons.compress.archivers.ArchiveException
import java.io.File
import java.io.IOException
import java.util.*
import java.lang.UnsupportedOperationException

class SevenZipHelperCallable(
private val filePath: String,
Expand Down Expand Up @@ -64,7 +65,12 @@ class SevenZipHelperCallable(
elements.add(
CompressedObjectParcelable(
entry.name,
entry.lastModifiedDate.time,
try {
entry.lastModifiedDate.time
} catch (e: UnsupportedOperationException) {
Log.w(javaClass.simpleName, "Unable to get modified date for 7zip file")
0L
},
entry.size,
entry.isDirectory
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package com.amaze.filemanager.filesystem.compressed.extractcontents.helpers

import android.content.Context
import android.util.Log
import com.amaze.filemanager.R
import com.amaze.filemanager.application.AppConfig
import com.amaze.filemanager.file_operations.filesystem.compressed.ArchivePasswordCache
Expand All @@ -36,7 +37,7 @@ import org.tukaani.xz.CorruptedInputException
import java.io.BufferedOutputStream
import java.io.File
import java.io.IOException
import java.util.*
import java.lang.UnsupportedOperationException

class SevenZipExtractor(
context: Context,
Expand Down Expand Up @@ -126,7 +127,13 @@ class SevenZipExtractor(
progress += length.toLong()
}
close()
outputFile.setLastModified(entry.lastModifiedDate.time)
val lastModifiedDate = try {
entry.lastModifiedDate.time
} catch (e: UnsupportedOperationException) {
Log.w(javaClass.simpleName, "Unable to get modified date for 7zip file")
System.currentTimeMillis()
}
outputFile.setLastModified(lastModifiedDate)
}
}?.onFailure {
throw it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
package com.amaze.filemanager.asynchronous.asynctasks.compress

import android.os.Environment
import org.junit.Assert.*
import com.amaze.filemanager.adapters.data.CompressedObjectParcelable
import org.junit.Assert.assertEquals
import org.junit.Test
import java.io.File
import java.time.ZoneId
Expand All @@ -30,19 +31,28 @@ import java.time.ZonedDateTime
@Suppress("TooManyFunctions", "StringLiteralDuplication")
abstract class AbstractCompressedHelperCallableArchiveTest : AbstractCompressedHelperCallableTest() {

private val EXPECTED_TIMESTAMP = ZonedDateTime.of(
2018,
5,
29,
10,
38,
0,
0,
ZoneId.of("UTC")
).toInstant().toEpochMilli()
companion object {
@JvmStatic
private val EXPECTED_TIMESTAMP = ZonedDateTime.of(
2018,
5,
29,
10,
38,
0,
0,
ZoneId.of("UTC")
).toInstant().toEpochMilli()
}

protected abstract val archiveFileName: String

/**
* Assert archive entry timestamp is correct.
*/
protected open fun assertEntryTimestampCorrect(entry: CompressedObjectParcelable) =
assertEquals(EXPECTED_TIMESTAMP, entry.date)

/**
* Test browse archive top level.
*/
Expand All @@ -52,7 +62,7 @@ abstract class AbstractCompressedHelperCallableArchiveTest : AbstractCompressedH
val result = task.call()
assertEquals(1, result.size.toLong())
assertEquals("test-archive", result[0].name)
assertEquals(EXPECTED_TIMESTAMP, result[0].date)
assertEntryTimestampCorrect(result[0])
}

/**
Expand All @@ -64,55 +74,55 @@ abstract class AbstractCompressedHelperCallableArchiveTest : AbstractCompressedH
var result = task.call()
assertEquals("Thrown from $javaClass.name", 5, result.size.toLong())
assertEquals("1", result[0].name)
assertEquals(EXPECTED_TIMESTAMP, result[0].date)
assertEntryTimestampCorrect(result[0])
assertEquals("2", result[1].name)
assertEquals(EXPECTED_TIMESTAMP, result[1].date)
assertEntryTimestampCorrect(result[1])
assertEquals("3", result[2].name)
assertEquals(EXPECTED_TIMESTAMP, result[2].date)
assertEntryTimestampCorrect(result[2])
assertEquals("4", result[3].name)
assertEquals(EXPECTED_TIMESTAMP, result[3].date)
assertEntryTimestampCorrect(result[3])
assertEquals("a", result[4].name)
assertEquals(EXPECTED_TIMESTAMP, result[4].date)
assertEntryTimestampCorrect(result[4])
task = createCallable("test-archive/1")
result = task.call()
assertEquals(1, result.size.toLong())
assertEquals("8", result[0].name)
assertEquals(EXPECTED_TIMESTAMP, result[0].date)
assertEntryTimestampCorrect(result[0])
task = createCallable("test-archive/2")
result = task.call()
assertEquals(1, result.size.toLong())
assertEquals("7", result[0].name)
assertEquals(EXPECTED_TIMESTAMP, result[0].date)
assertEntryTimestampCorrect(result[0])
task = createCallable("test-archive/3")
result = task.call()
assertEquals(1, result.size.toLong())
assertEquals("6", result[0].name)
assertEquals(EXPECTED_TIMESTAMP, result[0].date)
assertEntryTimestampCorrect(result[0])
task = createCallable("test-archive/4")
result = task.call()
assertEquals(1, result.size.toLong())
assertEquals("5", result[0].name)
assertEquals(EXPECTED_TIMESTAMP, result[0].date)
assertEntryTimestampCorrect(result[0])
task = createCallable("test-archive/a")
result = task.call()
assertEquals(1, result.size.toLong())
assertEquals("b", result[0].name)
assertEquals(EXPECTED_TIMESTAMP, result[0].date)
assertEntryTimestampCorrect(result[0])
task = createCallable("test-archive/a/b")
result = task.call()
assertEquals(1, result.size.toLong())
assertEquals("c", result[0].name)
assertEquals(EXPECTED_TIMESTAMP, result[0].date)
assertEntryTimestampCorrect(result[0])
task = createCallable("test-archive/a/b/c")
result = task.call()
assertEquals(1, result.size.toLong())
assertEquals("d", result[0].name)
assertEquals(EXPECTED_TIMESTAMP, result[0].date)
assertEntryTimestampCorrect(result[0])
task = createCallable("test-archive/a/b/c/d")
result = task.call()
assertEquals(1, result.size.toLong())
assertEquals("lipsum.bin", result[0].name)
assertEquals(EXPECTED_TIMESTAMP, result[0].date)
assertEntryTimestampCorrect(result[0])
// assertEquals(512, result.get(0).size);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import org.junit.runners.Suite.SuiteClasses
TarXzHelperCallableTest2::class,
SevenZipHelperCallableTest::class,
SevenZipHelperCallableTest2::class,
SevenZipHelperCallableTest3::class,
EncryptedRarHelperCallableTest::class,
EncryptedZipHelperCallableTest::class,
EncryptedSevenZipHelperCallableTest::class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class SevenZipHelperCallableTest : AbstractCompressedHelperCallableArchiveTest()
get() = "test-archive.7z"

override fun doCreateCallable(archive: File, relativePath: String): CompressedHelperCallable =
SevenZipHelperCallable(
SevenZipHelperCallable(
archive.absolutePath,
relativePath,
false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ class SevenZipHelperCallableTest2 : AbstractCompressedHelperCallableArchiveTest(
override fun testSublevels() = Unit

override fun doCreateCallable(archive: File, relativePath: String): CompressedHelperCallable =
SevenZipHelperCallable(
archive.absolutePath,
relativePath,
false
)
SevenZipHelperCallable(
archive.absolutePath,
relativePath,
false
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2014-2021 Arpit Khurana <arpitkh96@gmail.com>, Vishal Nehra <vishalmeham2@gmail.com>,
* Emmanuel Messulam<emmanuelbendavid@gmail.com>, Raymond Lai <airwave209gt at gmail.com> and Contributors.
*
* This file is part of Amaze File Manager.
*
* Amaze File Manager is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.amaze.filemanager.asynchronous.asynctasks.compress

import com.amaze.filemanager.adapters.data.CompressedObjectParcelable
import org.junit.Assert.assertEquals
import java.io.File

/**
* Test for viewing 7z archives without timestamps in entries. See #3035
*/
class SevenZipHelperCallableTest3 : AbstractCompressedHelperCallableArchiveTest() {

override val archiveFileName: String
get() = "test-archive-no-timestamp.7z"

override fun assertEntryTimestampCorrect(entry: CompressedObjectParcelable) {
assertEquals(0, entry.date)
}

override fun doCreateCallable(archive: File, relativePath: String): CompressedHelperCallable =
SevenZipHelperCallable(
archive.absolutePath,
relativePath,
false
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,25 @@ import java.util.concurrent.CountDownLatch

abstract class AbstractArchiveExtractorTest : AbstractExtractorTest() {

private val EXPECTED_TIMESTAMP = ZonedDateTime.of(
2018,
5,
29,
10,
38,
0,
0,
ZoneId.of("UTC")
).toInstant().toEpochMilli()
companion object {
@JvmStatic
private val EXPECTED_TIMESTAMP = ZonedDateTime.of(
2018,
5,
29,
10,
38,
0,
0,
ZoneId.of("UTC")
).toInstant().toEpochMilli()
}

/**
* run assertion on file timestamp correctness.
*/
protected open fun assertFileTimestampCorrect(file: File) =
assertEquals(EXPECTED_TIMESTAMP, file.lastModified())

/**
* Test extractor ability to correct problematic archive entries for security
Expand Down Expand Up @@ -145,27 +154,27 @@ abstract class AbstractArchiveExtractorTest : AbstractExtractorTest() {

File(File(this, "1"), "8").run {
assertTrue(FileInputStream(this).readBytes().size == 2)
assertEquals(EXPECTED_TIMESTAMP, lastModified())
assertFileTimestampCorrect(this)
}

File(File(this, "2"), "7").run {
assertTrue(FileInputStream(this).readBytes().size == 3)
assertEquals(EXPECTED_TIMESTAMP, lastModified())
assertFileTimestampCorrect(this)
}

File(File(this, "3"), "6").run {
assertTrue(FileInputStream(this).readBytes().size == 4)
assertEquals(EXPECTED_TIMESTAMP, lastModified())
assertFileTimestampCorrect(this)
}

File(File(this, "4"), "5").run {
assertTrue(FileInputStream(this).readBytes().size == 5)
assertEquals(EXPECTED_TIMESTAMP, lastModified())
assertFileTimestampCorrect(this)
}

File(File(this, "a/b/c/d"), "lipsum.bin").run {
assertTrue(FileInputStream(this).readBytes().size == 512)
assertEquals(EXPECTED_TIMESTAMP, lastModified())
assertFileTimestampCorrect(this)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import org.junit.runners.Suite.SuiteClasses
TarLzmaExtractorTest::class,
TarXzExtractorTest::class,
SevenZipExtractorTest::class,
SevenZipWithoutTimestampTest::class,
PasswordProtectedRarTest::class,
PasswordProtectedZipTest::class,
PasswordProtected7ZipTest::class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ package com.amaze.filemanager.filesystem.compressed.extractcontents

import com.amaze.filemanager.filesystem.compressed.extractcontents.helpers.SevenZipExtractor

class SevenZipExtractorTest : AbstractArchiveExtractorTest() {
open class SevenZipExtractorTest : AbstractArchiveExtractorTest() {

override val archiveType: String = "7z"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2014-2021 Arpit Khurana <arpitkh96@gmail.com>, Vishal Nehra <vishalmeham2@gmail.com>,
* Emmanuel Messulam<emmanuelbendavid@gmail.com>, Raymond Lai <airwave209gt at gmail.com> and Contributors.
*
* This file is part of Amaze File Manager.
*
* Amaze File Manager is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.amaze.filemanager.filesystem.compressed.extractcontents

import android.os.Environment
import org.junit.Assert.assertTrue
import java.io.File

/**
* Test for extracting 7z archives without timestamps in entries. See #3035
*/
class SevenZipWithoutTimestampTest : SevenZipExtractorTest() {

override val archiveFile: File
get() = File(Environment.getExternalStorageDirectory(), "test-archive-no-timestamp.$archiveType")

/**
* As timestamp is only the time we extract the file, we just check it's created recently.
*/
override fun assertFileTimestampCorrect(file: File) {
assertTrue(System.currentTimeMillis() - file.lastModified() < 1000)
}
}
Binary file added app/src/test/resources/test-archive-no-timestamp.7z
Binary file not shown.
Loading

0 comments on commit e58a26b

Please sign in to comment.