This commit is contained in:
kunfei 2023-03-13 17:07:59 +08:00
parent dc25ac7cb0
commit f9cf583d8d
4 changed files with 30 additions and 131 deletions

View File

@ -28,6 +28,7 @@ import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import splitties.init.appCtx
import java.io.File
import java.util.*
import kotlin.coroutines.coroutineContext
@ -141,7 +142,7 @@ object AppWebDav {
val webDav = WebDav(rootWebDavUrl + name, it)
webDav.downloadTo(Backup.zipFilePath, true)
FileUtils.delete(Backup.backupPath)
ZipUtils.unzipFile(Backup.zipFilePath, Backup.backupPath)
ZipUtils.unZipToPath(File(Backup.zipFilePath), Backup.backupPath)
Restore.restoreDatabase()
Restore.restoreConfig()
}

View File

@ -389,7 +389,7 @@ object ReadBookConfig {
val configDir = appCtx.externalCache.getFile("readConfig")
configDir.createFolderReplace()
@Suppress("BlockingMethodInNonBlockingContext")
ZipUtils.unzipFile(zipFile, configDir)
ZipUtils.unZipToPath(zipFile, configDir)
val configFile = configDir.getFile(configFileName)
val config: Config = GSON.fromJsonObject<Config>(configFile.readText()).getOrThrow()
if (config.textFont.isNotEmpty()) {

View File

@ -42,7 +42,7 @@ object Restore {
ZipUtils.unZipToPath(it, Backup.backupPath)
}
} else {
ZipUtils.unzipFile(uri.path!!, Backup.backupPath)
ZipUtils.unZipToPath(File(uri.path!!), Backup.backupPath)
}
}.onFailure {
AppLog.put("恢复复制文件出错\n${it.localizedMessage}", it)

View File

@ -177,18 +177,39 @@ object ZipUtils {
}
@Throws(SecurityException::class)
fun unZipToPath(inputStream: InputStream, path: String) {
ZipInputStream(inputStream).use {
fun unZipToPath(file: File, path: String) {
FileInputStream(file).use {
unZipToPath(it, path)
}
}
@Throws(SecurityException::class)
fun unZipToPath(zipInputStream: ZipInputStream, path: String) {
fun unZipToPath(file: File, dir: File) {
FileInputStream(file).use {
unZipToPath(it, dir)
}
}
@Throws(SecurityException::class)
fun unZipToPath(inputStream: InputStream, path: String) {
ZipInputStream(inputStream).use {
unZipToPath(it, File(path))
}
}
@Throws(SecurityException::class)
fun unZipToPath(inputStream: InputStream, dir: File) {
ZipInputStream(inputStream).use {
unZipToPath(it, dir)
}
}
@Throws(SecurityException::class)
fun unZipToPath(zipInputStream: ZipInputStream, dir: File) {
var entry: ZipEntry?
while (zipInputStream.nextEntry.also { entry = it } != null) {
val entryFile = File(path, entry!!.name)
if (!entryFile.canonicalPath.startsWith(path)) {
val entryFile = File(dir, entry!!.name)
if (!entryFile.canonicalPath.startsWith(dir.canonicalPath)) {
throw SecurityException("压缩文件只能解压到指定路径")
}
if (entry!!.isDirectory) {
@ -211,129 +232,6 @@ object ZipUtils {
}
}
/**
* Unzip the file.
*
* @param zipFilePath The path of ZIP file.
* @param destDirPath The path of destination directory.
* @return the unzipped files
* @throws IOException if unzip unsuccessfully
*/
@Throws(IOException::class)
fun unzipFile(zipFilePath: String, destDirPath: String): List<File>? {
return unzipFileByKeyword(zipFilePath, destDirPath, null)
}
/**
* Unzip the file.
*
* @param zipFile The ZIP file.
* @param destDir The destination directory.
* @return the unzipped files
* @throws IOException if unzip unsuccessfully
*/
@Throws(IOException::class)
fun unzipFile(
zipFile: File,
destDir: File
): List<File>? {
return unzipFileByKeyword(zipFile, destDir, null)
}
/**
* Unzip the file by keyword.
*
* @param zipFilePath The path of ZIP file.
* @param destDirPath The path of destination directory.
* @param keyword The keyboard.
* @return the unzipped files
* @throws IOException if unzip unsuccessfully
*/
@Throws(IOException::class)
fun unzipFileByKeyword(
zipFilePath: String,
destDirPath: String,
keyword: String?
): List<File>? {
return unzipFileByKeyword(
getFileByPath(zipFilePath),
getFileByPath(destDirPath),
keyword
)
}
/**
* Unzip the file by keyword.
*
* @param zipFile The ZIP file.
* @param destDir The destination directory.
* @param keyword The keyboard.
* @return the unzipped files
* @throws IOException if unzip unsuccessfully
*/
@Throws(IOException::class)
fun unzipFileByKeyword(
zipFile: File?,
destDir: File?,
keyword: String?
): List<File>? {
if (zipFile == null || destDir == null) return null
val files = ArrayList<File>()
val zip = ZipFile(zipFile)
val entries = zip.entries()
zip.use {
if (isSpace(keyword)) {
while (entries.hasMoreElements()) {
val entry = entries.nextElement() as ZipEntry
val entryName = entry.name
if (entryName.contains("../")) {
DebugLog.e(javaClass.name, "entryName: $entryName is dangerous!")
continue
}
if (!unzipChildFile(destDir, files, zip, entry, entryName)) return files
}
} else {
while (entries.hasMoreElements()) {
val entry = entries.nextElement() as ZipEntry
val entryName = entry.name
if (entryName.contains("../")) {
DebugLog.e(javaClass.name, "entryName: $entryName is dangerous!")
continue
}
if (entryName.contains(keyword!!)) {
if (!unzipChildFile(destDir, files, zip, entry, entryName)) return files
}
}
}
}
return files
}
@Throws(IOException::class, SecurityException::class)
private fun unzipChildFile(
destDir: File,
files: MutableList<File>,
zip: ZipFile,
entry: ZipEntry,
name: String
): Boolean {
val file = File(destDir, name)
if (!file.canonicalPath.startsWith(destDir.canonicalPath)) {
throw SecurityException("压缩文件只能解压到指定路径")
}
files.add(file)
if (entry.isDirectory) {
return createOrExistsDir(file)
} else {
if (!createOrExistsFile(file)) return false
zip.getInputStream(entry).use { input ->
FileOutputStream(file).use { out ->
input.copyTo(out)
}
}
}
return true
}
/**
* Return the files' path in ZIP file.