mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-23 04:39:55 +00:00
GP-4062_4063: Handling Ghidra installation moving, and capping supported
PyDev version at 9.3.0 (Python 2 support was dropped in 10.0)
This commit is contained in:
parent
280d5ce8d1
commit
f20e649273
@ -2,7 +2,7 @@
|
||||
<feature
|
||||
id="ghidra.ghidradev"
|
||||
label="GhidraDev"
|
||||
version="3.0.1.qualifier"
|
||||
version="3.0.2.qualifier"
|
||||
provider-name="Ghidra">
|
||||
|
||||
<description>
|
||||
|
@ -53,6 +53,16 @@ change with future releases.</p>
|
||||
</ul>
|
||||
|
||||
<h2><a name="ChangeHistory"></a>Change History</h2>
|
||||
<p><u><b>3.0.2</b>:</u>
|
||||
<ul>
|
||||
<li>
|
||||
GhidraDev no longer throws an IOException when performing a "Link Ghidra" action on a Ghidra
|
||||
project whose original Ghidra installation moved.
|
||||
</li>
|
||||
<li>
|
||||
GhidraDev now prevents unsupported versions of PyDev from being used.
|
||||
</li>
|
||||
</ul>
|
||||
<p><u><b>3.0.1</b>:</u>
|
||||
<ul>
|
||||
<li>
|
||||
@ -157,7 +167,7 @@ that specify other projects on their build paths.</p>
|
||||
|
||||
<h2><a name="OptionalRequirements"></a>Optional Requirements</h2>
|
||||
<ul>
|
||||
<li>PyDev 6.3.1 or later (<a href="#PyDevSupport">more info</a>)</li>
|
||||
<li>PyDev 6.3.1 - 9.3.0 (<a href="#PyDevSupport">more info</a>)</li>
|
||||
<li>CDT 8.6.0 or later</li>
|
||||
<li>
|
||||
Gradle - required version(s) specified by linked Ghidra release
|
||||
@ -413,6 +423,15 @@ installation directory.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b><i>Why doesn't GhidraDev support PyDev 10.0 or later?</i></b>
|
||||
<ul>
|
||||
<li>
|
||||
<p>PyDev dropped support for Python 2 in their 10.0 release. Ghidra currently does not
|
||||
support Python 3.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>(<a href="#top">Back to Top</a>)</p>
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user