Merge remote-tracking branch 'origin/GP-1430-dragonmacher-symbol-table-set-namespace--SQUASHED'

This commit is contained in:
ghidra1
2021-11-09 20:15:51 -05:00
11 changed files with 290 additions and 176 deletions

View File

@@ -32,30 +32,25 @@ public class AutoRenameLabelsScript extends GhidraScript {
return;
}
String base = askString("Auto Rename Labels", "Enter label base name:");
if (base == null) {
println("No base value entered.");
String baseName = askString("Auto Rename Labels", "Enter label name prefix:");
if (baseName == null) {
return;
}
int num = 1;
AddressSetView view = currentSelection;
if ((view == null) || (view.isEmpty()))
if ((view == null) || (view.isEmpty())) {
return;
}
// Obtain the symbol table and listing from program
SymbolTable symbolTable = currentProgram.getSymbolTable();
// Get the addresses in the set.
AddressIterator it = view.getAddresses(true);
CompoundCmd cmd = new CompoundCmd("Auto Rename Labels");
while (it.hasNext()) {
Address address = it.next();
Symbol primary = symbolTable.getPrimarySymbol(address);
if (primary != null && primary.getSource() == SourceType.DEFAULT) {
cmd.add(new RenameLabelCmd(address, null, base + num++, SourceType.USER_DEFINED));
cmd.add(new RenameLabelCmd(primary, baseName + num++, SourceType.USER_DEFINED));
}
}
if (cmd.size() > 0) {

View File

@@ -15,6 +15,12 @@
*/
package ghidra.app.cmd.label;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import ghidra.app.util.NamespaceUtils;
import ghidra.app.util.SymbolPath;
import ghidra.framework.cmd.Command;
import ghidra.framework.model.DomainObject;
import ghidra.program.model.address.Address;
@@ -25,92 +31,119 @@ import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.InvalidInputException;
/**
* Command for renaming labels. Handles converting back and forth between
* default and named labels as well.
* Command for renaming labels. Handles converting back and forth between default and named labels
* as well.
*/
public class RenameLabelCmd implements Command {
private Address addr;
private String oldName;
private String newName;
private Symbol existingSymbol;
private Namespace currentNamespace;
private Namespace newNamespace;
private SourceType source;
private String errorMsg = "";
private String errorMessage = "";
/**
* Constructs a new command for renaming a label within a specified namespace.
* @param addr Address of label to be renamed.
* @param oldName the current name of the label to be renamed.
* @param newName the new name for the label. (null for default)
* @param currentNamespace the symbol's current name space. (The namespace to associate this label with)
* Constructs a new command for renaming <B>global</B> labels.
*
* @param addr Address of label to be renamed
* @param oldName the name of the label to be renamed; may be null if the existing label is a
* dynamic label
* @param newName the new name for the label
* @param source the source of this symbol
*/
public RenameLabelCmd(Address addr, String oldName, String newName, Namespace currentNamespace,
public RenameLabelCmd(Address addr, String oldName, String newName, SourceType source) {
this(addr, oldName, newName, null, null, source);
}
/**
* Constructor renaming an existing symbol, but not changing its namespace
*
* @param symbol the existing symbol; may not be null
* @param newName the new symbol name
* @param source the desired symbol source
*/
public RenameLabelCmd(Symbol symbol, String newName, SourceType source) {
this(symbol, newName, symbol.getParentNamespace(), source);
}
/**
* Constructor renaming an existing symbol and changing its namespace. If you do not need
* to change the namespace, then call {@link #RenameLabelCmd(Symbol, String, SourceType)}.
*
* @param symbol the existing symbol; may not be null
* @param newName the new symbol name
* @param newNamespace the new symbol namespace
* @param source the desired symbol source
*/
public RenameLabelCmd(Symbol symbol, String newName, Namespace newNamespace,
SourceType source) {
this.addr = addr;
this.oldName = oldName;
this.existingSymbol = Objects.requireNonNull(symbol);
this.addr = symbol.getAddress();
this.oldName = symbol.getName();
this.newName = newName;
this.currentNamespace = currentNamespace;
this.newNamespace = currentNamespace;
this.currentNamespace = symbol.getParentNamespace();
this.newNamespace = newNamespace;
this.source = source;
}
/**
* Constructs a new command for renaming a label within currentNamespace and changing the
* namespace to newNamespace.
* @param addr Address of label to be renamed.
* @param oldName the current name of the label to be renamed.
*
* @param addr Address of label to be renamed
* @param oldName the current name of the label to be renamed
* @param newName the new name for the label. (null for default)
* @param currentNamespace the symbol's current parent name space (null indicates global namespace)
* @param newNamespace final namespace (null indicates global namespace)
* @param currentNamespace the symbol's current parent name space; null for global namespace
* @param newNamespace the desired namespace; null for global namespace
* @param source the source of this symbol
*/
public RenameLabelCmd(Address addr, String oldName, String newName, Namespace currentNamespace,
private RenameLabelCmd(Address addr, String oldName, String newName, Namespace currentNamespace,
Namespace newNamespace, SourceType source) {
this(addr, oldName, newName, currentNamespace, source);
this.addr = addr;
this.oldName = oldName;
this.newName = newName;
this.currentNamespace = currentNamespace;
this.newNamespace = newNamespace;
this.source = source;
}
/**
* Constructs a new command for renaming global labels.
* @param addr Address of label to be renamed.
* @param oldName the name of the label to be renamed; may be null
* of the existing label is a dynamic label
* @param newName the new name for the label
* @param source the source of this symbol
*/
public RenameLabelCmd(Address addr, String oldName, String newName, SourceType source) {
this(addr, oldName, newName, null, source);
@Override
public String getName() {
return "Rename Label";
}
@Override
public String getStatusMsg() {
return errorMessage;
}
/**
*
* @see ghidra.framework.cmd.Command#applyTo(ghidra.framework.model.DomainObject)
*/
@Override
public boolean applyTo(DomainObject obj) {
Program program = (Program) obj;
if (currentNamespace == null) {
currentNamespace = program.getGlobalNamespace();
}
if (newNamespace == null) {
newNamespace = program.getGlobalNamespace();
}
SymbolTable st = ((Program) obj).getSymbolTable();
Symbol s = null;
if (oldName == null) {
s = st.getPrimarySymbol(addr);
}
else {
s = st.getSymbol(oldName, addr, currentNamespace);
if (!parseNameAndNamespace(program, newNamespace, newName)) {
return false; // errorMessage already set
}
Symbol s = getSymbol(program);
if (s == null) {
errorMsg = "Symbol not found: " + oldName;
return false; // errorMessage already set
}
if (StringUtils.isBlank(newName) && s.getSource() != SourceType.DEFAULT) {
errorMessage = "Cannot set non-default symbol name to \"\"";
return false;
}
@@ -120,45 +153,121 @@ public class RenameLabelCmd implements Command {
}
else {
s.setName(newName, source);
if (newName.length() == 0 && s.getSource() != SourceType.DEFAULT) {
errorMsg = "Rename failed - cannot set non-default symbol name to \"\"";
return false;
}
if (!newName.equals(s.getName())) {
errorMsg = "Rename failed";
errorMessage = "Rename failed";
return false;
}
}
return true;
}
catch (DuplicateNameException e) {
errorMsg = "Symbol already exists: " + newName;
errorMessage = "Symbol already exists: " + newName;
}
catch (InvalidInputException e) {
errorMsg = "Invalid entry: " + e.getMessage();
errorMessage = "Invalid entry: " + e.getMessage();
}
catch (CircularDependencyException e) {
errorMsg = e.getMessage();
errorMessage = e.getMessage();
}
return false;
}
/**
* @see ghidra.framework.cmd.Command#getName()
*/
@Override
public String getName() {
return "Rename Label";
private boolean parseNameAndNamespace(Program program, Namespace rootNamespace, String name) {
SymbolPath symbolPath = getSymbolPath(name);
if (symbolPath == null) {
return false; // invalid symbol name
}
// see if the user specified a namespace path
Namespace parent = getOrCreateNamespaces(program, symbolPath, rootNamespace);
if (parent == null) {
return false; // create namespace failed
}
// update the new namespace and symbol name to reflect the parse results
newNamespace = parent;
newName = symbolPath.getName();
return true;
}
/**
* @see ghidra.framework.cmd.Command#getStatusMsg()
*/
@Override
public String getStatusMsg() {
return errorMsg;
private Symbol getSymbol(Program program) {
if (existingSymbol != null) {
return existingSymbol;
}
SymbolTable st = program.getSymbolTable();
Symbol s = null;
if (oldName != null) {
s = st.getSymbol(oldName, addr, currentNamespace);
}
else {
s = st.getPrimarySymbol(addr);
if (s != null && !s.isDynamic()) {
// noted by the constructor, a null name can only be used to rename dynamic symbols
errorMessage = "Must specify name of symbol to be renamed";
return null;
}
}
if (s == null) {
errorMessage = "Symbol not found: " + oldName;
return null;
}
return s;
}
// note: the root namespace will be used as the parent for any namespaces found in 'symbolPath'
private Namespace getOrCreateNamespaces(Program program, SymbolPath symbolPath,
Namespace rootNamespace) {
SymbolPath parentPath = symbolPath.getParent();
if (parentPath == null) {
return rootNamespace;
}
//
// Prefer a non-function namespace. This allows us to put a function inside of a namespace
// sharing the same name.
//
SymbolPath fullPath = new SymbolPath(rootNamespace.getSymbol()).append(parentPath);
Namespace nonFunctionNs = NamespaceUtils.getNonFunctionNamespace(program, fullPath);
if (nonFunctionNs != null) {
return nonFunctionNs;
}
//
// At this point we can either reuse an existing function namespace or we have to create
// a new non-function namespaces, depending upon the names being used. Only use an
// existing function as a namespace if none of namespace path entries match the function
// name.
//
String name = symbolPath.getName();
if (!parentPath.containsPathEntry(name)) {
Namespace functionNamespace =
NamespaceUtils.getFunctionNamespaceContaining(program, parentPath, addr);
if (functionNamespace != null) {
return functionNamespace;
}
}
CreateNamespacesCmd cmd =
new CreateNamespacesCmd(parentPath.getPath(), rootNamespace, SourceType.USER_DEFINED);
if (cmd.applyTo(program)) {
return cmd.getNamespace();
}
errorMessage = cmd.getStatusMsg();
return null;
}
private SymbolPath getSymbolPath(String symbolName) {
if (StringUtils.isBlank(symbolName)) {
errorMessage = "Name cannot be blank";
return null;
}
return new SymbolPath(symbolName);
}
}

View File

@@ -443,11 +443,7 @@ public class CodeBrowserClipboardProvider extends ByteCopier
SymbolTable symbolTable = currentProgram.getSymbolTable();
Symbol symbol = symbolTable.getSymbol(reference);
if ((symbol instanceof CodeSymbol) || (symbol instanceof FunctionSymbol)) {
String oldName = symbol.getName();
Namespace namespace = symbol.getParentNamespace();
Address symbolAddress = symbol.getAddress();
RenameLabelCmd cmd = new RenameLabelCmd(symbolAddress, oldName, labelName, namespace,
SourceType.USER_DEFINED);
RenameLabelCmd cmd = new RenameLabelCmd(symbol, labelName, SourceType.USER_DEFINED);
return tool.execute(cmd, currentProgram);
}

View File

@@ -23,7 +23,6 @@ import ghidra.app.cmd.function.DeleteFunctionCmd;
import ghidra.app.cmd.label.DeleteLabelCmd;
import ghidra.app.cmd.label.RenameLabelCmd;
import ghidra.docking.settings.Settings;
import ghidra.framework.cmd.Command;
import ghidra.framework.cmd.CompoundCmd;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.plugintool.ServiceProvider;
@@ -207,17 +206,19 @@ class SymbolTableModel extends AddressBasedTableModel<Symbol> {
return;
}
if (columnIndex == LABEL_COL) {
String newName = aValue.toString();
if (!symbol.getName().equals(newName)) {
Command renameCmd = new RenameLabelCmd(symbol.getAddress(), symbol.getName(),
newName, symbol.getParentNamespace(), SourceType.USER_DEFINED);
if (columnIndex != LABEL_COL) {
return;
}
if (!tool.execute(renameCmd, getProgram())) {
Msg.showError(getClass(), provider.getComponent(), "Error Renaming Symbol",
renameCmd.getStatusMsg());
}
}
String newName = aValue.toString();
if (symbol.getName().equals(newName)) {
return;
}
RenameLabelCmd renameCmd = new RenameLabelCmd(symbol, newName, SourceType.USER_DEFINED);
if (!tool.execute(renameCmd, getProgram())) {
Msg.showError(getClass(), provider.getComponent(), "Error Renaming Symbol",
renameCmd.getStatusMsg());
}
}

View File

@@ -168,12 +168,16 @@ public class AddEditDialog extends DialogComponentProvider {
cmd.add(new AddLabelCmd(addr, symbolName, parent, SourceType.USER_DEFINED));
}
else {
cmd.add(new RenameLabelCmd(addr, symbol.getName(), symbolName,
symbol.getParentNamespace(), parent, SourceType.USER_DEFINED));
cmd.add(new RenameLabelCmd(symbol, labelText, namespace, SourceType.USER_DEFINED));
isCurrentlyEntryPoint = symbol.isExternalEntryPoint();
isCurrentlyPinned = symbol.isPinned();
}
if (!tool.execute(cmd, program)) {
setStatusText(cmd.getStatusMsg());
return;
}
if (primaryCheckBox.isEnabled() && primaryCheckBox.isSelected()) {
cmd.add(new SetLabelPrimaryCmd(addr, symbolName, parent));
}
@@ -185,14 +189,12 @@ public class AddEditDialog extends DialogComponentProvider {
cmd.add(new PinSymbolCmd(addr, symbolName, !isCurrentlyPinned));
}
if (cmd.size() > 0) {
if (!tool.execute(cmd, program)) {
setStatusText(cmd.getStatusMsg());
return;
}
updateRecentLabels(symbolName);
if (!tool.execute(cmd, program)) {
setStatusText(cmd.getStatusMsg());
return;
}
updateRecentLabels(symbolName);
program = null;
close();
}

View File

@@ -430,8 +430,7 @@ public class ClearTest extends AbstractGhidraHeadedIntegrationTest {
Symbol[] symbols = program.getSymbolTable().getSymbols(addr("0x10022bf"));
Symbol s = symbols[0];
RenameLabelCmd cmd = new RenameLabelCmd(s.getAddress(), s.getName(), "Fred",
s.getParentNamespace(), SourceType.USER_DEFINED);
RenameLabelCmd cmd = new RenameLabelCmd(s, "Fred", SourceType.USER_DEFINED);
applyCmd(program, cmd);
makeSelection(tool, program, addr("0x10022bf"), addr("0x10022c4"));

View File

@@ -136,25 +136,25 @@ public class LabelActionTest extends AbstractGhidraHeadedIntegrationTest
@Test
public void testNotepadLocations() {
ActionContext context = new ActionContext();
assertEquals(false, addLabel.isEnabledForContext(context));
assertFalse(addLabel.isEnabledForContext(context));
assertEquals(false, editLabel.isEnabledForContext(context));
assertFalse(editLabel.isEnabledForContext(context));
assertEquals(false, removeLabel.isEnabledForContext(context));
assertFalse(removeLabel.isEnabledForContext(context));
assertEquals(false, setLabel.isEnabledForContext(context));
assertFalse(setLabel.isEnabledForContext(context));
env.open(program);
cb.updateNow();
context = cb.getProvider().getActionContext(null);
assertEquals(true, addLabel.isEnabledForContext(context));
assertTrue(addLabel.isEnabledForContext(context));
assertEquals(false, editLabel.isEnabledForContext(context));
assertFalse(editLabel.isEnabledForContext(context));
assertEquals(false, removeLabel.isEnabledForContext(context));
assertFalse(removeLabel.isEnabledForContext(context));
assertEquals(false, setLabel.isEnabledForContext(context));
assertFalse(setLabel.isEnabledForContext(context));
SampleLocationGenerator locGen = new SampleLocationGenerator(program);
locGen.toggleOpenComposites(cb);
@@ -162,9 +162,6 @@ public class LabelActionTest extends AbstractGhidraHeadedIntegrationTest
}
/**
* @see ghidra.app.LocationCallback#locationGenerated(ghidra.program.singleuser.util.ProgramLocation)
*/
@Override
public void locationGenerated(ProgramLocation loc) {
@@ -184,11 +181,11 @@ public class LabelActionTest extends AbstractGhidraHeadedIntegrationTest
if (loc instanceof LabelFieldLocation) {
Symbol s = labelMgrPlugin.getSymbol((ListingActionContext) context);
assertEquals(caseName, false, addLabel.isEnabledForContext(context));
assertEquals(caseName, true, editLabel.isEnabledForContext(context));
assertEquals(caseName, false, editExternalLocation.isEnabledForContext(context));
assertFalse(caseName, addLabel.isEnabledForContext(context));
assertTrue(caseName, editLabel.isEnabledForContext(context));
assertFalse(caseName, editExternalLocation.isEnabledForContext(context));
assertEquals(caseName, !s.isDynamic(), removeLabel.isEnabledForContext(context));
assertEquals(caseName, false, setLabel.isEnabledForContext(context));
assertFalse(caseName, setLabel.isEnabledForContext(context));
assertEquals(EditLabelAction.EDIT_LABEL,
editLabel.getPopupMenuData().getMenuItemName());
@@ -249,8 +246,8 @@ public class LabelActionTest extends AbstractGhidraHeadedIntegrationTest
assertEquals(caseName, !hasComponentPath, addLabel.isEnabledForContext(context));
assertEquals(caseName, component != null, editLabel.isEnabledForContext(context));
assertEquals(caseName, false, removeLabel.isEnabledForContext(context));
assertEquals(caseName, false, setLabel.isEnabledForContext(context));
assertFalse(caseName, removeLabel.isEnabledForContext(context));
assertFalse(caseName, setLabel.isEnabledForContext(context));
if (component != null) {
assertEquals(EditLabelAction.EDIT_FIELDNAME,
@@ -258,16 +255,16 @@ public class LabelActionTest extends AbstractGhidraHeadedIntegrationTest
}
}
else if (!(loc instanceof FunctionLocation)) {
assertEquals(caseName, true, addLabel.isEnabledForContext(context));
assertEquals(caseName, false, editLabel.isEnabledForContext(context));
assertEquals(caseName, false, removeLabel.isEnabledForContext(context));
assertEquals(caseName, false, setLabel.isEnabledForContext(context));
assertTrue(caseName, addLabel.isEnabledForContext(context));
assertFalse(caseName, editLabel.isEnabledForContext(context));
assertFalse(caseName, removeLabel.isEnabledForContext(context));
assertFalse(caseName, setLabel.isEnabledForContext(context));
}
else {
assertEquals(caseName, false, addLabel.isEnabledForContext(context));
assertEquals(caseName, false, editLabel.isEnabledForContext(context));
assertEquals(caseName, false, removeLabel.isEnabledForContext(context));
assertEquals(caseName, false, setLabel.isEnabledForContext(context));
assertFalse(caseName, addLabel.isEnabledForContext(context));
assertFalse(caseName, editLabel.isEnabledForContext(context));
assertFalse(caseName, removeLabel.isEnabledForContext(context));
assertFalse(caseName, setLabel.isEnabledForContext(context));
}
}
}

View File

@@ -25,7 +25,6 @@ import javax.swing.JTextField;
import org.junit.*;
import ghidra.app.cmd.function.CreateFunctionCmd;
import ghidra.app.events.ProgramSelectionPluginEvent;
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
import ghidra.app.services.ProgramManager;
import ghidra.framework.Application;
@@ -33,7 +32,6 @@ import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.Program;
import ghidra.program.model.symbol.*;
import ghidra.program.util.ProgramSelection;
import ghidra.test.*;
/**
@@ -58,8 +56,9 @@ public class AutoRenameLabelsScriptTest extends AbstractGhidraHeadedIntegrationT
env.showTool();
script =
Application.getModuleFile("Base", "ghidra_scripts/AutoRenameLabelsScript.java").getFile(
true);
Application.getModuleFile("Base", "ghidra_scripts/AutoRenameLabelsScript.java")
.getFile(
true);
env.showTool();
}
@@ -88,12 +87,8 @@ public class AutoRenameLabelsScriptTest extends AbstractGhidraHeadedIntegrationT
return builder.getProgram();
}
/*
* @see TestCase#tearDown()
*/
@After
public void tearDown() throws Exception {
env.release(program);
env.dispose();
}
@@ -102,29 +97,23 @@ public class AutoRenameLabelsScriptTest extends AbstractGhidraHeadedIntegrationT
SymbolTable symbolTable = program.getSymbolTable();
Symbol s1 = symbolTable.getPrimarySymbol(addr(0x01003a94));
assertNotNull(s1);
assertTrue(s1.getSource() == SourceType.DEFAULT);
assertEquals(s1.getSource(), SourceType.DEFAULT);
Symbol s2 = symbolTable.getPrimarySymbol(addr(0x01003a97));
assertNotNull(s2);
assertTrue(s2.getSource() == SourceType.DEFAULT);
assertEquals(s2.getSource(), SourceType.DEFAULT);
ProgramSelection sel = new ProgramSelection(addr(0x01003a94), addr(0x01003a9b));
tool.firePluginEvent(new ProgramSelectionPluginEvent("test", sel, program));
waitForPostedSwingRunnables();
makeSelection(tool, program, addr(0x01003a94), addr(0x01003a9b));
ScriptTaskListener scriptID = env.runScript(script);
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Auto Rename Labels", 2000);
final JTextField tf = findComponent(dialog, JTextField.class);
JDialog dialog = waitForJDialog("Auto Rename Labels");
JTextField tf = findComponent(dialog, JTextField.class);
runSwing(() -> tf.setText("My_Label"));
pressButtonByText(dialog, "OK");
waitForScriptCompletion(scriptID, 100000);
program.flushEvents();
waitForPostedSwingRunnables();
s1 = symbolTable.getPrimarySymbol(addr(0x01003a94));
s2 = symbolTable.getPrimarySymbol(addr(0x01003a97));
waitForProgram(program);
assertEquals("My_Label1", s1.getName());
assertEquals("My_Label2", s2.getName());
@@ -134,39 +123,34 @@ public class AutoRenameLabelsScriptTest extends AbstractGhidraHeadedIntegrationT
public void testNoRenameOnUserDefined() throws Exception {
SymbolTable symbolTable = program.getSymbolTable();
Symbol s1 = symbolTable.getPrimarySymbol(addr(0x010046cc));
assertTrue(s1.getSource() == SourceType.DEFAULT);
assertEquals(s1.getSource(), SourceType.DEFAULT);
// create a function at 10046d0 so we don't have a default label
CreateFunctionCmd cmd =
new CreateFunctionCmd("My_Function1", addr(0x010046d0), null, SourceType.ANALYSIS);
tool.execute(cmd, program);
program.flushEvents();
waitForPostedSwingRunnables();
applyCmd(program, cmd);
Symbol s2 = symbolTable.getPrimarySymbol(addr(0x010046d0));
assertNotNull(s2);
assertTrue(s2.getSource() != SourceType.DEFAULT);
assertNotEquals(s2.getSource(), SourceType.DEFAULT);
String s2Name = s2.getName();
ProgramSelection sel = new ProgramSelection(addr(0x010046cc), addr(0x010046d0));
tool.firePluginEvent(new ProgramSelectionPluginEvent("test", sel, program));
waitForPostedSwingRunnables();
makeSelection(tool, program, addr(0x010046cc), addr(0x010046d0));
ScriptTaskListener scriptID = env.runScript(script);
JDialog dialog = waitForJDialog(tool.getToolFrame(), "Auto Rename Labels", 2000);
final JTextField tf = findComponent(dialog, JTextField.class);
JDialog dialog = waitForJDialog("Auto Rename Labels");
JTextField tf = findComponent(dialog, JTextField.class);
runSwing(() -> tf.setText("My_Label"));
pressButtonByText(dialog, "OK");
waitForScriptCompletion(scriptID, 100000);
program.flushEvents();
waitForPostedSwingRunnables();
s1 = symbolTable.getPrimarySymbol(addr(0x010046cc));
waitForProgram(program);
assertEquals("My_Label1", s1.getName());
// only dynamic label should get renamed
s2 = symbolTable.getPrimarySymbol(addr(0x010046d0));
assertTrue(!s2.getName().equals("My_Label2"));
assertFalse(s2.getName().equals("My_Label2"));
assertEquals(s2Name, s2.getName());
}

View File

@@ -450,21 +450,16 @@ public class SymbolTreeNavigationTest extends AbstractProgramBasedTest {
}
private void rename(Symbol symbol, String newName) {
String oldName = symbol.getName();
RenameLabelCmd cmd =
new RenameLabelCmd(symbol.getAddress(), oldName, newName, SourceType.USER_DEFINED);
RenameLabelCmd cmd = new RenameLabelCmd(symbol, newName, SourceType.USER_DEFINED);
applyCmd(cmd);
util.waitForTree();
}
private Symbol createGlobalLabel(Address addr) {
return createGlobalLabel(addr, "GlobalLabel");
}
private Symbol createGlobalLabel(Address addr, String labelName) {
AddLabelCmd cmd = new AddLabelCmd(addr, labelName, SourceType.USER_DEFINED);
applyCmd(cmd);
Symbol symbol = cmd.getSymbol();

View File

@@ -28,6 +28,7 @@ import java.util.function.BiConsumer;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.table.TableModel;
import javax.swing.text.JTextComponent;
import org.jdom.Element;
import org.junit.*;
@@ -346,12 +347,47 @@ public class SymbolTablePluginTest extends AbstractGhidraHeadedIntegrationTest {
waitForNotBusy();
assertTrue(!symbolTable.isEditing());
assertFalse(symbolTable.isEditing());
Symbol s = getSymbol(row);
assertEquals("ghidra.Is.Cool", s.getName());
}
@Test
public void testEditName_AddNamespace() throws Exception {
openProgram("sample");
waitForNotBusy();
String symbolName = "ghidra";
int row = findRow(symbolName);
doubleClick(symbolTable, row, SymbolTableModel.LABEL_COL);
waitForSwing();
assertTrue(symbolTable.isEditing());
Component editor = symbolTable.getEditorComponent();
assertNotNull(editor);
JTextField textField = (JTextField) editor;
String currentText = getText(textField);
assertEquals(symbolName, currentText);
String newNamespaceName = "NS1";
JTextComponent textComponent = (JTextComponent) editor;
runSwing(() -> textComponent.selectAll());
myTypeText(editor, newNamespaceName + Namespace.DELIMITER + symbolName);
runSwing(() -> symbolTable.editingStopped(new ChangeEvent(symbolTable)));
waitForNotBusy();
assertFalse(symbolTable.isEditing());
Symbol s = getSymbol(row);
assertEquals(symbolName, s.getName());
Namespace namespace = s.getParentNamespace();
assertEquals(newNamespaceName, namespace.getName());
}
@Test
public void testQuickLookup() throws Exception {
openProgram("sample");
@@ -400,7 +436,7 @@ public class SymbolTablePluginTest extends AbstractGhidraHeadedIntegrationTest {
openProgram("sample");
int rowCount = symbolTable.getRowCount();
assertTrue(!deleteAction.isEnabled());
assertFalse(deleteAction.isEnabled());
int row = findRow("ghidra");
Rectangle rect = symbolTable.getCellRect(row, 0, true);
@@ -488,7 +524,7 @@ public class SymbolTablePluginTest extends AbstractGhidraHeadedIntegrationTest {
public void testMakeSelection() throws Exception {
openProgram("sample");
assertTrue(!makeSelectionAction.isEnabled());
assertFalse(makeSelectionAction.isEnabled());
int row1 = findRow("ghidra");
int row2 = findRow("KERNEL32.dll_GetProcAddress");

View File

@@ -508,8 +508,10 @@ public class FillOutStructureCmd extends BackgroundCommand {
if (isThisParam) {
Namespace rootNamespace = currentProgram.getGlobalNamespace();
Namespace newNamespace = createUniqueClassName(rootNamespace);
RenameLabelCmd command = new RenameLabelCmd(f.getEntryPoint(), f.getName(), f.getName(),
rootNamespace, newNamespace, SourceType.USER_DEFINED);
String name = f.getName();
Symbol symbol = f.getSymbol();
RenameLabelCmd command =
new RenameLabelCmd(symbol, name, newNamespace, SourceType.USER_DEFINED);
if (!command.applyTo(currentProgram)) {
return null;
}
@@ -545,12 +547,10 @@ public class FillOutStructureCmd extends BackgroundCommand {
symbolTable.createClass(rootNamespace, newClassName, SourceType.USER_DEFINED);
}
catch (DuplicateNameException e) {
// Shouldn't happen
e.printStackTrace();
Msg.error(this, "Error creating class '" + newClassName + "'", e);
}
catch (InvalidInputException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Msg.error(this, "Error creating class '" + newClassName + "'", e);
}
return newClass;
}