Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2bbeb0e

Browse files
committed
Merged revisions 75145 via svnmerge from
svn+ssh://pythondev@www.python.org/python/branches/py3k ................ r75145 | mark.dickinson | 2009-09-29 20:21:35 +0100 (Tue, 29 Sep 2009) | 10 lines Merged revisions 75141 via svnmerge from svn+ssh://[email protected]/python/trunk ........ r75141 | mark.dickinson | 2009-09-29 20:01:06 +0100 (Tue, 29 Sep 2009) | 3 lines Issue #7019: Unmarshalling of bad long data could produce unnormalized PyLongs. Raise ValueError instead. ........ ................
1 parent 595ad32 commit 2bbeb0e

3 files changed

Lines changed: 21 additions & 3 deletions

File tree

Lib/test/test_marshal.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,11 @@ def test_large_marshal(self):
212212
testString = 'abc' * size
213213
marshal.dumps(testString)
214214

215+
def test_invalid_longs(self):
216+
# Issue #7019: marshal.loads shouldn't produce unnormalized PyLongs
217+
invalid_string = b'l\x02\x00\x00\x00\x00\x00\x00\x00'
218+
self.assertRaises(ValueError, marshal.loads, invalid_string)
219+
215220

216221
def test_main():
217222
support.run_unittest(IntTestCase,

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 3.1.2?
1212
Core and Builtins
1313
-----------------
1414

15+
- Issue #7019: Raise ValueError when unmarshalling bad long data, instead
16+
of producing internally inconsistent Python longs.
17+
1518
- Issue #6990: Fix threading.local subclasses leaving old state around
1619
after a reference cycle GC which could be recycled by new locals.
1720

Python/marshal.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ static PyObject *
553553
r_PyLong(RFILE *p)
554554
{
555555
PyLongObject *ob;
556-
int size, i, j, md;
556+
int size, i, j, md, shorts_in_top_digit;
557557
long n;
558558
digit d;
559559

@@ -566,7 +566,8 @@ r_PyLong(RFILE *p)
566566
return NULL;
567567
}
568568

569-
size = 1 + (ABS(n)-1) / PyLong_MARSHAL_RATIO;
569+
size = 1 + (ABS(n) - 1) / PyLong_MARSHAL_RATIO;
570+
shorts_in_top_digit = 1 + (ABS(n) - 1) % PyLong_MARSHAL_RATIO;
570571
ob = _PyLong_New(size);
571572
if (ob == NULL)
572573
return NULL;
@@ -583,12 +584,21 @@ r_PyLong(RFILE *p)
583584
ob->ob_digit[i] = d;
584585
}
585586
d = 0;
586-
for (j=0; j < (ABS(n)-1)%PyLong_MARSHAL_RATIO + 1; j++) {
587+
for (j=0; j < shorts_in_top_digit; j++) {
587588
md = r_short(p);
588589
if (md < 0 || md > PyLong_MARSHAL_BASE)
589590
goto bad_digit;
591+
/* topmost marshal digit should be nonzero */
592+
if (md == 0 && j == shorts_in_top_digit - 1) {
593+
Py_DECREF(ob);
594+
PyErr_SetString(PyExc_ValueError,
595+
"bad marshal data (unnormalized long data)");
596+
return NULL;
597+
}
590598
d += (digit)md << j*PyLong_MARSHAL_SHIFT;
591599
}
600+
/* top digit should be nonzero, else the resulting PyLong won't be
601+
normalized */
592602
ob->ob_digit[size-1] = d;
593603
return (PyObject *)ob;
594604
bad_digit:

0 commit comments

Comments
 (0)