Thrift: Maximum read length for Java.
Summary:
A feature to improve handling of invalid wire data by the Java Thrift library.
Reviewed By: mcslee
Test Plan: I trust Dave Engberg.
Revert Plan: ok
Other Notes:
Submitted by Dave Engberg.
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665393 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/java/src/protocol/TBinaryProtocol.java b/lib/java/src/protocol/TBinaryProtocol.java
index b74c03d..2e487cd 100644
--- a/lib/java/src/protocol/TBinaryProtocol.java
+++ b/lib/java/src/protocol/TBinaryProtocol.java
@@ -8,6 +8,8 @@
import com.facebook.thrift.TException;
import com.facebook.thrift.transport.TTransport;
+import com.facebook.thrift.transport.TTransportException;
+
import java.io.UnsupportedEncodingException;
/**
@@ -23,6 +25,9 @@
protected boolean strictRead_ = false;
protected boolean strictWrite_ = true;
+ protected int readLength_;
+ protected boolean checkReadLength_ = false;
+
/**
* Factory
*/
@@ -57,7 +62,6 @@
strictWrite_ = strictWrite;
}
-
public void writeMessageBegin(TMessage message) throws TException {
if (strictWrite_) {
int version = VERSION_1 | message.type;
@@ -248,13 +252,13 @@
private byte[] bin = new byte[1];
public byte readByte() throws TException {
- trans_.readAll(bin, 0, 1);
+ readAll(bin, 0, 1);
return bin[0];
}
private byte[] i16rd = new byte[2];
public short readI16() throws TException {
- trans_.readAll(i16rd, 0, 2);
+ readAll(i16rd, 0, 2);
return
(short)
(((i16rd[0] & 0xff) << 8) |
@@ -263,7 +267,7 @@
private byte[] i32rd = new byte[4];
public int readI32() throws TException {
- trans_.readAll(i32rd, 0, 4);
+ readAll(i32rd, 0, 4);
return
((i32rd[0] & 0xff) << 24) |
((i32rd[1] & 0xff) << 16) |
@@ -273,7 +277,7 @@
private byte[] i64rd = new byte[8];
public long readI64() throws TException {
- trans_.readAll(i64rd, 0, 8);
+ readAll(i64rd, 0, 8);
return
((long)(i64rd[0] & 0xff) << 56) |
((long)(i64rd[1] & 0xff) << 48) |
@@ -296,6 +300,7 @@
public String readStringBody(int size) throws TException {
try {
+ checkReadLength(size);
byte[] buf = new byte[size];
trans_.readAll(buf, 0, size);
return new String(buf, "UTF-8");
@@ -306,9 +311,29 @@
public byte[] readBinary() throws TException {
int size = readI32();
+ checkReadLength(size);
byte[] buf = new byte[size];
trans_.readAll(buf, 0, size);
return buf;
}
+ private int readAll(byte[] buf, int off, int len) throws TException {
+ checkReadLength(len);
+ return trans_.readAll(buf, off, len);
+ }
+
+ public void setReadLength(int readLength) {
+ readLength_ = readLength;
+ checkReadLength_ = true;
+ }
+
+ protected void checkReadLength(int length) throws TException {
+ if (checkReadLength_) {
+ readLength_ -= length;
+ if (readLength_ < 0) {
+ throw new TException("Message length exceeded: " + length);
+ }
+ }
+ }
+
}