mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
GT-3530 corrected some regression issues with char formatting
This commit is contained in:
parent
0f335d0250
commit
d1d5f9ea16
6 changed files with 53 additions and 36 deletions
|
@ -48,8 +48,6 @@ public class ConvertToCharAction extends AbstractConvertAction {
|
|||
@Override
|
||||
protected String convertToString(Program program, Scalar scalar, boolean isData) {
|
||||
byte[] bytes = scalar.byteArrayValue();
|
||||
|
||||
return StringDataInstance.getCharRepresentation(ByteDataType.dataType, bytes, null,
|
||||
program.getMemory().isBigEndian());
|
||||
return StringDataInstance.getCharRepresentation(ByteDataType.dataType, bytes, null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -818,7 +818,7 @@ public class DataAction4Test extends AbstractDataActionTest {
|
|||
|
||||
d = getContextData();
|
||||
assertEquals("ChooseFontW\0\u0015\0ReplaceTextW\0\0\u0004", d.getValue());
|
||||
assertEquals("\"ChooseFontW\\0\",15,\"\\0ReplaceTextW\\0\\0\",04",
|
||||
assertEquals("\"ChooseFontW\\0\",15h,\"\\0ReplaceTextW\\0\\0\",04h",
|
||||
d.getDefaultValueRepresentation());
|
||||
|
||||
}
|
||||
|
@ -851,7 +851,7 @@ public class DataAction4Test extends AbstractDataActionTest {
|
|||
assertEquals("\"ChooseFontW\"", d.getDefaultValueRepresentation());
|
||||
|
||||
d = checkNextData(dit, TerminatedStringDataType.class, 0x01006a0e, 2);
|
||||
assertEquals("15", d.getDefaultValueRepresentation());
|
||||
assertEquals("15h", d.getDefaultValueRepresentation());
|
||||
|
||||
d = checkNextData(dit, TerminatedStringDataType.class, 0x01006a10, 13);
|
||||
assertEquals("ReplaceTextW", d.getValue());
|
||||
|
@ -862,7 +862,7 @@ public class DataAction4Test extends AbstractDataActionTest {
|
|||
assertEquals("\"\"", d.getDefaultValueRepresentation());
|
||||
|
||||
d = checkNextData(dit, TerminatedStringDataType.class, 0x01006a1e, 2);
|
||||
assertEquals("04", d.getDefaultValueRepresentation());
|
||||
assertEquals("04h", d.getDefaultValueRepresentation());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -890,7 +890,7 @@ public class DataAction4Test extends AbstractDataActionTest {
|
|||
checkOnDefined(null, UnicodeDataType.class);
|
||||
|
||||
d = getContextData();
|
||||
assertEquals("01,00,\"\\0Sample\"", d.getDefaultValueRepresentation());
|
||||
assertEquals("01h,00h,\"\\0Sample\"", d.getDefaultValueRepresentation());
|
||||
assertEquals("\1\0Sample", d.getValue());
|
||||
|
||||
}
|
||||
|
@ -925,7 +925,7 @@ public class DataAction4Test extends AbstractDataActionTest {
|
|||
// check for wchar16[2] garbage string
|
||||
d = checkNextData(dit, TerminatedUnicodeDataType.class, 0x01008014, 4);
|
||||
assertEquals(d.getLength(), 4);
|
||||
assertEquals("01,00", d.getDefaultValueRepresentation());
|
||||
assertEquals("01h,00h", d.getDefaultValueRepresentation());
|
||||
assertEquals("\1", d.getValue());
|
||||
|
||||
// check for "Sample" string
|
||||
|
|
|
@ -1175,7 +1175,7 @@ public class EquatePlugin1Test extends AbstractEquatePluginTest {
|
|||
performAction("Convert To Char");
|
||||
|
||||
ListingTextField tf = (ListingTextField) cb.getCurrentField();
|
||||
assertEquals("'\\x02'", tf.getFieldElement(0, 11).getText());
|
||||
assertEquals("02h", tf.getFieldElement(0, 11).getText());
|
||||
|
||||
undo(program);
|
||||
tf = (ListingTextField) cb.getCurrentField();
|
||||
|
@ -1184,7 +1184,7 @@ public class EquatePlugin1Test extends AbstractEquatePluginTest {
|
|||
|
||||
redo(program);
|
||||
tf = (ListingTextField) cb.getCurrentField();
|
||||
assertEquals("'\\x02'", tf.getFieldElement(0, 11).getText());
|
||||
assertEquals("02h", tf.getFieldElement(0, 11).getText());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -173,14 +173,8 @@ public abstract class AbstractIntegerDataType extends BuiltIn implements ArraySt
|
|||
return null;
|
||||
}
|
||||
|
||||
boolean isBigEndian = ENDIAN.isBigEndian(settings, buf);
|
||||
|
||||
if (!isBigEndian) {
|
||||
byte[] flipped = new byte[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
flipped[i] = bytes[size - i - 1];
|
||||
}
|
||||
bytes = flipped;
|
||||
if (!ENDIAN.isBigEndian(settings, buf)) {
|
||||
bytes = ArrayUtilities.reverse(bytes);
|
||||
}
|
||||
|
||||
if (size > 8) {
|
||||
|
@ -225,16 +219,17 @@ public abstract class AbstractIntegerDataType extends BuiltIn implements ArraySt
|
|||
return "??";
|
||||
}
|
||||
|
||||
boolean isLE = !ENDIAN.isBigEndian(settings, buf);
|
||||
if (isLE) {
|
||||
if (!ENDIAN.isBigEndian(settings, buf)) {
|
||||
bytes = ArrayUtilities.reverse(bytes);
|
||||
}
|
||||
|
||||
BigInteger value = new BigInteger(bytes);
|
||||
|
||||
if (getFormatSettingsDefinition().getFormat(settings) == FormatSettingsDefinition.CHAR) {
|
||||
return StringDataInstance.getCharRepresentation(this, bytes, settings, !isLE);
|
||||
return StringDataInstance.getCharRepresentation(this, bytes, settings);
|
||||
}
|
||||
|
||||
return getRepresentation(new BigInteger(bytes), settings, 8 * length);
|
||||
return getRepresentation(value, settings, 8 * length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -366,11 +366,21 @@ public class BitFieldDataType extends AbstractDataType {
|
|||
return big;
|
||||
}
|
||||
|
||||
public BigInteger getBigIntegerValue(MemBuffer buf, Settings settings) {
|
||||
private BigInteger getBigIntegerValue(MemBuffer buf, Settings settings) {
|
||||
if (effectiveBitSize == 0) {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
try {
|
||||
|
||||
byte[] bytes = new byte[storageSize];
|
||||
if (buf.getBytes(bytes, 0) != storageSize) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!EndianSettingsDefinition.ENDIAN.isBigEndian(settings, buf)) {
|
||||
bytes = ArrayUtilities.reverse(bytes);
|
||||
}
|
||||
|
||||
BigInteger big = buf.getBigInteger(0, storageSize, false);
|
||||
BigInteger pow = BigInteger.valueOf(2).pow(effectiveBitSize);
|
||||
BigInteger mask = pow.subtract(BigInteger.ONE);
|
||||
|
@ -415,12 +425,8 @@ public class BitFieldDataType extends AbstractDataType {
|
|||
}
|
||||
int bytesLen = BitFieldDataType.getMinimumStorageSize(bitSize);
|
||||
byte[] bytes = DataConverter.getInstance(buf.isBigEndian()).getBytes(big, bytesLen);
|
||||
if (!EndianSettingsDefinition.ENDIAN.isBigEndian(settings, buf)) {
|
||||
bytes = ArrayUtilities.reverse(bytes);
|
||||
}
|
||||
|
||||
return StringDataInstance.getCharRepresentation(this, bytes, settings,
|
||||
buf.isBigEndian());
|
||||
return StringDataInstance.getCharRepresentation(this, bytes, settings);
|
||||
}
|
||||
|
||||
return intDT.getRepresentation(big, settings, effectiveBitSize);
|
||||
|
|
|
@ -44,6 +44,9 @@ import ghidra.util.*;
|
|||
* <p>
|
||||
*/
|
||||
public class StringDataInstance {
|
||||
|
||||
private static final int ASCII_MAX = 0x7f;
|
||||
|
||||
/**
|
||||
* Returns true if the {@link Data} instance is a 'string'.
|
||||
*
|
||||
|
@ -105,16 +108,31 @@ public class StringDataInstance {
|
|||
* <p>
|
||||
*
|
||||
* @param dataType the {@link DataType} of the element containing the bytes (most likely a ByteDataType)
|
||||
* @param bytes the bytes to convert
|
||||
* @param bytes the big-endian ordered bytes to convert to a char representation
|
||||
* @param settings the {@link Settings} object for the location where the bytes came from, or null
|
||||
* @param isBigEndian boolean flag indicating data is big endian
|
||||
* @return formatted string (typically with quotes around the contents): single character: 'a', multiple characters: "a\x12bc"
|
||||
*/
|
||||
public static String getCharRepresentation(DataType dataType, byte[] bytes, Settings settings,
|
||||
boolean isBigEndian) {
|
||||
MemBuffer memBuf = new ByteMemBufferImpl(null, bytes, isBigEndian);
|
||||
StringDataInstance sdi =
|
||||
new StringDataInstance(dataType, settings, memBuf, bytes.length);
|
||||
public static String getCharRepresentation(DataType dataType, byte[] bytes, Settings settings) {
|
||||
if (bytes == null || bytes.length == 0) {
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
// ignore leading 0 bytes
|
||||
int lsbIndex = bytes.length - 1;
|
||||
if (bytes[lsbIndex] >= 0 && bytes[lsbIndex] <= 0x7f) {
|
||||
boolean isAsciiChar = true;
|
||||
for (int i = 0; i < lsbIndex; i++) {
|
||||
if (bytes[i] != 0) {
|
||||
isAsciiChar = false;
|
||||
}
|
||||
}
|
||||
if (isAsciiChar) {
|
||||
bytes = new byte[] { bytes[lsbIndex] };
|
||||
}
|
||||
}
|
||||
|
||||
MemBuffer memBuf = new ByteMemBufferImpl(null, bytes, true);
|
||||
StringDataInstance sdi = new StringDataInstance(dataType, settings, memBuf, bytes.length);
|
||||
return sdi.getCharRepresentation();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue