From 0797cf45d92a86e080661f9c97db6a8b72782871 Mon Sep 17 00:00:00 2001 From: ghidra1 Date: Wed, 22 Jun 2022 17:52:18 -0400 Subject: [PATCH] GP-2134 corrected structure edit issue when adding pointer-to-self component --- .../CompositeViewerDataTypeManager.java | 29 ++++++++++++++----- .../StructureEditorUnlockedCellEdit2Test.java | 23 ++++++++++++++- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeViewerDataTypeManager.java b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeViewerDataTypeManager.java index 0af8174333..fbdde9a48f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeViewerDataTypeManager.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/compositeeditor/CompositeViewerDataTypeManager.java @@ -19,25 +19,28 @@ import ghidra.program.model.data.*; public class CompositeViewerDataTypeManager extends StandAloneDataTypeManager { - /** The full name of the composite data type being edited. */ - /** The data type manager for original composite data type being edited. + /** + * The data type manager for original composite data type being edited. * This is where the edited datatype will be written back to. */ private DataTypeManager originalDTM; + private Composite originalComposite; + private Composite viewComposite; private int transactionID; /** * Creates a data type manager that the structure editor will use * internally for updating the structure being edited. * @param rootName the root name for this data type manager (usually the program name). - * @param composite the composite data type that is being edited. (cannot be null). + * @param originalComposite the original composite data type that is being edited. (cannot be null). */ - public CompositeViewerDataTypeManager(String rootName, Composite composite) { - super(rootName, composite.getDataTypeManager().getDataOrganization()); + public CompositeViewerDataTypeManager(String rootName, Composite originalComposite) { + super(rootName, originalComposite.getDataTypeManager().getDataOrganization()); + this.originalComposite = originalComposite; transactionID = startTransaction(""); - originalDTM = composite.getDataTypeManager(); + originalDTM = originalComposite.getDataTypeManager(); universalID = originalDTM.getUniversalID(); // mimic original DTM - super.resolve(composite, null); + viewComposite = (Composite) super.resolve(originalComposite, null); } @Override @@ -56,4 +59,16 @@ public class CompositeViewerDataTypeManager extends StandAloneDataTypeManager { return originalDTM.allowsDefaultBuiltInSettings(); } + @Override + public DataType resolve(DataType dataType, DataTypeConflictHandler handler) { + if (dataType == originalComposite && viewComposite != null) { + // be sure to resolve use of original composite (e.g., pointer use) + // from program/archive to view instance. The viewComposite will + // be null while resolving it during instantiation of this + // DataTypeManager instance. + return viewComposite; + } + return super.resolve(dataType, handler); + } + } diff --git a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/compositeeditor/StructureEditorUnlockedCellEdit2Test.java b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/compositeeditor/StructureEditorUnlockedCellEdit2Test.java index 82d4270b16..e2bdfdee2f 100644 --- a/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/compositeeditor/StructureEditorUnlockedCellEdit2Test.java +++ b/Ghidra/Features/Base/src/test.slow/java/ghidra/app/plugin/core/compositeeditor/StructureEditorUnlockedCellEdit2Test.java @@ -527,6 +527,27 @@ public class StructureEditorUnlockedCellEdit2Test assertEquals(29, model.getLength()); assertEquals(4, dt.getLength()); + + // insert new component at end first to force difference + // between program type and editor type. This is done to + // ensure we do not incorrectly update the edited structure + // during the resolve processing + + int newRow = model.getNumComponents(); + editCell(getTable(), newRow, column); // blank row + assertIsEditingField(newRow, column); + + setText("byte"); + pressEnterToSelectChoice(); + + assertNotEditingField(); + assertEquals(1, model.getNumSelectedRows()); + assertEquals(newRow + 1, model.getMinIndexSelected()); // blank row + assertCellString("byte", newRow, column); + assertEquals(30, model.getLength()); + + // change row-3 datatype from dword to simpleStructure* + editCell(getTable(), 3, column); assertIsEditingField(3, column); @@ -537,7 +558,7 @@ public class StructureEditorUnlockedCellEdit2Test assertEquals(1, model.getNumSelectedRows()); assertEquals(3, model.getMinIndexSelected()); assertCellString("simpleStructure *", 3, column); - assertEquals(29, model.getLength()); + assertEquals(30, model.getLength()); dt = getDataType(3); assertEquals(4, dt.getLength()); assertEquals("simpleStructure *", dt.getDisplayName());