THRIFT-4405: fix negative sequence id handling in python TCompactProtocol
diff --git a/lib/py/src/protocol/TCompactProtocol.py b/lib/py/src/protocol/TCompactProtocol.py
index e485cff..da50513 100644
--- a/lib/py/src/protocol/TCompactProtocol.py
+++ b/lib/py/src/protocol/TCompactProtocol.py
@@ -58,6 +58,7 @@
def writeVarint(trans, n):
+ assert n >= 0, "Input to TCompactProtocol writeVarint cannot be negative!"
out = bytearray()
while True:
if n & ~0x7f == 0:
@@ -156,7 +157,14 @@
assert self.state == CLEAR
self.__writeUByte(self.PROTOCOL_ID)
self.__writeUByte(self.VERSION | (type << self.TYPE_SHIFT_AMOUNT))
- self.__writeVarint(seqid)
+ # The sequence id is a signed 32-bit integer but the compact protocol
+ # writes this out as a "var int" which is always positive, and attempting
+ # to write a negative number results in an infinite loop, so we may
+ # need to do some conversion here...
+ tseqid = seqid;
+ if tseqid < 0:
+ tseqid = 2147483648 + (2147483648 + tseqid)
+ self.__writeVarint(tseqid)
self.__writeBinary(str_to_binary(name))
self.state = VALUE_WRITE
@@ -334,6 +342,10 @@
raise TProtocolException(TProtocolException.BAD_VERSION,
'Bad version: %d (expect %d)' % (version, self.VERSION))
seqid = self.__readVarint()
+ # the sequence is a compact "var int" which is treaded as unsigned,
+ # however the sequence is actually signed...
+ if seqid > 2147483647:
+ seqid = -2147483648 - (2147483648 - seqid)
name = binary_to_str(self.__readBinary())
return (name, type, seqid)