|
@@ -723,17 +723,31 @@ public class FSEditLogLoader {
|
|
|
|
|
|
/**
|
|
/**
|
|
* Stream wrapper that keeps track of the current stream position.
|
|
* Stream wrapper that keeps track of the current stream position.
|
|
|
|
+ *
|
|
|
|
+ * This stream also allows us to set a limit on how many bytes we can read
|
|
|
|
+ * without getting an exception.
|
|
*/
|
|
*/
|
|
- public static class PositionTrackingInputStream extends FilterInputStream {
|
|
|
|
|
|
+ public static class PositionTrackingInputStream extends FilterInputStream
|
|
|
|
+ implements StreamLimiter {
|
|
private long curPos = 0;
|
|
private long curPos = 0;
|
|
private long markPos = -1;
|
|
private long markPos = -1;
|
|
|
|
+ private long limitPos = Long.MAX_VALUE;
|
|
|
|
|
|
public PositionTrackingInputStream(InputStream is) {
|
|
public PositionTrackingInputStream(InputStream is) {
|
|
super(is);
|
|
super(is);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private void checkLimit(long amt) throws IOException {
|
|
|
|
+ long extra = (curPos + amt) - limitPos;
|
|
|
|
+ if (extra > 0) {
|
|
|
|
+ throw new IOException("Tried to read " + amt + " byte(s) past " +
|
|
|
|
+ "the limit at offset " + limitPos);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public int read() throws IOException {
|
|
public int read() throws IOException {
|
|
|
|
+ checkLimit(1);
|
|
int ret = super.read();
|
|
int ret = super.read();
|
|
if (ret != -1) curPos++;
|
|
if (ret != -1) curPos++;
|
|
return ret;
|
|
return ret;
|
|
@@ -741,6 +755,7 @@ public class FSEditLogLoader {
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public int read(byte[] data) throws IOException {
|
|
public int read(byte[] data) throws IOException {
|
|
|
|
+ checkLimit(data.length);
|
|
int ret = super.read(data);
|
|
int ret = super.read(data);
|
|
if (ret > 0) curPos += ret;
|
|
if (ret > 0) curPos += ret;
|
|
return ret;
|
|
return ret;
|
|
@@ -748,11 +763,17 @@ public class FSEditLogLoader {
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public int read(byte[] data, int offset, int length) throws IOException {
|
|
public int read(byte[] data, int offset, int length) throws IOException {
|
|
|
|
+ checkLimit(length);
|
|
int ret = super.read(data, offset, length);
|
|
int ret = super.read(data, offset, length);
|
|
if (ret > 0) curPos += ret;
|
|
if (ret > 0) curPos += ret;
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public void setLimit(long limit) {
|
|
|
|
+ limitPos = curPos + limit;
|
|
|
|
+ }
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public void mark(int limit) {
|
|
public void mark(int limit) {
|
|
super.mark(limit);
|
|
super.mark(limit);
|
|
@@ -775,6 +796,11 @@ public class FSEditLogLoader {
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public long skip(long amt) throws IOException {
|
|
public long skip(long amt) throws IOException {
|
|
|
|
+ long extra = (curPos + amt) - limitPos;
|
|
|
|
+ if (extra > 0) {
|
|
|
|
+ throw new IOException("Tried to skip " + extra + " bytes past " +
|
|
|
|
+ "the limit at offset " + limitPos);
|
|
|
|
+ }
|
|
long ret = super.skip(amt);
|
|
long ret = super.skip(amt);
|
|
curPos += ret;
|
|
curPos += ret;
|
|
return ret;
|
|
return ret;
|