Prevent make_span from working with vectors and arrays of pointers (#8735)

* Prevent `make_span` from working with vectors and arrays of pointers

* support `make_structs_span` for little-endian

* fix build: add the required parentheses

---------

Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
This commit is contained in:
are-you-tilted-already
2025-11-05 00:47:44 +03:00
committed by GitHub
parent 592dc50037
commit 5ed02dc04a
2 changed files with 39 additions and 4 deletions

View File

@@ -39,10 +39,11 @@ class Array {
typedef VectorConstIterator<T, return_type, uoffset_t> const_iterator;
typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
// If T is a LE-scalar or a struct (!scalar_tag::value).
// If T is a non-pointer and a LE-scalar or a struct (!scalar_tag::value).
static FLATBUFFERS_CONSTEXPR bool is_span_observable =
(scalar_tag::value && (FLATBUFFERS_LITTLEENDIAN || sizeof(T) == 1)) ||
!scalar_tag::value;
!std::is_pointer<T>::value &&
((scalar_tag::value && (FLATBUFFERS_LITTLEENDIAN || sizeof(T) == 1)) ||
!scalar_tag::value);
FLATBUFFERS_CONSTEXPR uint16_t size() const { return length; }

View File

@@ -172,7 +172,8 @@ class Vector {
scalar_tag;
static FLATBUFFERS_CONSTEXPR bool is_span_observable =
scalar_tag::value && (FLATBUFFERS_LITTLEENDIAN || sizeof(T) == 1);
scalar_tag::value && !std::is_pointer<T>::value &&
(FLATBUFFERS_LITTLEENDIAN || sizeof(T) == 1);
SizeT size() const { return EndianScalar(length_); }
@@ -359,6 +360,22 @@ FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const uint8_t> make_bytes_span(
return span<const uint8_t>(vec.Data(), vec.size() * sizeof(U));
}
#if FLATBUFFERS_LITTLEENDIAN
template <class U>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_structs_span(
Vector<const U*>& vec) FLATBUFFERS_NOEXCEPT {
return span<U>(reinterpret_cast<U*>(vec.data()), vec.size());
}
template <class U>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_structs_span(
const Vector<const U*>& vec) FLATBUFFERS_NOEXCEPT {
return span<const U>(reinterpret_cast<const U*>(vec.data()), vec.size());
}
#endif
// Convenient helper functions to get a span of any vector, regardless
// of whether it is null or not (the field is not set).
template <class U>
@@ -377,6 +394,23 @@ FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
return ptr ? make_span(*ptr) : span<const U>();
}
#if FLATBUFFERS_LITTLEENDIAN
template <class U>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_structs_span(
Vector<const U*>* ptr) FLATBUFFERS_NOEXCEPT {
return ptr ? make_span(*ptr) : span<U>();
}
template <class U>
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_structs_span(
const Vector<const U*>* ptr) FLATBUFFERS_NOEXCEPT {
return ptr ? make_span(*ptr) : span<const U>();
}
#endif
// Represent a vector much like the template above, but in this case we
// don't know what the element types are (used with reflection.h).
class VectorOfAny {