mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GP-4847: Unify Debugger param dialogs. Prefixed integers allowed.
This commit is contained in:
@@ -33,6 +33,8 @@ public final class NumericUtilities {
|
||||
|
||||
private final static String HEX_PREFIX_X = "0X";
|
||||
private final static String HEX_PREFIX_x = "0x";
|
||||
private final static String BIN_PREFIX = "0B";
|
||||
private final static String OCT_PREFIX = "0";
|
||||
|
||||
private final static Set<Class<? extends Number>> INTEGER_TYPES = new HashSet<>();
|
||||
static {
|
||||
@@ -235,6 +237,49 @@ public final class NumericUtilities {
|
||||
return new BigInteger(s, 16);
|
||||
}
|
||||
|
||||
private static BigInteger decodeMagnitude(int p, String s) {
|
||||
// Special case, so it doesn't get chewed by octal parser
|
||||
if ("0".equals(s)) {
|
||||
return BigInteger.ZERO;
|
||||
}
|
||||
if (s.regionMatches(true, p, HEX_PREFIX_X, 0, HEX_PREFIX_X.length())) {
|
||||
return new BigInteger(s.substring(p + HEX_PREFIX_X.length()), 16);
|
||||
}
|
||||
if (s.regionMatches(true, p, BIN_PREFIX, 0, BIN_PREFIX.length())) {
|
||||
return new BigInteger(s.substring(p + BIN_PREFIX.length()), 2);
|
||||
}
|
||||
// Check last, because prefix is shortest.
|
||||
if (s.regionMatches(true, p, OCT_PREFIX, 0, OCT_PREFIX.length())) {
|
||||
return new BigInteger(s.substring(p + OCT_PREFIX.length()), 8);
|
||||
}
|
||||
return new BigInteger(s.substring(p), 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a big integer in hex, binary, octal, or decimal, based on the prefix 0x, 0b, or 0.
|
||||
*
|
||||
* <p>
|
||||
* This checks for the presence of a case-insensitive prefix. 0x denotes hex, 0b denotes binary,
|
||||
* 0 denotes octal. If no prefix is given, decimal is assumed. A sign +/- may immediately
|
||||
* precede the prefix. If no sign is given, a positive value is assumed.
|
||||
*
|
||||
* @param s the string to parse
|
||||
* @return the decoded value
|
||||
*/
|
||||
public static BigInteger decodeBigInteger(String s) {
|
||||
int p = 0;
|
||||
boolean negative = false;
|
||||
if (s.startsWith("+")) {
|
||||
p = 1;
|
||||
}
|
||||
else if (s.startsWith("-")) {
|
||||
p = 1;
|
||||
negative = true;
|
||||
}
|
||||
BigInteger mag = decodeMagnitude(p, s);
|
||||
return negative ? mag.negate() : mag;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the value of the specified long as hexadecimal, prefixing with the
|
||||
* {@link #HEX_PREFIX_x} string.
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -18,6 +18,7 @@ package ghidra.util;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -332,4 +333,89 @@ public class NumericUtilitiesTest {
|
||||
assertEquals(errorMessage, expected[i], actual[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDecodeBigInteger() {
|
||||
// Zero special cases
|
||||
assertEquals(BigInteger.ZERO, NumericUtilities.decodeBigInteger("0"));
|
||||
assertEquals(BigInteger.ZERO, NumericUtilities.decodeBigInteger("000"));
|
||||
// Decimal
|
||||
assertEquals(BigInteger.valueOf(99), NumericUtilities.decodeBigInteger("99"));
|
||||
assertEquals(BigInteger.valueOf(99), NumericUtilities.decodeBigInteger("+99"));
|
||||
assertEquals(BigInteger.valueOf(-99), NumericUtilities.decodeBigInteger("-99"));
|
||||
// Hex
|
||||
assertEquals(BigInteger.valueOf(0x99), NumericUtilities.decodeBigInteger("0x99"));
|
||||
assertEquals(BigInteger.valueOf(0x99), NumericUtilities.decodeBigInteger("+0x99"));
|
||||
assertEquals(BigInteger.valueOf(-0x99), NumericUtilities.decodeBigInteger("-0x99"));
|
||||
// Binary
|
||||
assertEquals(BigInteger.valueOf(0b110), NumericUtilities.decodeBigInteger("0b110"));
|
||||
assertEquals(BigInteger.valueOf(0b110), NumericUtilities.decodeBigInteger("+0b110"));
|
||||
assertEquals(BigInteger.valueOf(-0b110), NumericUtilities.decodeBigInteger("-0b110"));
|
||||
// Octal
|
||||
assertEquals(BigInteger.valueOf(0755), NumericUtilities.decodeBigInteger("0755"));
|
||||
assertEquals(BigInteger.valueOf(0755), NumericUtilities.decodeBigInteger("+0755"));
|
||||
assertEquals(BigInteger.valueOf(-0755), NumericUtilities.decodeBigInteger("-0755"));
|
||||
|
||||
// Errors
|
||||
try {
|
||||
NumericUtilities.decodeBigInteger("");
|
||||
fail();
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
}
|
||||
try {
|
||||
NumericUtilities.decodeBigInteger("+");
|
||||
fail();
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
}
|
||||
try {
|
||||
NumericUtilities.decodeBigInteger("-");
|
||||
fail();
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
}
|
||||
try {
|
||||
NumericUtilities.decodeBigInteger("0x");
|
||||
fail();
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
}
|
||||
try {
|
||||
NumericUtilities.decodeBigInteger("0b");
|
||||
fail();
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
}
|
||||
try {
|
||||
NumericUtilities.decodeBigInteger("a01");
|
||||
fail();
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
}
|
||||
try {
|
||||
NumericUtilities.decodeBigInteger("081");
|
||||
fail();
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
}
|
||||
try {
|
||||
NumericUtilities.decodeBigInteger("0x9g");
|
||||
fail();
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
}
|
||||
try {
|
||||
NumericUtilities.decodeBigInteger(" 10");
|
||||
fail();
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
}
|
||||
try {
|
||||
NumericUtilities.decodeBigInteger("10 ");
|
||||
fail();
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user