From: Bryan Duxbury Date: Mon, 26 Sep 2011 21:29:15 +0000 (+0000) Subject: THRIFT-1365. java: TupleProtocol#writeBitSet unintentionally writes a variable length... X-Git-Tag: 0.8.0~70 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=40d51a28d7c49074a8c9de585540aa47c2b683ee;p=common%2Fthrift.git 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 --- diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc index ce832015..6cdfe439 100644 --- a/compiler/cpp/src/generate/t_java_generator.cc +++ b/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& fields = tstruct->get_members(); vector::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) { diff --git a/lib/java/src/org/apache/thrift/protocol/TTupleProtocol.java b/lib/java/src/org/apache/thrift/protocol/TTupleProtocol.java index 4592738d..14d50a6e 100644 --- a/lib/java/src/org/apache/thrift/protocol/TTupleProtocol.java +++ b/lib/java/src/org/apache/thrift/protocol/TTupleProtocol.java @@ -43,8 +43,8 @@ public final class TTupleProtocol extends TCompactProtocol { 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 final class TTupleProtocol extends TCompactProtocol { * 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); diff --git a/lib/java/test/org/apache/thrift/protocol/TestTTupleProtocol.java b/lib/java/test/org/apache/thrift/protocol/TestTTupleProtocol.java index 948df9f6..b654db3f 100644 --- a/lib/java/test/org/apache/thrift/protocol/TestTTupleProtocol.java +++ b/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 @@ public class TestTTupleProtocol extends ProtocolTestBase { 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)); + } } diff --git a/test/DebugProtoTest.thrift b/test/DebugProtoTest.thrift index b8b89b75..e2bba40e 100644 --- a/test/DebugProtoTest.thrift +++ b/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; +} \ No newline at end of file