GT-3530 corrected some regression issues with char formatting

This commit is contained in:
ghidra1 2020-02-06 18:35:17 -05:00
parent 0f335d0250
commit d1d5f9ea16
6 changed files with 53 additions and 36 deletions

View file

@ -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);
}
/**

View file

@ -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);

View file

@ -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'.
*
@ -83,7 +86,7 @@ public class StringDataInstance {
return dt instanceof AbstractStringDataType || (dt instanceof Array &&
ArrayStringable.getArrayStringable(((Array) dt).getDataType()) != null);
}
/**
* Returns true if the {@link Data} instance is one of the many 'char' data types.
*
@ -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();
}