mirror of https://github.com/python/cpython
bpo-38643: Raise SystemError instead of crashing when PyNumber_ToBase is called with invalid base. (GH-18863)
This commit is contained in:
parent
413f01352a
commit
e5ccc94bbb
|
@ -502,6 +502,20 @@ class CAPITest(unittest.TestCase):
|
||||||
# Test that subtype_dealloc decref the newly assigned __class__ only once
|
# Test that subtype_dealloc decref the newly assigned __class__ only once
|
||||||
self.assertEqual(new_type_refcnt, sys.getrefcount(_testcapi.HeapCTypeSubclass))
|
self.assertEqual(new_type_refcnt, sys.getrefcount(_testcapi.HeapCTypeSubclass))
|
||||||
|
|
||||||
|
def test_pynumber_tobase(self):
|
||||||
|
from _testcapi import pynumber_tobase
|
||||||
|
self.assertEqual(pynumber_tobase(123, 2), '0b1111011')
|
||||||
|
self.assertEqual(pynumber_tobase(123, 8), '0o173')
|
||||||
|
self.assertEqual(pynumber_tobase(123, 10), '123')
|
||||||
|
self.assertEqual(pynumber_tobase(123, 16), '0x7b')
|
||||||
|
self.assertEqual(pynumber_tobase(-123, 2), '-0b1111011')
|
||||||
|
self.assertEqual(pynumber_tobase(-123, 8), '-0o173')
|
||||||
|
self.assertEqual(pynumber_tobase(-123, 10), '-123')
|
||||||
|
self.assertEqual(pynumber_tobase(-123, 16), '-0x7b')
|
||||||
|
self.assertRaises(TypeError, pynumber_tobase, 123.0, 10)
|
||||||
|
self.assertRaises(TypeError, pynumber_tobase, '123', 10)
|
||||||
|
self.assertRaises(SystemError, pynumber_tobase, 123, 0)
|
||||||
|
|
||||||
|
|
||||||
class TestPendingCalls(unittest.TestCase):
|
class TestPendingCalls(unittest.TestCase):
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
:c:func:`PyNumber_ToBase` now raises a :exc:`SystemError` instead of
|
||||||
|
crashing when called with invalid base.
|
|
@ -5259,6 +5259,19 @@ meth_fastcall_keywords(PyObject* self, PyObject* const* args,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
pynumber_tobase(PyObject *module, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *obj;
|
||||||
|
int base;
|
||||||
|
if (!PyArg_ParseTuple(args, "Oi:pynumber_tobase",
|
||||||
|
&obj, &base)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return PyNumber_ToBase(obj, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *);
|
static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *);
|
||||||
|
|
||||||
static PyMethodDef TestMethods[] = {
|
static PyMethodDef TestMethods[] = {
|
||||||
|
@ -5519,6 +5532,7 @@ static PyMethodDef TestMethods[] = {
|
||||||
{"meth_noargs", meth_noargs, METH_NOARGS},
|
{"meth_noargs", meth_noargs, METH_NOARGS},
|
||||||
{"meth_fastcall", (PyCFunction)(void(*)(void))meth_fastcall, METH_FASTCALL},
|
{"meth_fastcall", (PyCFunction)(void(*)(void))meth_fastcall, METH_FASTCALL},
|
||||||
{"meth_fastcall_keywords", (PyCFunction)(void(*)(void))meth_fastcall_keywords, METH_FASTCALL|METH_KEYWORDS},
|
{"meth_fastcall_keywords", (PyCFunction)(void(*)(void))meth_fastcall_keywords, METH_FASTCALL|METH_KEYWORDS},
|
||||||
|
{"pynumber_tobase", pynumber_tobase, METH_VARARGS},
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1551,18 +1551,15 @@ PyNumber_Float(PyObject *o)
|
||||||
PyObject *
|
PyObject *
|
||||||
PyNumber_ToBase(PyObject *n, int base)
|
PyNumber_ToBase(PyObject *n, int base)
|
||||||
{
|
{
|
||||||
PyObject *res = NULL;
|
if (!(base == 2 || base == 8 || base == 10 || base == 16)) {
|
||||||
|
PyErr_SetString(PyExc_SystemError,
|
||||||
|
"PyNumber_ToBase: base must be 2, 8, 10 or 16");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
PyObject *index = PyNumber_Index(n);
|
PyObject *index = PyNumber_Index(n);
|
||||||
|
|
||||||
if (!index)
|
if (!index)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (PyLong_Check(index))
|
PyObject *res = _PyLong_Format(index, base);
|
||||||
res = _PyLong_Format(index, base);
|
|
||||||
else
|
|
||||||
/* It should not be possible to get here, as
|
|
||||||
PyNumber_Index already has a check for the same
|
|
||||||
condition */
|
|
||||||
PyErr_SetString(PyExc_ValueError, "PyNumber_ToBase: index not int");
|
|
||||||
Py_DECREF(index);
|
Py_DECREF(index);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue