Merge remote-tracking branch 'origin/GP-3695_Dan_removeGhidraBangUrls'

This commit is contained in:
Ryan Kurtz 2023-08-11 07:10:54 -04:00
commit 03d0bd8a4f
6 changed files with 68 additions and 74 deletions

View File

@ -902,7 +902,7 @@ public class DebuggerListingProvider extends CodeViewerProvider {
Address address = loc.getAddress();
TraceStaticMapping mapping = trace.getStaticMappingManager().findContaining(address, snap);
if (mapping != null) {
DomainFile df = ProgramURLUtils.getFileForHackedUpGhidraURL(tool.getProject(),
DomainFile df = ProgramURLUtils.getDomainFileFromOpenProject(tool.getProject(),
mapping.getStaticProgramURL());
if (df != null) {
doTryOpenProgram(df, DomainFile.DEFAULT_VERSION, ProgramManager.OPEN_CURRENT);

View File

@ -970,7 +970,7 @@ public class DebuggerStaticMappingServicePlugin extends Plugin
Set<Program> result = new HashSet<>();
for (URL url : urls) {
try {
Program program = ProgramURLUtils.openHackedUpGhidraURL(programManager,
Program program = ProgramURLUtils.openDomainFileFromOpenProject(programManager,
tool.getProject(), url, ProgramManager.OPEN_VISIBLE);
if (program == null) {
failures.add(new FileNotFoundException(url.toString()));

View File

@ -371,7 +371,7 @@ public class ProgramModuleIndexer implements DomainFolderChangeAdapter {
new AddressRangeImpl(space.getMinAddress(), space.getMaxAddress()),
module.getLifespan())
.stream()
.map(m -> ProgramURLUtils.getFileForHackedUpGhidraURL(project,
.map(m -> ProgramURLUtils.getDomainFileFromOpenProject(project,
m.getStaticProgramURL()))
.filter(Objects::nonNull)
.collect(Collectors.toSet());

View File

@ -15,76 +15,94 @@
*/
package ghidra.app.plugin.core.debug.utils;
import java.net.MalformedURLException;
import java.net.URL;
import ghidra.app.services.ProgramManager;
import ghidra.framework.client.RepositoryAdapter;
import ghidra.framework.model.*;
import ghidra.framework.protocol.ghidra.GhidraURL;
import ghidra.program.model.listing.Program;
import ghidra.util.Msg;
public enum ProgramURLUtils {
;
/**
* Get any URL for the given program, preferably its URL in a shared project.
*
* @param program the program
* @return the URL or null, if the program does not belong to a project
*/
public static URL getUrlFromProgram(Program program) {
DomainFile file = program.getDomainFile();
ProjectLocator projectLocator = file.getProjectLocator();
if (projectLocator == null) {
return null;
/**
* TODO: Could we have a version that does not take ref? Could be a default method in
* DomainFile that just delegates using ref=null.
*/
URL sharedUrl = file.getSharedProjectURL(null);
if (sharedUrl != null) {
return sharedUrl;
}
DomainFolder parent = file.getParent();
ProjectData projectData = parent == null ? null : parent.getProjectData();
RepositoryAdapter repository = projectData == null ? null : projectData.getRepository();
if (repository != null) { // There is an associated remote repo
if (file.isVersioned()) { // The domain file exists there
ServerInfo server = repository.getServerInfo();
return GhidraURL.makeURL(server.getServerName(), server.getPortNumber(),
repository.getName(), file.getPathname());
}
}
return hackAddLocalDomainFilePath(projectLocator.getURL(), file.getPathname());
return file.getLocalProjectURL(null);
}
protected static URL hackAddLocalDomainFilePath(URL localProjectURL, String pathname) {
try {
return new URL(localProjectURL.toExternalForm() + "!" + pathname);
public static boolean isProjectDataURL(ProjectData data, URL url) {
URL projectURL = GhidraURL.getProjectURL(url);
// TODO: This is a bit awkward. Could ProjectData have getSharedProjectURL?
URL sharedURL = data.getRootFolder().getSharedProjectURL();
if (sharedURL != null && GhidraURL.getProjectURL(sharedURL).equals(projectURL)) {
return true;
}
catch (MalformedURLException e) {
throw new AssertionError(e);
// TODO: This is a bit awkward. Could ProjectData have getLocalProjectURL?
URL localURL = data.getRootFolder().getLocalProjectURL();
if (localURL != null && GhidraURL.getProjectURL(localURL).equals(projectURL)) {
return true;
}
return false;
}
public static DomainFile getFileForHackedUpGhidraURL(Project project, URL ghidraURL) {
try {
String asString = ghidraURL.toExternalForm();
int bangLoc = asString.indexOf('!');
if (bangLoc == -1) {
ProjectData projectData =
project.getProjectData(GhidraURL.getProjectURL(ghidraURL));
if (projectData == null) {
return null;
}
return projectData.getFile(GhidraURL.getProjectPathname(ghidraURL));
}
URL localProjURL = new URL(asString.substring(0, bangLoc));
ProjectData projectData = project.getProjectData(localProjURL);
if (projectData == null) {
Msg.error(ProgramURLUtils.class, "The repository containing " + ghidraURL +
" is not open in the Project manager.");
return null;
}
return projectData.getFile(asString.substring(bangLoc + 1));
/**
* Get the domain file for the given URL from the given project or any of its open views.
*
* <p>
* The URL may point to a file in a local or shared project. If the URL points to a shared
* project and there is a local checkout of the file, this will return the checked out copy,
* even though it may not be the latest from the repository (or maybe even hijacked). If the
* containing project is not currently open, this will return {@code null}.
*
* @param project the active project
* @param url the URL of the domain file
* @return the domain file, or null
*/
public static DomainFile getDomainFileFromOpenProject(Project project, URL url) {
if (isProjectDataURL(project.getProjectData(), url)) {
return project.getProjectData().getFile(GhidraURL.getProjectPathname(url));
}
catch (MalformedURLException e) {
throw new AssertionError(e);
for (ProjectData data : project.getViewedProjectData()) {
if (isProjectDataURL(data, url)) {
return data.getFile(GhidraURL.getProjectPathname(url));
}
}
return null;
}
public static Program openHackedUpGhidraURL(ProgramManager programManager, Project project,
URL ghidraURL, int state) {
DomainFile file = getFileForHackedUpGhidraURL(project, ghidraURL);
/**
* Open the domain file for the given URL from the given project or any of its open views.
*
* <p>
* This uses {@link #getDomainFileFromOpenProject(Project, URL)} to locate the domain file, so
* see its behavior and caveats. It opens the default version of the file. If the file does not
* exist, or its project is not currently open, this returns {@code null}.
*
* @see #getDomainFileFromOpenProject(Project, URL)
* @param programManager the program manager
* @param project the active project
* @param url the URL fo the domain file
* @param state the initial open state of the program in the manager
* @return the program or null
*/
public static Program openDomainFileFromOpenProject(ProgramManager programManager,
Project project, URL url, int state) {
DomainFile file = getDomainFileFromOpenProject(project, url);
if (file == null) {
return null;
}

View File

@ -168,12 +168,6 @@ public interface Project {
*/
public ProjectData getProjectData(ProjectLocator projectLocator);
/**
* Returns the Project Data for the given Project URL. The Project URL must
* correspond to the current active project or an currently open project view.
*/
public ProjectData getProjectData(URL url);
/**
* Get the project data for visible viewed projects that are
* managed by this project.

View File

@ -677,24 +677,6 @@ public class DefaultProject implements Project {
return null;
}
@Override
public ProjectData getProjectData(URL url) {
if (projectLocator.getURL().equals(url)) {
return fileMgr;
}
URL remoteURL = getProjectData().getRootFolder().getSharedProjectURL();
if (remoteURL != null) {
remoteURL = GhidraURL.getProjectURL(url);
}
if (remoteURL.equals(url)) {
return fileMgr;
}
synchronized (otherViews) {
return otherViews.get(url);
}
}
@Override
public ProjectData[] getViewedProjectData() {
synchronized (otherViews) {