mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-01-10 06:27:59 -05:00
Merge remote-tracking branch 'origin/GP-3410-dragonmacher-symbol-tree-exception' into Ghidra_10.3
This commit is contained in:
@@ -27,7 +27,6 @@ import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
import ghidra.util.task.TaskMonitorAdapter;
|
||||
|
||||
public abstract class SymbolCategoryNode extends SymbolTreeNode {
|
||||
public static final int MAX_NODES_BEFORE_ORGANIZING = 40;
|
||||
@@ -198,7 +197,7 @@ public abstract class SymbolCategoryNode extends SymbolTreeNode {
|
||||
List<GTreeNode> children = parentNode.getChildren();
|
||||
int index = Collections.binarySearch(children, newNode, comparator);
|
||||
if (index >= 0) { // found a match
|
||||
GTreeNode matchingNode = getChild(index);
|
||||
GTreeNode matchingNode = parentNode.getChild(index);
|
||||
|
||||
// we must handle OrganizationNodes specially, since they may be recursively defined
|
||||
if (matchingNode instanceof OrganizationNode) {
|
||||
|
||||
@@ -40,12 +40,12 @@ import generic.test.AbstractGenericTest;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||
import ghidra.app.plugin.core.marker.MarkerManagerPlugin;
|
||||
import ghidra.app.plugin.core.programtree.ProgramTreePlugin;
|
||||
import ghidra.app.plugin.core.symboltree.nodes.SymbolCategoryNode;
|
||||
import ghidra.app.plugin.core.symboltree.nodes.SymbolNode;
|
||||
import ghidra.app.plugin.core.symboltree.nodes.*;
|
||||
import ghidra.app.services.ProgramManager;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.listing.GhidraClass;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
|
||||
@@ -60,7 +60,6 @@ public class SymbolTreePlugin1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||
private PluginTool tool;
|
||||
private Program program;
|
||||
private SymbolTreePlugin plugin;
|
||||
private DockingActionIf symTreeAction;
|
||||
private CodeBrowserPlugin cbPlugin;
|
||||
private GTreeNode rootNode;
|
||||
private GTreeNode namespacesNode;
|
||||
@@ -93,7 +92,6 @@ public class SymbolTreePlugin1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||
tool.addPlugin(SymbolTreePlugin.class.getName());
|
||||
plugin = env.getPlugin(SymbolTreePlugin.class);
|
||||
|
||||
symTreeAction = getAction(plugin, "Symbol Tree");
|
||||
cbPlugin = env.getPlugin(CodeBrowserPlugin.class);
|
||||
|
||||
util = new SymbolTreeTestUtils(plugin);
|
||||
@@ -133,17 +131,6 @@ public class SymbolTreePlugin1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||
assertEquals(4, functionsNode.getChildCount());
|
||||
}
|
||||
|
||||
private void addFunctions(int count) throws Exception {
|
||||
tx(program, () -> {
|
||||
for (int i = 0; i < count; i++) {
|
||||
String name = "FUNCTION_" + i;
|
||||
Address address = util.addr(0x1002000 + i);
|
||||
AddressSet body = new AddressSet(address);
|
||||
program.getListing().createFunction(name, address, body, SourceType.USER_DEFINED);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowDisplay() throws Exception {
|
||||
showSymbolTree();
|
||||
@@ -232,7 +219,7 @@ public class SymbolTreePlugin1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||
performAction(goToExtLocAction, util.getSymbolTreeContext(), false);
|
||||
waitForSwing();
|
||||
|
||||
OptionDialog d = waitForDialogComponent(tool.getToolFrame(), OptionDialog.class, 2000);
|
||||
OptionDialog d = waitForDialogComponent(OptionDialog.class);
|
||||
assertNotNull(d);
|
||||
pressButtonByText(d, "Cancel");
|
||||
}
|
||||
@@ -567,7 +554,7 @@ public class SymbolTreePlugin1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||
GTreeNode cnode = rootNode.getChild(4);
|
||||
util.expandNode(cnode);
|
||||
|
||||
// wait until NewClass gets added
|
||||
// wait until NewClass gets added
|
||||
GTreeNode newNode = waitForValue(() -> cnode.getChild(0));
|
||||
|
||||
assertNotNull(newNode);
|
||||
@@ -778,6 +765,63 @@ public class SymbolTreePlugin1Test extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddNode_FunctionInAClass() throws Exception {
|
||||
|
||||
//
|
||||
// This tests a particular edge case where adding a function inside of a class would cause
|
||||
// the tree to throw an exception to to an improper child node lookup. This test was
|
||||
// triggering the exception before the fix.
|
||||
//
|
||||
showSymbolTree();
|
||||
GTreeNode classesNode = rootNode.getChild("Classes");
|
||||
assertFalse(classesNode.isLoaded());
|
||||
classesNode.expand();
|
||||
waitForTree(tree);
|
||||
assertTrue(classesNode.isLoaded());
|
||||
addFunctionInClass(100);
|
||||
waitForTree(tree);
|
||||
|
||||
GTreeNode parentClassNode = classesNode.getChild("PARENT_CLASS");
|
||||
parentClassNode.expand();
|
||||
waitForTree(tree);
|
||||
|
||||
// Grab a node with a large index that will not be in the parent node
|
||||
FunctionSymbolNode fNode = (FunctionSymbolNode) parentClassNode.getChild("FUNCTION_99");
|
||||
SymbolTreeRootNode symbolRootNode = (SymbolTreeRootNode) rootNode;
|
||||
Symbol symbol = fNode.getSymbol();
|
||||
|
||||
// symbolAdded() was throwing an exception before the fix
|
||||
symbolRootNode.symbolAdded(symbol);
|
||||
}
|
||||
|
||||
private void addFunctions(int count) throws Exception {
|
||||
tx(program, () -> {
|
||||
for (int i = 0; i < count; i++) {
|
||||
String name = "FUNCTION_" + i;
|
||||
Address address = util.addr(0x1002000 + i);
|
||||
AddressSet body = new AddressSet(address);
|
||||
program.getListing().createFunction(name, address, body, SourceType.USER_DEFINED);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void addFunctionInClass(int count) throws Exception {
|
||||
tx(program, () -> {
|
||||
|
||||
GhidraClass parentClass =
|
||||
program.getSymbolTable().createClass(null, "PARENT_CLASS", SourceType.USER_DEFINED);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
String name = "FUNCTION_" + i;
|
||||
Address address = util.addr(0x1002000 + i);
|
||||
AddressSet body = new AddressSet(address);
|
||||
program.getListing()
|
||||
.createFunction(name, parentClass, address, body, SourceType.USER_DEFINED);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Private Methods
|
||||
//==================================================================================================
|
||||
|
||||
Reference in New Issue
Block a user