IDEA-202726 AccessDeniedException on project name change if .name file is read-only

This commit is contained in:
Vladimir Krivosheev
2019-01-02 17:53:10 +01:00
parent 6335fc265e
commit abe5663270
2 changed files with 42 additions and 20 deletions
@@ -37,6 +37,7 @@ import com.intellij.util.containers.mapSmart
import com.intellij.util.io.*
import com.intellij.util.lang.CompoundRuntimeException
import com.intellij.util.text.nullize
import java.nio.file.AccessDeniedException
import java.nio.file.Path
import java.nio.file.Paths
@@ -294,12 +295,30 @@ private open class ProjectStoreImpl(project: Project, private val pathMacroManag
lastSavedProjectName = currentProjectName
val basePath = projectBasePath
if (currentProjectName == PathUtilRt.getFileName(basePath)) {
// name equals to base path name - just remove name
nameFile.delete()
fun doSave() {
if (currentProjectName == PathUtilRt.getFileName(basePath)) {
// name equals to base path name - just remove name
nameFile.delete()
}
else if (Paths.get(basePath).isDirectory()) {
nameFile.write(currentProjectName.toByteArray())
}
}
else if (Paths.get(basePath).isDirectory()) {
nameFile.write(currentProjectName.toByteArray())
try {
doSave()
}
catch (e: AccessDeniedException) {
val status = runReadAction {
ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(
listOf(LocalFileSystem.getInstance().refreshAndFindFileByPath(nameFile.systemIndependentPath)))
}
if (status.hasReadonlyFiles()) {
throw e
}
doSave()
}
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.configurationStore
import com.intellij.ide.highlighter.ProjectFileType
@@ -23,6 +9,8 @@ import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.project.ex.ProjectEx
import com.intellij.openapi.project.impl.ProjectImpl
import com.intellij.openapi.util.io.FileUtilRt
import com.intellij.openapi.vcs.readOnlyHandler.ReadonlyStatusHandlerImpl
import com.intellij.openapi.vfs.ReadonlyStatusHandler
import com.intellij.project.stateStore
import com.intellij.testFramework.*
import com.intellij.testFramework.assertions.Assertions.assertThat
@@ -33,7 +21,9 @@ import org.intellij.lang.annotations.Language
import org.junit.ClassRule
import org.junit.Rule
import org.junit.Test
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.attribute.PosixFilePermission
internal class ProjectStoreTest {
companion object {
@@ -113,6 +103,19 @@ internal class ProjectStoreTest {
project.saveStore()
assertThat(store.nameFile).hasContent(newName)
project.setProjectName("clear-read-only")
Files.setPosixFilePermissions(store.nameFile, setOf(PosixFilePermission.OWNER_READ))
val handler = ReadonlyStatusHandler.getInstance(project) as ReadonlyStatusHandlerImpl
try {
handler.setClearReadOnlyInTests(true)
project.saveStore()
}
finally {
handler.setClearReadOnlyInTests(false)
}
assertThat(store.nameFile).hasContent("clear-read-only")
project.setProjectName(oldName)
project.saveStore()
assertThat(store.nameFile).doesNotExist()