Fixed screenshots broken due to archive type change

This commit is contained in:
dragonmacher
2026-03-31 18:20:44 -04:00
parent ca5dab04d2
commit a0893d6c59
14 changed files with 53 additions and 61 deletions
@@ -555,6 +555,9 @@ public abstract class AbstractGhidraHeadedDebuggerTest
if (provider == null) { if (provider == null) {
ctx = new DefaultActionContext(); ctx = new DefaultActionContext();
} }
else {
ctx = provider.getActionContext(null);
}
ctx.setContextProvider(provider); ctx.setContextProvider(provider);
Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 27 KiB

@@ -1283,14 +1283,16 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
resolvedDataType = resolveDataTypeNoSource(dataType); resolvedDataType = resolveDataTypeNoSource(dataType);
} }
else if (!sourceArchive.getSourceArchiveID().equals(getUniversalID()) && else if (!sourceArchive.getSourceArchiveID().equals(getUniversalID()) &&
(sourceArchive.getArchiveType() == ArchiveType.PROGRAM || !sourceArchive.getArchiveType().isValidSourceArchive()) {
sourceArchive.getArchiveType() == ArchiveType.TEMPORARY)) {
// dataTypes from a program or temporary archive don't carry over their identity // dataTypes from a invalid source (program, built-in, temporary) archive
// don't carry over their identity
resolvedDataType = resolveDataTypeNoSource(dataType); resolvedDataType = resolveDataTypeNoSource(dataType);
} }
else { else {
resolvedDataType = resolveDataTypeWithSource(dataType); resolvedDataType = resolveDataTypeWithSource(dataType);
} }
cacheResolvedDataType(dataType, resolvedDataType); cacheResolvedDataType(dataType, resolvedDataType);
if (resolvedDataType instanceof DataTypeDB) { if (resolvedDataType instanceof DataTypeDB) {
setCachedEquivalence((DataTypeDB) resolvedDataType, dataType); setCachedEquivalence((DataTypeDB) resolvedDataType, dataType);
@@ -4594,8 +4596,7 @@ abstract public class DataTypeManagerDB implements DataTypeManager {
} }
} }
private record DedupedConflicts(int processCnt, int replaceCnt) { private record DedupedConflicts(int processCnt, int replaceCnt) {}
}
private DedupedConflicts doDedupeConflicts(DataType dataType) { private DedupedConflicts doDedupeConflicts(DataType dataType) {
@@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,4 +27,11 @@ public enum ArchiveType {
public boolean isBuiltIn() { public boolean isBuiltIn() {
return this == BUILT_IN; return this == BUILT_IN;
} }
/**
* {@return true if this type is a valid type of source archive for adding types to the program}
*/
public boolean isValidSourceArchive() {
return this == FILE || this == PROJECT;
}
} }
@@ -79,17 +79,6 @@ public class DataTypeManagerPluginScreenShots extends GhidraScreenShotGenerator
captureIsolatedProvider(DataTypesProvider.class, 500, 400); captureIsolatedProvider(DataTypesProvider.class, 500, 400);
} }
@Test
public void testDataTypeTreeWithAssociations() {
DataTypesProvider provider = getProvider(DataTypesProvider.class);
GTree tree = (GTree) getInstanceField("archiveGTree", provider);
GTreeNode rootNode = tree.getViewRoot();
GTreeNode child = rootNode.getChild("WinHelloCPP.exe");
child = child.getChild("basetsd.h");
tree.expandPath(child);
captureIsolatedProvider(DataTypesProvider.class, 500, 400);
}
@Test @Test
public void testDisassociateDialog() { public void testDisassociateDialog() {
DataTypeManagerPlugin plugin = getPlugin(tool, DataTypeManagerPlugin.class); DataTypeManagerPlugin plugin = getPlugin(tool, DataTypeManagerPlugin.class);
@@ -196,8 +185,8 @@ public class DataTypeManagerPluginScreenShots extends GhidraScreenShotGenerator
@Test @Test
public void testFindDataTypes() { public void testFindDataTypes() {
performAction("Find Data Types", "DataTypeManagerPlugin", false); performAction("Find Data Types by Name", "DataTypeManagerPlugin", false);
JDialog d = waitForJDialog("Find Data Types"); JDialog d = waitForJDialog("Find Data Types by Name");
captureDialog(); captureDialog();
pressButtonByText(d, "Cancel"); pressButtonByText(d, "Cancel");
} }
@@ -260,7 +249,8 @@ public class DataTypeManagerPluginScreenShots extends GhidraScreenShotGenerator
closeNonProgramArchives(); closeNonProgramArchives();
closeProvider(DataTypesProvider.class); closeProvider(DataTypesProvider.class);
runSwing(() -> performAction("Find Data Types", "DataTypeManagerPlugin", false), false); runSwing(() -> performAction("Find Data Types by Name", "DataTypeManagerPlugin", false),
false);
final DialogComponentProvider dialog = getDialog(); final DialogComponentProvider dialog = getDialog();
runSwing(() -> { runSwing(() -> {
@@ -281,41 +271,26 @@ public class DataTypeManagerPluginScreenShots extends GhidraScreenShotGenerator
DataTypeManagerPlugin plugin = getPlugin(tool, DataTypeManagerPlugin.class); DataTypeManagerPlugin plugin = getPlugin(tool, DataTypeManagerPlugin.class);
List<DataTypeSyncInfo> list = new ArrayList<>(); List<DataTypeSyncInfo> list = new ArrayList<>();
Set<DataTypeSyncInfo> set = new HashSet<>(); Set<DataTypeSyncInfo> set = new HashSet<>();
createChangedDatatypesFromArchive(list, set); StandAloneDataTypeManager sourceDtm = createChangedDatatypesFromArchive(list, set);
DataTypeManager dtm = program.getDataTypeManager(); DataType dt1 = sourceDtm.getDataType("/MyDataType1");
StandAloneDataTypeManager sourceDTM = new StandAloneDataTypeManager("MyArhcive"); Structure struct = tx(program, () -> {
StructureDataType sdt1 = new StructureDataType("MyDataType1", 0); DataTypeManager dtm = program.getDataTypeManager();
sdt1.add(new PointerDataType(new StringDataType()), "name", null); return (Structure) dtm.addDataType(dt1, null);
sdt1.add(new IntegerDataType(), "age", null); });
sdt1.add(new PointerDataType(new VoidDataType()), "data", null);
StructureDataType sdt2 = new StructureDataType("MyDataType2", 0); tx(sourceDtm, () -> {
sdt2.add(new PointerDataType(new IntegerDataType())); ((Structure) dt1).add(new IntegerDataType(), "id", null);
sdt2.add(new IntegerDataType()); });
sdt2.add(new WordDataType());
int id = sourceDTM.startTransaction("Test"); DataTypeSyncInfo sync1 = new DataTypeSyncInfo(struct, sourceDtm);
DataType dt1 = sourceDTM.addDataType(sdt1, null);
sourceDTM.endTransaction(id, true);
int txID = program.startTransaction("Test");
Structure struct = (Structure) dtm.addDataType(dt1, null);
program.endTransaction(txID, true);
id = sourceDTM.startTransaction("Test2");
((Structure) dt1).add(new IntegerDataType(), "id", null);
sourceDTM.endTransaction(id, true);
DataTypeSyncInfo sync1 = new DataTypeSyncInfo(struct, sourceDTM);
list.add(sync1); list.add(sync1);
set.add(sync1); set.add(sync1);
final DataTypeSyncDialog dialog = DataTypeSyncDialog dialog =
new DataTypeSyncDialog(plugin, "WinHelloCPP.exe", "MyArchive", list, set, "Update", new DataTypeSyncDialog(plugin, "WinHelloCPP.exe", "MyArchive", list, set, "Update",
"Update DataType Changes From Archive \"MyArchive\" To \"WinHelloCpp.exe\" "); "Update DataType Changes From Archive \"MyArchive\" To \"WinHelloCpp.exe\" ");
showModalDialogInTool(dialog); showModalDialogInTool(dialog);
runSwing(() -> { runSwing(() -> {
@@ -360,11 +335,18 @@ public class DataTypeManagerPluginScreenShots extends GhidraScreenShotGenerator
return null;// cannot get here return null;// cannot get here
} }
private void createChangedDatatypesFromArchive(List<DataTypeSyncInfo> list, private StandAloneDataTypeManager createChangedDatatypesFromArchive(List<DataTypeSyncInfo> list,
Set<DataTypeSyncInfo> set) { Set<DataTypeSyncInfo> set) {
DataTypeManager dtm = program.getDataTypeManager(); DataTypeManager dtm = program.getDataTypeManager();
StandAloneDataTypeManager sourceDTM = new StandAloneDataTypeManager("MyArhcive"); StandAloneDataTypeManager sourceDtm = new StandAloneDataTypeManager("MyArhcive") {
@Override
public ArchiveType getType() {
// Need to not be the default TEMPORARY type so that the universal ID of our data
// types will be maintained. This is needed to associate the types.
return ArchiveType.FILE;
}
};
StructureDataType sdt1 = new StructureDataType("MyDataType1", 0); StructureDataType sdt1 = new StructureDataType("MyDataType1", 0);
sdt1.add(new PointerDataType(new StringDataType()), "name", null); sdt1.add(new PointerDataType(new StringDataType()), "name", null);
sdt1.add(new IntegerDataType(), "age", null); sdt1.add(new IntegerDataType(), "age", null);
@@ -375,27 +357,26 @@ public class DataTypeManagerPluginScreenShots extends GhidraScreenShotGenerator
sdt2.add(new IntegerDataType()); sdt2.add(new IntegerDataType());
sdt2.add(new WordDataType()); sdt2.add(new WordDataType());
int id = sourceDTM.startTransaction("Test"); int id = sourceDtm.startTransaction("Test");
DataType dt1 = sourceDTM.addDataType(sdt1, null); DataType dt1 = sourceDtm.addDataType(sdt1, null);
DataType dt2 = sourceDTM.addDataType(sdt2, null); DataType dt2 = sourceDtm.addDataType(sdt2, null);
sourceDTM.endTransaction(id, true); sourceDtm.endTransaction(id, true);
tx(program, () -> {
int txID = program.startTransaction("Test");
try {
Structure struct = (Structure) dtm.addDataType(dt1, null); Structure struct = (Structure) dtm.addDataType(dt1, null);
struct.add(new IntegerDataType(), "id", null); struct.add(new IntegerDataType(), "id", null);
Structure struct2 = (Structure) dtm.addDataType(dt2, null); Structure struct2 = (Structure) dtm.addDataType(dt2, null);
struct2.add(new IntegerDataType()); struct2.add(new IntegerDataType());
DataTypeSyncInfo sync1 = new DataTypeSyncInfo(struct, sourceDTM); DataTypeSyncInfo sync1 = new DataTypeSyncInfo(struct, sourceDtm);
DataTypeSyncInfo sync2 = new DataTypeSyncInfo(struct2, sourceDTM); DataTypeSyncInfo sync2 = new DataTypeSyncInfo(struct2, sourceDtm);
list.add(sync1); list.add(sync1);
list.add(sync2); list.add(sync2);
set.add(sync1); set.add(sync1);
} });
finally {
program.endTransaction(txID, true); return sourceDtm;
}
} }
private void showModalDialogInTool(final DialogComponentProvider dialog) { private void showModalDialogInTool(final DialogComponentProvider dialog) {