fix: fully qualify usages of concat to protect against ADL (#4955)

* Call concat with proper namespace in cast.h

* Apply suggestions from code review

* tests: add test for ADL on concat

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* fix: fully qualify all usages of concat

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
This commit is contained in:
Matthias Volk 2024-03-27 21:51:03 +01:00 committed by GitHub
parent 0efff79f01
commit 67c9c5687b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 31 additions and 13 deletions

View File

@ -672,8 +672,9 @@ public:
return cast(*src, policy, parent); return cast(*src, policy, parent);
} }
static constexpr auto name static constexpr auto name = const_name("tuple[")
= const_name("tuple[") + concat(make_caster<Ts>::name...) + const_name("]"); + ::pybind11::detail::concat(make_caster<Ts>::name...)
+ const_name("]");
template <typename T> template <typename T>
using cast_op_type = type; using cast_op_type = type;
@ -1569,7 +1570,8 @@ public:
static_assert(args_pos == -1 || args_pos == constexpr_first<argument_is_args, Args...>(), static_assert(args_pos == -1 || args_pos == constexpr_first<argument_is_args, Args...>(),
"py::args cannot be specified more than once"); "py::args cannot be specified more than once");
static constexpr auto arg_names = concat(type_descr(make_caster<Args>::name)...); static constexpr auto arg_names
= ::pybind11::detail::concat(type_descr(make_caster<Args>::name)...);
bool load_args(function_call &call) { return load_impl_sequence(call, indices{}); } bool load_args(function_call &call) { return load_impl_sequence(call, indices{}); }

View File

@ -70,7 +70,7 @@ struct eigen_tensor_helper<Eigen::Tensor<Scalar_, NumIndices_, Options_, IndexTy
template <size_t... Is> template <size_t... Is>
struct helper<index_sequence<Is...>> { struct helper<index_sequence<Is...>> {
static constexpr auto value = concat(const_name(((void) Is, "?"))...); static constexpr auto value = ::pybind11::detail::concat(const_name(((void) Is, "?"))...);
}; };
static constexpr auto dimensions_descriptor static constexpr auto dimensions_descriptor
@ -104,7 +104,8 @@ struct eigen_tensor_helper<
return get_shape() == shape; return get_shape() == shape;
} }
static constexpr auto dimensions_descriptor = concat(const_name<Indices>()...); static constexpr auto dimensions_descriptor
= ::pybind11::detail::concat(const_name<Indices>()...);
template <typename... Args> template <typename... Args>
static Type *alloc(Args &&...args) { static Type *alloc(Args &&...args) {

View File

@ -128,7 +128,8 @@ public:
} }
PYBIND11_TYPE_CASTER(type, PYBIND11_TYPE_CASTER(type,
const_name("Callable[[") + concat(make_caster<Args>::name...) const_name("Callable[[")
+ ::pybind11::detail::concat(make_caster<Args>::name...)
+ const_name("], ") + make_caster<retval_type>::name + const_name("], ") + make_caster<retval_type>::name
+ const_name("]")); + const_name("]"));
}; };

View File

@ -446,7 +446,7 @@ struct array_info<std::array<T, N>> {
} }
static constexpr auto extents = const_name<array_info<T>::is_array>( static constexpr auto extents = const_name<array_info<T>::is_array>(
concat(const_name<N>(), array_info<T>::extents), const_name<N>()); ::pybind11::detail::concat(const_name<N>(), array_info<T>::extents), const_name<N>());
}; };
// For numpy we have special handling for arrays of characters, so we don't include // For numpy we have special handling for arrays of characters, so we don't include
// the size in the array extents. // the size in the array extents.

View File

@ -421,7 +421,8 @@ struct variant_caster<V<Ts...>> {
using Type = V<Ts...>; using Type = V<Ts...>;
PYBIND11_TYPE_CASTER(Type, PYBIND11_TYPE_CASTER(Type,
const_name("Union[") + detail::concat(make_caster<Ts>::name...) const_name("Union[")
+ ::pybind11::detail::concat(make_caster<Ts>::name...)
+ const_name("]")); + const_name("]"));
}; };

View File

@ -69,8 +69,9 @@ PYBIND11_NAMESPACE_BEGIN(detail)
template <typename... Types> template <typename... Types>
struct handle_type_name<typing::Tuple<Types...>> { struct handle_type_name<typing::Tuple<Types...>> {
static constexpr auto name static constexpr auto name = const_name("tuple[")
= const_name("tuple[") + concat(make_caster<Types>::name...) + const_name("]"); + ::pybind11::detail::concat(make_caster<Types>::name...)
+ const_name("]");
}; };
template <> template <>
@ -115,9 +116,9 @@ struct handle_type_name<typing::Iterator<T>> {
template <typename Return, typename... Args> template <typename Return, typename... Args>
struct handle_type_name<typing::Callable<Return(Args...)>> { struct handle_type_name<typing::Callable<Return(Args...)>> {
using retval_type = conditional_t<std::is_same<Return, void>::value, void_type, Return>; using retval_type = conditional_t<std::is_same<Return, void>::value, void_type, Return>;
static constexpr auto name = const_name("Callable[[") + concat(make_caster<Args>::name...) static constexpr auto name
+ const_name("], ") + make_caster<retval_type>::name = const_name("Callable[[") + ::pybind11::detail::concat(make_caster<Args>::name...)
+ const_name("]"); + const_name("], ") + make_caster<retval_type>::name + const_name("]");
}; };
PYBIND11_NAMESPACE_END(detail) PYBIND11_NAMESPACE_END(detail)

View File

@ -134,6 +134,16 @@ struct type_caster<other_lib::MyType> : public other_lib::my_caster {};
} // namespace detail } // namespace detail
} // namespace PYBIND11_NAMESPACE } // namespace PYBIND11_NAMESPACE
// This simply is required to compile
namespace ADL_issue {
template <typename OutStringType = std::string, typename... Args>
OutStringType concat(Args &&...) {
return OutStringType();
}
struct test {};
} // namespace ADL_issue
TEST_SUBMODULE(custom_type_casters, m) { TEST_SUBMODULE(custom_type_casters, m) {
// test_custom_type_casters // test_custom_type_casters
@ -206,4 +216,6 @@ TEST_SUBMODULE(custom_type_casters, m) {
py::return_value_policy::reference); py::return_value_policy::reference);
m.def("other_lib_type", [](other_lib::MyType x) { return x; }); m.def("other_lib_type", [](other_lib::MyType x) { return x; });
m.def("_adl_issue", [](const ADL_issue::test &) {});
} }