mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 19:42:36 +02:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
commit
a42754fb8e
5 changed files with 147 additions and 32 deletions
|
@ -153,6 +153,11 @@ public class AddEditDialog extends DialogComponentProvider {
|
|||
}
|
||||
|
||||
String symbolName = symbolPath.getName();
|
||||
if (StringUtils.isBlank(symbolName)) {
|
||||
// this is the case of having a namespace without a name, such as "Namespace::"
|
||||
setStatusText("Name cannot be blank while changing namespace");
|
||||
return;
|
||||
}
|
||||
|
||||
// see if the user specified a namespace path and if so, then get the
|
||||
// new namespace name from that path
|
||||
|
@ -178,6 +183,7 @@ public class AddEditDialog extends DialogComponentProvider {
|
|||
return;
|
||||
}
|
||||
|
||||
cmd = new CompoundCmd(symbol == null ? "Add Label" : "Edit Label");
|
||||
if (primaryCheckBox.isEnabled() && primaryCheckBox.isSelected()) {
|
||||
cmd.add(new SetLabelPrimaryCmd(addr, symbolName, parent));
|
||||
}
|
||||
|
|
|
@ -754,6 +754,32 @@ public class AddEditDialoglTest extends AbstractGhidraHeadedIntegrationTest {
|
|||
assertEquals(nsName, parentNs.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetNamespace_NamespaceWithoutFunctionName() throws Exception {
|
||||
|
||||
//
|
||||
// Test that we can cannot create a new namespace and clear a symbol name using this form:
|
||||
// "Namespace::"
|
||||
//
|
||||
// A blank name is a signal to reset to a default name, but we do not currently support
|
||||
// changing a namespace and resetting the name in the same operation.
|
||||
//
|
||||
|
||||
String functionName = "FUN_010065f0";
|
||||
Symbol functionSymbol = getSymbol(functionName);
|
||||
Namespace originalNamespace = functionSymbol.getParentNamespace();
|
||||
editLabel(functionSymbol);
|
||||
String nsName = "NewNamespace";
|
||||
setText(nsName + Namespace.DELIMITER);
|
||||
pressOk();
|
||||
assertTrue("Rename unsuccesful", dialog.isShowing());
|
||||
assertStatusText("Name cannot be blank while changing namespace");
|
||||
|
||||
Symbol newFunction = functionSymbol;
|
||||
Namespace parentNs = newFunction.getParentNamespace();
|
||||
assertSame(originalNamespace, parentNs);
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Private Methods
|
||||
//==================================================================================================
|
||||
|
|
|
@ -42,6 +42,10 @@ public class GBooleanCellRenderer extends GTableCellRenderer {
|
|||
return this;
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return cb.isSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
superValidate();
|
||||
|
|
|
@ -77,7 +77,7 @@ public final class GTableToCSV {
|
|||
private static List<TableColumn> getVisibleColumnsInOrder(JTable table, TaskMonitor monitor) {
|
||||
|
||||
TableColumnModel columnModel = table.getColumnModel();
|
||||
List<TableColumn> columns = new ArrayList<TableColumn>();
|
||||
List<TableColumn> columns = new ArrayList<>();
|
||||
for (int columnIndex = 0; columnIndex < table.getColumnCount(); ++columnIndex) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
|
@ -92,7 +92,7 @@ public final class GTableToCSV {
|
|||
List<Integer> columnIndices) {
|
||||
|
||||
TableColumnModel columnModel = table.getColumnModel();
|
||||
List<TableColumn> columns = new ArrayList<TableColumn>();
|
||||
List<TableColumn> columns = new ArrayList<>();
|
||||
for (Integer index : columnIndices) {
|
||||
TableColumn column = columnModel.getColumn(index);
|
||||
columns.add(column);
|
||||
|
@ -163,7 +163,7 @@ public final class GTableToCSV {
|
|||
}
|
||||
|
||||
/**
|
||||
* Attempts to get the text value for the cell so that the data will match what the user sees.
|
||||
* Attempts to get the text value for the cell so that the data will match what the user sees.
|
||||
*/
|
||||
private static String getTableCellValue(JTable table, TableModel model, int row, int column) {
|
||||
TableCellRenderer renderer = table.getCellRenderer(row, column);
|
||||
|
@ -174,6 +174,10 @@ public final class GTableToCSV {
|
|||
Component component =
|
||||
renderer.getTableCellRendererComponent(table, value, false, false, row, column);
|
||||
|
||||
if (isCheckBox(component)) {
|
||||
return getCheckBoxValue(component);
|
||||
}
|
||||
|
||||
if (component instanceof JLabel) {
|
||||
JLabel label = (JLabel) component;
|
||||
return getTextForLabel(label);
|
||||
|
@ -187,7 +191,27 @@ public final class GTableToCSV {
|
|||
return value == null ? "" : value.toString();
|
||||
}
|
||||
|
||||
private static boolean isCheckBox(Component component) {
|
||||
return component instanceof JCheckBox || component instanceof GBooleanCellRenderer;
|
||||
}
|
||||
|
||||
private static String getCheckBoxValue(Component component) {
|
||||
|
||||
if (component instanceof JCheckBox) {
|
||||
JCheckBox cb = (JCheckBox) component;
|
||||
return Boolean.toString(cb.isSelected());
|
||||
}
|
||||
|
||||
if (component instanceof GBooleanCellRenderer) {
|
||||
GBooleanCellRenderer renderer = (GBooleanCellRenderer) component;
|
||||
return Boolean.toString(renderer.isSelected());
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String getTextForLabel(JLabel label) {
|
||||
|
||||
String text = label.getText();
|
||||
if (text != null) {
|
||||
return text;
|
||||
|
@ -334,7 +358,7 @@ public final class GTableToCSV {
|
|||
private final GTable table;
|
||||
|
||||
private File file;
|
||||
private List<Integer> columns = new ArrayList<Integer>();
|
||||
private List<Integer> columns = new ArrayList<>();
|
||||
|
||||
ConvertTask(File file, GTable table) {
|
||||
super(GTableToCSV.TITLE, true, true, true);
|
||||
|
|
|
@ -28,20 +28,17 @@ import ghidra.util.task.TaskMonitor;
|
|||
public class GTableCSVTest {
|
||||
|
||||
@Test
|
||||
public void testCSV_QuotesGetEscaped() {
|
||||
public void testCsv_QuotesGetEscaped() {
|
||||
|
||||
AnyObjectTableModel<CSVRowObject> model =
|
||||
new AnyObjectTableModel<>("MyModel", CSVRowObject.class,
|
||||
AnyObjectTableModel<CsvRowObject> model =
|
||||
new AnyObjectTableModel<>("MyModel", CsvRowObject.class,
|
||||
"getName", "getDescription", "getNumber");
|
||||
|
||||
//@formatter:off
|
||||
List<CSVRowObject> data = Arrays.asList(
|
||||
new CSVRowObject("Bob", "Bobby", 11),
|
||||
new CSVRowObject("Joan", "Joan has \"quoted\" text", 0),
|
||||
new CSVRowObject("Sam", "\"Sam has a single quote text", 23),
|
||||
new CSVRowObject("Time", "Tim is last", 33)
|
||||
);
|
||||
//@formatter:on
|
||||
List<CsvRowObject> data = Arrays.asList(
|
||||
new CsvRowObject("Bob", "Bobby", 11),
|
||||
new CsvRowObject("Joan", "Joan has \"quoted\" text", 0),
|
||||
new CsvRowObject("Sam", "\"Sam has a single quote text", 23),
|
||||
new CsvRowObject("Time", "Tim is last", 33));
|
||||
model.setModelData(data);
|
||||
|
||||
GTable table = new GTable(model);
|
||||
|
@ -50,24 +47,21 @@ public class GTableCSVTest {
|
|||
PrintWriterSpy writer = new PrintWriterSpy();
|
||||
GTableToCSV.writeCSV(writer, table, columns, TaskMonitor.DUMMY);
|
||||
|
||||
assertRowValues(data, writer);
|
||||
assertCsvRowValues(data, writer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCSV_CommasGetEscaped() {
|
||||
public void testCsv_CommasGetEscaped() {
|
||||
|
||||
AnyObjectTableModel<CSVRowObject> model =
|
||||
new AnyObjectTableModel<>("MyModel", CSVRowObject.class,
|
||||
AnyObjectTableModel<CsvRowObject> model =
|
||||
new AnyObjectTableModel<>("MyModel", CsvRowObject.class,
|
||||
"getName", "getDescription", "getNumber");
|
||||
|
||||
//@formatter:off
|
||||
List<CSVRowObject> data = Arrays.asList(
|
||||
new CSVRowObject("Bob", "Bobby", 11),
|
||||
new CSVRowObject("Joan", "Joan has a comma, in her text", 0),
|
||||
new CSVRowObject("Sam", ",Sam has a leading comma", 23),
|
||||
new CSVRowObject("Time", "Tim is last", 33)
|
||||
);
|
||||
//@formatter:on
|
||||
List<CsvRowObject> data = Arrays.asList(
|
||||
new CsvRowObject("Bob", "Bobby", 11),
|
||||
new CsvRowObject("Joan", "Joan has a comma, in her text", 0),
|
||||
new CsvRowObject("Sam", ",Sam has a leading comma", 23),
|
||||
new CsvRowObject("Time", "Tim is last", 33));
|
||||
model.setModelData(data);
|
||||
|
||||
GTable table = new GTable(model);
|
||||
|
@ -76,16 +70,39 @@ public class GTableCSVTest {
|
|||
PrintWriterSpy writer = new PrintWriterSpy();
|
||||
GTableToCSV.writeCSV(writer, table, columns, TaskMonitor.DUMMY);
|
||||
|
||||
assertRowValues(data, writer);
|
||||
assertCsvRowValues(data, writer);
|
||||
}
|
||||
|
||||
private void assertRowValues(List<CSVRowObject> data, PrintWriterSpy writer) {
|
||||
@Test
|
||||
public void testCsv_BooleaValues() {
|
||||
|
||||
AnyObjectTableModel<BooleanCsvRowObject> model =
|
||||
new AnyObjectTableModel<>("MyModel", BooleanCsvRowObject.class,
|
||||
"getName", "isSelected");
|
||||
|
||||
List<BooleanCsvRowObject> data = Arrays.asList(
|
||||
new BooleanCsvRowObject("Bob", true),
|
||||
new BooleanCsvRowObject("Joan", false),
|
||||
new BooleanCsvRowObject("Sam", false),
|
||||
new BooleanCsvRowObject("Time", true));
|
||||
model.setModelData(data);
|
||||
|
||||
GTable table = new GTable(model);
|
||||
List<Integer> columns = new ArrayList<>();
|
||||
|
||||
PrintWriterSpy writer = new PrintWriterSpy();
|
||||
GTableToCSV.writeCSV(writer, table, columns, TaskMonitor.DUMMY);
|
||||
|
||||
assertBooleanCsvRowValues(data, writer);
|
||||
}
|
||||
|
||||
private void assertCsvRowValues(List<CsvRowObject> data, PrintWriterSpy writer) {
|
||||
|
||||
String results = writer.toString();
|
||||
String[] lines = results.split("\n");
|
||||
for (int i = 1; i < lines.length; i++) {
|
||||
int index = i - 1; // the first line is the header
|
||||
CSVRowObject row = data.get(index);
|
||||
CsvRowObject row = data.get(index);
|
||||
String line = lines[i];
|
||||
String[] columns = line.split("(?<!\\\\),");
|
||||
|
||||
|
@ -103,13 +120,32 @@ public class GTableCSVTest {
|
|||
}
|
||||
}
|
||||
|
||||
class CSVRowObject {
|
||||
private void assertBooleanCsvRowValues(List<BooleanCsvRowObject> data, PrintWriterSpy writer) {
|
||||
|
||||
String results = writer.toString();
|
||||
String[] lines = results.split("\n");
|
||||
for (int i = 1; i < lines.length; i++) {
|
||||
int index = i - 1; // the first line is the header
|
||||
BooleanCsvRowObject row = data.get(index);
|
||||
String line = lines[i];
|
||||
String[] columns = line.split("(?<!\\\\),");
|
||||
|
||||
String name = columns[0].replaceAll("\\\\,", ",");
|
||||
name = name.replaceAll("\\\\\"", "\"");
|
||||
assertEquals("\"" + row.getName() + "\"", name);
|
||||
|
||||
String isSelected = columns[1];
|
||||
assertEquals("\"" + row.isSelected() + "\"", isSelected);
|
||||
}
|
||||
}
|
||||
|
||||
class CsvRowObject {
|
||||
|
||||
private String name;
|
||||
private String description;
|
||||
private int number;
|
||||
|
||||
CSVRowObject(String name, String description, int number) {
|
||||
CsvRowObject(String name, String description, int number) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.number = number;
|
||||
|
@ -128,6 +164,25 @@ public class GTableCSVTest {
|
|||
}
|
||||
}
|
||||
|
||||
class BooleanCsvRowObject {
|
||||
|
||||
private String name;
|
||||
private boolean isSelected;
|
||||
|
||||
BooleanCsvRowObject(String name, boolean isSelected) {
|
||||
this.name = name;
|
||||
this.isSelected = isSelected;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return isSelected;
|
||||
}
|
||||
}
|
||||
|
||||
private class PrintWriterSpy extends PrintWriter {
|
||||
|
||||
private StringWriter stringWriter;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue