diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/coff/CoffArchiveFileSystemFactory.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/coff/CoffArchiveFileSystemFactory.java index 8b501333db..fed0fa7a7e 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/coff/CoffArchiveFileSystemFactory.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/coff/CoffArchiveFileSystemFactory.java @@ -15,6 +15,8 @@ */ package ghidra.file.formats.coff; +import java.util.Arrays; + import java.io.IOException; import ghidra.app.util.bin.ByteProvider; @@ -24,7 +26,6 @@ import ghidra.formats.gfilesystem.factory.GFileSystemFactoryByteProvider; import ghidra.formats.gfilesystem.factory.GFileSystemProbeBytesOnly; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -import utilities.util.ArrayUtilities; public class CoffArchiveFileSystemFactory implements GFileSystemFactoryByteProvider, GFileSystemProbeBytesOnly { @@ -48,7 +49,8 @@ public class CoffArchiveFileSystemFactory implements @Override public boolean probeStartBytes(FSRL containerFSRL, byte[] startBytes) { - return ArrayUtilities.arrayRangesEquals(CoffArchiveConstants.MAGIC_BYTES, 0, startBytes, 0, - CoffArchiveConstants.MAGIC_BYTES.length); + return Arrays.equals( + CoffArchiveConstants.MAGIC_BYTES, 0, CoffArchiveConstants.MAGIC_BYTES.length, + startBytes, 0, CoffArchiveConstants.MAGIC_BYTES.length); } } diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/apple8900/Apple8900Header.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/apple8900/Apple8900Header.java index 175c7bede6..1cdbc77801 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/apple8900/Apple8900Header.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/apple8900/Apple8900Header.java @@ -20,13 +20,12 @@ import java.io.IOException; import ghidra.app.util.bin.*; import ghidra.program.model.data.*; import ghidra.util.exception.DuplicateNameException; -import utilities.util.ArrayUtilities; public class Apple8900Header implements StructConverter { - private byte[] magic; - private byte[] version; - private byte encrypted; + private byte[] magic; // "8900" + private byte[] version; // "1.0" + private byte encrypted; // format, plaintext=0x4, encrypted=0x3 private byte[] unknown0; private int sizeOfData; private int footerSignatureOffset; @@ -61,7 +60,7 @@ public class Apple8900Header implements StructConverter { } public String getVersion() { - return new String(ArrayUtilities.reverse(version)); + return new String(version); } public boolean isEncrypted() { diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/dmg/DmgClientFileSystemFactory.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/dmg/DmgClientFileSystemFactory.java index 920674dd0a..baacafefe0 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/dmg/DmgClientFileSystemFactory.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/dmg/DmgClientFileSystemFactory.java @@ -15,6 +15,8 @@ */ package ghidra.file.formats.ios.dmg; +import java.util.Arrays; + import java.io.File; import java.io.IOException; @@ -29,7 +31,6 @@ import ghidra.util.Msg; import ghidra.util.exception.CancelledException; import ghidra.util.exception.CryptoException; import ghidra.util.task.TaskMonitor; -import utilities.util.ArrayUtilities; /** * Handles probing for and creating {@link DmgClientFileSystem} instances. @@ -58,10 +59,10 @@ public class DmgClientFileSystemFactory implements } private static boolean isEncrypted(byte[] startBytes) { - return ArrayUtilities.arrayRangesEquals(startBytes, 0, DmgConstants.DMG_MAGIC_BYTES_v1, 0, - DmgConstants.DMG_MAGIC_BYTES_v1.length) || - ArrayUtilities.arrayRangesEquals(startBytes, 0, DmgConstants.DMG_MAGIC_BYTES_v2, 0, - DmgConstants.DMG_MAGIC_BYTES_v2.length); + return Arrays.equals(startBytes, 0, DmgConstants.DMG_MAGIC_BYTES_v1.length, + DmgConstants.DMG_MAGIC_BYTES_v1, 0, DmgConstants.DMG_MAGIC_BYTES_v1.length) || + Arrays.equals(startBytes, 0, DmgConstants.DMG_MAGIC_BYTES_v2.length, + DmgConstants.DMG_MAGIC_BYTES_v2, 0, DmgConstants.DMG_MAGIC_BYTES_v2.length); } private static boolean isEncrypted(ByteProvider bp) { diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/img2/Img2FileSystemFactory.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/img2/Img2FileSystemFactory.java index 07379e32b1..108d31fad4 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/img2/Img2FileSystemFactory.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/img2/Img2FileSystemFactory.java @@ -15,6 +15,8 @@ */ package ghidra.file.formats.ios.img2; +import java.util.Arrays; + import java.io.IOException; import ghidra.app.util.bin.ByteProvider; @@ -23,7 +25,6 @@ import ghidra.formats.gfilesystem.factory.GFileSystemFactoryByteProvider; import ghidra.formats.gfilesystem.factory.GFileSystemProbeBytesOnly; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -import utilities.util.ArrayUtilities; public class Img2FileSystemFactory implements GFileSystemFactoryByteProvider, GFileSystemProbeBytesOnly { @@ -34,8 +35,8 @@ public class Img2FileSystemFactory implements GFileSystemFactoryByteProvider, GFileSystemProbeBytesOnly { @Override public int getBytesRequired() { - return Img3Constants.IMG3_SIGNATURE_LENGTH; + return Img3Constants.IMG3_SIGNATURE_BYTES.length; } @Override public boolean probeStartBytes(FSRL containerFSRL, byte[] startBytes) { - return ArrayUtilities.arrayRangesEquals(startBytes, 0, Img3Constants.IMG3_SIGNATURE_BYTES, - 0, Img3Constants.IMG3_SIGNATURE_LENGTH); + return Arrays.equals(startBytes, 0, Img3Constants.IMG3_SIGNATURE_BYTES.length, + Img3Constants.IMG3_SIGNATURE_BYTES, 0, Img3Constants.IMG3_SIGNATURE_BYTES.length); } @Override diff --git a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/java/JavaClassDecompilerFileSystemFactory.java b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/java/JavaClassDecompilerFileSystemFactory.java index 81c0f955ca..65ccf6f3db 100644 --- a/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/java/JavaClassDecompilerFileSystemFactory.java +++ b/Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/java/JavaClassDecompilerFileSystemFactory.java @@ -15,6 +15,8 @@ */ package ghidra.file.formats.java; +import java.util.Arrays; + import java.io.IOException; import org.apache.commons.io.FilenameUtils; @@ -26,7 +28,6 @@ import ghidra.formats.gfilesystem.factory.GFileSystemFactoryByteProvider; import ghidra.formats.gfilesystem.factory.GFileSystemProbeBytesOnly; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; -import utilities.util.ArrayUtilities; /** * Creates instances of {@link JavaClassDecompilerFileSystem}. @@ -42,8 +43,8 @@ public class JavaClassDecompilerFileSystemFactory implements @Override public boolean probeStartBytes(FSRL containerFSRL, byte[] startBytes) { return JadProcessWrapper.isJadPresent() && - ArrayUtilities.arrayRangesEquals(startBytes, 0, JavaClassConstants.MAGIC_BYTES, 0, - JavaClassConstants.MAGIC_BYTES.length) && + Arrays.equals(startBytes, 0, JavaClassConstants.MAGIC_BYTES.length, + JavaClassConstants.MAGIC_BYTES, 0, JavaClassConstants.MAGIC_BYTES.length) && "class".equalsIgnoreCase(FilenameUtils.getExtension(containerFSRL.getName())); } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/RowObjectSelectionManager.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/RowObjectSelectionManager.java index 573bbf3346..07d1204cb7 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/RowObjectSelectionManager.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/table/RowObjectSelectionManager.java @@ -15,10 +15,11 @@ */ package docking.widgets.table; +import java.util.*; + import java.awt.Rectangle; import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.util.*; import javax.swing.*; import javax.swing.event.*; @@ -30,7 +31,6 @@ import org.apache.logging.log4j.Logger; import ghidra.util.Msg; import ghidra.util.datastruct.WeakDataStructureFactory; import ghidra.util.datastruct.WeakSet; -import utilities.util.ArrayUtilities; import utilities.util.reflection.ReflectionUtilities; /** @@ -405,7 +405,7 @@ public class RowObjectSelectionManager extends DefaultListSelectionModel private boolean restoreSelectedRows(int[] rows) { traceRows("restoreSelectedRows(): ", rows); - if (ArrayUtilities.isArrayPrimativeEqual(rows, table.getSelectedRows())) { + if (Arrays.equals(rows, table.getSelectedRows())) { trace("\tselection hasn't changed--nothing to do"); // the selection is the same, nothing to change; don't send out excess events return false; diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractIntegerDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractIntegerDataType.java index 1d2c24624f..0e5d906ed6 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractIntegerDataType.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/AbstractIntegerDataType.java @@ -24,8 +24,8 @@ import ghidra.pcode.utils.Utils; import ghidra.program.model.data.StringRenderParser.StringParseException; import ghidra.program.model.mem.MemBuffer; import ghidra.program.model.scalar.Scalar; +import ghidra.util.DataConverter; import ghidra.util.StringFormat; -import utilities.util.ArrayUtilities; /** * Base type for integer data types such as {@link CharDataType chars}, {@link IntegerDataType @@ -166,25 +166,14 @@ public abstract class AbstractIntegerDataType extends BuiltIn implements ArraySt return null; } - if (!ENDIAN.isBigEndian(settings, buf)) { - bytes = ArrayUtilities.reverse(bytes); - } + DataConverter dc = DataConverter.getInstance(ENDIAN.isBigEndian(settings, buf)); if (size > 8) { - if (!isSigned()) { - // ensure that bytes are treated as unsigned - byte[] unsignedBytes = new byte[bytes.length + 1]; - System.arraycopy(bytes, 0, unsignedBytes, 1, bytes.length); - bytes = unsignedBytes; - } - return new BigInteger(bytes); + return dc.getBigInteger(bytes, size, isSigned()); } // Use long when possible - long val = 0; - for (byte b : bytes) { - val = (val << 8) + (b & 0x0ffL); - } + long val = dc.getValue(bytes, size); return new Scalar(size * 8, val, isSigned()); } @@ -294,11 +283,8 @@ public abstract class AbstractIntegerDataType extends BuiltIn implements ArraySt return "??"; } - if (!ENDIAN.isBigEndian(settings, buf)) { - bytes = ArrayUtilities.reverse(bytes); - } - - BigInteger value = new BigInteger(bytes); + BigInteger value = DataConverter.getInstance(ENDIAN.isBigEndian(settings, buf)) + .getBigInteger(bytes, size, true); if (getFormatSettingsDefinition().getFormat(settings) == FormatSettingsDefinition.CHAR) { return StringDataInstance.getCharRepresentation(this, bytes, settings); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/BitFieldDataType.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/BitFieldDataType.java index e51393f681..ebfbbe168f 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/BitFieldDataType.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/BitFieldDataType.java @@ -15,6 +15,8 @@ */ package ghidra.program.model.data; +import java.util.*; + import java.math.BigInteger; import ghidra.docking.settings.*; @@ -22,7 +24,6 @@ import ghidra.program.model.mem.MemBuffer; import ghidra.program.model.scalar.Scalar; import ghidra.util.DataConverter; import ghidra.util.exception.AssertException; -import utilities.util.ArrayUtilities; /** * BitFieldDataType provides a means of defining a minimally sized bit-field @@ -251,7 +252,11 @@ public class BitFieldDataType extends AbstractDataType { */ @Override public final SettingsDefinition[] getSettingsDefinitions() { - return baseDataType.getSettingsDefinitions(); + // exclude any ENDIAN setting that the base data type might support + List baseDTSettings = + new ArrayList<>(Arrays.asList(baseDataType.getSettingsDefinitions())); + baseDTSettings.remove(EndianSettingsDefinition.DEF); + return baseDTSettings.toArray(SettingsDefinition[]::new); } @Override @@ -369,16 +374,6 @@ public class BitFieldDataType extends AbstractDataType { 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); diff --git a/Ghidra/Framework/Utility/src/main/java/utilities/util/ArrayUtilities.java b/Ghidra/Framework/Utility/src/main/java/utilities/util/ArrayUtilities.java deleted file mode 100644 index 0dff55192a..0000000000 --- a/Ghidra/Framework/Utility/src/main/java/utilities/util/ArrayUtilities.java +++ /dev/null @@ -1,146 +0,0 @@ -/* ### - * IP: GHIDRA - * - * 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. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package utilities.util; - -import java.lang.reflect.Array; -import java.util.Arrays; - -import ghidra.util.SystemUtilities; - -public final class ArrayUtilities { - - /** - * Returns a new copy of the specified byte {@code array} with the elements in reversed order. - * - * @param array byte array to reverse - * @return new array instance with elements in reverse order - */ - public static byte[] reverse(byte[] array) { - - byte[] reversed = new byte[array.length]; - - for (int i = 0; i < reversed.length; i++) { - reversed[i] = array[array.length - 1 - i]; - } - return reversed; - } - - /** - * Compares two primitive arrays for equality - * - * @param o1 the first array - * @param o2 the second array - * @return true if each element of the array is equal - * @throws IllegalArgumentException if either argument is not an array - */ - public static boolean isArrayPrimativeEqual(Object o1, Object o2) { - if (o1 == null) { - return (o2 == null); - } - - if (o2 == null) { - return false; - } - - Class class1 = o1.getClass(); - if (!class1.isArray()) { - throw new IllegalArgumentException( - "Object parameters must be an array! Instead found class: " + class1); - } - - Class class2 = o2.getClass(); - if (!class2.isArray()) { - throw new IllegalArgumentException( - "Object parameters must be an array! Instead found class: " + class2); - } - - if (Array.getLength(o1) != Array.getLength(o2)) { - return false; - } - - for (int i = 0; i < Array.getLength(o1); i++) { - if (!SystemUtilities.isEqual(Array.get(o1, i), Array.get(o2, i))) { - return false; - } - } - return true; - } - - /** - * Returns true if a portion of byte array b1 equals an equally sized portion of byte array - * b2. - *

- * If the sizes of b1 or b2 do not allow for a full comparison of {@code len} bytes, this - * function will return false. - *

- * @param b1 first byte array - * @param start_b1 offset to start comparison in b1 - * @param b2 second byte array - * @param start_b2 offset to start comparison in b2 - * @param len number of bytes to compare - * @return true or false if the portion is equal - */ - public static boolean arrayRangesEquals(byte[] b1, int start_b1, byte[] b2, int start_b2, - int len) { - if (start_b1 + len > b1.length || start_b2 + len > b2.length) { - return false; - } - for (int i = 0; i < len; i++) { - if (b1[start_b1 + i] != b2[start_b2 + i]) { - return false; - } - } - return true; - } - - /** - * Returns a copy of the given array with the provided element appended. The length of - * the returned array will be one element greater than the given array. - * - * @param array The array to copy. - * @param element The element to append to the copy. - * @return A copy of the given array with the provided element appended. - */ - public static T[] copyAndAppend(T[] array, T element) { - T[] newArray = Arrays.copyOf(array, array.length + 1); - newArray[array.length] = element; - return newArray; - } - - /** - * Compare two byte arrays by their corresponding entries - * - * If the two arrays have differing lengths, the shorter precedes the longer. Otherwise, they - * are compared as in C's {@code memcmp}, except that Java {@code byte}s are signed. - * @param a the first array - * @param b the second array - * @return a comparison result as in {@link Comparable#compareTo(Object)} - */ - public static int compare(byte[] a, byte[] b) { - int result; - result = a.length - b.length; - if (result != 0) { - return result; - } - for (int i = 0; i < a.length; i++) { - result = a[i] - b[i]; - if (result != 0) { - return result; - } - } - return 0; - } -}