mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[platform] fixes symlink resolve in Windows file access helper (platform part, binaries, tests)
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -15,6 +15,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
@@ -164,7 +165,7 @@ public class FileSystemUtil {
|
||||
else {
|
||||
realPath = ourMediator.resolveSymLink(path);
|
||||
}
|
||||
if (realPath != null && new File(realPath).exists()) {
|
||||
if (realPath != null && (SystemInfo.isWindows && realPath.startsWith("\\\\") || new File(realPath).exists())) {
|
||||
return realPath;
|
||||
}
|
||||
}
|
||||
@@ -364,18 +365,39 @@ public class FileSystemUtil {
|
||||
private final IdeaWin32 myInstance = IdeaWin32.getInstance();
|
||||
|
||||
@Override
|
||||
protected FileAttributes getAttributes(@NotNull final String path) {
|
||||
final FileInfo fileInfo = myInstance.getInfo(path);
|
||||
protected FileAttributes getAttributes(@NotNull String path) {
|
||||
FileInfo fileInfo = myInstance.getInfo(path);
|
||||
return fileInfo != null ? fileInfo.toFileAttributes() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String resolveSymLink(@NotNull final String path) {
|
||||
return myInstance.resolveSymLink(path);
|
||||
protected String resolveSymLink(@NotNull String path) throws FileNotFoundException {
|
||||
path = new File(path).getAbsolutePath();
|
||||
|
||||
char drive = Character.toUpperCase(path.charAt(0));
|
||||
if (!(path.length() > 3 && drive >= 'A' && drive <= 'Z' && path.charAt(1) == ':' && path.charAt(2) == '\\')) {
|
||||
return path; // unknown format
|
||||
}
|
||||
|
||||
int remainder = 4;
|
||||
while (remainder < path.length()) {
|
||||
int next = path.indexOf('\\', remainder);
|
||||
String subPath = next > 0 ? path.substring(0, next) : path;
|
||||
FileAttributes attributes = getAttributes(subPath);
|
||||
if (attributes == null) {
|
||||
throw new FileNotFoundException(subPath);
|
||||
}
|
||||
if (attributes.isSymLink()) {
|
||||
return myInstance.resolveSymLink(path);
|
||||
}
|
||||
|
||||
remainder = next > 0 ? next + 1 : path.length();
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// thanks to SVNKit for the idea of platform-specific offsets
|
||||
private static class JnaUnixMediatorImpl extends Mediator {
|
||||
@SuppressWarnings({"OctalInteger", "SpellCheckingInspection"})
|
||||
@@ -433,7 +455,7 @@ public class FileSystemUtil {
|
||||
private final boolean myCoarseTs = SystemProperties.getBooleanProperty(COARSE_TIMESTAMP_KEY, false);
|
||||
|
||||
private JnaUnixMediatorImpl() {
|
||||
if ("linux-x86".equals(Platform.RESOURCE_PREFIX)) myOffsets = LINUX_32;
|
||||
if ("linux-x86".equals(Platform.RESOURCE_PREFIX)) myOffsets = LINUX_32;
|
||||
else if ("linux-x86-64".equals(Platform.RESOURCE_PREFIX)) myOffsets = LINUX_64;
|
||||
else if ("linux-arm".equals(Platform.RESOURCE_PREFIX)) myOffsets = LNX_ARM32;
|
||||
else if ("linux-ppc".equals(Platform.RESOURCE_PREFIX)) myOffsets = LNX_PPC32;
|
||||
|
||||
@@ -60,7 +60,9 @@ public abstract class FileAttributesReadingTest {
|
||||
@Override public void linkToDirectory() { }
|
||||
@Override public void missingLink() { }
|
||||
@Override public void selfLink() { }
|
||||
@Override public void innerSymlinkResolve() { }
|
||||
@Override public void junction() { }
|
||||
@Override public void innerJunctionResolve() { }
|
||||
@Override public void permissionsCloning() { }
|
||||
}
|
||||
|
||||
@@ -292,13 +294,22 @@ public abstract class FileAttributesReadingTest {
|
||||
assertEquals(dir.getPath(), target);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void innerSymlinkResolve() throws IOException {
|
||||
File file = tempDir.newFile("dir/file.txt");
|
||||
File link = new File(tempDir.getRoot(), "link");
|
||||
Files.createSymbolicLink(link.toPath(), file.getParentFile().toPath());
|
||||
|
||||
String target = FileSystemUtil.resolveSymLink(link.getPath() + '/' + file.getName());
|
||||
assertEquals(file.getPath(), target);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void junction() throws IOException {
|
||||
assumeTrue(SystemInfo.isWinVistaOrNewer);
|
||||
|
||||
File target = tempDir.newFolder("dir");
|
||||
File path = new File(tempDir.getRoot(), "junction.dir");
|
||||
File junction = IoTestUtil.createJunction(target.getPath(), path.getAbsolutePath());
|
||||
File junction = IoTestUtil.createJunction(target.getPath(), tempDir.getRoot() + "/junction.dir");
|
||||
|
||||
try {
|
||||
FileAttributes attributes = getAttributes(junction);
|
||||
@@ -324,6 +335,18 @@ public abstract class FileAttributesReadingTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void innerJunctionResolve() throws IOException {
|
||||
assumeTrue(SystemInfo.isWinVistaOrNewer);
|
||||
|
||||
File file = tempDir.newFile("dir/file.txt");
|
||||
File junction = new File(tempDir.getRoot(), "junction");
|
||||
IoTestUtil.createJunction(file.getParent(), junction.getPath());
|
||||
|
||||
String target = FileSystemUtil.resolveSymLink(junction.getPath() + '/' + file.getName());
|
||||
assertEquals(file.getPath(), target);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hiddenDir() throws IOException {
|
||||
assumeTrue(SystemInfo.isWindows);
|
||||
@@ -535,7 +558,7 @@ public abstract class FileAttributesReadingTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnicodeName() throws IOException {
|
||||
public void unicodeName() throws IOException {
|
||||
String name = IoTestUtil.getUnicodeName();
|
||||
assumeTrue(name != null);
|
||||
File file = tempDir.newFile(name + ".txt");
|
||||
@@ -560,9 +583,9 @@ public abstract class FileAttributesReadingTest {
|
||||
if (SystemInfo.isWindows && checkList) {
|
||||
String parent = file.getParent();
|
||||
if (parent != null) {
|
||||
FileInfo[] infos = IdeaWin32.getInstance().listChildren(parent);
|
||||
assertNotNull(infos);
|
||||
for (FileInfo info : infos) {
|
||||
FileInfo[] children = IdeaWin32.getInstance().listChildren(parent);
|
||||
assertNotNull(children);
|
||||
for (FileInfo info : children) {
|
||||
if (file.getName().equals(info.getName())) {
|
||||
assertEquals(attributes, info.toFileAttributes());
|
||||
return attributes;
|
||||
|
||||
Reference in New Issue
Block a user