r75141 - in python/trunk: Lib/test/test_marshal.py Misc/NEWS Python/marshal.c
![](https://secure.gravatar.com/avatar/8ac615df352a970211b0e3d94a307c6d.jpg?s=120&d=mm&r=g)
Author: mark.dickinson Date: Tue Sep 29 21:01:06 2009 New Revision: 75141 Log: Issue #7019: Unmarshalling of bad long data could produce unnormalized PyLongs. Raise ValueError instead. Modified: python/trunk/Lib/test/test_marshal.py python/trunk/Misc/NEWS python/trunk/Python/marshal.c Modified: python/trunk/Lib/test/test_marshal.py ============================================================================== --- python/trunk/Lib/test/test_marshal.py (original) +++ python/trunk/Lib/test/test_marshal.py Tue Sep 29 21:01:06 2009 @@ -262,6 +262,11 @@ testString = 'abc' * size marshal.dumps(testString) + def test_invalid_longs(self): + # Issue #7019: marshal.loads shouldn't produce unnormalized PyLongs + invalid_string = 'l\x02\x00\x00\x00\x00\x00\x00\x00' + self.assertRaises(ValueError, marshal.loads, invalid_string) + def test_main(): test_support.run_unittest(IntTestCase, Modified: python/trunk/Misc/NEWS ============================================================================== --- python/trunk/Misc/NEWS (original) +++ python/trunk/Misc/NEWS Tue Sep 29 21:01:06 2009 @@ -12,6 +12,9 @@ Core and Builtins ----------------- +- Issue #7019: Raise ValueError when unmarshalling bad long data, instead + of producing internally inconsistent Python longs. + - Issue #6990: Fix threading.local subclasses leaving old state around after a reference cycle GC which could be recycled by new locals. Modified: python/trunk/Python/marshal.c ============================================================================== --- python/trunk/Python/marshal.c (original) +++ python/trunk/Python/marshal.c Tue Sep 29 21:01:06 2009 @@ -556,7 +556,7 @@ r_PyLong(RFILE *p) { PyLongObject *ob; - int size, i, j, md; + int size, i, j, md, shorts_in_top_digit; long n; digit d; @@ -569,7 +569,8 @@ return NULL; } - size = 1 + (ABS(n)-1) / PyLong_MARSHAL_RATIO; + size = 1 + (ABS(n) - 1) / PyLong_MARSHAL_RATIO; + shorts_in_top_digit = 1 + (ABS(n) - 1) % PyLong_MARSHAL_RATIO; ob = _PyLong_New(size); if (ob == NULL) return NULL; @@ -586,12 +587,21 @@ ob->ob_digit[i] = d; } d = 0; - for (j=0; j < (ABS(n)-1)%PyLong_MARSHAL_RATIO + 1; j++) { + for (j=0; j < shorts_in_top_digit; j++) { md = r_short(p); if (md < 0 || md > PyLong_MARSHAL_BASE) goto bad_digit; + /* topmost marshal digit should be nonzero */ + if (md == 0 && j == shorts_in_top_digit - 1) { + Py_DECREF(ob); + PyErr_SetString(PyExc_ValueError, + "bad marshal data (unnormalized long data)"); + return NULL; + } d += (digit)md << j*PyLong_MARSHAL_SHIFT; } + /* top digit should be nonzero, else the resulting PyLong won't be + normalized */ ob->ob_digit[size-1] = d; return (PyObject *)ob; bad_digit:
participants (1)
-
mark.dickinson