Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
7b1de1e5
Commit
7b1de1e5
authored
Sep 03, 2017
by
Dean Moldovan
Browse files
Fix nullptr dereference when loading an external-only module_local type
parent
3c4933cb
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
40 additions
and
6 deletions
+40
-6
docs/changelog.rst
docs/changelog.rst
+4
-0
include/pybind11/cast.h
include/pybind11/cast.h
+5
-3
tests/local_bindings.h
tests/local_bindings.h
+7
-3
tests/pybind11_cross_module_tests.cpp
tests/pybind11_cross_module_tests.cpp
+4
-0
tests/test_local_bindings.cpp
tests/test_local_bindings.cpp
+4
-0
tests/test_local_bindings.py
tests/test_local_bindings.py
+16
-0
No files found.
docs/changelog.rst
View file @
7b1de1e5
...
...
@@ -28,6 +28,10 @@ v2.2.1 (Not yet released)
* Relax overly strict ``py::picke()`` check for matching get and set types.
`#1064 <https://github.com/pybind/pybind11/pull/1064>`_.
* Fixed a nullptr dereference when loading a ``py::module_local`` type
that's only registered in an external module.
`#1058 <https://github.com/pybind/pybind11/pull/1058>`_.
v2.2.0 (August 31, 2017)
-----------------------------------------------------
...
...
include/pybind11/cast.h
View file @
7b1de1e5
...
...
@@ -482,9 +482,10 @@ inline PyObject *make_new_instance(PyTypeObject *type);
class
type_caster_generic
{
public:
PYBIND11_NOINLINE
type_caster_generic
(
const
std
::
type_info
&
type_info
)
:
typeinfo
(
get_type_info
(
type_info
))
{
}
:
typeinfo
(
get_type_info
(
type_info
))
,
cpptype
(
&
type_info
)
{
}
type_caster_generic
(
const
type_info
*
typeinfo
)
:
typeinfo
(
typeinfo
)
{
}
type_caster_generic
(
const
type_info
*
typeinfo
)
:
typeinfo
(
typeinfo
),
cpptype
(
typeinfo
?
typeinfo
->
cpptype
:
nullptr
)
{
}
bool
load
(
handle
src
,
bool
convert
)
{
return
load_impl
<
type_caster_generic
>
(
src
,
convert
);
...
...
@@ -610,7 +611,7 @@ public:
type_info
*
foreign_typeinfo
=
reinterpret_borrow
<
capsule
>
(
getattr
(
pytype
,
local_key
));
// Only consider this foreign loader if actually foreign and is a loader of the correct cpp type
if
(
foreign_typeinfo
->
module_local_load
==
&
local_load
||
!
same_type
(
*
typeinfo
->
cpptype
,
*
foreign_typeinfo
->
cpptype
))
||
(
cpptype
&&
!
same_type
(
*
cpptype
,
*
foreign_typeinfo
->
cpptype
))
)
return
false
;
if
(
auto
result
=
foreign_typeinfo
->
module_local_load
(
src
.
ptr
(),
foreign_typeinfo
))
{
...
...
@@ -722,6 +723,7 @@ public:
}
const
type_info
*
typeinfo
=
nullptr
;
const
std
::
type_info
*
cpptype
=
nullptr
;
void
*
value
=
nullptr
;
};
...
...
tests/local_bindings.h
View file @
7b1de1e5
...
...
@@ -8,9 +8,9 @@ public:
int
i
=
-
1
;
};
/// Registered with py::local in both main and secondary modules:
/// Registered with py::
module_
local in both main and secondary modules:
using
LocalType
=
LocalBase
<
0
>
;
/// Registered without py::local in both modules:
/// Registered without py::
module_
local in both modules:
using
NonLocalType
=
LocalBase
<
1
>
;
/// A second non-local type (for stl_bind tests):
using
NonLocal2
=
LocalBase
<
2
>
;
...
...
@@ -21,6 +21,10 @@ using MixedLocalGlobal = LocalBase<4>;
/// Mixed: global first, then local
using
MixedGlobalLocal
=
LocalBase
<
5
>
;
/// Registered with py::module_local only in the secondary module:
using
ExternalType1
=
LocalBase
<
6
>
;
using
ExternalType2
=
LocalBase
<
7
>
;
using
LocalVec
=
std
::
vector
<
LocalType
>
;
using
LocalVec2
=
std
::
vector
<
NonLocal2
>
;
using
LocalMap
=
std
::
unordered_map
<
std
::
string
,
LocalType
>
;
...
...
@@ -39,7 +43,7 @@ PYBIND11_MAKE_OPAQUE(NonLocalMap2);
// Simple bindings (used with the above):
template
<
typename
T
,
int
Adjust
,
typename
...
Args
>
template
<
typename
T
,
int
Adjust
=
0
,
typename
...
Args
>
py
::
class_
<
T
>
bind_local
(
Args
&&
...
args
)
{
return
py
::
class_
<
T
>
(
std
::
forward
<
Args
>
(
args
)...)
.
def
(
py
::
init
<
int
>
())
...
...
tests/pybind11_cross_module_tests.cpp
View file @
7b1de1e5
...
...
@@ -20,6 +20,10 @@ PYBIND11_MODULE(pybind11_cross_module_tests, m) {
// Definitions here are tested by importing both this module and the
// relevant pybind11_tests submodule from a test_whatever.py
// test_load_external
bind_local
<
ExternalType1
>
(
m
,
"ExternalType1"
,
py
::
module_local
());
bind_local
<
ExternalType2
>
(
m
,
"ExternalType2"
,
py
::
module_local
());
// test_exceptions.py
m
.
def
(
"raise_runtime_error"
,
[]()
{
PyErr_SetString
(
PyExc_RuntimeError
,
"My runtime error"
);
throw
py
::
error_already_set
();
});
m
.
def
(
"raise_value_error"
,
[]()
{
PyErr_SetString
(
PyExc_ValueError
,
"My value error"
);
throw
py
::
error_already_set
();
});
...
...
tests/test_local_bindings.cpp
View file @
7b1de1e5
...
...
@@ -15,6 +15,10 @@
#include <numeric>
TEST_SUBMODULE
(
local_bindings
,
m
)
{
// test_load_external
m
.
def
(
"load_external1"
,
[](
ExternalType1
&
e
)
{
return
e
.
i
;
});
m
.
def
(
"load_external2"
,
[](
ExternalType2
&
e
)
{
return
e
.
i
;
});
// test_local_bindings
// Register a class with py::module_local:
bind_local
<
LocalType
,
-
1
>
(
m
,
"LocalType"
,
py
::
module_local
())
...
...
tests/test_local_bindings.py
View file @
7b1de1e5
...
...
@@ -3,6 +3,22 @@ import pytest
from
pybind11_tests
import
local_bindings
as
m
def
test_load_external
():
"""Load a `py::module_local` type that's only registered in an external module"""
import
pybind11_cross_module_tests
as
cm
assert
m
.
load_external1
(
cm
.
ExternalType1
(
11
))
==
11
assert
m
.
load_external2
(
cm
.
ExternalType2
(
22
))
==
22
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
assert
m
.
load_external2
(
cm
.
ExternalType1
(
21
))
==
21
assert
"incompatible function arguments"
in
str
(
excinfo
.
value
)
with
pytest
.
raises
(
TypeError
)
as
excinfo
:
assert
m
.
load_external1
(
cm
.
ExternalType2
(
12
))
==
12
assert
"incompatible function arguments"
in
str
(
excinfo
.
value
)
def
test_local_bindings
():
"""Tests that duplicate `py::module_local` class bindings work across modules"""
...
...
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