diff --git a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevFeature/feature.xml b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevFeature/feature.xml
index c4c90c6f50..6a2e836ab5 100644
--- a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevFeature/feature.xml
+++ b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevFeature/feature.xml
@@ -2,7 +2,7 @@
3.0.2: +
3.0.1:
diff --git a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/META-INF/MANIFEST.MF b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/META-INF/MANIFEST.MF index 2bfa85bf32..7c81298ea6 100644 --- a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/META-INF/MANIFEST.MF +++ b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: GhidraDev Bundle-SymbolicName: ghidra.ghidradev;singleton:=true -Bundle-Version: 3.0.1.qualifier +Bundle-Version: 3.0.2.qualifier Bundle-Activator: ghidradev.Activator Require-Bundle: org.eclipse.ant.core;bundle-version="3.6.200", org.eclipse.buildship.core;bundle-version="3.1.5", diff --git a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/GhidraProjectUtils.java b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/GhidraProjectUtils.java index b65c0d752e..5edcc8f094 100644 --- a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/GhidraProjectUtils.java +++ b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/GhidraProjectUtils.java @@ -357,9 +357,17 @@ public class GhidraProjectUtils { // Get the project's existing linked Ghidra installation folder and path (it may not exist) IFolder ghidraFolder = javaProject.getProject().getFolder(GhidraProjectUtils.GHIDRA_FOLDER_NAME); - GhidraApplicationLayout oldGhidraLayout = ghidraFolder.exists() - ? new GhidraApplicationLayout(ghidraFolder.getLocation().toFile()) - : null; + IPath oldGhidraPath = null; + GhidraApplicationLayout oldGhidraLayout = null; + if (ghidraFolder.exists() ) { + oldGhidraPath = ghidraFolder.getLocation(); + if (oldGhidraPath != null) { + File oldGhidraDir = oldGhidraPath.toFile(); + if (oldGhidraDir.exists()) { + oldGhidraLayout = new GhidraApplicationLayout(oldGhidraDir); + } + } + } // Loop through the project's existing classpath to decide what to keep (things that aren't // related to Ghidra), and things to not keep (things that will be added fresh from the new @@ -372,7 +380,7 @@ public class GhidraProjectUtils { // We'll decide whether or not to keep it later. if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER && entry.getPath().toString().startsWith(JavaRuntime.JRE_CONTAINER)) { - if (oldGhidraLayout == null) { + if (oldGhidraPath == null) { vmEntryCandidate = entry; } } @@ -394,19 +402,17 @@ public class GhidraProjectUtils { entryFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(entry.getPath()); } if (entryFolder != null && entryFolder.isLinked() && - inGhidraInstallation(oldGhidraLayout, entryFolder.getLocation())) { - String oldGhidraInstallPath = - oldGhidraLayout.getApplicationInstallationDir().getAbsolutePath(); + inGhidraInstallation(oldGhidraPath, entryFolder.getLocation())) { String origPath = entryFolder.getLocation().toString(); String newPath = ghidraInstallDir.getAbsolutePath() + - origPath.substring(oldGhidraInstallPath.length()); + origPath.substring(oldGhidraPath.toString().length()); entryFolder.createLink(new Path(newPath), IResource.REPLACE, monitor); classpathEntriesToKeep.add(JavaCore.newSourceEntry(entryFolder.getFullPath())); } // If it's anything else that doesn't live in the old Ghidra installation, keep it. // Note that installed Ghidra extensions can live in the user settings directory // which is outside the installation directory. We don't want to keep these. - else if (!inGhidraInstallation(oldGhidraLayout, entry.getPath()) && + else if (!inGhidraInstallation(oldGhidraPath, entry.getPath()) && !isGhidraExtension(oldGhidraLayout, entry.getPath())) { classpathEntriesToKeep.add(entry); ghidraLayout.getExtensionInstallationDirs(); @@ -459,18 +465,15 @@ public class GhidraProjectUtils { } /** - * Checks to see if the given path is contained within the given Ghidra layout's installation - * directory. + * Checks to see if the given path is contained within the given Ghidra installation path. * - * @param ghidraLayout A Ghidra layout that contains the installation directory to check. + * @param ghidraInstallPath A Ghidra installation path. * @param path The path to check. - * @return True if the given path is contained within the given Ghidra layout's installation - * directory. + * @return True if the given path is contained within the given Ghidra installation directory + * path. */ - private static boolean inGhidraInstallation(GhidraApplicationLayout ghidraLayout, IPath path) { - return ghidraLayout != null && - new Path(ghidraLayout.getApplicationInstallationDir().getAbsolutePath()) - .isPrefixOf(path); + private static boolean inGhidraInstallation(IPath ghidraInstallPath, IPath path) { + return ghidraInstallPath != null && ghidraInstallPath.isPrefixOf(path); } /** diff --git a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/PyDevUtils.java b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/PyDevUtils.java index 8cdb2f7e74..b452f5311a 100644 --- a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/PyDevUtils.java +++ b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/PyDevUtils.java @@ -29,8 +29,7 @@ import javax.naming.OperationNotSupportedException; import org.eclipse.core.runtime.*; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; -import org.osgi.framework.Bundle; -import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.*; import ghidradev.Activator; @@ -40,6 +39,7 @@ import ghidradev.Activator; public class PyDevUtils { public final static String MIN_SUPPORTED_VERSION = "6.3.1"; + public final static String MAX_SUPPORTED_VERSION = "9.3.0"; /** * Checks to see if a supported version of PyDev is installed. @@ -47,12 +47,15 @@ public class PyDevUtils { * @return True if a supported version of PyDev is installed; otherwise, false. */ public static boolean isSupportedPyDevInstalled() { + Version min = Version.valueOf(MIN_SUPPORTED_VERSION); + Version max = Version.valueOf(MAX_SUPPORTED_VERSION); try { - if (PyDevUtilsInternal.isPyDevInstalled()) { + Version version = PyDevUtilsInternal.getPyDevVersion(); + if (version != null) { // Make sure the installed version of PyDev is new enough to support the following // operation. getJython27InterpreterNames(); - return true; + return version.compareTo(min) >= 0 && version.compareTo(max) <= 0; } } catch (OperationNotSupportedException | NoClassDefFoundError e) { diff --git a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/PyDevUtilsInternal.java b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/PyDevUtilsInternal.java index 109f0d6e14..17a9f6f375 100644 --- a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/PyDevUtilsInternal.java +++ b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/PyDevUtilsInternal.java @@ -22,8 +22,7 @@ import java.util.stream.Collectors; import org.eclipse.core.runtime.*; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; -import org.osgi.framework.Bundle; -import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.*; import org.python.pydev.ast.interpreter_managers.InterpreterInfo; import org.python.pydev.ast.interpreter_managers.InterpreterManagersAPI; import org.python.pydev.core.*; @@ -44,19 +43,22 @@ import ghidradev.EclipseMessageUtils; class PyDevUtilsInternal { /** - * Checks to see if PyDev is installed. + * Get the version of PyDev that is installed * - * @return True if PyDev is installed; otherwise, false. + * @return The {@link Version} of the installed PyDev, or null if PyDev is not installed. * @throws NoClassDefFoundError if PyDev is not installed. */ - public static boolean isPyDevInstalled() throws NoClassDefFoundError { - for (Bundle bundle : FrameworkUtil.getBundle( - PyDevUtilsInternal.class).getBundleContext().getBundles()) { + public static Version getPyDevVersion() throws NoClassDefFoundError { + for (Bundle bundle : FrameworkUtil.getBundle(PyDevUtilsInternal.class) + .getBundleContext() + .getBundles()) { if (bundle.getSymbolicName().contains("pydev")) { - return true; + // remove qualifier to make version comparisons more straightforward + Version version = bundle.getVersion(); + return new Version(version.getMajor(), version.getMinor(), version.getMicro()); } } - return false; + return null; } /** diff --git a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/wizards/pages/EnablePythonWizardPage.java b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/wizards/pages/EnablePythonWizardPage.java index 720507a3b7..1dcf6b71f8 100644 --- a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/wizards/pages/EnablePythonWizardPage.java +++ b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/wizards/pages/EnablePythonWizardPage.java @@ -68,7 +68,7 @@ public class EnablePythonWizardPage extends WizardPage { enablePythonCheckboxButton.setText("Enable Python"); enablePythonCheckboxButton.setToolTipText("Enables Python support using the PyDev " + "Eclipse plugin. Requires PyDev version " + PyDevUtils.MIN_SUPPORTED_VERSION + - " or later."); + " - " + PyDevUtils.MAX_SUPPORTED_VERSION); enablePythonCheckboxButton.setSelection(PyDevUtils.isSupportedPyDevInstalled()); enablePythonCheckboxButton.addSelectionListener(new SelectionListener() { @Override @@ -166,7 +166,7 @@ public class EnablePythonWizardPage extends WizardPage { if (pyDevEnabled) { if (!pyDevInstalled) { message = "PyDev version " + PyDevUtils.MIN_SUPPORTED_VERSION + - " or later is not installed."; + " - " + PyDevUtils.MAX_SUPPORTED_VERSION + " is not installed."; } else { try {