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
|
@ -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'.
|
||||
*
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue