summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/changelog8
-rw-r--r--python/string.cc28
-rw-r--r--tests/test_lp1030278.py22
3 files changed, 50 insertions, 8 deletions
diff --git a/debian/changelog b/debian/changelog
index 66da3ea0..894502e2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -14,6 +14,14 @@ python-apt (0.8.8) UNRELEASED; urgency=low
check the keys fingerprint before importing. This avoids
man-in-the-middle attacks (LP: #1016643)
+ [ Barry Warsaw ]
+ * python/string.cc, tests/test_lp1030278.py: Fix StrSizeToStr() so that
+ 1) it first checks for PyLong-ness so that in Python 3 on i386, it
+ will be able to convert larger numbers (via doubles rather than ints);
+ 2) before doing the conversions through the apt API, check to see if a
+ Python exception occurred, e.g. OverflowError, and return an error
+ condition in that case instead of masking it. (LP: #1030278)
+
[ James Hunt ]
* python/cache.cc: PkgCacheGetIsMultiArch(): Return calculated
value rather than a random one.
diff --git a/python/string.cc b/python/string.cc
index 7abe2d17..62aa34e7 100644
--- a/python/string.cc
+++ b/python/string.cc
@@ -64,17 +64,29 @@ MkInt(StrTimeRFC1123,TimeRFC1123, long long, "L");
PyObject *StrSizeToStr(PyObject *Self,PyObject *Args)
{
PyObject *Obj;
+ double value;
+
if (PyArg_ParseTuple(Args,"O",&Obj) == 0)
return 0;
- if (PyInt_Check(Obj))
- return CppPyString(SizeToStr(PyInt_AsLong(Obj)));
+ // In Python 3, PyInt_Check is aliased to PyLong_Check and PyInt_AsLong is
+ // aliased to PyLong_AsLong. Therefore we do the actual long checks first
+ // so that if it is a long in Python 3, the value will be converted to a
+ // double rather than a long. This avoids OverflowError regressions in
+ // Python 3. LP: #1030278
if (PyLong_Check(Obj))
- return CppPyString(SizeToStr(PyLong_AsDouble(Obj)));
- if (PyFloat_Check(Obj))
- return CppPyString(SizeToStr(PyFloat_AsDouble(Obj)));
-
- PyErr_SetString(PyExc_TypeError,"Only understand integers and floats");
- return 0;
+ value = PyLong_AsDouble(Obj);
+ else if (PyInt_Check(Obj))
+ value = PyInt_AsLong(Obj);
+ else if (PyFloat_Check(Obj))
+ value = PyFloat_AsDouble(Obj);
+ else {
+ PyErr_SetString(PyExc_TypeError,"Only understand integers and floats");
+ return 0;
+ }
+ // Check for OverflowErrors or other exceptions during conversion.
+ if (PyErr_Occurred())
+ return 0;
+ return CppPyString(SizeToStr(value));
}
PyObject *StrQuoteString(PyObject *Self,PyObject *Args)
diff --git a/tests/test_lp1030278.py b/tests/test_lp1030278.py
new file mode 100644
index 00000000..1cbc2c18
--- /dev/null
+++ b/tests/test_lp1030278.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""Regression test for LP: #1030278"""
+
+__author__ = "Barry Warsaw <barry@ubuntu.com>"
+
+import unittest
+import apt_pkg
+
+
+class RegressionTestCase(unittest.TestCase):
+
+ def test_no_overflow_error(self):
+ # LP: #1030278 produces an overflow error in size_to_str() with a big
+ # value under Python 3.
+ self.assertEqual(apt_pkg.size_to_str(2147483648000000000000), '2147 E')
+
+
+if __name__ == "__main__":
+ unittest.main()
+
+# vim: ts=4 et sts=4