summaryrefslogtreecommitdiff
path: root/src/android
diff options
context:
space:
mode:
authorGravatar PabloG022023-06-03 14:13:20 +0200
committerGravatar PabloG022023-06-04 20:50:00 +0200
commit19674ec78d0c8b831083de3e7cf2fa29aacf9d4d (patch)
tree831db80f8183e5d841c218ff7fb3d632dc0882d4 /src/android
parentandroid: cmake: Use cmake_dependent_option as appropriate. (diff)
downloadyuzu-19674ec78d0c8b831083de3e7cf2fa29aacf9d4d.tar.gz
yuzu-19674ec78d0c8b831083de3e7cf2fa29aacf9d4d.tar.xz
yuzu-19674ec78d0c8b831083de3e7cf2fa29aacf9d4d.zip
android: move unzip function to FileUtil and use SecurityException
Diffstat (limited to 'src/android')
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/ImportExportSavesFragment.kt34
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt32
2 files changed, 34 insertions, 32 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/ImportExportSavesFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/ImportExportSavesFragment.kt
index 5f107b37d..36e63bb9e 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/ImportExportSavesFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/ImportExportSavesFragment.kt
@@ -23,17 +23,14 @@ import org.yuzu.yuzu_emu.R
23import org.yuzu.yuzu_emu.YuzuApplication 23import org.yuzu.yuzu_emu.YuzuApplication
24import org.yuzu.yuzu_emu.features.DocumentProvider 24import org.yuzu.yuzu_emu.features.DocumentProvider
25import org.yuzu.yuzu_emu.getPublicFilesDir 25import org.yuzu.yuzu_emu.getPublicFilesDir
26import java.io.BufferedInputStream 26import org.yuzu.yuzu_emu.utils.FileUtil
27import java.io.BufferedOutputStream 27import java.io.BufferedOutputStream
28import java.io.File 28import java.io.File
29import java.io.FileOutputStream 29import java.io.FileOutputStream
30import java.io.FilenameFilter 30import java.io.FilenameFilter
31import java.io.IOException
32import java.io.InputStream
33import java.time.LocalDateTime 31import java.time.LocalDateTime
34import java.time.format.DateTimeFormatter 32import java.time.format.DateTimeFormatter
35import java.util.zip.ZipEntry 33import java.util.zip.ZipEntry
36import java.util.zip.ZipInputStream
37import java.util.zip.ZipOutputStream 34import java.util.zip.ZipOutputStream
38 35
39class ImportExportSavesFragment : DialogFragment() { 36class ImportExportSavesFragment : DialogFragment() {
@@ -125,33 +122,6 @@ class ImportExportSavesFragment : DialogFragment() {
125 } 122 }
126 123
127 /** 124 /**
128 * Extracts the save files located in the given zip file and copies them to the saves folder.
129 * @exception IOException if the file was being created outside of the target directory
130 */
131 private fun unzip(zipStream: InputStream, destDir: File): Boolean {
132 val zis = ZipInputStream(BufferedInputStream(zipStream))
133 var entry: ZipEntry? = zis.nextEntry
134 while (entry != null) {
135 val entryName = entry.name
136 val entryFile = File(destDir, entryName)
137 if (!entryFile.canonicalPath.startsWith(destDir.canonicalPath + File.separator)) {
138 zis.close()
139 throw IOException("Entry is outside of the target dir: " + entryFile.name)
140 }
141 if (entry.isDirectory) {
142 entryFile.mkdirs()
143 } else {
144 entryFile.parentFile?.mkdirs()
145 entryFile.createNewFile()
146 entryFile.outputStream().use { fos -> zis.copyTo(fos) }
147 }
148 entry = zis.nextEntry
149 }
150 zis.close()
151 return true
152 }
153
154 /**
155 * Exports the save file located in the given folder path by creating a zip file and sharing it via intent. 125 * Exports the save file located in the given folder path by creating a zip file and sharing it via intent.
156 */ 126 */
157 private fun exportSave() { 127 private fun exportSave() {
@@ -204,7 +174,7 @@ class ImportExportSavesFragment : DialogFragment() {
204 174
205 try { 175 try {
206 CoroutineScope(Dispatchers.IO).launch { 176 CoroutineScope(Dispatchers.IO).launch {
207 unzip(inputZip, cacheSaveDir) 177 FileUtil.unzip(inputZip, cacheSaveDir)
208 cacheSaveDir.list(filterTitleId)?.forEach { savePath -> 178 cacheSaveDir.list(filterTitleId)?.forEach { savePath ->
209 File(savesFolder, savePath).deleteRecursively() 179 File(savesFolder, savePath).deleteRecursively()
210 File(cacheSaveDir, savePath).copyRecursively(File(savesFolder, savePath), true) 180 File(cacheSaveDir, savePath).copyRecursively(File(savesFolder, savePath), true)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt
index 0a7b323b1..593dad8d3 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/FileUtil.kt
@@ -9,10 +9,14 @@ import android.net.Uri
9import android.provider.DocumentsContract 9import android.provider.DocumentsContract
10import androidx.documentfile.provider.DocumentFile 10import androidx.documentfile.provider.DocumentFile
11import org.yuzu.yuzu_emu.model.MinimalDocumentFile 11import org.yuzu.yuzu_emu.model.MinimalDocumentFile
12import java.io.BufferedInputStream
13import java.io.File
12import java.io.FileOutputStream 14import java.io.FileOutputStream
13import java.io.IOException 15import java.io.IOException
14import java.io.InputStream 16import java.io.InputStream
15import java.net.URLDecoder 17import java.net.URLDecoder
18import java.util.zip.ZipEntry
19import java.util.zip.ZipInputStream
16 20
17object FileUtil { 21object FileUtil {
18 const val PATH_TREE = "tree" 22 const val PATH_TREE = "tree"
@@ -276,6 +280,34 @@ object FileUtil {
276 return false 280 return false
277 } 281 }
278 282
283 /**
284 * Extracts the given zip file into the given directory.
285 * @exception IOException if the file was being created outside of the target directory
286 */
287 @Throws(SecurityException::class)
288 fun unzip(zipStream: InputStream, destDir: File): Boolean {
289 ZipInputStream(BufferedInputStream(zipStream)).use { zis ->
290 var entry: ZipEntry? = zis.nextEntry
291 while (entry != null) {
292 val entryName = entry.name
293 val entryFile = File(destDir, entryName)
294 if (!entryFile.canonicalPath.startsWith(destDir.canonicalPath + File.separator)) {
295 throw SecurityException("Entry is outside of the target dir: " + entryFile.name)
296 }
297 if (entry.isDirectory) {
298 entryFile.mkdirs()
299 } else {
300 entryFile.parentFile?.mkdirs()
301 entryFile.createNewFile()
302 entryFile.outputStream().use { fos -> zis.copyTo(fos) }
303 }
304 entry = zis.nextEntry
305 }
306 }
307
308 return true
309 }
310
279 fun isRootTreeUri(uri: Uri): Boolean { 311 fun isRootTreeUri(uri: Uri): Boolean {
280 val paths = uri.pathSegments 312 val paths = uri.pathSegments
281 return paths.size == 2 && PATH_TREE == paths[0] 313 return paths.size == 2 && PATH_TREE == paths[0]