diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/FileBytesProvider.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/FileBytesProvider.java index 94b28823da..f397eb6758 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/FileBytesProvider.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/FileBytesProvider.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. @@ -67,7 +67,12 @@ public class FileBytesProvider implements ByteProvider { @Override public byte readByte(long index) throws IOException { - return fileBytes.getOriginalByte(index); + try { + return fileBytes.getOriginalByte(index); + } + catch (IndexOutOfBoundsException e) { + throw new IOException(e); + } } @Override @@ -84,7 +89,12 @@ public class FileBytesProvider implements ByteProvider { throw new EOFException(); } byte[] bytes = new byte[(int) length]; - fileBytes.getOriginalBytes(index, bytes); + try { + fileBytes.getOriginalBytes(index, bytes); + } + catch (IndexOutOfBoundsException e) { + throw new IOException(e); + } return bytes; } @@ -105,18 +115,36 @@ public class FileBytesProvider implements ByteProvider { private long offset; FileBytesProviderInputStream(long offset) { + if (offset < 0) { + throw new IllegalArgumentException("Negative offset: " + offset); + } this.offset = offset; this.initialOffset = offset; } @Override public int read() throws IOException { - byte b = readByte(offset++); + if (offset >= length()) { + return -1; + } + byte b = readByte(offset); + ++offset; return b & 0xff; } @Override public int read(byte[] b, int off, int len) throws IOException { + if (off < 0 || off >= b.length) { + throw new IllegalArgumentException("Array index out of range: " + off); + } + long fileBytesLen = length(); + if (offset >= fileBytesLen) { + return -1; + } + long limit = fileBytesLen - offset; + if (len > limit) { + len = (int) limit; // reduce read length + } byte[] bytes = new byte[len]; int count = fileBytes.getOriginalBytes(offset, bytes); System.arraycopy(bytes, 0, b, off, count); diff --git a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/FileBytes.java b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/FileBytes.java index 13b00d4480..7cd34a79e6 100644 --- a/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/FileBytes.java +++ b/Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/mem/FileBytes.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. @@ -112,7 +112,8 @@ public class FileBytes { * @throws IOException if there is a problem reading the database. * @throws IndexOutOfBoundsException if the given offset is invalid. */ - public synchronized byte getModifiedByte(long offset) throws IOException { + public synchronized byte getModifiedByte(long offset) + throws IOException, IndexOutOfBoundsException { return getByte(layeredBuffers, offset); } @@ -123,7 +124,8 @@ public class FileBytes { * @throws IOException if there is a problem reading the database. * @throws IndexOutOfBoundsException if the given offset is invalid. */ - public synchronized byte getOriginalByte(long offset) throws IOException { + public synchronized byte getOriginalByte(long offset) + throws IOException, IndexOutOfBoundsException { return getByte(originalBuffers, offset); } @@ -135,8 +137,10 @@ public class FileBytes { * @param b the byte array to populate. * @return the number of bytes actually populated. * @throws IOException if there is an error reading from the database + * @throws IndexOutOfBoundsException if the given offset is invalid. */ - public synchronized int getModifiedBytes(long offset, byte[] b) throws IOException { + public synchronized int getModifiedBytes(long offset, byte[] b) + throws IOException, IndexOutOfBoundsException { return getBytes(layeredBuffers, offset, b, 0, b.length); } @@ -148,8 +152,10 @@ public class FileBytes { * @param b the byte array to populate. * @return the number of bytes actually populated. * @throws IOException if there is an error reading from the database + * @throws IndexOutOfBoundsException if the given offset is invalid. */ - public synchronized int getOriginalBytes(long offset, byte[] b) throws IOException { + public synchronized int getOriginalBytes(long offset, byte[] b) + throws IOException, IndexOutOfBoundsException { return getBytes(originalBuffers, offset, b, 0, b.length); } @@ -168,7 +174,7 @@ public class FileBytes { * size of the buffer b. */ public synchronized int getModifiedBytes(long offset, byte[] b, int off, int length) - throws IOException { + throws IOException, IndexOutOfBoundsException { return getBytes(layeredBuffers, offset, b, off, length); } @@ -187,7 +193,7 @@ public class FileBytes { * size of the buffer b. */ public synchronized int getOriginalBytes(long offset, byte[] b, int off, int length) - throws IOException { + throws IOException, IndexOutOfBoundsException { return getBytes(originalBuffers, offset, b, off, length); } @@ -237,9 +243,10 @@ public class FileBytes { * @param offset the offset into the file bytes. * @param b a byte array with the new values to write. * @return the number of bytes written + * @throws IndexOutOfBoundsException if invalid offset is specified * @throws IOException if the write to the database fails. */ - synchronized int putBytes(long offset, byte[] b) throws IOException { + synchronized int putBytes(long offset, byte[] b) throws IOException, IndexOutOfBoundsException { return putBytes(offset, b, 0, b.length); } @@ -256,7 +263,8 @@ public class FileBytes { * @throws IndexOutOfBoundsException if invalid offset is specified * @throws IOException if the write to the database fails. */ - synchronized int putBytes(long offset, byte[] b, int off, int length) throws IOException { + synchronized int putBytes(long offset, byte[] b, int off, int length) + throws IOException, IndexOutOfBoundsException { checkValid();