From 2d05b40b030cb6b5da0913e72b59a91b09faccab Mon Sep 17 00:00:00 2001 From: Pramukta Kumar Date: Tue, 17 Mar 2015 15:02:40 -0400 Subject: [PATCH 1/3] Test to demonstrate that the default function isn't always called (#133) --- test/test_extension.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/test_extension.py b/test/test_extension.py index 2f85ce3..c552498 100644 --- a/test/test_extension.py +++ b/test/test_extension.py @@ -55,3 +55,22 @@ def test_extension_type(): s = msgpack.packb(obj, default=default) obj2 = msgpack.unpackb(s, ext_hook=ext_hook) assert obj == obj2 + +import sys +if sys.version > '3': + long = int + +def test_overriding_hooks(): + def default(obj): + if isinstance(obj, long): + return {"__type__": "long", "__data__": str(obj)} + else: + return obj + + obj = {"testval": long(1823746192837461928374619)} + refobj = {"testval": default(obj["testval"])} + refout = msgpack.packb(refobj) + assert isinstance(refout, (str, bytes)) + testout = msgpack.packb(obj, default=default) + + assert refout == testout From 10cd2d2ebf6390e844c2bf59e9efd765f9b60e40 Mon Sep 17 00:00:00 2001 From: Pramukta Kumar Date: Tue, 17 Mar 2015 15:05:04 -0400 Subject: [PATCH 2/3] calling the default function upon integer overflow in the fallback routine --- msgpack/fallback.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/msgpack/fallback.py b/msgpack/fallback.py index 235c201..eb20002 100644 --- a/msgpack/fallback.py +++ b/msgpack/fallback.py @@ -655,6 +655,10 @@ class Packer(object): return self._buffer.write(struct.pack(">BQ", 0xcf, obj)) if -0x8000000000000000 <= obj < -0x80000000: return self._buffer.write(struct.pack(">Bq", 0xd3, obj)) + if not default_used and self._default is not None: + obj = self._default(obj) + default_used = True + continue raise PackValueError("Integer value out of range") if self._use_bin_type and isinstance(obj, bytes): n = len(obj) From 6f02d252e1dc66d67861b45c5bead8392ed822d4 Mon Sep 17 00:00:00 2001 From: Pramukta Kumar Date: Tue, 17 Mar 2015 15:16:17 -0400 Subject: [PATCH 3/3] corresponding change to cython implementation --- msgpack/_packer.pyx | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/msgpack/_packer.pyx b/msgpack/_packer.pyx index fcd20a7..7129208 100644 --- a/msgpack/_packer.pyx +++ b/msgpack/_packer.pyx @@ -136,12 +136,20 @@ cdef class Packer(object): elif PyLong_Check(o): # PyInt_Check(long) is True for Python 3. # Sow we should test long before int. - if o > 0: - ullval = o - ret = msgpack_pack_unsigned_long_long(&self.pk, ullval) - else: - llval = o - ret = msgpack_pack_long_long(&self.pk, llval) + try: + if o > 0: + ullval = o + ret = msgpack_pack_unsigned_long_long(&self.pk, ullval) + else: + llval = o + ret = msgpack_pack_long_long(&self.pk, llval) + except OverflowError, oe: + if not default_used and self._default is not None: + o = self._default(o) + default_used = True + continue + else: + raise elif PyInt_Check(o): longval = o ret = msgpack_pack_long(&self.pk, longval)