Hadoop: added boundary checks to HadoopDirectDataInput. This closes # 1416.
package org.apache.ignite.internal.processors.hadoop.shuffle.direct;
+import java.io.EOFException;
import org.apache.ignite.internal.util.GridUnsafe;
import org.apache.ignite.internal.util.typedef.internal.SB;
import org.jetbrains.annotations.NotNull;
@@ -59,6 +60,8 @@ public class HadoopDirectDataInput extends InputStream implements DataInput {
/** {@inheritDoc} */
@Override public void readFully(@NotNull byte[] b, int off, int len) throws IOException {
+ checkRange(len);
+
System.arraycopy(buf, pos, b, off, len);
pos += len;
@@ -66,9 +69,16 @@ public class HadoopDirectDataInput extends InputStream implements DataInput {
/** {@inheritDoc} */
@Override public int skipBytes(int n) throws IOException {
- pos += n;
+ if (n < 0)
+ throw new IllegalArgumentException();
+
+ assert pos <= buf.length;
+
+ int toSkip = Math.min(buf.length - pos, n);
- return n;
+ pos += toSkip;
+
+ return toSkip;
}
/** {@inheritDoc} */
@@ -78,6 +88,8 @@ public class HadoopDirectDataInput extends InputStream implements DataInput {
/** {@inheritDoc} */
@Override public byte readByte() throws IOException {
+ checkRange(1);
+
byte res = GridUnsafe.getByte(buf, BYTE_ARR_OFF + pos);
pos += 1;
@@ -92,6 +104,8 @@ public class HadoopDirectDataInput extends InputStream implements DataInput {
/** {@inheritDoc} */
@Override public short readShort() throws IOException {
+ checkRange(2);
+
short res = GridUnsafe.getShort(buf, BYTE_ARR_OFF + pos);
pos += 2;
@@ -106,6 +120,8 @@ public class HadoopDirectDataInput extends InputStream implements DataInput {
/** {@inheritDoc} */
@Override public char readChar() throws IOException {
+ checkRange(2);
+
char res = GridUnsafe.getChar(buf, BYTE_ARR_OFF + pos);
pos += 2;
@@ -115,6 +131,8 @@ public class HadoopDirectDataInput extends InputStream implements DataInput {
/** {@inheritDoc} */
@Override public int readInt() throws IOException {
+ checkRange(4);
+
int res = GridUnsafe.getInt(buf, BYTE_ARR_OFF + pos);
pos += 4;
@@ -124,6 +142,8 @@ public class HadoopDirectDataInput extends InputStream implements DataInput {
/** {@inheritDoc} */
@Override public long readLong() throws IOException {
+ checkRange(8);
+
long res = GridUnsafe.getLong(buf, BYTE_ARR_OFF + pos);
pos += 8;
@@ -133,6 +153,8 @@ public class HadoopDirectDataInput extends InputStream implements DataInput {
/** {@inheritDoc} */
@Override public float readFloat() throws IOException {
+ checkRange(4);
+
float res = GridUnsafe.getFloat(buf, BYTE_ARR_OFF + pos);
pos += 4;
@@ -142,6 +164,8 @@ public class HadoopDirectDataInput extends InputStream implements DataInput {
/** {@inheritDoc} */
@Override public double readDouble() throws IOException {
+ checkRange(8);
+
double res = GridUnsafe.getDouble(buf, BYTE_ARR_OFF + pos);
pos += 8;
@@ -193,4 +217,17 @@ public class HadoopDirectDataInput extends InputStream implements DataInput {
return new String(bytes, StandardCharsets.UTF_8);
}
+
+ /**
+ * Ensures the position is still within the buffer.
+ *
+ * @throws EOFException if an attempt is made to read beyond the buffer end.
+ */
+ private void checkRange(int bytesToRead) throws EOFException {
+ assert bytesToRead > 0;
+
+ if (pos + bytesToRead - 1 >= buf.length)
+ throw new EOFException("Attempt to read beyond the end of buffer: " + (pos + bytesToRead - 1)
+ + " >= " + buf.length);
+ }
}
