diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePointerPartNode.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePointerPartNode.java index 163d41b202c4..baa33674a94b 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePointerPartNode.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/FilePointerPartNode.java @@ -172,7 +172,12 @@ class FilePointerPartNode { } private void doCheckConsistency(boolean dotDotOccurred) { - dotDotOccurred |= part.contains(".."); // part must not contain ".." (except when the file pointer was created from URL with ".." inside) + int ddi = part.indexOf(".."); + if (ddi != -1) { + // part must not contain "/.." nor "../" nor be just ".." + // (except when the pointer was created from URL of non-existing file with ".." inside) + dotDotOccurred |= part.equals("..") || ddi != 0 && part.charAt(ddi-1) == '/' || ddi < part.length() - 2 && part.charAt(ddi+2) == '/'; + } int childSum = 0; for (FilePointerPartNode child : children) { childSum += child.pointersUnder; diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java index 2f48756a8298..5024fb696dce 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java @@ -690,14 +690,11 @@ public class VirtualFilePointerTest extends PlatformTestCase { // ptr is now null, cached as map VirtualFile v = PlatformTestUtil.notNull(LocalFileSystem.getInstance().findFileByIoFile(ioSandPtr)); - new WriteCommandAction.Simple(getProject()) { - @Override - protected void run() throws Throwable { - v.delete(this); //inc FS modCount - VirtualFile file = PlatformTestUtil.notNull(LocalFileSystem.getInstance().findFileByIoFile(ioSand)); - file.createChildData(this, ioSandPtr.getName()); - } - }.execute().throwException(); + WriteCommandAction.writeCommandAction(getProject()).run(() -> { + v.delete(this); //inc FS modCount + VirtualFile file = PlatformTestUtil.notNull(LocalFileSystem.getInstance().findFileByIoFile(ioSand)); + file.createChildData(this, ioSandPtr.getName()); + }); // ptr is still null @@ -1049,4 +1046,25 @@ public class VirtualFilePointerTest extends PlatformTestCase { createChildData(deep, "1"); assertEquals("[before:true, after:true]", listener.getLog().toString()); } + + public void testNotQuiteCanonicalPath() throws Exception { + final File dir = createTempDirectory(); + VirtualFile vDir = LocalFileSystem.getInstance().findFileByIoFile(dir); + assertNotNull(vDir); + VirtualFile deep = createChildDirectory(vDir, "deep"); + VirtualFile file = createChildData(deep, "x..txt"); + VirtualFilePointer ptr = myVirtualFilePointerManager.create(file, disposable, null); + assertTrue(ptr.isValid()); + assertTrue(ptr.getUrl(), ptr.getUrl().contains("..")); + + VirtualFile existing = createChildData(vDir, "existing.txt"); + assertNotNull(existing); + VirtualFilePointer ptr2 = myVirtualFilePointerManager.create(deep.getUrl()+"/../existing.txt", disposable, null); + assertTrue(ptr2.isValid()); + assertFalse(ptr2.getUrl(), ptr2.getUrl().contains("..")); + + VirtualFilePointer ptr3 = myVirtualFilePointerManager.create(deep.getUrl()+"/../madeup.txt", disposable, null); + assertFalse(ptr3.isValid()); + assertTrue(ptr3.getUrl(), ptr3.getUrl().contains("..")); + } }