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

Skip to content

Commit 2eb0b87

Browse files
committed
SF patch 514641 (Naofumi Honda) - Negative ob_size of LongObjects
Due to the bizarre definition of _PyLong_Copy(), creating an instance of a subclass of long with a negative value could cause core dumps later on. Unfortunately it looks like the behavior of _PyLong_Copy() is quite intentional, so the fix is more work than feels comfortable. This fix is almost, but not quite, the code that Naofumi Honda added; in addition, I added a test case.
1 parent 6f33250 commit 2eb0b87

4 files changed

Lines changed: 23 additions & 4 deletions

File tree

Lib/test/test_descr.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,6 +1748,10 @@ class longclone(long):
17481748
verify((a + 0).__class__ is long)
17491749
verify((0 + a).__class__ is long)
17501750

1751+
# Check that negative clones don't segfault
1752+
a = longclone(-1)
1753+
vereq(a.__dict__, {})
1754+
17511755
class precfloat(float):
17521756
__slots__ = ['prec']
17531757
def __init__(self, value=0.0, prec=12):

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ Chris Hoffman
203203
Albert Hofkamp
204204
Gerrit Holl
205205
Philip Homburg
206+
Naofumi Honda
206207
Jeffrey Honig
207208
Rob Hooft
208209
Brian Hooper

Objects/abstract.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -933,8 +933,16 @@ PyNumber_Long(PyObject *o)
933933
Py_INCREF(o);
934934
return o;
935935
}
936-
if (PyLong_Check(o))
937-
return _PyLong_Copy((PyLongObject *)o);
936+
if (PyLong_Check(o)) {
937+
PyObject *res;
938+
939+
res = _PyLong_Copy((PyLongObject *)o);
940+
if (res != NULL)
941+
((PyLongObject *)res)->ob_size =
942+
((PyLongObject *)o)->ob_size;
943+
944+
return res;
945+
}
938946
if (PyString_Check(o))
939947
/* need to do extra error checking that PyLong_FromString()
940948
* doesn't do. In particular long('9.5') must raise an

Objects/object.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,8 +1191,14 @@ _PyObject_GetDictPtr(PyObject *obj)
11911191
if (dictoffset == 0)
11921192
return NULL;
11931193
if (dictoffset < 0) {
1194-
const size_t size = _PyObject_VAR_SIZE(tp,
1195-
((PyVarObject *)obj)->ob_size);
1194+
int tsize;
1195+
size_t size;
1196+
1197+
tsize = ((PyVarObject *)obj)->ob_size;
1198+
if (tsize < 0)
1199+
tsize = -tsize;
1200+
size = _PyObject_VAR_SIZE(tp, tsize);
1201+
11961202
dictoffset += (long)size;
11971203
assert(dictoffset > 0);
11981204
assert(dictoffset % SIZEOF_VOID_P == 0);

0 commit comments

Comments
 (0)