diff --git a/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/remote/GhidraObjectInputFilter.java b/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/remote/GhidraObjectInputFilter.java index 7221945645..9f708d1864 100644 --- a/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/remote/GhidraObjectInputFilter.java +++ b/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/remote/GhidraObjectInputFilter.java @@ -28,6 +28,7 @@ import org.apache.logging.log4j.Logger; import generic.jar.ResourceFile; import ghidra.framework.Application; +import ghidra.util.Msg; /** * {@link GhidraObjectInputFilter} provides global serial input filter for use with Ghidra server @@ -64,11 +65,24 @@ public class GhidraObjectInputFilter implements ObjectInputFilter { private static final String MAXDEPTH = "maxdepth"; private static final String MAXBYTES = "maxbytes"; + private static int getMaxArrayFromProperties() { + String limitStr = System.getProperty("ghidra.serial.array.limit", "200000"); + try { + return Integer.parseInt(limitStr); + } + catch (Exception e) { + Msg.error(GhidraObjectInputFilter.class, + "Could not parse ghidra.serial.array.limit: %s. A decimal integer is required" + .formatted(limitStr)); + } + return 200_000; + } + // NOTE: Be sure to update serialFilterREADME.md if values are updated. - private int MAXARRAY_DEFAULT = 200_000; - private int MAXREFS_DEFAULT = 10_000; - private int MAXDEPTH_DEFAULT = 50; - private int MAXBYTES_DEFAULT = 32 * 1024 * 1024; // 32MB + public static final int MAXARRAY_DEFAULT = getMaxArrayFromProperties(); + public static final int MAXREFS_DEFAULT = 10_000; + public static final int MAXDEPTH_DEFAULT = 50; + public static final int MAXBYTES_DEFAULT = 32 * 1024 * 1024; // 32MB private long maxArray; private long maxRefs; diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/util/ObjectStorageStreamAdapter.java b/Ghidra/Framework/Generic/src/main/java/ghidra/util/ObjectStorageStreamAdapter.java index 9010b861ae..9a8bc99093 100644 --- a/Ghidra/Framework/Generic/src/main/java/ghidra/util/ObjectStorageStreamAdapter.java +++ b/Ghidra/Framework/Generic/src/main/java/ghidra/util/ObjectStorageStreamAdapter.java @@ -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,376 +18,454 @@ package ghidra.util; import java.io.*; /** - * Implementation for ObjectStorage to save and restore Strings and - * Java primitives using an ObjectOutputStream and ObjectInputStream, - * respectively. + * Implementation for ObjectStorage to save and restore Strings and Java primitives using an + * ObjectOutputStream and ObjectInputStream, respectively. * * */ public class ObjectStorageStreamAdapter implements ObjectStorage { + + private static int getMaxArrayFromProperties() { + String limitStr = System.getProperty("ghidra.serial.array.limit", "200000"); + try { + return Integer.parseInt(limitStr); + } + catch (Exception e) { + Msg.error(ObjectStorageStreamAdapter.class, + "Could not parse ghidra.serial.array.limit: %s. A decimal integer is required" + .formatted(limitStr)); + } + return 200_000; + } + + public static final int MAXARRAY = getMaxArrayFromProperties(); + ObjectOutputStream out; ObjectInputStream in; - /** - * Constructor for ObjectStorageStreamAdapter. - * @param out output stream to write to - */ - public ObjectStorageStreamAdapter(ObjectOutputStream out) { - this.out = out; - } - /** - * Constructor for new ObjectStorageStreamAdapter - * @param in input stream to read from - */ - public ObjectStorageStreamAdapter(ObjectInputStream in) { - this.in = in; - } + + /** + * Constructor for ObjectStorageStreamAdapter. + * + * @param out output stream to write to + */ + public ObjectStorageStreamAdapter(ObjectOutputStream out) { + this.out = out; + } + + /** + * Constructor for new ObjectStorageStreamAdapter + * + * @param in input stream to read from + */ + public ObjectStorageStreamAdapter(ObjectInputStream in) { + this.in = in; + } @Override - public void putInt(int value) { - try { - out.writeInt(value); - } catch (IOException e) {} - } + public void putInt(int value) { + try { + out.writeInt(value); + } + catch (IOException e) { + } + } @Override - public void putByte(byte value) { - try { - out.writeByte(value); - } catch (IOException e) {} - } + public void putByte(byte value) { + try { + out.writeByte(value); + } + catch (IOException e) { + } + } @Override - public void putShort(short value) { - try { - out.writeShort(value); - } catch (IOException e) {} - } + public void putShort(short value) { + try { + out.writeShort(value); + } + catch (IOException e) { + } + } @Override - public void putLong(long value) { - try { - out.writeLong(value); - } catch (IOException e) {} - } + public void putLong(long value) { + try { + out.writeLong(value); + } + catch (IOException e) { + } + } @Override - public void putString(String value) { - try { - out.writeObject(value); - } catch (IOException e) {} - } + public void putString(String value) { + try { + out.writeObject(value); + } + catch (IOException e) { + } + } @Override - public void putBoolean(boolean value) { - try { - out.writeBoolean(value); - } catch (IOException e) {} - } + public void putBoolean(boolean value) { + try { + out.writeBoolean(value); + } + catch (IOException e) { + } + } @Override - public void putFloat(float value) { - try { - out.writeFloat(value); - } catch (IOException e) {} - } + public void putFloat(float value) { + try { + out.writeFloat(value); + } + catch (IOException e) { + } + } @Override - public void putDouble(double value) { - try { - out.writeDouble(value); - } catch (IOException e) {} - } + public void putDouble(double value) { + try { + out.writeDouble(value); + } + catch (IOException e) { + } + } @Override - public int getInt() { - try { - return in.readInt(); - } catch (IOException e) { - return 0; - } - } + public int getInt() { + try { + return in.readInt(); + } + catch (IOException e) { + return 0; + } + } @Override - public byte getByte() { - try { - return in.readByte(); - } catch (IOException e) { - return (byte)0; - } - } + public byte getByte() { + try { + return in.readByte(); + } + catch (IOException e) { + return (byte) 0; + } + } @Override - public short getShort() { - try { - return in.readShort(); - } catch (IOException e) { - return (short)0; - } - } + public short getShort() { + try { + return in.readShort(); + } + catch (IOException e) { + return (short) 0; + } + } @Override - public long getLong() { - try { - return in.readLong(); - } catch (IOException e) { - return 0; - } - } + public long getLong() { + try { + return in.readLong(); + } + catch (IOException e) { + return 0; + } + } @Override - public boolean getBoolean() { - try { - return in.readBoolean(); - } catch (IOException e) { - return false; - } - } + public boolean getBoolean() { + try { + return in.readBoolean(); + } + catch (IOException e) { + return false; + } + } @Override - public String getString() { - try { - return (String)in.readObject(); - }catch(Exception e) { - return null; - } - } + public String getString() { + try { + return (String) in.readObject(); + } + catch (Exception e) { + return null; + } + } @Override - public float getFloat() { - try { - return in.readFloat(); - } catch (IOException e) { - return 0; - } - } + public float getFloat() { + try { + return in.readFloat(); + } + catch (IOException e) { + return 0; + } + } @Override - public double getDouble() { - try { - return in.readDouble(); - } catch (IOException e) { - return 0.0; - } - } + public double getDouble() { + try { + return in.readDouble(); + } + catch (IOException e) { + return 0.0; + } + } + + protected void checkWriteArrayLength(int n) throws IOException { + if (n > MAXARRAY) { + throw new IOException("Array size %d exceeds max of %d".formatted(n, MAXARRAY)); + } + out.writeInt(n); + } @Override - public void putInts(int[] value) { - try { - if (value == null) { - out.writeInt(-1); - return; - } - out.writeInt(value.length); - for (int i = 0; i < value.length; i++) { - out.writeInt(value[i]); - } - } catch (IOException e) {} - } + public void putInts(int[] value) { + try { + if (value == null) { + out.writeInt(-1); + return; + } + checkWriteArrayLength(value.length); + for (int i = 0; i < value.length; i++) { + out.writeInt(value[i]); + } + } + catch (IOException e) { + } + } @Override - public void putBytes(byte[] value) { - try { - if (value == null) { - out.writeInt(-1); - return; - } - out.writeInt(value.length); - for (int i = 0; i < value.length; i++) { - out.writeByte(value[i]); - } - } catch (IOException e) {} - } + public void putBytes(byte[] value) { + try { + if (value == null) { + out.writeInt(-1); + return; + } + checkWriteArrayLength(value.length); + for (int i = 0; i < value.length; i++) { + out.writeByte(value[i]); + } + } + catch (IOException e) { + } + } @Override - public void putShorts(short[] value) { - try { - if (value == null) { - out.writeInt(-1); - return; - } - out.writeInt(value.length); - for (int i = 0; i < value.length; i++) { - out.writeShort(value[i]); - } - } catch (IOException e) {} + public void putShorts(short[] value) { + try { + if (value == null) { + out.writeInt(-1); + return; + } + checkWriteArrayLength(value.length); + for (int i = 0; i < value.length; i++) { + out.writeShort(value[i]); + } + } + catch (IOException e) { + } - } + } @Override - public void putLongs(long[] value) { - try { - if (value == null) { - out.writeInt(-1); - return; - } - out.writeInt(value.length); - for (int i = 0; i < value.length; i++) { - out.writeLong(value[i]); - } - } catch (IOException e) {} + public void putLongs(long[] value) { + try { + if (value == null) { + out.writeInt(-1); + return; + } + checkWriteArrayLength(value.length); + for (int i = 0; i < value.length; i++) { + out.writeLong(value[i]); + } + } + catch (IOException e) { + } - } + } @Override - public void putFloats(float[] value) { - try { - if (value == null) { - out.writeInt(-1); - return; - } - out.writeInt(value.length); - for (int i = 0; i < value.length; i++) { - out.writeFloat(value[i]); - } - } catch (IOException e) {} - - } + public void putFloats(float[] value) { + try { + if (value == null) { + out.writeInt(-1); + return; + } + checkWriteArrayLength(value.length); + for (int i = 0; i < value.length; i++) { + out.writeFloat(value[i]); + } + } + catch (IOException e) { + } + + } @Override - public void putDoubles(double[] value) { - try { - if (value == null) { - out.writeInt(-1); - return; - } - out.writeInt(value.length); - for (int i = 0; i < value.length; i++) { - out.writeDouble(value[i]); - } - } catch (IOException e) {} - } + public void putDoubles(double[] value) { + try { + if (value == null) { + out.writeInt(-1); + return; + } + checkWriteArrayLength(value.length); + for (int i = 0; i < value.length; i++) { + out.writeDouble(value[i]); + } + } + catch (IOException e) { + } + } @Override - public void putStrings(String[] value) { - try { - if (value == null) { - out.writeInt(-1); - return; - } - out.writeInt(value.length); - for (int i = 0; i < value.length; i++) { - out.writeObject(value[i]); - } - } catch (IOException e) {} - } + public void putStrings(String[] value) { + try { + if (value == null) { + out.writeInt(-1); + return; + } + checkWriteArrayLength(value.length); + for (int i = 0; i < value.length; i++) { + out.writeObject(value[i]); + } + } + catch (IOException e) { + } + } + + protected int checkReadArrayLength() throws IOException { + int n = in.readInt(); + if (n > MAXARRAY) { + throw new IOException("Array size %d exceeds max of %d".formatted(n, MAXARRAY)); + } + return n; + } @Override - public int[] getInts() { - try { - int n = in.readInt(); - if (n < 0) { - return null; - } - int[] r = new int[n]; - for(int i=0;i