mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GP-6886: Fix OOM in ObjectStorageStreamAdapter
This commit is contained in:
@@ -28,6 +28,7 @@ import org.apache.logging.log4j.Logger;
|
|||||||
|
|
||||||
import generic.jar.ResourceFile;
|
import generic.jar.ResourceFile;
|
||||||
import ghidra.framework.Application;
|
import ghidra.framework.Application;
|
||||||
|
import ghidra.util.Msg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link GhidraObjectInputFilter} provides global serial input filter for use with Ghidra server
|
* {@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 MAXDEPTH = "maxdepth";
|
||||||
private static final String MAXBYTES = "maxbytes";
|
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.
|
// NOTE: Be sure to update serialFilterREADME.md if values are updated.
|
||||||
private int MAXARRAY_DEFAULT = 200_000;
|
public static final int MAXARRAY_DEFAULT = getMaxArrayFromProperties();
|
||||||
private int MAXREFS_DEFAULT = 10_000;
|
public static final int MAXREFS_DEFAULT = 10_000;
|
||||||
private int MAXDEPTH_DEFAULT = 50;
|
public static final int MAXDEPTH_DEFAULT = 50;
|
||||||
private int MAXBYTES_DEFAULT = 32 * 1024 * 1024; // 32MB
|
public static final int MAXBYTES_DEFAULT = 32 * 1024 * 1024; // 32MB
|
||||||
|
|
||||||
private long maxArray;
|
private long maxArray;
|
||||||
private long maxRefs;
|
private long maxRefs;
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -18,376 +18,454 @@ package ghidra.util;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation for ObjectStorage to save and restore Strings and
|
* Implementation for ObjectStorage to save and restore Strings and Java primitives using an
|
||||||
* Java primitives using an ObjectOutputStream and ObjectInputStream,
|
* ObjectOutputStream and ObjectInputStream, respectively.
|
||||||
* respectively.
|
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ObjectStorageStreamAdapter implements ObjectStorage {
|
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;
|
ObjectOutputStream out;
|
||||||
ObjectInputStream in;
|
ObjectInputStream in;
|
||||||
/**
|
|
||||||
* Constructor for ObjectStorageStreamAdapter.
|
/**
|
||||||
* @param out output stream to write to
|
* Constructor for ObjectStorageStreamAdapter.
|
||||||
*/
|
*
|
||||||
public ObjectStorageStreamAdapter(ObjectOutputStream out) {
|
* @param out output stream to write to
|
||||||
this.out = out;
|
*/
|
||||||
}
|
public ObjectStorageStreamAdapter(ObjectOutputStream out) {
|
||||||
/**
|
this.out = out;
|
||||||
* Constructor for new ObjectStorageStreamAdapter
|
}
|
||||||
* @param in input stream to read from
|
|
||||||
*/
|
/**
|
||||||
public ObjectStorageStreamAdapter(ObjectInputStream in) {
|
* Constructor for new ObjectStorageStreamAdapter
|
||||||
this.in = in;
|
*
|
||||||
}
|
* @param in input stream to read from
|
||||||
|
*/
|
||||||
|
public ObjectStorageStreamAdapter(ObjectInputStream in) {
|
||||||
|
this.in = in;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putInt(int value) {
|
public void putInt(int value) {
|
||||||
try {
|
try {
|
||||||
out.writeInt(value);
|
out.writeInt(value);
|
||||||
} catch (IOException e) {}
|
}
|
||||||
}
|
catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putByte(byte value) {
|
public void putByte(byte value) {
|
||||||
try {
|
try {
|
||||||
out.writeByte(value);
|
out.writeByte(value);
|
||||||
} catch (IOException e) {}
|
}
|
||||||
}
|
catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putShort(short value) {
|
public void putShort(short value) {
|
||||||
try {
|
try {
|
||||||
out.writeShort(value);
|
out.writeShort(value);
|
||||||
} catch (IOException e) {}
|
}
|
||||||
}
|
catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putLong(long value) {
|
public void putLong(long value) {
|
||||||
try {
|
try {
|
||||||
out.writeLong(value);
|
out.writeLong(value);
|
||||||
} catch (IOException e) {}
|
}
|
||||||
}
|
catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putString(String value) {
|
public void putString(String value) {
|
||||||
try {
|
try {
|
||||||
out.writeObject(value);
|
out.writeObject(value);
|
||||||
} catch (IOException e) {}
|
}
|
||||||
}
|
catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putBoolean(boolean value) {
|
public void putBoolean(boolean value) {
|
||||||
try {
|
try {
|
||||||
out.writeBoolean(value);
|
out.writeBoolean(value);
|
||||||
} catch (IOException e) {}
|
}
|
||||||
}
|
catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putFloat(float value) {
|
public void putFloat(float value) {
|
||||||
try {
|
try {
|
||||||
out.writeFloat(value);
|
out.writeFloat(value);
|
||||||
} catch (IOException e) {}
|
}
|
||||||
}
|
catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putDouble(double value) {
|
public void putDouble(double value) {
|
||||||
try {
|
try {
|
||||||
out.writeDouble(value);
|
out.writeDouble(value);
|
||||||
} catch (IOException e) {}
|
}
|
||||||
}
|
catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInt() {
|
public int getInt() {
|
||||||
try {
|
try {
|
||||||
return in.readInt();
|
return in.readInt();
|
||||||
} catch (IOException e) {
|
}
|
||||||
return 0;
|
catch (IOException e) {
|
||||||
}
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte getByte() {
|
public byte getByte() {
|
||||||
try {
|
try {
|
||||||
return in.readByte();
|
return in.readByte();
|
||||||
} catch (IOException e) {
|
}
|
||||||
return (byte)0;
|
catch (IOException e) {
|
||||||
}
|
return (byte) 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public short getShort() {
|
public short getShort() {
|
||||||
try {
|
try {
|
||||||
return in.readShort();
|
return in.readShort();
|
||||||
} catch (IOException e) {
|
}
|
||||||
return (short)0;
|
catch (IOException e) {
|
||||||
}
|
return (short) 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getLong() {
|
public long getLong() {
|
||||||
try {
|
try {
|
||||||
return in.readLong();
|
return in.readLong();
|
||||||
} catch (IOException e) {
|
}
|
||||||
return 0;
|
catch (IOException e) {
|
||||||
}
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getBoolean() {
|
public boolean getBoolean() {
|
||||||
try {
|
try {
|
||||||
return in.readBoolean();
|
return in.readBoolean();
|
||||||
} catch (IOException e) {
|
}
|
||||||
return false;
|
catch (IOException e) {
|
||||||
}
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getString() {
|
public String getString() {
|
||||||
try {
|
try {
|
||||||
return (String)in.readObject();
|
return (String) in.readObject();
|
||||||
}catch(Exception e) {
|
}
|
||||||
return null;
|
catch (Exception e) {
|
||||||
}
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getFloat() {
|
public float getFloat() {
|
||||||
try {
|
try {
|
||||||
return in.readFloat();
|
return in.readFloat();
|
||||||
} catch (IOException e) {
|
}
|
||||||
return 0;
|
catch (IOException e) {
|
||||||
}
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getDouble() {
|
public double getDouble() {
|
||||||
try {
|
try {
|
||||||
return in.readDouble();
|
return in.readDouble();
|
||||||
} catch (IOException e) {
|
}
|
||||||
return 0.0;
|
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
|
@Override
|
||||||
public void putInts(int[] value) {
|
public void putInts(int[] value) {
|
||||||
try {
|
try {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
out.writeInt(-1);
|
out.writeInt(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
out.writeInt(value.length);
|
checkWriteArrayLength(value.length);
|
||||||
for (int i = 0; i < value.length; i++) {
|
for (int i = 0; i < value.length; i++) {
|
||||||
out.writeInt(value[i]);
|
out.writeInt(value[i]);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {}
|
}
|
||||||
}
|
catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putBytes(byte[] value) {
|
public void putBytes(byte[] value) {
|
||||||
try {
|
try {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
out.writeInt(-1);
|
out.writeInt(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
out.writeInt(value.length);
|
checkWriteArrayLength(value.length);
|
||||||
for (int i = 0; i < value.length; i++) {
|
for (int i = 0; i < value.length; i++) {
|
||||||
out.writeByte(value[i]);
|
out.writeByte(value[i]);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {}
|
}
|
||||||
}
|
catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putShorts(short[] value) {
|
public void putShorts(short[] value) {
|
||||||
try {
|
try {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
out.writeInt(-1);
|
out.writeInt(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
out.writeInt(value.length);
|
checkWriteArrayLength(value.length);
|
||||||
for (int i = 0; i < value.length; i++) {
|
for (int i = 0; i < value.length; i++) {
|
||||||
out.writeShort(value[i]);
|
out.writeShort(value[i]);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {}
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putLongs(long[] value) {
|
public void putLongs(long[] value) {
|
||||||
try {
|
try {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
out.writeInt(-1);
|
out.writeInt(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
out.writeInt(value.length);
|
checkWriteArrayLength(value.length);
|
||||||
for (int i = 0; i < value.length; i++) {
|
for (int i = 0; i < value.length; i++) {
|
||||||
out.writeLong(value[i]);
|
out.writeLong(value[i]);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {}
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putFloats(float[] value) {
|
public void putFloats(float[] value) {
|
||||||
try {
|
try {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
out.writeInt(-1);
|
out.writeInt(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
out.writeInt(value.length);
|
checkWriteArrayLength(value.length);
|
||||||
for (int i = 0; i < value.length; i++) {
|
for (int i = 0; i < value.length; i++) {
|
||||||
out.writeFloat(value[i]);
|
out.writeFloat(value[i]);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {}
|
}
|
||||||
|
catch (IOException e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putDoubles(double[] value) {
|
public void putDoubles(double[] value) {
|
||||||
try {
|
try {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
out.writeInt(-1);
|
out.writeInt(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
out.writeInt(value.length);
|
checkWriteArrayLength(value.length);
|
||||||
for (int i = 0; i < value.length; i++) {
|
for (int i = 0; i < value.length; i++) {
|
||||||
out.writeDouble(value[i]);
|
out.writeDouble(value[i]);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {}
|
}
|
||||||
}
|
catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putStrings(String[] value) {
|
public void putStrings(String[] value) {
|
||||||
try {
|
try {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
out.writeInt(-1);
|
out.writeInt(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
out.writeInt(value.length);
|
checkWriteArrayLength(value.length);
|
||||||
for (int i = 0; i < value.length; i++) {
|
for (int i = 0; i < value.length; i++) {
|
||||||
out.writeObject(value[i]);
|
out.writeObject(value[i]);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {}
|
}
|
||||||
}
|
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
|
@Override
|
||||||
public int[] getInts() {
|
public int[] getInts() {
|
||||||
try {
|
try {
|
||||||
int n = in.readInt();
|
int n = checkReadArrayLength();
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
int[] r = new int[n];
|
int[] r = new int[n];
|
||||||
for(int i=0;i<n;i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
r[i] = in.readInt();
|
r[i] = in.readInt();
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
} catch (IOException e) {
|
}
|
||||||
return new int[0];
|
catch (IOException e) {
|
||||||
}
|
return new int[0];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] getBytes() {
|
public byte[] getBytes() {
|
||||||
try {
|
try {
|
||||||
int n = in.readInt();
|
int n = checkReadArrayLength();
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
byte[] r = new byte[n];
|
byte[] r = new byte[n];
|
||||||
for(int i=0;i<n;i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
r[i] = in.readByte();
|
r[i] = in.readByte();
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
} catch (IOException e) {
|
}
|
||||||
return new byte[0];
|
catch (IOException e) {
|
||||||
}
|
return new byte[0];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public short[] getShorts() {
|
public short[] getShorts() {
|
||||||
try {
|
try {
|
||||||
int n = in.readInt();
|
int n = checkReadArrayLength();
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
short[] r = new short[n];
|
short[] r = new short[n];
|
||||||
for(int i=0;i<n;i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
r[i] = in.readShort();
|
r[i] = in.readShort();
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
} catch (IOException e) {
|
}
|
||||||
return new short[0];
|
catch (IOException e) {
|
||||||
}
|
return new short[0];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long[] getLongs() {
|
public long[] getLongs() {
|
||||||
try {
|
try {
|
||||||
int n = in.readInt();
|
int n = checkReadArrayLength();
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
long[] r = new long[n];
|
long[] r = new long[n];
|
||||||
for(int i=0;i<n;i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
r[i] = in.readLong();
|
r[i] = in.readLong();
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
} catch (IOException e) {
|
}
|
||||||
return new long[0];
|
catch (IOException e) {
|
||||||
}
|
return new long[0];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float[] getFloats() {
|
public float[] getFloats() {
|
||||||
try {
|
try {
|
||||||
int n = in.readInt();
|
int n = checkReadArrayLength();
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
float[] r = new float[n];
|
float[] r = new float[n];
|
||||||
for(int i=0;i<n;i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
r[i] = in.readFloat();
|
r[i] = in.readFloat();
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
} catch (IOException e) {
|
}
|
||||||
return new float[0];
|
catch (IOException e) {
|
||||||
}
|
return new float[0];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double[] getDoubles() {
|
public double[] getDoubles() {
|
||||||
try {
|
try {
|
||||||
int n = in.readInt();
|
int n = checkReadArrayLength();
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
double[] r = new double[n];
|
double[] r = new double[n];
|
||||||
for(int i=0;i<n;i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
r[i] = in.readDouble();
|
r[i] = in.readDouble();
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
} catch (IOException e) {
|
}
|
||||||
return new double[0];
|
catch (IOException e) {
|
||||||
}
|
return new double[0];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getStrings() {
|
public String[] getStrings() {
|
||||||
try {
|
try {
|
||||||
int n = in.readInt();
|
int n = checkReadArrayLength();
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String[] r = new String[n];
|
String[] r = new String[n];
|
||||||
for(int i=0;i<n;i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
r[i] = (String)in.readObject();
|
r[i] = (String) in.readObject();
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
} catch (Exception e) {
|
}
|
||||||
return new String[0];
|
catch (Exception e) {
|
||||||
}
|
return new String[0];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user