mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[vfs] makes visitors safe against symlink loops
This commit is contained in:
@@ -18,6 +18,7 @@ package com.intellij.openapi.vfs;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.roots.ContentIterator;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.SystemInfoRt;
|
||||
import com.intellij.openapi.util.io.BufferExposingByteArrayInputStream;
|
||||
@@ -440,6 +441,7 @@ public class VfsUtilCore {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
public static String fixURLforIDEA(@NotNull String url) {
|
||||
// removeLocalhostPrefix - false due to backward compatibility reasons
|
||||
return toIdeaUrl(url, false);
|
||||
@@ -590,27 +592,20 @@ public class VfsUtilCore {
|
||||
return file;
|
||||
}
|
||||
|
||||
public static boolean processFilesRecursively(@NotNull VirtualFile root, @NotNull Processor<VirtualFile> processor) {
|
||||
if (!processor.process(root)) return false;
|
||||
|
||||
if (root.isDirectory()) {
|
||||
final LinkedList<VirtualFile[]> queue = new LinkedList<VirtualFile[]>();
|
||||
|
||||
queue.add(root.getChildren());
|
||||
|
||||
do {
|
||||
final VirtualFile[] files = queue.removeFirst();
|
||||
|
||||
for (VirtualFile file : files) {
|
||||
if (!processor.process(file)) return false;
|
||||
if (file.isDirectory()) {
|
||||
queue.add(file.getChildren());
|
||||
}
|
||||
public static boolean processFilesRecursively(@NotNull final VirtualFile root, @NotNull final Processor<VirtualFile> processor) {
|
||||
final Ref<Boolean> result = Ref.create(true);
|
||||
visitChildrenRecursively(root, new VirtualFileVisitor() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Result visitFileEx(@NotNull VirtualFile file) {
|
||||
if (!processor.process(file)) {
|
||||
result.set(Boolean.FALSE);
|
||||
return skipTo(root);
|
||||
}
|
||||
} while (!queue.isEmpty());
|
||||
}
|
||||
|
||||
return true;
|
||||
return CONTINUE;
|
||||
}
|
||||
});
|
||||
return result.get();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -676,8 +671,7 @@ public class VfsUtilCore {
|
||||
* this collection will keep only distinct files/folders, e.g. C:\foo\bar will be removed when C:\foo is added
|
||||
*/
|
||||
public static class DistinctVFilesRootsCollection extends DistinctRootsCollection<VirtualFile> {
|
||||
public DistinctVFilesRootsCollection() {
|
||||
}
|
||||
public DistinctVFilesRootsCollection() { }
|
||||
|
||||
public DistinctVFilesRootsCollection(Collection<VirtualFile> virtualFiles) {
|
||||
super(virtualFiles);
|
||||
@@ -693,6 +687,8 @@ public class VfsUtilCore {
|
||||
}
|
||||
}
|
||||
|
||||
//<editor-fold desc="Deprecated stuff.">
|
||||
/** @deprecated does not handle recursive symlinks, use {@link #visitChildrenRecursively(VirtualFile, VirtualFileVisitor)} (to be removed in IDEA 2018) */
|
||||
public static void processFilesRecursively(@NotNull VirtualFile root,
|
||||
@NotNull Processor<VirtualFile> processor,
|
||||
@NotNull Convertor<VirtualFile, Boolean> directoryFilter) {
|
||||
@@ -715,4 +711,5 @@ public class VfsUtilCore {
|
||||
} while (!queue.isEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
//</editor-fold>
|
||||
}
|
||||
+10
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -30,9 +30,9 @@ import com.intellij.openapi.roots.FileIndexFacade;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileVisitor;
|
||||
import com.intellij.project.ProjectKt;
|
||||
import com.intellij.util.LineSeparator;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -93,22 +93,16 @@ public abstract class AbstractConvertLineSeparatorsAction extends AnAction {
|
||||
VirtualFile projectVirtualDirectory = ProjectKt.getStateStore(project).getDirectoryStoreFile();
|
||||
final FileTypeRegistry fileTypeManager = FileTypeRegistry.getInstance();
|
||||
for (VirtualFile file : virtualFiles) {
|
||||
VfsUtilCore.processFilesRecursively(
|
||||
file,
|
||||
file1 -> {
|
||||
if (shouldProcess(file1, project)) {
|
||||
changeLineSeparators(project, file1, mySeparator);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
new Convertor<VirtualFile, Boolean>() {
|
||||
@Override
|
||||
public Boolean convert(VirtualFile dir) {
|
||||
return !dir.equals(projectVirtualDirectory)
|
||||
&& !fileTypeManager.isFileIgnored(dir); // Exclude files like '.git'
|
||||
VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Result visitFileEx(@NotNull VirtualFile file) {
|
||||
if (shouldProcess(file, project)) {
|
||||
changeLineSeparators(project, file, mySeparator);
|
||||
}
|
||||
return file.isDirectory() && (file.equals(projectVirtualDirectory) || fileTypeManager.isFileIgnored(file)) ? SKIP_CHILDREN : CONTINUE;
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.util.io.URLUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -451,11 +450,14 @@ public class VfsUtil extends VfsUtilCore {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void processFileRecursivelyWithoutIgnored(@NotNull final VirtualFile root, @NotNull final Processor<VirtualFile> processor) {
|
||||
final FileTypeManager ftm = FileTypeManager.getInstance();
|
||||
processFilesRecursively(root, processor, new Convertor<VirtualFile, Boolean>() {
|
||||
public Boolean convert(final VirtualFile vf) {
|
||||
return ! ftm.isFileIgnored(vf);
|
||||
public static void processFileRecursivelyWithoutIgnored(@NotNull VirtualFile root, @NotNull Processor<VirtualFile> processor) {
|
||||
FileTypeManager ftm = FileTypeManager.getInstance();
|
||||
visitChildrenRecursively(root, new VirtualFileVisitor() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Result visitFileEx(@NotNull VirtualFile file) {
|
||||
if (!processor.process(file)) return skipTo(root);
|
||||
return file.isDirectory() && ftm.isFileIgnored(file) ? SKIP_CHILDREN : CONTINUE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+17
-39
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -18,62 +18,40 @@ package com.intellij.cvsSupport2.cvsoperations.common;
|
||||
import com.intellij.cvsSupport2.CvsUtil;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.ObjectsConvertor;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.openapi.vfs.VirtualFileVisitor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class FindAllRootsHelper {
|
||||
private FindAllRootsHelper() {
|
||||
}
|
||||
private FindAllRootsHelper() { }
|
||||
|
||||
public static List<VirtualFile> findVersionedUnder(final List<VirtualFile> coll) {
|
||||
final List<FilePath> pathList = ObjectsConvertor.vf2fp(coll);
|
||||
return impl(pathList.iterator());
|
||||
}
|
||||
final MyVisitor visitor = new MyVisitor();
|
||||
|
||||
public static FilePath[] findVersionedUnder(final FilePath[] roots) {
|
||||
final List<VirtualFile> found = impl(Arrays.asList(roots).iterator());
|
||||
return ObjectsConvertor.vf2fp(found).toArray(new FilePath[found.size()]);
|
||||
}
|
||||
|
||||
private static List<VirtualFile> impl(final Iterator<FilePath> iterator) {
|
||||
final MyProcessor processor = new MyProcessor();
|
||||
|
||||
for (; iterator.hasNext();) {
|
||||
final FilePath root = iterator.next();
|
||||
for (FilePath root : pathList) {
|
||||
final VirtualFile vf = root.getVirtualFile();
|
||||
if (vf == null) continue;
|
||||
VfsUtil.processFilesRecursively(vf, processor, processor);
|
||||
VfsUtilCore.visitChildrenRecursively(vf, visitor);
|
||||
}
|
||||
return processor.getFound();
|
||||
|
||||
return visitor.found;
|
||||
}
|
||||
|
||||
private static class MyProcessor implements Processor<VirtualFile>, Convertor<VirtualFile, Boolean> {
|
||||
private final List<VirtualFile> myFound;
|
||||
private static class MyVisitor extends VirtualFileVisitor {
|
||||
private final List<VirtualFile> found = new LinkedList<>();
|
||||
|
||||
private MyProcessor() {
|
||||
myFound = new LinkedList<>();
|
||||
}
|
||||
|
||||
public Boolean convert(VirtualFile o) {
|
||||
return ! myFound.contains(o);
|
||||
}
|
||||
|
||||
public boolean process(VirtualFile file) {
|
||||
@NotNull
|
||||
@Override
|
||||
public Result visitFileEx(@NotNull VirtualFile file) {
|
||||
if (CvsUtil.fileIsUnderCvsMaybeWithVfs(file)) {
|
||||
myFound.add(file);
|
||||
found.add(file);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<VirtualFile> getFound() {
|
||||
return myFound;
|
||||
return file.isDirectory() && found.contains(file) ? SKIP_CHILDREN : CONTINUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 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.
|
||||
@@ -21,12 +21,12 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.changes.LocalChangeList;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.openapi.vfs.VirtualFileVisitor;
|
||||
import com.intellij.util.TimeoutUtil;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import junit.framework.Assert;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.svn.info.Info;
|
||||
import org.jetbrains.idea.svn.status.StatusType;
|
||||
|
||||
@@ -107,44 +107,22 @@ public class ConflictCreator {
|
||||
}
|
||||
}
|
||||
}
|
||||
final IOException[] ioe = new IOException[1];
|
||||
VfsUtil.processFilesRecursively(myTheirsDir, new Processor<VirtualFile>() {
|
||||
|
||||
VfsUtilCore.visitChildrenRecursively(myTheirsDir, new VirtualFileVisitor() {
|
||||
@NotNull
|
||||
@Override
|
||||
public boolean process(VirtualFile file) {
|
||||
if (myTheirsDir.equals(file)) return true;
|
||||
if (file.isDirectory() && file.getChildren().length == 0) {
|
||||
public Result visitFileEx(@NotNull VirtualFile file) {
|
||||
if (!myTheirsDir.equals(file) && file.isDirectory() && file.getChildren().length == 0) {
|
||||
try {
|
||||
myClientRunner.delete(myTheirsDir, file.getPath());
|
||||
}
|
||||
catch (IOException e) {
|
||||
ioe[0] = e;
|
||||
throw new VisitorException(e);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return file.isDirectory() && SvnUtil.isAdminDirectory(file) ? SKIP_CHILDREN : CONTINUE;
|
||||
}
|
||||
}, new Convertor<VirtualFile, Boolean>() {
|
||||
@Override
|
||||
public Boolean convert(VirtualFile o) {
|
||||
return ! SvnUtil.isAdminDirectory(o);
|
||||
}
|
||||
});
|
||||
/*FileUtil.processFilesRecursively(new File(myTheirsDir.getPath()), new Processor<File>() {
|
||||
@Override
|
||||
public boolean process(File file) {
|
||||
if (file.isDirectory() && file.listFiles().length == 0) {
|
||||
try {
|
||||
myClientRunner.delete(myTheirsDir, file.getPath());
|
||||
}
|
||||
catch (IOException e) {
|
||||
ioe[0] = e;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});*/
|
||||
if (ioe[0] != null) {
|
||||
throw ioe[0];
|
||||
}
|
||||
}, IOException.class);
|
||||
|
||||
// this will commit all patch changes
|
||||
myClientRunner.checkin(myTheirsDir);
|
||||
|
||||
Reference in New Issue
Block a user