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
1d0bb9c8
Commit
1d0bb9c8
authored
Feb 04, 2013
by
Serhiy Storchaka
Browse files
Options
Browse Files
Download
Plain Diff
Issue #6083: Fix multiple segmentation faults occured when PyArg_ParseTuple
parses nested mutating sequence.
parents
cfe34744
19c4e0df
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
117 additions
and
14 deletions
+117
-14
Lib/ctypes/test/test_returnfuncptrs.py
Lib/ctypes/test/test_returnfuncptrs.py
+28
-0
Lib/test/test_functools.py
Lib/test/test_functools.py
+20
-0
Lib/test/test_resource.py
Lib/test/test_resource.py
+17
-0
Misc/NEWS
Misc/NEWS
+3
-0
Modules/_ctypes/_ctypes.c
Modules/_ctypes/_ctypes.c
+21
-3
Modules/_functoolsmodule.c
Modules/_functoolsmodule.c
+3
-3
Modules/resource.c
Modules/resource.c
+25
-8
No files found.
Lib/ctypes/test/test_returnfuncptrs.py
View file @
1d0bb9c8
...
@@ -33,5 +33,33 @@ class ReturnFuncPtrTestCase(unittest.TestCase):
...
@@ -33,5 +33,33 @@ class ReturnFuncPtrTestCase(unittest.TestCase):
self
.
assertRaises
(
ArgumentError
,
strchr
,
b"abcdef"
,
3.0
)
self
.
assertRaises
(
ArgumentError
,
strchr
,
b"abcdef"
,
3.0
)
self
.
assertRaises
(
TypeError
,
strchr
,
b"abcdef"
)
self
.
assertRaises
(
TypeError
,
strchr
,
b"abcdef"
)
def
test_from_dll
(
self
):
dll
=
CDLL
(
_ctypes_test
.
__file__
)
# _CFuncPtr instances are now callable with a tuple argument
# which denotes a function name and a dll:
strchr
=
CFUNCTYPE
(
c_char_p
,
c_char_p
,
c_char
)((
"strchr"
,
dll
))
self
.
assertTrue
(
strchr
(
b"abcdef"
,
b"b"
),
"bcdef"
)
self
.
assertEqual
(
strchr
(
b"abcdef"
,
b"x"
),
None
)
self
.
assertRaises
(
ArgumentError
,
strchr
,
b"abcdef"
,
3.0
)
self
.
assertRaises
(
TypeError
,
strchr
,
b"abcdef"
)
# Issue 6083: Reference counting bug
def
test_test_from_dll_refcount
(
self
):
class
BadSequence
(
tuple
):
def
__getitem__
(
self
,
key
):
if
key
==
0
:
return
"strchr"
if
key
==
1
:
return
CDLL
(
_ctypes_test
.
__file__
)
raise
IndexError
# _CFuncPtr instances are now callable with a tuple argument
# which denotes a function name and a dll:
strchr
=
CFUNCTYPE
(
c_char_p
,
c_char_p
,
c_char
)(
BadSequence
((
"strchr"
,
CDLL
(
_ctypes_test
.
__file__
))))
self
.
assertTrue
(
strchr
(
b"abcdef"
,
b"b"
),
"bcdef"
)
self
.
assertEqual
(
strchr
(
b"abcdef"
,
b"x"
),
None
)
self
.
assertRaises
(
ArgumentError
,
strchr
,
b"abcdef"
,
3.0
)
self
.
assertRaises
(
TypeError
,
strchr
,
b"abcdef"
)
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
unittest
.
main
()
unittest
.
main
()
Lib/test/test_functools.py
View file @
1d0bb9c8
...
@@ -179,6 +179,25 @@ class TestPartial(unittest.TestCase):
...
@@ -179,6 +179,25 @@ class TestPartial(unittest.TestCase):
f_copy
=
pickle
.
loads
(
pickle
.
dumps
(
f
))
f_copy
=
pickle
.
loads
(
pickle
.
dumps
(
f
))
self
.
assertEqual
(
signature
(
f
),
signature
(
f_copy
))
self
.
assertEqual
(
signature
(
f
),
signature
(
f_copy
))
# Issue 6083: Reference counting bug
def
test_setstate_refcount
(
self
):
class
BadSequence
:
def
__len__
(
self
):
return
4
def
__getitem__
(
self
,
key
):
if
key
==
0
:
return
max
elif
key
==
1
:
return
tuple
(
range
(
1000000
))
elif
key
in
(
2
,
3
):
return
{}
raise
IndexError
f
=
self
.
thetype
(
object
)
self
.
assertRaisesRegex
(
SystemError
,
"new style getargs format but argument is not a tuple"
,
f
.
__setstate__
,
BadSequence
())
class
PartialSubclass
(
functools
.
partial
):
class
PartialSubclass
(
functools
.
partial
):
pass
pass
...
@@ -195,6 +214,7 @@ class TestPythonPartial(TestPartial):
...
@@ -195,6 +214,7 @@ class TestPythonPartial(TestPartial):
# the python version isn't picklable
# the python version isn't picklable
def
test_pickle
(
self
):
pass
def
test_pickle
(
self
):
pass
def
test_setstate_refcount
(
self
):
pass
class
TestUpdateWrapper
(
unittest
.
TestCase
):
class
TestUpdateWrapper
(
unittest
.
TestCase
):
...
...
Lib/test/test_resource.py
View file @
1d0bb9c8
...
@@ -107,6 +107,23 @@ class ResourceTest(unittest.TestCase):
...
@@ -107,6 +107,23 @@ class ResourceTest(unittest.TestCase):
except
(
ValueError
,
AttributeError
):
except
(
ValueError
,
AttributeError
):
pass
pass
# Issue 6083: Reference counting bug
def
test_setrusage_refcount
(
self
):
try
:
limits
=
resource
.
getrlimit
(
resource
.
RLIMIT_CPU
)
except
AttributeError
:
pass
else
:
class
BadSequence
:
def
__len__
(
self
):
return
2
def
__getitem__
(
self
,
key
):
if
key
in
(
0
,
1
):
return
len
(
tuple
(
range
(
1000000
)))
raise
IndexError
resource
.
setrlimit
(
resource
.
RLIMIT_CPU
,
BadSequence
())
def
test_main
(
verbose
=
None
):
def
test_main
(
verbose
=
None
):
support
.
run_unittest
(
ResourceTest
)
support
.
run_unittest
(
ResourceTest
)
...
...
Misc/NEWS
View file @
1d0bb9c8
...
@@ -163,6 +163,9 @@ Core and Builtins
...
@@ -163,6 +163,9 @@ Core and Builtins
Library
Library
-------
-------
- Issue #6083: Fix multiple segmentation faults occured when PyArg_ParseTuple
parses nested mutating sequence.
- Issue #5289: Fix ctypes.util.find_library on Solaris.
- Issue #5289: Fix ctypes.util.find_library on Solaris.
- Issue #17106: Fix a segmentation fault in io.TextIOWrapper when an underlying
- Issue #17106: Fix a segmentation fault in io.TextIOWrapper when an underlying
...
...
Modules/_ctypes/_ctypes.c
View file @
1d0bb9c8
...
@@ -3188,23 +3188,37 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
...
@@ -3188,23 +3188,37 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
{
char
*
name
;
char
*
name
;
int
(
*
address
)(
void
);
int
(
*
address
)(
void
);
PyObject
*
ftuple
;
PyObject
*
dll
;
PyObject
*
dll
;
PyObject
*
obj
;
PyObject
*
obj
;
PyCFuncPtrObject
*
self
;
PyCFuncPtrObject
*
self
;
void
*
handle
;
void
*
handle
;
PyObject
*
paramflags
=
NULL
;
PyObject
*
paramflags
=
NULL
;
if
(
!
PyArg_ParseTuple
(
args
,
"
(O&O)|O"
,
_get_name
,
&
name
,
&
dll
,
&
paramflags
))
if
(
!
PyArg_ParseTuple
(
args
,
"
O|O"
,
&
ftuple
,
&
paramflags
))
return
NULL
;
return
NULL
;
if
(
paramflags
==
Py_None
)
if
(
paramflags
==
Py_None
)
paramflags
=
NULL
;
paramflags
=
NULL
;
ftuple
=
PySequence_Tuple
(
ftuple
);
if
(
!
ftuple
)
/* Here ftuple is a borrowed reference */
return
NULL
;
if
(
!
PyArg_ParseTuple
(
ftuple
,
"O&O"
,
_get_name
,
&
name
,
&
dll
))
{
Py_DECREF
(
ftuple
);
return
NULL
;
}
obj
=
PyObject_GetAttrString
(
dll
,
"_handle"
);
obj
=
PyObject_GetAttrString
(
dll
,
"_handle"
);
if
(
!
obj
)
if
(
!
obj
)
{
Py_DECREF
(
ftuple
);
return
NULL
;
return
NULL
;
}
if
(
!
PyLong_Check
(
obj
))
{
if
(
!
PyLong_Check
(
obj
))
{
PyErr_SetString
(
PyExc_TypeError
,
PyErr_SetString
(
PyExc_TypeError
,
"the _handle attribute of the second argument must be an integer"
);
"the _handle attribute of the second argument must be an integer"
);
Py_DECREF
(
ftuple
);
Py_DECREF
(
obj
);
Py_DECREF
(
obj
);
return
NULL
;
return
NULL
;
}
}
...
@@ -3213,6 +3227,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
...
@@ -3213,6 +3227,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
if
(
PyErr_Occurred
())
{
if
(
PyErr_Occurred
())
{
PyErr_SetString
(
PyExc_ValueError
,
PyErr_SetString
(
PyExc_ValueError
,
"could not convert the _handle attribute to a pointer"
);
"could not convert the _handle attribute to a pointer"
);
Py_DECREF
(
ftuple
);
return
NULL
;
return
NULL
;
}
}
...
@@ -3227,6 +3242,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
...
@@ -3227,6 +3242,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
PyErr_Format
(
PyExc_AttributeError
,
PyErr_Format
(
PyExc_AttributeError
,
"function ordinal %d not found"
,
"function ordinal %d not found"
,
(
WORD
)(
size_t
)
name
);
(
WORD
)(
size_t
)
name
);
Py_DECREF
(
ftuple
);
return
NULL
;
return
NULL
;
}
}
#else
#else
...
@@ -3240,9 +3256,12 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
...
@@ -3240,9 +3256,12 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
#else
#else
PyErr_SetString
(
PyExc_AttributeError
,
ctypes_dlerror
());
PyErr_SetString
(
PyExc_AttributeError
,
ctypes_dlerror
());
#endif
#endif
Py_DECREF
(
ftuple
);
return
NULL
;
return
NULL
;
}
}
#endif
#endif
Py_INCREF
(
dll
);
/* for KeepRef */
Py_DECREF
(
ftuple
);
if
(
!
_validate_paramflags
(
type
,
paramflags
))
if
(
!
_validate_paramflags
(
type
,
paramflags
))
return
NULL
;
return
NULL
;
...
@@ -3255,7 +3274,6 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
...
@@ -3255,7 +3274,6 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
*
(
void
**
)
self
->
b_ptr
=
address
;
*
(
void
**
)
self
->
b_ptr
=
address
;
Py_INCREF
((
PyObject
*
)
dll
);
/* for KeepRef */
if
(
-
1
==
KeepRef
((
CDataObject
*
)
self
,
0
,
dll
))
{
if
(
-
1
==
KeepRef
((
CDataObject
*
)
self
,
0
,
dll
))
{
Py_DECREF
((
PyObject
*
)
self
);
Py_DECREF
((
PyObject
*
)
self
);
return
NULL
;
return
NULL
;
...
...
Modules/_functoolsmodule.c
View file @
1d0bb9c8
...
@@ -218,10 +218,10 @@ partial_reduce(partialobject *pto, PyObject *unused)
...
@@ -218,10 +218,10 @@ partial_reduce(partialobject *pto, PyObject *unused)
}
}
static
PyObject
*
static
PyObject
*
partial_setstate
(
partialobject
*
pto
,
PyObject
*
args
)
partial_setstate
(
partialobject
*
pto
,
PyObject
*
state
)
{
{
PyObject
*
fn
,
*
fnargs
,
*
kw
,
*
dict
;
PyObject
*
fn
,
*
fnargs
,
*
kw
,
*
dict
;
if
(
!
PyArg_ParseTuple
(
args
,
"(OOOO):__setstate__
"
,
if
(
!
PyArg_ParseTuple
(
state
,
"OOOO
"
,
&
fn
,
&
fnargs
,
&
kw
,
&
dict
))
&
fn
,
&
fnargs
,
&
kw
,
&
dict
))
return
NULL
;
return
NULL
;
Py_XDECREF
(
pto
->
fn
);
Py_XDECREF
(
pto
->
fn
);
...
@@ -245,7 +245,7 @@ partial_setstate(partialobject *pto, PyObject *args)
...
@@ -245,7 +245,7 @@ partial_setstate(partialobject *pto, PyObject *args)
static
PyMethodDef
partial_methods
[]
=
{
static
PyMethodDef
partial_methods
[]
=
{
{
"__reduce__"
,
(
PyCFunction
)
partial_reduce
,
METH_NOARGS
},
{
"__reduce__"
,
(
PyCFunction
)
partial_reduce
,
METH_NOARGS
},
{
"__setstate__"
,
(
PyCFunction
)
partial_setstate
,
METH_
VARARGS
},
{
"__setstate__"
,
(
PyCFunction
)
partial_setstate
,
METH_
O
},
{
NULL
,
NULL
}
/* sentinel */
{
NULL
,
NULL
}
/* sentinel */
};
};
...
...
Modules/resource.c
View file @
1d0bb9c8
...
@@ -142,10 +142,9 @@ resource_setrlimit(PyObject *self, PyObject *args)
...
@@ -142,10 +142,9 @@ resource_setrlimit(PyObject *self, PyObject *args)
{
{
struct
rlimit
rl
;
struct
rlimit
rl
;
int
resource
;
int
resource
;
PyObject
*
curobj
,
*
maxobj
;
PyObject
*
limits
,
*
curobj
,
*
maxobj
;
if
(
!
PyArg_ParseTuple
(
args
,
"i(OO):setrlimit"
,
if
(
!
PyArg_ParseTuple
(
args
,
"iO:setrlimit"
,
&
resource
,
&
limits
))
&
resource
,
&
curobj
,
&
maxobj
))
return
NULL
;
return
NULL
;
if
(
resource
<
0
||
resource
>=
RLIM_NLIMITS
)
{
if
(
resource
<
0
||
resource
>=
RLIM_NLIMITS
)
{
...
@@ -154,21 +153,34 @@ resource_setrlimit(PyObject *self, PyObject *args)
...
@@ -154,21 +153,34 @@ resource_setrlimit(PyObject *self, PyObject *args)
return
NULL
;
return
NULL
;
}
}
limits
=
PySequence_Tuple
(
limits
);
if
(
!
limits
)
/* Here limits is a borrowed reference */
return
NULL
;
if
(
PyTuple_GET_SIZE
(
limits
)
!=
2
)
{
PyErr_SetString
(
PyExc_ValueError
,
"expected a tuple of 2 integers"
);
goto
error
;
}
curobj
=
PyTuple_GET_ITEM
(
limits
,
0
);
maxobj
=
PyTuple_GET_ITEM
(
limits
,
1
);
#if !defined(HAVE_LARGEFILE_SUPPORT)
#if !defined(HAVE_LARGEFILE_SUPPORT)
rl
.
rlim_cur
=
PyLong_AsLong
(
curobj
);
rl
.
rlim_cur
=
PyLong_AsLong
(
curobj
);
if
(
rl
.
rlim_cur
==
(
rlim_t
)
-
1
&&
PyErr_Occurred
())
if
(
rl
.
rlim_cur
==
(
rlim_t
)
-
1
&&
PyErr_Occurred
())
return
NULL
;
goto
error
;
rl
.
rlim_max
=
PyLong_AsLong
(
maxobj
);
rl
.
rlim_max
=
PyLong_AsLong
(
maxobj
);
if
(
rl
.
rlim_max
==
(
rlim_t
)
-
1
&&
PyErr_Occurred
())
if
(
rl
.
rlim_max
==
(
rlim_t
)
-
1
&&
PyErr_Occurred
())
return
NULL
;
goto
error
;
#else
#else
/* The limits are probably bigger than a long */
/* The limits are probably bigger than a long */
rl
.
rlim_cur
=
PyLong_AsLongLong
(
curobj
);
rl
.
rlim_cur
=
PyLong_AsLongLong
(
curobj
);
if
(
rl
.
rlim_cur
==
(
rlim_t
)
-
1
&&
PyErr_Occurred
())
if
(
rl
.
rlim_cur
==
(
rlim_t
)
-
1
&&
PyErr_Occurred
())
return
NULL
;
goto
error
;
rl
.
rlim_max
=
PyLong_AsLongLong
(
maxobj
);
rl
.
rlim_max
=
PyLong_AsLongLong
(
maxobj
);
if
(
rl
.
rlim_max
==
(
rlim_t
)
-
1
&&
PyErr_Occurred
())
if
(
rl
.
rlim_max
==
(
rlim_t
)
-
1
&&
PyErr_Occurred
())
return
NULL
;
goto
error
;
#endif
#endif
rl
.
rlim_cur
=
rl
.
rlim_cur
&
RLIM_INFINITY
;
rl
.
rlim_cur
=
rl
.
rlim_cur
&
RLIM_INFINITY
;
...
@@ -182,10 +194,15 @@ resource_setrlimit(PyObject *self, PyObject *args)
...
@@ -182,10 +194,15 @@ resource_setrlimit(PyObject *self, PyObject *args)
"not allowed to raise maximum limit"
);
"not allowed to raise maximum limit"
);
else
else
PyErr_SetFromErrno
(
PyExc_OSError
);
PyErr_SetFromErrno
(
PyExc_OSError
);
return
NULL
;
goto
error
;
}
}
Py_DECREF
(
limits
);
Py_INCREF
(
Py_None
);
Py_INCREF
(
Py_None
);
return
Py_None
;
return
Py_None
;
error:
Py_DECREF
(
limits
);
return
NULL
;
}
}
static
PyObject
*
static
PyObject
*
...
...
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