Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
8c126f17
Commit
8c126f17
authored
Jul 17, 2016
by
Stefan Krah
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #26974: Fix segfault in the presence of absurd subclassing. Proactively
eliminate all internal uses of overridden methods.
parent
80ab069f
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
75 additions
and
3 deletions
+75
-3
Lib/test/test_decimal.py
Lib/test/test_decimal.py
+28
-0
Modules/_decimal/_decimal.c
Modules/_decimal/_decimal.c
+47
-3
No files found.
Lib/test/test_decimal.py
View file @
8c126f17
...
...
@@ -5398,6 +5398,34 @@ class CWhitebox(unittest.TestCase):
y
=
Decimal
(
10
**
(
9
*
25
)).
__sizeof__
()
self
.
assertEqual
(
y
,
x
+
4
)
def
test_internal_use_of_overridden_methods
(
self
):
Decimal
=
C
.
Decimal
# Unsound subtyping
class
X
(
float
):
def
as_integer_ratio
(
self
):
return
1
def
__abs__
(
self
):
return
self
class
Y
(
float
):
def
__abs__
(
self
):
return
[
1
]
*
200
class
I
(
int
):
def
bit_length
(
self
):
return
[
1
]
*
200
class
Z
(
float
):
def
as_integer_ratio
(
self
):
return
(
I
(
1
),
I
(
1
))
def
__abs__
(
self
):
return
self
for
cls
in
X
,
Y
,
Z
:
self
.
assertEqual
(
Decimal
.
from_float
(
cls
(
101.1
)),
Decimal
.
from_float
(
101.1
))
@
requires_docstrings
@
unittest
.
skipUnless
(
C
,
"test requires C version"
)
class
SignatureTest
(
unittest
.
TestCase
):
...
...
Modules/_decimal/_decimal.c
View file @
8c126f17
...
...
@@ -2208,6 +2208,14 @@ PyDecType_FromLongExact(PyTypeObject *type, const PyObject *pylong,
return
dec
;
}
/* External C-API functions */
static
binaryfunc
_py_long_multiply
;
static
binaryfunc
_py_long_floor_divide
;
static
ternaryfunc
_py_long_power
;
static
unaryfunc
_py_float_abs
;
static
PyCFunction
_py_long_bit_length
;
static
PyCFunction
_py_float_as_integer_ratio
;
/* Return a PyDecObject or a subtype from a PyFloatObject.
Conversion is exact. */
static
PyObject
*
...
...
@@ -2258,13 +2266,13 @@ PyDecType_FromFloatExact(PyTypeObject *type, PyObject *v,
}
/* absolute value of the float */
tmp
=
PyObject_CallMethod
(
v
,
"__abs__"
,
NULL
);
tmp
=
_py_float_abs
(
v
);
if
(
tmp
==
NULL
)
{
return
NULL
;
}
/* float as integer ratio: numerator/denominator */
n_d
=
PyObject_CallMethod
(
tmp
,
"as_integer_ratio"
,
NULL
);
n_d
=
_py_float_as_integer_ratio
(
tmp
,
NULL
);
Py_DECREF
(
tmp
);
if
(
n_d
==
NULL
)
{
return
NULL
;
...
...
@@ -2272,7 +2280,7 @@ PyDecType_FromFloatExact(PyTypeObject *type, PyObject *v,
n
=
PyTuple_GET_ITEM
(
n_d
,
0
);
d
=
PyTuple_GET_ITEM
(
n_d
,
1
);
tmp
=
PyObject_CallMethod
(
d
,
"bit_length"
,
NULL
);
tmp
=
_py_long_bit_length
(
d
,
NULL
);
if
(
tmp
==
NULL
)
{
Py_DECREF
(
n_d
);
return
NULL
;
...
...
@@ -5511,6 +5519,32 @@ static struct int_constmap int_constants [] = {
#define CHECK_PTR(expr) \
do { if ((expr) == NULL) goto error; } while (0)
static
PyCFunction
cfunc_noargs
(
PyTypeObject
*
t
,
const
char
*
name
)
{
struct
PyMethodDef
*
m
;
if
(
t
->
tp_methods
==
NULL
)
{
goto
error
;
}
for
(
m
=
t
->
tp_methods
;
m
->
ml_name
!=
NULL
;
m
++
)
{
if
(
strcmp
(
name
,
m
->
ml_name
)
==
0
)
{
if
(
!
(
m
->
ml_flags
&
METH_NOARGS
))
{
goto
error
;
}
return
m
->
ml_meth
;
}
}
error:
PyErr_Format
(
PyExc_RuntimeError
,
"internal error: could not find method %s"
,
name
);
return
NULL
;
}
PyMODINIT_FUNC
PyInit__decimal
(
void
)
{
...
...
@@ -5535,6 +5569,16 @@ PyInit__decimal(void)
mpd_setminalloc
(
_Py_DEC_MINALLOC
);
/* Init external C-API functions */
_py_long_multiply
=
PyLong_Type
.
tp_as_number
->
nb_multiply
;
_py_long_floor_divide
=
PyLong_Type
.
tp_as_number
->
nb_floor_divide
;
_py_long_power
=
PyLong_Type
.
tp_as_number
->
nb_power
;
_py_float_abs
=
PyFloat_Type
.
tp_as_number
->
nb_absolute
;
ASSIGN_PTR
(
_py_float_as_integer_ratio
,
cfunc_noargs
(
&
PyFloat_Type
,
"as_integer_ratio"
));
ASSIGN_PTR
(
_py_long_bit_length
,
cfunc_noargs
(
&
PyLong_Type
,
"bit_length"
));
/* Init types */
PyDec_Type
.
tp_base
=
&
PyBaseObject_Type
;
PyDecContext_Type
.
tp_base
=
&
PyBaseObject_Type
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment