GP-943 Added support for zero-length arrays and

zero-length components.  NOTE: We still never return 0 for
DataType.getLength().  Added DataType.isZeroLength().
This commit is contained in:
ghidra1 2021-08-10 17:51:35 -04:00
parent 579e3bacf7
commit cfdec26da4
188 changed files with 7968 additions and 6645 deletions

View file

@ -15,7 +15,7 @@
*/
package ghidra.program.model.data;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.*;
import java.io.IOException;
import java.io.StringWriter;
@ -24,7 +24,7 @@ import org.junit.*;
import generic.test.AbstractGTest;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitorAdapter;
import ghidra.util.task.TaskMonitor;
public class DataTypeWriterTest extends AbstractGTest {
@ -53,7 +53,7 @@ public class DataTypeWriterTest extends AbstractGTest {
@Test
public void testTypeDef() throws IOException, CancelledException {
TypeDef typedef = new TypedefDataType("BOB", new CharDataType());
dtWriter.write(typedef, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(typedef, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
String expected = "typedef char BOB;" + EOL + EOL;
assertEquals(expected, actual);
@ -62,7 +62,7 @@ public class DataTypeWriterTest extends AbstractGTest {
@Test
public void testTypeDef2() throws IOException, CancelledException {
TypeDef typedef = new TypedefDataType("unsigned int", new DWordDataType());
dtWriter.write(typedef, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(typedef, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
String expected = "";
assertEquals(expected, actual);
@ -71,7 +71,7 @@ public class DataTypeWriterTest extends AbstractGTest {
@Test
public void testTypeDef3() throws IOException, CancelledException {
TypeDef typedef = new TypedefDataType("const float", new DWordDataType());
dtWriter.write(typedef, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(typedef, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
String expected = "";
assertEquals(expected, actual);
@ -89,7 +89,7 @@ public class DataTypeWriterTest extends AbstractGTest {
TypeDef typedef =
new TypedefDataType("static const " + pointer2.getDisplayName(), pointer2);
dtWriter.write(typedef, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(typedef, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
String expected = "";
assertEquals(expected, actual);
@ -103,7 +103,7 @@ public class DataTypeWriterTest extends AbstractGTest {
enumm.add("C", 2);
enumm.add("D", 3);
enumm.add("E", 4);
dtWriter.write(enumm, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(enumm, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
String expected = "typedef enum myEnum {" + EOL + " A=0," + EOL + " B=1," + EOL +
" C=2," + EOL + " D=3," + EOL + " E=4" + EOL + "} myEnum;" + EOL + EOL;
@ -118,7 +118,7 @@ public class DataTypeWriterTest extends AbstractGTest {
enumm.add("C", 16);
enumm.add("D", 32);
enumm.add("E", 254);
dtWriter.write(enumm, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(enumm, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
String expected = "typedef enum myEnum {" + EOL + " A=4," + EOL + " B=8," + EOL +
" C=16," + EOL + " D=32," + EOL + " E=254" + EOL + "} myEnum;" + EOL + EOL;
@ -130,6 +130,8 @@ public class DataTypeWriterTest extends AbstractGTest {
Structure struct = new StructureDataType("MyStruct", 0);
struct.setDescription("this is my structure");
struct.add(new CharDataType(), "myChar", "this is a character");
struct.add(new ArrayDataType(CharDataType.dataType, 5, -1), "myCharArray",
"this is a character array");
struct.add(new ByteDataType(), "myByte", "this is a byte");
struct.add(new WordDataType(), "myWord", "this is a word");
struct.add(new DWordDataType(), "myDWord", "this is a dword");
@ -138,14 +140,16 @@ public class DataTypeWriterTest extends AbstractGTest {
struct.add(new DoubleDataType(), "myDouble", "this is a double");
struct.add(PointerDataType.getPointer(new FloatDataType(), 4), "myFloatPointer",
"this is a float pointer");
struct.setFlexibleArrayComponent(new CharDataType(), "myFlexArray", "this is a flex array");
dtWriter.write(struct, TaskMonitorAdapter.DUMMY_MONITOR);
struct.add(new ArrayDataType(CharDataType.dataType, 0, -1), 0, "myFlexArray",
"this is a flex array");
dtWriter.write(struct, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
String expected = "typedef struct MyStruct MyStruct, *PMyStruct;" + EOL + EOL +
"typedef unsigned char byte;" + EOL + "typedef unsigned short word;" + EOL +
"typedef unsigned int dword;" + EOL + "typedef unsigned long long qword;" + EOL +
"struct MyStruct { /* this is my structure */" + EOL +
" char myChar; /* this is a character */" + EOL +
" char myCharArray[5]; /* this is a character array */" + EOL +
" byte myByte; /* this is a byte */" + EOL +
" word myWord; /* this is a word */" + EOL +
" dword myDWord; /* this is a dword */" + EOL +
@ -153,7 +157,7 @@ public class DataTypeWriterTest extends AbstractGTest {
" float myFloat; /* this is a float */" + EOL +
" double myDouble; /* this is a double */" + EOL +
" float * myFloatPointer; /* this is a float pointer */" + EOL +
" char[0] myFlexArray; /* this is a flex array */" + EOL + "};" + EOL + EOL;
" char myFlexArray[0]; /* this is a flex array */" + EOL + "};" + EOL + EOL;
assertEquals(expected, actual);
}
@ -168,15 +172,15 @@ public class DataTypeWriterTest extends AbstractGTest {
struct.add(new FloatDataType());
struct.add(new DoubleDataType());
struct.add(PointerDataType.getPointer(new FloatDataType(), 4));
dtWriter.write(struct, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(struct, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
String expected = "typedef struct MyBasicStruct MyBasicStruct, *PMyBasicStruct;" + EOL +
EOL + "typedef unsigned char byte;" + EOL + "typedef unsigned short word;" + EOL +
"typedef unsigned int dword;" + EOL + "typedef unsigned long long qword;" + EOL +
"struct MyBasicStruct {" + EOL + " char field_0x0;" + EOL + " byte field_0x1;" +
EOL + " word field_0x2;" + EOL + " dword field_0x4;" + EOL +
" qword field_0x8;" + EOL + " float field_0x10;" + EOL +
" double field_0x14;" + EOL + " float * field_0x1c;" + EOL + "};" + EOL + EOL;
"struct MyBasicStruct {" + EOL + " char field0_0x0;" + EOL + " byte field1_0x1;" +
EOL + " word field2_0x2;" + EOL + " dword field3_0x4;" + EOL +
" qword field4_0x8;" + EOL + " float field5_0x10;" + EOL +
" double field6_0x14;" + EOL + " float * field7_0x1c;" + EOL + "};" + EOL + EOL;
assertEquals(expected, actual);
}
@ -196,7 +200,7 @@ public class DataTypeWriterTest extends AbstractGTest {
"this is a outer inner structure");
outerStructure.add(new CharDataType(), "myOuterChar", "this is a outer character");
dtWriter.write(outerStructure, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(outerStructure, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
@ -230,7 +234,7 @@ public class DataTypeWriterTest extends AbstractGTest {
outerUnion.add(innerStructure, "myOuterInnerStructure", "this is a outer inner structure");
outerUnion.add(new CharDataType(), "myOuterChar", "this is a outer character");
dtWriter.write(outerUnion, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(outerUnion, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
@ -256,12 +260,12 @@ public class DataTypeWriterTest extends AbstractGTest {
struct.add(PointerDataType.getPointer(struct, 4));
struct.add(new DoubleDataType());
dtWriter.write(struct, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(struct, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
String expected = "typedef struct MySelfRefStruct MySelfRefStruct, *PMySelfRefStruct;" +
EOL + EOL + "typedef unsigned short word;" + EOL + "struct MySelfRefStruct {" + EOL +
" word field_0x0;" + EOL + " struct MySelfRefStruct * field_0x2;" + EOL +
" double field_0x6;" + EOL + "};" + EOL + EOL;
" word field0_0x0;" + EOL + " struct MySelfRefStruct * field1_0x2;" + EOL +
" double field2_0x6;" + EOL + "};" + EOL + EOL;
assertEquals(expected, actual);
}
@ -279,7 +283,7 @@ public class DataTypeWriterTest extends AbstractGTest {
union.add(new DoubleDataType(), "myDouble", "this is a double");
union.add(PointerDataType.getPointer(new FloatDataType(), 4), "myFloatPointer",
"this is a float pointer");
dtWriter.write(union, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(union, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
String expected = "typedef union MyUnion MyUnion, *PMyUnion;" + EOL + EOL +
"typedef unsigned char byte;" + EOL + "typedef unsigned short word;" + EOL +
@ -312,7 +316,7 @@ public class DataTypeWriterTest extends AbstractGTest {
outerUnion.add(innerUnion, "myOuterInnerUnion", "this is a outer inner union");
outerUnion.add(new CharDataType(), "myOuterChar", "this is a outer character");
dtWriter.write(outerUnion, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(outerUnion, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
@ -346,7 +350,7 @@ public class DataTypeWriterTest extends AbstractGTest {
outerStructure.add(innerUnion, "myOuterInnerUnion", "this is a outer inner union");
outerStructure.add(new CharDataType(), "myOuterChar", "this is a outer character");
dtWriter.write(outerStructure, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(outerStructure, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
@ -380,7 +384,7 @@ public class DataTypeWriterTest extends AbstractGTest {
struct.add(PointerDataType.getPointer(new FloatDataType(), 4), "myFloatPointer",
"this is my float pointer");
dtWriter.write(struct, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(struct, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
@ -408,7 +412,7 @@ public class DataTypeWriterTest extends AbstractGTest {
struct.add(PointerDataType.getPointer(new FloatDataType(), 4), "myFloatPointer",
"this is my float pointer");
dtWriter.write(struct, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(struct, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
@ -436,7 +440,7 @@ public class DataTypeWriterTest extends AbstractGTest {
union.add(PointerDataType.getPointer(new FloatDataType(), 4), "myFloatPointer",
"this is my float pointer");
dtWriter.write(union, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(union, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
@ -458,7 +462,7 @@ public class DataTypeWriterTest extends AbstractGTest {
union.add(PointerDataType.getPointer(union, 4));
union.add(new DoubleDataType());
dtWriter.write(union, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(union, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
String expected = "typedef union MySelfRefUnion MySelfRefUnion, *PMySelfRefUnion;" + EOL +
EOL + "typedef unsigned short word;" + EOL + "union MySelfRefUnion {" + EOL +
@ -474,20 +478,20 @@ public class DataTypeWriterTest extends AbstractGTest {
// Only base type is written-out - not pointer
Pointer ptr = PointerDataType.getPointer(null, null);
dtWriter.write(ptr, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(ptr, TaskMonitor.DUMMY);
String actual = writer.getBuffer().toString();
String expected = "";
assertEquals(expected, actual);
ptr = PointerDataType.getPointer(DataType.DEFAULT, null);
dtWriter.write(ptr, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(ptr, TaskMonitor.DUMMY);
actual = writer.getBuffer().toString();
expected += "typedef unsigned char undefined;" + EOL + EOL;
assertEquals(expected, actual);
TypeDef typedef = new TypedefDataType("BOB", new CharDataType());
ptr = PointerDataType.getPointer(typedef, null);
dtWriter.write(ptr, TaskMonitorAdapter.DUMMY_MONITOR);
dtWriter.write(ptr, TaskMonitor.DUMMY);
actual = writer.getBuffer().toString();
expected += "typedef char BOB;" + EOL + EOL;
assertEquals(expected, actual);