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();
|
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
|
// see if the user specified a namespace path and if so, then get the
|
||||||
// new namespace name from that path
|
// new namespace name from that path
|
||||||
|
@ -178,6 +183,7 @@ public class AddEditDialog extends DialogComponentProvider {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd = new CompoundCmd(symbol == null ? "Add Label" : "Edit Label");
|
||||||
if (primaryCheckBox.isEnabled() && primaryCheckBox.isSelected()) {
|
if (primaryCheckBox.isEnabled() && primaryCheckBox.isSelected()) {
|
||||||
cmd.add(new SetLabelPrimaryCmd(addr, symbolName, parent));
|
cmd.add(new SetLabelPrimaryCmd(addr, symbolName, parent));
|
||||||
}
|
}
|
||||||
|
|
|
@ -754,6 +754,32 @@ public class AddEditDialoglTest extends AbstractGhidraHeadedIntegrationTest {
|
||||||
assertEquals(nsName, parentNs.getName());
|
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
|
// Private Methods
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
|
|
@ -42,6 +42,10 @@ public class GBooleanCellRenderer extends GTableCellRenderer {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSelected() {
|
||||||
|
return cb.isSelected();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidate() {
|
public void invalidate() {
|
||||||
superValidate();
|
superValidate();
|
||||||
|
|
|
@ -77,7 +77,7 @@ public final class GTableToCSV {
|
||||||
private static List<TableColumn> getVisibleColumnsInOrder(JTable table, TaskMonitor monitor) {
|
private static List<TableColumn> getVisibleColumnsInOrder(JTable table, TaskMonitor monitor) {
|
||||||
|
|
||||||
TableColumnModel columnModel = table.getColumnModel();
|
TableColumnModel columnModel = table.getColumnModel();
|
||||||
List<TableColumn> columns = new ArrayList<TableColumn>();
|
List<TableColumn> columns = new ArrayList<>();
|
||||||
for (int columnIndex = 0; columnIndex < table.getColumnCount(); ++columnIndex) {
|
for (int columnIndex = 0; columnIndex < table.getColumnCount(); ++columnIndex) {
|
||||||
if (monitor.isCancelled()) {
|
if (monitor.isCancelled()) {
|
||||||
break;
|
break;
|
||||||
|
@ -92,7 +92,7 @@ public final class GTableToCSV {
|
||||||
List<Integer> columnIndices) {
|
List<Integer> columnIndices) {
|
||||||
|
|
||||||
TableColumnModel columnModel = table.getColumnModel();
|
TableColumnModel columnModel = table.getColumnModel();
|
||||||
List<TableColumn> columns = new ArrayList<TableColumn>();
|
List<TableColumn> columns = new ArrayList<>();
|
||||||
for (Integer index : columnIndices) {
|
for (Integer index : columnIndices) {
|
||||||
TableColumn column = columnModel.getColumn(index);
|
TableColumn column = columnModel.getColumn(index);
|
||||||
columns.add(column);
|
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) {
|
private static String getTableCellValue(JTable table, TableModel model, int row, int column) {
|
||||||
TableCellRenderer renderer = table.getCellRenderer(row, column);
|
TableCellRenderer renderer = table.getCellRenderer(row, column);
|
||||||
|
@ -174,6 +174,10 @@ public final class GTableToCSV {
|
||||||
Component component =
|
Component component =
|
||||||
renderer.getTableCellRendererComponent(table, value, false, false, row, column);
|
renderer.getTableCellRendererComponent(table, value, false, false, row, column);
|
||||||
|
|
||||||
|
if (isCheckBox(component)) {
|
||||||
|
return getCheckBoxValue(component);
|
||||||
|
}
|
||||||
|
|
||||||
if (component instanceof JLabel) {
|
if (component instanceof JLabel) {
|
||||||
JLabel label = (JLabel) component;
|
JLabel label = (JLabel) component;
|
||||||
return getTextForLabel(label);
|
return getTextForLabel(label);
|
||||||
|
@ -187,7 +191,27 @@ public final class GTableToCSV {
|
||||||
return value == null ? "" : value.toString();
|
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) {
|
private static String getTextForLabel(JLabel label) {
|
||||||
|
|
||||||
String text = label.getText();
|
String text = label.getText();
|
||||||
if (text != null) {
|
if (text != null) {
|
||||||
return text;
|
return text;
|
||||||
|
@ -334,7 +358,7 @@ public final class GTableToCSV {
|
||||||
private final GTable table;
|
private final GTable table;
|
||||||
|
|
||||||
private File file;
|
private File file;
|
||||||
private List<Integer> columns = new ArrayList<Integer>();
|
private List<Integer> columns = new ArrayList<>();
|
||||||
|
|
||||||
ConvertTask(File file, GTable table) {
|
ConvertTask(File file, GTable table) {
|
||||||
super(GTableToCSV.TITLE, true, true, true);
|
super(GTableToCSV.TITLE, true, true, true);
|
||||||
|
|
|
@ -28,20 +28,17 @@ import ghidra.util.task.TaskMonitor;
|
||||||
public class GTableCSVTest {
|
public class GTableCSVTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCSV_QuotesGetEscaped() {
|
public void testCsv_QuotesGetEscaped() {
|
||||||
|
|
||||||
AnyObjectTableModel<CSVRowObject> model =
|
AnyObjectTableModel<CsvRowObject> model =
|
||||||
new AnyObjectTableModel<>("MyModel", CSVRowObject.class,
|
new AnyObjectTableModel<>("MyModel", CsvRowObject.class,
|
||||||
"getName", "getDescription", "getNumber");
|
"getName", "getDescription", "getNumber");
|
||||||
|
|
||||||
//@formatter:off
|
List<CsvRowObject> data = Arrays.asList(
|
||||||
List<CSVRowObject> data = Arrays.asList(
|
new CsvRowObject("Bob", "Bobby", 11),
|
||||||
new CSVRowObject("Bob", "Bobby", 11),
|
new CsvRowObject("Joan", "Joan has \"quoted\" text", 0),
|
||||||
new CSVRowObject("Joan", "Joan has \"quoted\" text", 0),
|
new CsvRowObject("Sam", "\"Sam has a single quote text", 23),
|
||||||
new CSVRowObject("Sam", "\"Sam has a single quote text", 23),
|
new CsvRowObject("Time", "Tim is last", 33));
|
||||||
new CSVRowObject("Time", "Tim is last", 33)
|
|
||||||
);
|
|
||||||
//@formatter:on
|
|
||||||
model.setModelData(data);
|
model.setModelData(data);
|
||||||
|
|
||||||
GTable table = new GTable(model);
|
GTable table = new GTable(model);
|
||||||
|
@ -50,24 +47,21 @@ public class GTableCSVTest {
|
||||||
PrintWriterSpy writer = new PrintWriterSpy();
|
PrintWriterSpy writer = new PrintWriterSpy();
|
||||||
GTableToCSV.writeCSV(writer, table, columns, TaskMonitor.DUMMY);
|
GTableToCSV.writeCSV(writer, table, columns, TaskMonitor.DUMMY);
|
||||||
|
|
||||||
assertRowValues(data, writer);
|
assertCsvRowValues(data, writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCSV_CommasGetEscaped() {
|
public void testCsv_CommasGetEscaped() {
|
||||||
|
|
||||||
AnyObjectTableModel<CSVRowObject> model =
|
AnyObjectTableModel<CsvRowObject> model =
|
||||||
new AnyObjectTableModel<>("MyModel", CSVRowObject.class,
|
new AnyObjectTableModel<>("MyModel", CsvRowObject.class,
|
||||||
"getName", "getDescription", "getNumber");
|
"getName", "getDescription", "getNumber");
|
||||||
|
|
||||||
//@formatter:off
|
List<CsvRowObject> data = Arrays.asList(
|
||||||
List<CSVRowObject> data = Arrays.asList(
|
new CsvRowObject("Bob", "Bobby", 11),
|
||||||
new CSVRowObject("Bob", "Bobby", 11),
|
new CsvRowObject("Joan", "Joan has a comma, in her text", 0),
|
||||||
new CSVRowObject("Joan", "Joan has a comma, in her text", 0),
|
new CsvRowObject("Sam", ",Sam has a leading comma", 23),
|
||||||
new CSVRowObject("Sam", ",Sam has a leading comma", 23),
|
new CsvRowObject("Time", "Tim is last", 33));
|
||||||
new CSVRowObject("Time", "Tim is last", 33)
|
|
||||||
);
|
|
||||||
//@formatter:on
|
|
||||||
model.setModelData(data);
|
model.setModelData(data);
|
||||||
|
|
||||||
GTable table = new GTable(model);
|
GTable table = new GTable(model);
|
||||||
|
@ -76,16 +70,39 @@ public class GTableCSVTest {
|
||||||
PrintWriterSpy writer = new PrintWriterSpy();
|
PrintWriterSpy writer = new PrintWriterSpy();
|
||||||
GTableToCSV.writeCSV(writer, table, columns, TaskMonitor.DUMMY);
|
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 results = writer.toString();
|
||||||
String[] lines = results.split("\n");
|
String[] lines = results.split("\n");
|
||||||
for (int i = 1; i < lines.length; i++) {
|
for (int i = 1; i < lines.length; i++) {
|
||||||
int index = i - 1; // the first line is the header
|
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 line = lines[i];
|
||||||
String[] columns = line.split("(?<!\\\\),");
|
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 name;
|
||||||
private String description;
|
private String description;
|
||||||
private int number;
|
private int number;
|
||||||
|
|
||||||
CSVRowObject(String name, String description, int number) {
|
CsvRowObject(String name, String description, int number) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.number = number;
|
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 class PrintWriterSpy extends PrintWriter {
|
||||||
|
|
||||||
private StringWriter stringWriter;
|
private StringWriter stringWriter;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue