diff --git a/asyncpg/protocol/codecs/tid.pyx b/asyncpg/protocol/codecs/tid.pyx index 85f0aed5..fef7e7c3 100644 --- a/asyncpg/protocol/codecs/tid.pyx +++ b/asyncpg/protocol/codecs/tid.pyx @@ -7,7 +7,7 @@ cdef tid_encode(ConnectionSettings settings, WriteBuffer buf, obj): cdef int overflow = 0 - cdef long block, offset + cdef unsigned long block, offset if not (cpython.PyTuple_Check(obj) or cpython.PyList_Check(obj)): raise TypeError( @@ -18,25 +18,24 @@ cdef tid_encode(ConnectionSettings settings, WriteBuffer buf, obj): 'invalid number of elements in tid tuple, expecting 2') try: - block = cpython.PyLong_AsLong(obj[0]) + block = cpython.PyLong_AsUnsignedLong(obj[0]) except OverflowError: overflow = 1 # "long" and "long long" have the same size for x86_64, need an extra check - if overflow or (sizeof(block) > 4 and (block < -2147483648 or - block > 2147483647)): + if overflow or (sizeof(block) > 4 and block > 4294967295): raise OverflowError( - 'block too big to be encoded as INT4: {!r}'.format(obj[0])) + 'block too big to be encoded as UINT4: {!r}'.format(obj[0])) try: - offset = cpython.PyLong_AsLong(obj[1]) + offset = cpython.PyLong_AsUnsignedLong(obj[1]) overflow = 0 except OverflowError: overflow = 1 - if overflow or offset < -32768 or offset > 32767: + if overflow or offset > 65535: raise OverflowError( - 'offset too big to be encoded as INT2: {!r}'.format(obj[1])) + 'offset too big to be encoded as UINT2: {!r}'.format(obj[1])) buf.write_int32(6) buf.write_int32(block) @@ -45,11 +44,11 @@ cdef tid_encode(ConnectionSettings settings, WriteBuffer buf, obj): cdef tid_decode(ConnectionSettings settings, FastReadBuffer buf): cdef: - int32_t block - int16_t offset + uint32_t block + uint16_t offset - block = hton.unpack_int32(buf.read(4)) - offset = hton.unpack_int16(buf.read(2)) + block = hton.unpack_int32(buf.read(4)) + offset = hton.unpack_int16(buf.read(2)) return (block, offset) diff --git a/tests/test_codecs.py b/tests/test_codecs.py index 5ed7d2b6..cf93be69 100644 --- a/tests/test_codecs.py +++ b/tests/test_codecs.py @@ -380,7 +380,13 @@ def _timezone(offset): asyncpg.Circle((0.0, 0.0), 100), ]), ('tid', 'tid', [ - (0, 2), + (100, 200), + (0, 0), + (2147483647, 0), + (4294967295, 0), + (0, 32767), + (0, 65535), + (4294967295, 65535), ]), ] @@ -611,20 +617,18 @@ async def test_invalid_input(self): [1, 2, 3], (4,), ]), - ('tid', OverflowError, 'block too big to be encoded as INT4', [ + ('tid', OverflowError, 'block too big to be encoded as UINT4', [ + (-1, 0), (2**256, 0), - (decimal.Decimal("2000000000000000000000000000000"), 0), - (0xffffffff, 0), - (2**31, 0), - (-2**31 - 1, 0), + (0xffffffff + 1, 0), + (2**32, 0), ]), - ('tid', OverflowError, 'offset too big to be encoded as INT2', [ + ('tid', OverflowError, 'offset too big to be encoded as UINT2', [ + (0, -1), (0, 2**256), - (0, decimal.Decimal("2000000000000000000000000000000")), - (0, 0xffff), + (0, 0xffff + 1), (0, 0xffffffff), - (0, 32768), - (0, -32769), + (0, 65536), ]), ]