GP-5527 Sturcture component unpack bug

This commit is contained in:
ghidra1 2025-03-25 22:16:29 -04:00
parent 877ff2e8ad
commit dcc87e7fb7
2 changed files with 28 additions and 3 deletions

View file

@ -1365,7 +1365,13 @@ class StructureEditorModel extends CompEditorModel {
if (numComps > 0) {
// Remove the structure.
int currentOffset = currentComp.getOffset();
deleteComponent(rowIndex); // TODO: Should clear for non-packed
// NOTE: There is still a case which is unhandled: if there is a zero-length
// component at the same offset as the component to be unpacked, the unpacking
// will be inserted before the zero-length component. More work is needed to
// handle this case.
deleteComponent(rowIndex);
// Add the structure's elements
Stack<DataTypeComponent> zeroDtcStack = new Stack<>();
@ -1379,6 +1385,7 @@ class StructureEditorModel extends CompEditorModel {
int compOffset = dtc.getOffset();
if (compOffset != zeroStackOffset && !zeroDtcStack.isEmpty()) {
packedOrdinal += zeroDtcStack.size();
applyZeroDtcStack(viewStruct, currentOffset, componentOrdinal,
zeroDtcStack, zeroStackOffset, zeroStackOrdinal);
}
@ -1443,7 +1450,9 @@ class StructureEditorModel extends CompEditorModel {
private void applyZeroDtcStack(Structure viewStruct, int unpackOffset, int unpackOrdinal,
Stack<DataTypeComponent> zeroDtcStack, int zeroStackOffset, int zeroStackOrdinal) {
zeroDtcStack.forEach(zeroDtc -> {
while (!zeroDtcStack.isEmpty()) {
DataTypeComponent zeroDtc = zeroDtcStack.pop();
if (!isPackingEnabled()) {
viewStruct.insertAtOffset(unpackOffset + zeroStackOffset, zeroDtc.getDataType(), 0,
zeroDtc.getFieldName(), zeroDtc.getComment());
@ -1452,7 +1461,7 @@ class StructureEditorModel extends CompEditorModel {
viewStruct.insert(unpackOrdinal + zeroStackOrdinal, zeroDtc.getDataType(), 0,
zeroDtc.getFieldName(), zeroDtc.getComment());
}
});
}
zeroDtcStack.clear();
}
}

View file

@ -24,6 +24,8 @@ import docking.ActionContext;
import docking.action.KeyBindingData;
import docking.widgets.OptionDialog;
import generic.theme.GIcon;
import ghidra.program.model.data.DataTypeComponent;
import ghidra.util.Msg;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.UsrException;
import ghidra.util.task.TaskLauncher;
@ -53,9 +55,23 @@ public class UnpackageAction extends CompositeEditorTableAction {
if (!isEnabledForContext(context)) {
return;
}
// If lots of components, verify the user really wants to unpackage.
int currentRowIndex =
model.getSelection().getFieldRange(0).getStart().getIndex().intValue();
// Check for unsupported unpack case.
StructureEditorModel structModel = (StructureEditorModel) model;
if (!structModel.isPackingEnabled()) {
DataTypeComponent dtc = structModel.getComponent(currentRowIndex);
if (dtc != null && dtc.getOrdinal() != 0 &&
structModel.getComponent(currentRowIndex - 1).getOffset() == dtc.getOffset()) {
Msg.showInfo(this, model.getProvider().getComponent(), "Unsupported Unpack",
"Unpack is not supported when component offset is shared with a zero-length component.");
return;
}
}
int subComps = model.getNumSubComponents(currentRowIndex);
if (subComps > 1000) {
String question = "Are you sure you want to unpackage " + subComps + " components?";