diff options
author | Mark Dickinson <dickinsm@gmail.com> | 2009-09-29 19:01:06 (GMT) |
---|---|---|
committer | Mark Dickinson <dickinsm@gmail.com> | 2009-09-29 19:01:06 (GMT) |
commit | 7e7a3ec901be55c868c800d541b5a1622e0ec7fb (patch) | |
tree | 0d99456b092c46913a9358c743ed3270f0d34c25 /Python | |
parent | 13305f681ba7ef1bb23c82fee674ec47d822bbbc (diff) | |
download | cpython-7e7a3ec901be55c868c800d541b5a1622e0ec7fb.zip cpython-7e7a3ec901be55c868c800d541b5a1622e0ec7fb.tar.gz cpython-7e7a3ec901be55c868c800d541b5a1622e0ec7fb.tar.bz2 |
Issue #7019: Unmarshalling of bad long data could produce unnormalized
PyLongs. Raise ValueError instead.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/marshal.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/Python/marshal.c b/Python/marshal.c index 8f8ac36..1ef41b0 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -556,7 +556,7 @@ static PyObject * 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 @@ r_PyLong(RFILE *p) 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 @@ r_PyLong(RFILE *p) 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: |