From 9e3d212ff948337eedca7d782a21ad1075b58545 Mon Sep 17 00:00:00 2001 From: Michael Bangas Date: Wed, 31 Jul 2024 09:10:55 +0200 Subject: [PATCH] Allow WAR and JAR files All ZIP-based zip files like zip, jar and war can be put on the classpath of the project. To avoid UI bugs, only zip files can be opened that are not added to the project's classpath. This commit introduces a check for the classpath. --- .../propertytester/ZipFilePropertyTester.java | 4 +- .../core/resources/ZipFileTransformer.java | 49 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/propertytester/ZipFilePropertyTester.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/propertytester/ZipFilePropertyTester.java index 7160df98f29..14909c7aed3 100644 --- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/propertytester/ZipFilePropertyTester.java +++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/propertytester/ZipFilePropertyTester.java @@ -24,7 +24,9 @@ public class ZipFilePropertyTester extends ResourcePropertyTester { /** Enum representing allowed file extensions for zip files. */ private enum ZipFileExtensions { - ZIP("zip"); //$NON-NLS-1$ + ZIP("zip"), //$NON-NLS-1$ + JAR("jar"), //$NON-NLS-1$ + WAR("war"); //$NON-NLS-1$ private final String value; diff --git a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/ZipFileTransformer.java b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/ZipFileTransformer.java index 01fcf43541d..cc6c27997c3 100644 --- a/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/ZipFileTransformer.java +++ b/resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/ZipFileTransformer.java @@ -17,6 +17,9 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.zip.ZipException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.filesystem.URIUtil; @@ -25,6 +28,10 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; /** * Utility class for opening and closing zip files. @@ -99,6 +106,11 @@ public static void openZipFile(IFile file, boolean backgroundRefresh) "Nested ZIP files are not allowed to be opened: " + file.getName())); //$NON-NLS-1$ } + if (isOnClasspath(file)) { + throw new CoreException(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, + "ZIP files on classpath are not allowed to be opened: " + file.getName())); //$NON-NLS-1$ + } + URI zipURI = new URI("zip", null, "/", file.getLocationURI().toString(), null); //$NON-NLS-1$ //$NON-NLS-2$ IFolder link = file.getParent().getFolder(IPath.fromOSString(file.getName())); @@ -112,4 +124,41 @@ public static void openZipFile(IFile file, boolean backgroundRefresh) new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, "Zip File could not be opened")); //$NON-NLS-1$ } } + + /** + * Checks if the given file is on the project's classpath. + * + * @param file The file to check. + * @return true if the file is on the classpath; false otherwise. + * @throws CoreException + */ + private static boolean isOnClasspath(IFile file) throws CoreException { + IProject project = file.getProject(); + IFile classpathFile = project.getFile(".classpath"); //$NON-NLS-1$ + if (!classpathFile.exists()) { + return false; + } + try (InputStream inputStream = classpathFile.getContents()) { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.parse(inputStream); + NodeList classpathEntries = document.getElementsByTagName("classpathentry"); //$NON-NLS-1$ + + for (int i = 0; i < classpathEntries.getLength(); i++) { + Element classpathEntry = (Element) classpathEntries.item(i); + String kind = classpathEntry.getAttribute("kind"); //$NON-NLS-1$ + String path = classpathEntry.getAttribute("path"); //$NON-NLS-1$ + + if ("lib".equals(kind) || "src".equals(kind)) { //$NON-NLS-1$//$NON-NLS-2$ + if (file.exists() && file.getLocation().toString().contains(path)) { + return true; + } + } + } + } catch (IOException | CoreException | ParserConfigurationException | SAXException e) { + throw new CoreException(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, + "ZIP files on classpath are not allowed to be opened: " + file.getName())); //$NON-NLS-1$ + } + return false; + } }