Merge remote-tracking branch

'origin/GP-2134_ghidra1_StructureEditPointertoSelf_SQUASHED' (Closes
#3721)
This commit is contained in:
ghidra1 2022-06-24 15:56:11 -04:00
commit 9289ceb746
3 changed files with 58 additions and 14 deletions

View File

@ -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);
}
}

View File

@ -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());

View File

@ -106,12 +106,19 @@ public interface DataType {
public Settings getDefaultSettings();
/**
* Returns an instance of this DataType with its universalID and SourceArchive identity
* retained.
* Returns an instance of this DataType using the specified {@link DataTypeManager} to allow
* its use of the corresponding {@link DataOrganization} while retaining its unique identity
* (see {@link #getUniversalID()} and archive association (see {@link #getSourceArchive()}) if
* applicable.
* <p>
* The current instanceof will be returned if this datatype's DataTypeManager matches the
* specified dtm. The recursion depth of a clone will stop on any datatype whose DataTypeManager
* matches the specified dtm and simply use the existing datatype instance.
* This instance will be returned if this datatype's DataTypeManager matches the
* specified dtm. The recursion depth of a clone will stop on any datatype whose
* {@link DataTypeManager} matches the specified dtm and simply use the existing datatype
* instance.
* <p>
* NOTE: In general, this method should not be used to obtain an instance to be modified.
* In most cases changes shuold be made directly to this instance if supported or to a
* {@link #copy(DataTypeManager)}.
*
* @param dtm the data-type manager instance whose data-organization should apply.
* @return cloned instance which may be the same as this instance
@ -119,7 +126,8 @@ public interface DataType {
public DataType clone(DataTypeManager dtm);
/**
* Returns a new instance (shallow copy) of this DataType with a new identity.
* Returns a new instance (shallow copy) of this DataType with a new identity and no
* source archive association.
* <p>
* Any reference to other datatypes will use {@link #clone(DataTypeManager)}.
*