Эх сурвалжийг харах

Add checks for move or copy

Signed-off-by: alperozturk <alper_ozturk@proton.me>
alperozturk 1 жил өмнө
parent
commit
b6a732cdfd

+ 72 - 0
app/src/androidTest/java/com/nextcloud/utils/FileNameValidatorTests.kt

@@ -84,4 +84,76 @@ class FileNameValidatorTests : AbstractIT() {
         assertTrue(FileNameValidator.isFileNameAlreadyExist("existingFile", existingFiles))
         assertFalse(FileNameValidator.isFileNameAlreadyExist("newFile", existingFiles))
     }
+
+    @Test
+    fun testValidFolderAndFilePaths() {
+        val folderPath = "validFolder"
+        val filePaths = listOf("file1.txt", "file2.doc", "file3.jpg")
+
+        val result = FileNameValidator.checkPath(folderPath, filePaths, capability, targetContext)
+        assertTrue(result)
+    }
+
+    @Test
+    fun testFolderPathWithReservedName() {
+        val folderPath = "CON"
+        val filePaths = listOf("file1.txt", "file2.doc", "file3.jpg")
+
+        val result = FileNameValidator.checkPath(folderPath, filePaths, capability, targetContext)
+        assertFalse(result)
+    }
+
+    @Test
+    fun testFilePathWithReservedName() {
+        val folderPath = "validFolder"
+        val filePaths = listOf("file1.txt", "PRN.doc", "file3.jpg")
+
+        val result = FileNameValidator.checkPath(folderPath, filePaths, capability, targetContext)
+        assertFalse(result)
+    }
+
+    @Test
+    fun testFolderPathWithInvalidCharacter() {
+        val folderPath = "invalid<Folder"
+        val filePaths = listOf("file1.txt", "file2.doc", "file3.jpg")
+
+        val result = FileNameValidator.checkPath(folderPath, filePaths, capability, targetContext)
+        assertFalse(result)
+    }
+
+    @Test
+    fun testFilePathWithInvalidCharacter() {
+        val folderPath = "validFolder"
+        val filePaths = listOf("file1.txt", "file|2.doc", "file3.jpg")
+
+        val result = FileNameValidator.checkPath(folderPath, filePaths, capability, targetContext)
+        assertFalse(result)
+    }
+
+    @Test
+    fun testFolderPathEndingWithSpace() {
+        val folderPath = "folderWithSpace "
+        val filePaths = listOf("file1.txt", "file2.doc", "file3.jpg")
+
+        val result = FileNameValidator.checkPath(folderPath, filePaths, capability, targetContext)
+        assertFalse(result)
+    }
+
+    @Test
+    fun testFilePathEndingWithPeriod() {
+        val folderPath = "validFolder"
+        val filePaths = listOf("file1.txt", "file2.doc", "file3.")
+
+        val result = FileNameValidator.checkPath(folderPath, filePaths, capability, targetContext)
+        assertFalse(result)
+    }
+
+    @Test
+    fun testFilePathWithNestedFolder() {
+        val folderPath = "validFolder\\secondValidFolder\\CON"
+        val filePaths = listOf("file1.txt", "file2.doc", "file3.")
+
+        val result = FileNameValidator.checkPath(folderPath, filePaths, capability, targetContext)
+        assertFalse(result)
+    }
 }

+ 9 - 0
app/src/main/java/com/nextcloud/utils/extensions/StringExtensions.kt

@@ -15,3 +15,12 @@ fun String.getRandomString(length: Int): String {
 
     return this + result
 }
+
+fun String.removeFileExtension(): String {
+    val dotIndex = lastIndexOf('.')
+    return if (dotIndex != -1) {
+        substring(0, dotIndex)
+    } else {
+        this
+    }
+}

+ 22 - 1
app/src/main/java/com/nextcloud/utils/fileNameValidator/FileNameValidator.kt

@@ -9,6 +9,7 @@ package com.nextcloud.utils.fileNameValidator
 
 import android.content.Context
 import android.text.TextUtils
+import com.nextcloud.utils.extensions.removeFileExtension
 import com.owncloud.android.R
 import com.owncloud.android.lib.resources.status.OCCapability
 
@@ -46,7 +47,9 @@ object FileNameValidator {
             return it
         }
 
-        if (capability.forbiddenFilenames.isTrue && reservedWindowsNames.contains(name.uppercase())) {
+        if (capability.forbiddenFilenames.isTrue &&
+            (reservedWindowsNames.contains(name.uppercase()) || reservedWindowsNames.contains(name.removeFileExtension().uppercase()))
+        ) {
             return context.getString(R.string.file_name_validator_error_reserved_names)
         }
 
@@ -57,6 +60,24 @@ object FileNameValidator {
         return null
     }
 
+    fun checkPath(folderPath: String, filePaths: List<String>, capability: OCCapability, context: Context): Boolean {
+        val folderPaths = folderPath.split("/", "\\")
+
+        for (item in folderPaths) {
+            if (isValid(item, capability, context) != null) {
+                return false
+            }
+        }
+
+        for (item in filePaths) {
+            if (isValid(item, capability, context) != null) {
+                return false
+            }
+        }
+
+        return true
+    }
+
     private fun checkInvalidCharacters(name: String, capability: OCCapability, context: Context): String? {
         if (capability.forbiddenFilenameCharacters.isFalse) return null
 

+ 16 - 0
app/src/main/java/com/owncloud/android/ui/activity/FolderPickerActivity.kt

@@ -15,6 +15,8 @@ import android.content.Intent
 import android.content.IntentFilter
 import android.content.res.Resources
 import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
 import android.os.Parcelable
 import android.view.ActionMode
 import android.view.Menu
@@ -23,6 +25,7 @@ import android.view.View
 import androidx.activity.OnBackPressedCallback
 import androidx.localbroadcastmanager.content.LocalBroadcastManager
 import com.nextcloud.client.di.Injectable
+import com.nextcloud.utils.fileNameValidator.FileNameValidator
 import com.owncloud.android.R
 import com.owncloud.android.databinding.FilesFolderPickerBinding
 import com.owncloud.android.databinding.FilesPickerBinding
@@ -441,6 +444,7 @@ open class FolderPickerActivity :
         }
     }
 
+    @Suppress("MagicNumber")
     private fun processOperation(action: String?) {
         val i = intent
         val resultData = Intent()
@@ -451,6 +455,18 @@ open class FolderPickerActivity :
         }
 
         targetFilePaths?.let { filePaths ->
+
+            val isPathValid = FileNameValidator.checkPath(file.remotePath, filePaths, capabilities, this)
+            if (!isPathValid) {
+                DisplayUtils.showSnackMessage(this, R.string.file_name_validator_error_copy_or_move)
+                Handler(Looper.getMainLooper()).postDelayed({
+                    setResult(RESULT_CANCELED, resultData)
+                    finish()
+
+                }, 1000L)
+                return
+            }
+
             action?.let { action ->
                 fileOperationsHelper.moveOrCopyFiles(action, filePaths, file)
             }

+ 2 - 0
app/src/main/res/values/strings.xml

@@ -1219,6 +1219,8 @@
     <string name="unified_search_fragment_contact_not_found">Contact not found, you can always sync to update. Redirecting to web…</string>
     <string name="unified_search_fragment_permission_needed">Permissions are required to open search result otherwise it will redirected to web…</string>
 
+
+    <string name="file_name_validator_error_copy_or_move">Folder path contains reserved names or invalid character</string>
     <string name="file_name_validator_error_invalid_character">File name contains invalid characters: %s</string>
     <string name="file_name_validator_error_reserved_names">File name is a reserved name</string>
     <string name="file_name_validator_error_ends_with_space_period">File name ends with a space or a period</string>