Merge remote-tracking branch 'origin/GP-3410-dragonmacher-symbol-tree-exception' into Ghidra_10.3

This commit is contained in:
ghidra1
2023-05-08 15:00:42 -04:00
2 changed files with 62 additions and 19 deletions

View File

@@ -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) {

View File

@@ -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
//==================================================================================================