mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-08-08 07:40:39 -09:00
GP-6576 Corrected Structure insertAtOffset bug
This commit is contained in:
@@ -540,6 +540,40 @@ public class StructureDataTypeTest extends AbstractGenericTest {
|
||||
"Length: 13 Alignment: 1\n", struct.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertWithZeroArrayAtOffset3() {
|
||||
Array zeroArray = new ArrayDataType(FloatDataType.dataType, 0, -1);
|
||||
|
||||
// Clear structure and set length to 8 with only zero-length components
|
||||
struct.setLength(0);
|
||||
struct.setLength(8);
|
||||
|
||||
struct.insertAtOffset(2, zeroArray, -1, "z4", null);
|
||||
struct.insertAtOffset(0, zeroArray, -1, "z1", null);
|
||||
struct.insertAtOffset(0, zeroArray, -1, "z2", null);
|
||||
|
||||
assertEquals("/TestStruct\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure TestStruct {\n" +
|
||||
" 0 float[0] 0 z1 \"\"\n" +
|
||||
" 0 float[0] 0 z2 \"\"\n" +
|
||||
" 2 float[0] 0 z4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 8 Alignment: 1\n", struct.toString());
|
||||
|
||||
struct.insertAtOffset(0, zeroArray, -1, "z3", null);
|
||||
|
||||
assertEquals("/TestStruct\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure TestStruct {\n" +
|
||||
" 0 float[0] 0 z1 \"\"\n" +
|
||||
" 0 float[0] 0 z2 \"\"\n" +
|
||||
" 0 float[0] 0 z3 \"\"\n" +
|
||||
" 2 float[0] 0 z4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 8 Alignment: 1\n", struct.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertAtOffsetPastEnd() {
|
||||
struct.insertAtOffset(100, new FloatDataType(), 4);
|
||||
@@ -861,6 +895,44 @@ public class StructureDataTypeTest extends AbstractGenericTest {
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertZeroLengthBitfieldAtOffset() {
|
||||
Array zeroArray = new ArrayDataType(FloatDataType.dataType, 0, -1);
|
||||
|
||||
// Clear structure and set length to 8 with only zero-length components
|
||||
struct.setLength(0);
|
||||
struct.setLength(8);
|
||||
struct.insertAtOffset(0, zeroArray, -1, "z1", null);
|
||||
struct.insertAtOffset(0, zeroArray, -1, "z2", null);
|
||||
struct.insertAtOffset(2, zeroArray, -1, "z4", null);
|
||||
|
||||
assertEquals("/TestStruct\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure TestStruct {\n" +
|
||||
" 0 float[0] 0 z1 \"\"\n" +
|
||||
" 0 float[0] 0 z2 \"\"\n" +
|
||||
" 2 float[0] 0 z4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 8 Alignment: 1\n", struct.toString());
|
||||
|
||||
try {
|
||||
struct.insertBitFieldAt(0, 1, 0, CharDataType.dataType, 0, null, null);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
failWithException("Unexpected", e);
|
||||
}
|
||||
|
||||
assertEquals("/TestStruct\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure TestStruct {\n" +
|
||||
" 0 float[0] 0 z1 \"\"\n" +
|
||||
" 0 float[0] 0 z2 \"\"\n" +
|
||||
" 0 char:0(0) 0 \"\"\n" +
|
||||
" 2 float[0] 0 z4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 8 Alignment: 1\n", struct.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertBitFieldAtBigEndian() throws Exception {
|
||||
|
||||
@@ -2053,6 +2125,39 @@ public class StructureDataTypeTest extends AbstractGenericTest {
|
||||
assertTrue(ByteDataType.dataType.isEquivalent(comps[4].getDataType()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplaceAtWithZeroLength1() {
|
||||
Array zeroArray = new ArrayDataType(FloatDataType.dataType, 0, -1);
|
||||
|
||||
// Clear structure and set length to 8 with only zero-length components
|
||||
struct.setLength(0);
|
||||
struct.setLength(8);
|
||||
struct.replaceAtOffset(0, zeroArray, -1, "z1", null);
|
||||
struct.replaceAtOffset(0, zeroArray, -1, "z2", null);
|
||||
struct.replaceAtOffset(2, zeroArray, -1, "z4", null);
|
||||
|
||||
assertEquals("/TestStruct\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure TestStruct {\n" +
|
||||
" 0 float[0] 0 z1 \"\"\n" +
|
||||
" 0 float[0] 0 z2 \"\"\n" +
|
||||
" 2 float[0] 0 z4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 8 Alignment: 1\n", struct.toString());
|
||||
|
||||
struct.replaceAtOffset(0, zeroArray, -1, "z3", null);
|
||||
|
||||
assertEquals("/TestStruct\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure TestStruct {\n" +
|
||||
" 0 float[0] 0 z1 \"\"\n" +
|
||||
" 0 float[0] 0 z2 \"\"\n" +
|
||||
" 0 float[0] 0 z3 \"\"\n" +
|
||||
" 2 float[0] 0 z4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 8 Alignment: 1\n", struct.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetName() throws Exception {
|
||||
Structure s1 = new StructureDataType("Test1", 0);
|
||||
|
||||
@@ -1337,6 +1337,8 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
||||
dataType = resolve(dataType);
|
||||
DataTypeUtilities.checkAncestry(this, dataType);
|
||||
|
||||
length = getPreferredComponentLength(dataType, length);
|
||||
|
||||
if ((offset > structLength) && !isPackingEnabled()) {
|
||||
numComponents += offset - structLength;
|
||||
structLength = offset;
|
||||
@@ -1352,7 +1354,8 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
||||
if (index >= 0) {
|
||||
index = backupToFirstComponentContainingOffset(index, offset);
|
||||
index = afterNonZeroComponentsAtOffset(index, offset);
|
||||
if (index < components.size()) {
|
||||
if (length != 0 && index < components.size()) {
|
||||
// NOTE: zero-length component insert does not trigger offset shift
|
||||
DataTypeComponentDB dtc = components.get(index);
|
||||
additionalShift = offset - dtc.getOffset();
|
||||
}
|
||||
@@ -1364,7 +1367,13 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
||||
int ordinal = offset;
|
||||
if (index > 0) {
|
||||
DataTypeComponentDB dtc = components.get(index - 1);
|
||||
ordinal = dtc.getOrdinal() + offset - dtc.getEndOffset();
|
||||
ordinal = dtc.getOrdinal();
|
||||
if (dtc.getOffset() == offset) {
|
||||
ordinal += 1;
|
||||
}
|
||||
else {
|
||||
ordinal += offset - dtc.getEndOffset(); // account for undefined components
|
||||
}
|
||||
}
|
||||
|
||||
if (dataType == DataType.DEFAULT) {
|
||||
@@ -1375,8 +1384,6 @@ class StructureDB extends CompositeDB implements StructureInternal {
|
||||
return new DataTypeComponentDB(dataMgr, this, ordinal, offset);
|
||||
}
|
||||
|
||||
length = getPreferredComponentLength(dataType, length);
|
||||
|
||||
DBRecord rec = componentAdapter.createRecord(dataMgr.getResolvedID(dataType), key,
|
||||
length, ordinal, offset, name, comment);
|
||||
dataType.addParent(this);
|
||||
|
||||
@@ -520,6 +520,8 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
||||
dataType = dataType.clone(dataMgr);
|
||||
DataTypeUtilities.checkAncestry(this, dataType);
|
||||
|
||||
length = getPreferredComponentLength(dataType, length);
|
||||
|
||||
if ((offset > structLength) && !isPackingEnabled()) {
|
||||
numComponents += offset - structLength;
|
||||
structLength = offset;
|
||||
@@ -535,7 +537,8 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
||||
if (index >= 0) {
|
||||
index = backupToFirstComponentContainingOffset(index, offset);
|
||||
index = afterNonZeroComponentsAtOffset(index, offset);
|
||||
if (index < components.size()) {
|
||||
if (length != 0 && index < components.size()) {
|
||||
// NOTE: zero-length component insert does not trigger offset shift
|
||||
DataTypeComponentImpl dtc = components.get(index);
|
||||
additionalShift = offset - dtc.getOffset();
|
||||
}
|
||||
@@ -547,7 +550,13 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
||||
int ordinal = offset;
|
||||
if (index > 0) {
|
||||
DataTypeComponent dtc = components.get(index - 1);
|
||||
ordinal = dtc.getOrdinal() + offset - dtc.getEndOffset();
|
||||
ordinal = dtc.getOrdinal();
|
||||
if (dtc.getOffset() == offset) {
|
||||
ordinal += 1;
|
||||
}
|
||||
else {
|
||||
ordinal += offset - dtc.getEndOffset(); // account for undefined components
|
||||
}
|
||||
}
|
||||
|
||||
if (dataType == DataType.DEFAULT) {
|
||||
@@ -556,8 +565,6 @@ public class StructureDataType extends CompositeDataTypeImpl implements Structur
|
||||
return new DataTypeComponentImpl(DataType.DEFAULT, this, 1, ordinal, offset);
|
||||
}
|
||||
|
||||
length = getPreferredComponentLength(dataType, length);
|
||||
|
||||
DataTypeComponentImpl dtc = new DataTypeComponentImpl(dataType, this, length, ordinal,
|
||||
offset, componentName, comment);
|
||||
dataType.addParent(this);
|
||||
|
||||
@@ -567,6 +567,42 @@ public class StructureDBTest extends AbstractGenericTest {
|
||||
"Length: 13 Alignment: 1\n", struct.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertWithZeroArrayAtOffset3() {
|
||||
Array zeroArray = new ArrayDataType(FloatDataType.dataType, 0, -1);
|
||||
|
||||
// Clear structure and set length to 8 with only zero-length components
|
||||
struct.setLength(0);
|
||||
struct.setLength(8);
|
||||
|
||||
struct.insertAtOffset(2, zeroArray, -1, "z4", null);
|
||||
struct.insertAtOffset(0, zeroArray, -1, "z1", null);
|
||||
struct.insertAtOffset(0, zeroArray, -1, "z2", null);
|
||||
|
||||
assertEquals("/Test\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Test {\n" +
|
||||
" 0 float[0] 0 z1 \"\"\n" +
|
||||
" 0 float[0] 0 z2 \"\"\n" +
|
||||
" 2 float[0] 0 z4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 8 Alignment: 1\n" +
|
||||
"", struct.toString());
|
||||
|
||||
struct.insertAtOffset(0, zeroArray, -1, "z3", null);
|
||||
|
||||
assertEquals("/Test\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Test {\n" +
|
||||
" 0 float[0] 0 z1 \"\"\n" +
|
||||
" 0 float[0] 0 z2 \"\"\n" +
|
||||
" 0 float[0] 0 z3 \"\"\n" +
|
||||
" 2 float[0] 0 z4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 8 Alignment: 1\n" +
|
||||
"", struct.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertAtOffsetPastEnd() {
|
||||
struct.insertAtOffset(100, new FloatDataType(), 4);
|
||||
@@ -1017,6 +1053,44 @@ public class StructureDBTest extends AbstractGenericTest {
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertZeroLengthBitfieldAtOffset() {
|
||||
Array zeroArray = new ArrayDataType(FloatDataType.dataType, 0, -1);
|
||||
|
||||
// Clear structure and set length to 8 with only zero-length components
|
||||
struct.setLength(0);
|
||||
struct.setLength(8);
|
||||
struct.insertAtOffset(0, zeroArray, -1, "z1", null);
|
||||
struct.insertAtOffset(0, zeroArray, -1, "z2", null);
|
||||
struct.insertAtOffset(2, zeroArray, -1, "z4", null);
|
||||
|
||||
assertEquals("/Test\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Test {\n" +
|
||||
" 0 float[0] 0 z1 \"\"\n" +
|
||||
" 0 float[0] 0 z2 \"\"\n" +
|
||||
" 2 float[0] 0 z4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 8 Alignment: 1\n", struct.toString());
|
||||
|
||||
try {
|
||||
struct.insertBitFieldAt(0, 1, 0, CharDataType.dataType, 0, null, null);
|
||||
}
|
||||
catch (InvalidDataTypeException e) {
|
||||
failWithException("Unexpected", e);
|
||||
}
|
||||
|
||||
assertEquals("/Test\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Test {\n" +
|
||||
" 0 float[0] 0 z1 \"\"\n" +
|
||||
" 0 float[0] 0 z2 \"\"\n" +
|
||||
" 0 char:0(0) 0 \"\"\n" +
|
||||
" 2 float[0] 0 z4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 8 Alignment: 1\n", struct.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertBitFieldAtBigEndian() throws Exception {
|
||||
|
||||
@@ -2488,6 +2562,41 @@ public class StructureDBTest extends AbstractGenericTest {
|
||||
assertTrue(ByteDataType.dataType.isEquivalent(comps[4].getDataType()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReplaceAtWithZeroLength1() {
|
||||
Array zeroArray = new ArrayDataType(FloatDataType.dataType, 0, -1);
|
||||
|
||||
// Clear structure and set length to 8 with only zero-length components
|
||||
struct.setLength(0);
|
||||
struct.setLength(8);
|
||||
struct.replaceAtOffset(0, zeroArray, -1, "z1", null);
|
||||
struct.replaceAtOffset(0, zeroArray, -1, "z2", null);
|
||||
struct.replaceAtOffset(2, zeroArray, -1, "z4", null);
|
||||
|
||||
assertEquals("/Test\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Test {\n" +
|
||||
" 0 float[0] 0 z1 \"\"\n" +
|
||||
" 0 float[0] 0 z2 \"\"\n" +
|
||||
" 2 float[0] 0 z4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 8 Alignment: 1\n" +
|
||||
"", struct.toString());
|
||||
|
||||
struct.replaceAtOffset(0, zeroArray, -1, "z3", null);
|
||||
|
||||
assertEquals("/Test\n" +
|
||||
"pack(disabled)\n" +
|
||||
"Structure Test {\n" +
|
||||
" 0 float[0] 0 z1 \"\"\n" +
|
||||
" 0 float[0] 0 z2 \"\"\n" +
|
||||
" 0 float[0] 0 z3 \"\"\n" +
|
||||
" 2 float[0] 0 z4 \"\"\n" +
|
||||
"}\n" +
|
||||
"Length: 8 Alignment: 1\n" +
|
||||
"", struct.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetName() throws Exception {
|
||||
Structure s1 = new StructureDataType("Test1", 0);
|
||||
|
||||
Reference in New Issue
Block a user