@@ -58,6 +58,7 @@ class CopyTask(
5858 if (deleteSourceFiles) {
5959 performSourceDeletion()
6060 }
61+ alignApkIfNecessary()
6162 finalizeTask()
6263 } catch (e: Exception ) {
6364 handleTaskError(e)
@@ -76,6 +77,23 @@ class CopyTask(
7677
7778 // Private helper methods
7879
80+ private fun alignApkIfNecessary () {
81+ val destinationHolder = parameters!! .destHolder
82+
83+ if (destinationHolder !is ZipFileHolder ) return
84+
85+ if (progressMonitor.status == TaskStatus .RUNNING ) {
86+ if (destinationHolder.zipTree.source.extension == apkFileType) {
87+ progressMonitor.apply {
88+ processName = globalClass.resources.getString(R .string.aligning_apk)
89+ progress = - 1f
90+ contentName = emptyString
91+ }
92+ ZipAlign .alignApk(destinationHolder.zipTree.source.file)
93+ }
94+ }
95+ }
96+
7997 private fun createTaskMetadata (): TaskMetadata {
8098 val time = System .currentTimeMillis().toFormattedDate()
8199 return TaskMetadata (
@@ -139,15 +157,11 @@ class CopyTask(
139157 val destFile = destHolder.zipTree.source.file.canonicalPath
140158
141159 if (sourceFile == destFile) {
142- val destPath = destHolder.node.path
143- val hasInvalidNesting = sourceFiles
144- .filterIsInstance<ZipFileHolder >()
145- .filter { ! it.isFile() }
146- .any { destPath.startsWith(it.node.path) }
147-
148- if (hasInvalidNesting) {
149- markAsFailed(globalClass.resources.getString(R .string.task_summary_invalid_dest))
150- return false
160+ runBlocking {
161+ if (firstSource.getParent()?.uniquePath == destHolder.uniquePath) {
162+ markAsFailed(globalClass.resources.getString(R .string.task_summary_invalid_dest))
163+ return @runBlocking false
164+ }
151165 }
152166 }
153167 }
@@ -209,9 +223,32 @@ class CopyTask(
209223 }
210224
211225 private fun preparePendingFiles (sourcePath : String ) {
226+ val destHolder = parameters!! .destHolder
227+ var hasInvalidNesting = false
228+ val isSameZipFiles = (sourceFiles.first() is ZipFileHolder && destHolder is ZipFileHolder )
229+ && (sourceFiles.first() as ZipFileHolder ).zipTree.source.uniquePath == destHolder.zipTree.source.uniquePath
230+
212231 if (pendingFiles.isEmpty()) {
213232 sourceFiles.forEach { source ->
214- pendingFiles.addAll(listFilesWithRelativePath(sourcePath, source))
233+ // Prevent moving into source subdirectories
234+ if (deleteSourceFiles
235+ && source.isFolder
236+ && (((source is ZipFileHolder && destHolder is ZipFileHolder ) && (isSameZipFiles))
237+ || (source is LocalFileHolder && destHolder is LocalFileHolder ))
238+ ) {
239+ val destPath = destHolder.uniquePath
240+ if (! hasInvalidNesting && destPath.startsWith(source.uniquePath)) {
241+ hasInvalidNesting = true
242+ } else {
243+ pendingFiles.addAll(listFilesWithRelativePath(sourcePath, source))
244+ }
245+ } else {
246+ pendingFiles.addAll(listFilesWithRelativePath(sourcePath, source))
247+ }
248+ }
249+
250+ if (hasInvalidNesting) {
251+ markAsFailed(globalClass.getString(R .string.some_files_are_moved_into_their_subdirectories_those_will_be_excluded))
215252 }
216253 }
217254 }
@@ -326,6 +363,8 @@ class CopyTask(
326363 progressMonitor.processName = globalClass.resources.getString(R .string.counting_files)
327364 preparePendingFiles(sourcePath)
328365
366+ if (progressMonitor.status == TaskStatus .FAILED ) return
367+
329368 progressMonitor.apply {
330369 totalContent = pendingFiles.size
331370 processName = if (deleteSourceFiles)
@@ -438,6 +477,8 @@ class CopyTask(
438477 progressMonitor.processName = globalClass.resources.getString(R .string.counting_files)
439478 preparePendingFiles(sourcePath)
440479
480+ if (progressMonitor.status == TaskStatus .FAILED ) return
481+
441482 progressMonitor.apply {
442483 totalContent = pendingFiles.size
443484 processName = if (deleteSourceFiles)
@@ -496,16 +537,6 @@ class CopyTask(
496537 }
497538 }
498539 }
499- if (progressMonitor.status == TaskStatus .RUNNING ) {
500- if (destinationHolder.zipTree.source.extension == apkFileType) {
501- progressMonitor.apply {
502- processName = globalClass.resources.getString(R .string.aligning_apk)
503- progress = - 1f
504- contentName = emptyString
505- }
506- ZipAlign .alignApk(destinationHolder.zipTree.source.file)
507- }
508- }
509540 }
510541 } catch (e: Exception ) {
511542 throw RuntimeException (globalClass.getString(R .string.failed_to_copy_files_to_zip), e)
@@ -541,6 +572,8 @@ class CopyTask(
541572 progressMonitor.processName = globalClass.resources.getString(R .string.counting_files)
542573 preparePendingFiles(sourcePath)
543574
575+ if (progressMonitor.status == TaskStatus .FAILED ) return
576+
544577 progressMonitor.apply {
545578 totalContent = pendingFiles.size
546579 processName = globalClass.resources.getString(R .string.extracting)
@@ -629,6 +662,8 @@ class CopyTask(
629662 progressMonitor.processName = globalClass.resources.getString(R .string.counting_files)
630663 preparePendingFiles(sourcePath)
631664
665+ if (progressMonitor.status == TaskStatus .FAILED ) return
666+
632667 progressMonitor.apply {
633668 totalContent = pendingFiles.size
634669 processName = if (deleteSourceFiles)
@@ -697,16 +732,6 @@ class CopyTask(
697732 }
698733 }
699734 }
700- if (progressMonitor.status == TaskStatus .RUNNING ) {
701- if (destinationHolder.zipTree.source.extension == apkFileType) {
702- progressMonitor.apply {
703- processName = globalClass.resources.getString(R .string.aligning_apk)
704- progress = - 1f
705- contentName = emptyString
706- }
707- ZipAlign .alignApk(destinationHolder.zipTree.source.file)
708- }
709- }
710735 }
711736 }
712737 } catch (e: Exception ) {
0 commit comments