mirror of
https://github.com/nextcloud/android.git
synced 2024-12-18 06:51:55 +03:00
Add checks for move or copy
Signed-off-by: alperozturk <alper_ozturk@proton.me>
This commit is contained in:
parent
7e85d80d8e
commit
b6a732cdfd
5 changed files with 121 additions and 1 deletions
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue