Skip to content

Commit

Permalink
fix: opening file outside of workspace may throw Exception. Fixes #913 (
Browse files Browse the repository at this point in the history
#1050)

Trying to open an external file located at the root of a filesystem
results in:

java.lang.IllegalArgumentException: Path must include project and
resource name: /solarized-dark-color-theme.json
	at org.eclipse.core.runtime.Assert.isLegal(Assert.java:66)
	at org.eclipse.core.internal.resources.Workspace.newResource(Workspace.java:2234)
	at org.eclipse.core.internal.resources.Container.getFile(Container.java:196)
	at org.eclipse.lsp4e.LSPEclipseUtils.getFile(LSPEclipseUtils.java:1229)
	at org.eclipse.lsp4e.LSPEclipseUtils.toUri(LSPEclipseUtils.java:371)
	at org.eclipse.lsp4e.operations.codelens.CodeLensProvider.provideCodeMinings(CodeLensProvider.java:34)
	at org.eclipse.lsp4e.operations.codelens.CodeLensProvider.provideCodeMinings(CodeLensProvider.java:66)
	at org.eclipse.jface.internal.text.codemining.CodeMiningManager.lambda$2(CodeMiningManager.java:189)
  • Loading branch information
sebthom authored Aug 13, 2024
1 parent 0be2cb2 commit 9d6b137
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@
*******************************************************************************/
package org.eclipse.lsp4e.test.edit;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
Expand All @@ -25,19 +22,23 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Random;
import java.util.UUID;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.text.IDocument;
Expand Down Expand Up @@ -416,6 +417,54 @@ public void testTextEditDoesntAutomaticallySaveOpenExternalFiles() throws Except
assertTrue(editor.isDirty());
}

private IPath generateNonExistingIPath(String directory, final String fileExtension) {
if (directory.startsWith("/")) {
@SuppressWarnings("resource") //
final var rootDir = FileSystems.getDefault().getRootDirectories().iterator().next();
directory = rootDir + directory.substring(1);
}
while (true) {
final var path = Paths.get(directory, UUID.randomUUID() + "." + fileExtension);
if (!path.toFile().exists())
return org.eclipse.core.runtime.Path.fromOSString(path.toString());
}
}

@Test
public void testGetFile() throws Exception {
IPath path;

/*
* test relative path to non-existing file in workspace
*/
path = org.eclipse.core.runtime.Path.fromPortableString("non-existing-file.txt");
assertNull(LSPEclipseUtils.getFile(path));

path = org.eclipse.core.runtime.Path.fromPortableString("non-existing-folder/non-existing-file.txt");
assertNull(LSPEclipseUtils.getFile(path));

/*
* test relative path to existing file in workspace
*/
path = TestUtils.createFile(project, "testGetFile", "txt").getFullPath();
assertNotNull(LSPEclipseUtils.getFile(path));

/*
* test absolute path to non-existing files outside of current workspace
*/
path = generateNonExistingIPath("/", "txt"); // tests with path pointing to file at the FS root, e.g. C:\\test.txt or /text.txt
assertNull(LSPEclipseUtils.getFile(path));

path = generateNonExistingIPath("/folder", "txt"); // tests with path pointing to file in a folder below FS root
assertNull(LSPEclipseUtils.getFile(path));

/*
* test absolute path to existing files outside of current workspace
*/
path = org.eclipse.core.runtime.Path.fromOSString(TestUtils.createTempFile("testGetFile", ".txt").getAbsolutePath());
assertNull(LSPEclipseUtils.getFile(path));
}

@Test
public void testGetOpenEditorExternalFile() throws Exception {
File file = TestUtils.createTempFile("testDiagnosticsOnExternalFile", ".lspt");
Expand Down
17 changes: 11 additions & 6 deletions org.eclipse.lsp4e/src/org/eclipse/lsp4e/LSPEclipseUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -903,7 +903,7 @@ protected static void openFileLocationInEditor(String uri, IWorkbenchPage page,
if(editorInput instanceof IFileEditorInput fileEditorInput) {
return getDocument(fileEditorInput.getFile());
}else if(editorInput instanceof IPathEditorInput pathEditorInput) {
return getDocument(ResourcesPlugin.getWorkspace().getRoot().getFile(pathEditorInput.getPath()));
return getDocument(getFile(pathEditorInput.getPath()));
}else if(editorInput instanceof IURIEditorInput uriEditorInput) {
IResource resource = findResourceFor(uriEditorInput.getURI());
if (resource != null) {
Expand Down Expand Up @@ -1282,7 +1282,7 @@ public static URI toUri(IPath absolutePath) {

public static @Nullable URI toUri(IFileBuffer buffer) {
IPath bufferLocation = buffer.getLocation();
IFile res = bufferLocation != null && bufferLocation.segmentCount() > 1 ? ResourcesPlugin.getWorkspace().getRoot().getFile(buffer.getLocation()) : null;
IFile res = bufferLocation != null && bufferLocation.segmentCount() > 1 ? getFile(buffer.getLocation()) : null;
if (res != null) {
URI uri = toUri(res);
if (uri != null) {
Expand Down Expand Up @@ -1310,16 +1310,21 @@ public static URI toUri(File file) {
return getFile(path);
}

/**
* @return null if no file exists at the given path or the given path points to a file outside the workspace
*/
public static @Nullable IFile getFile(@Nullable IPath path) {
if(path == null) {
return null;
}
IFile res = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
if (res.exists()) {

final IFile res = path.segmentCount() == 1 //
? ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path)
: ResourcesPlugin.getWorkspace().getRoot().getFile(path);
if (res != null && res.exists()) {
return res;
} else {
return null;
}
return null;
}

/**
Expand Down

0 comments on commit 9d6b137

Please sign in to comment.