Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

THRIFT-1365. java: TupleProtocol#writeBitSet unintentionally writes a…

… variable length byte array

git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1176072 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
commit 40d51a28d7c49074a8c9de585540aa47c2b683ee 1 parent f357417
Bryan Duxbury authored
View
4 compiler/cpp/src/generate/t_java_generator.cc
@@ -4059,8 +4059,10 @@ void t_java_generator::generate_java_struct_tuple_writer(ofstream& out, t_struct
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
bool has_optional = false;
+ int optional_count = 0;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if ((*f_iter)->get_req() == t_field::T_OPTIONAL || (*f_iter)->get_req() == t_field::T_OPT_IN_REQ_OUT) {
+ optional_count++;
has_optional = true;
}
if ((*f_iter)->get_req() == t_field::T_REQUIRED) {
@@ -4081,7 +4083,7 @@ void t_java_generator::generate_java_struct_tuple_writer(ofstream& out, t_struct
}
}
- indent(out) << "oprot.writeBitSet(optionals);" << endl;
+ indent(out) << "oprot.writeBitSet(optionals, " << optional_count << ");" << endl;
int j = 0;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if ((*f_iter)->get_req() == t_field::T_OPTIONAL || (*f_iter)->get_req() == t_field::T_OPT_IN_REQ_OUT) {
View
9 lib/java/src/org/apache/thrift/protocol/TTupleProtocol.java
@@ -43,8 +43,8 @@ public TTupleProtocol(TTransport transport) {
return TupleScheme.class;
}
- public void writeBitSet(BitSet bs) throws TException {
- byte[] bytes = toByteArray(bs);
+ public void writeBitSet(BitSet bs, int vectorWidth) throws TException {
+ byte[] bytes = toByteArray(bs, vectorWidth);
for (byte b : bytes) {
writeByte(b);
}
@@ -82,10 +82,11 @@ public static BitSet fromByteArray(byte[] bytes) {
* assumed to be the least significant bit.
*
* @param bits
+ * @param vectorWidth
* @return a byte array of at least length 1
*/
- public static byte[] toByteArray(BitSet bits) {
- byte[] bytes = new byte[bits.length() / 8 + 1];
+ public static byte[] toByteArray(BitSet bits, int vectorWidth) {
+ byte[] bytes = new byte[vectorWidth / 8 + 1];
for (int i = 0; i < bits.length(); i++) {
if (bits.get(i)) {
bytes[bytes.length - i / 8 - 1] |= 1 << (i % 8);
View
17 lib/java/test/org/apache/thrift/protocol/TestTTupleProtocol.java
@@ -1,14 +1,10 @@
package org.apache.thrift.protocol;
-import java.util.HashMap;
-import java.util.Map;
+import org.apache.thrift.TDeserializer;
+import org.apache.thrift.TSerializer;
-import org.apache.thrift.TException;
-import org.apache.thrift.transport.TMemoryBuffer;
-import org.apache.thrift.transport.TMemoryInputTransport;
+import thrift.test.TupleProtocolTestStruct;
-import thrift.test.Complex;
-import thrift.test.Simple;
public class TestTTupleProtocol extends ProtocolTestBase {
@@ -21,4 +17,11 @@ protected boolean canBeUsedNaked() {
protected TProtocolFactory getFactory() {
return new TTupleProtocol.Factory();
}
+
+ public void testBitsetLengthIssue() throws Exception {
+ final TupleProtocolTestStruct t1 = new TupleProtocolTestStruct();
+ t1.setField1(0);
+ t1.setField2(12);
+ new TDeserializer(new TTupleProtocol.Factory()).deserialize(new TupleProtocolTestStruct(), new TSerializer(new TTupleProtocol.Factory()).serialize(t1));
+ }
}
View
14 test/DebugProtoTest.thrift
@@ -351,3 +351,17 @@ struct BreaksRubyCompactProtocol {
3: i32 field3;
}
+struct TupleProtocolTestStruct {
+ optional i32 field1;
+ optional i32 field2;
+ optional i32 field3;
+ optional i32 field4;
+ optional i32 field5;
+ optional i32 field6;
+ optional i32 field7;
+ optional i32 field8;
+ optional i32 field9;
+ optional i32 field10;
+ optional i32 field11;
+ optional i32 field12;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.