Check that types passed to PHYSFS_read are POD
More is needed to trap some misuses, but those traps flag existing code.
This commit is contained in:
parent
e6a691c5c7
commit
dc42dad15a
|
@ -55,6 +55,61 @@
|
|||
DXX_PHYSFS_CHECK_WRITE_ELEMENT_SIZE_CONSTANT(S,C); \
|
||||
DXX_PHYSFS_CHECK_WRITE_SIZE_ARRAY_SIZE(S,C); \
|
||||
|
||||
template <typename V>
|
||||
static inline typename tt::enable_if<tt::is_integral<V>::value, PHYSFS_sint64>::type PHYSFSX_check_read(PHYSFS_file *file, V *v, PHYSFS_uint32 S, PHYSFS_uint32 C)
|
||||
{
|
||||
static_assert(tt::is_pod<V>::value, "non-POD integral value read");
|
||||
#if defined(DXX_HAVE_BUILTIN_CONSTANT_P) && defined(DXX_HAVE_BUILTIN_OBJECT_SIZE)
|
||||
if (__builtin_object_size(v, 1) != -1 && dxx_builtin_constant_p(S * C) && S * C > __builtin_object_size(v, 1))
|
||||
DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_overwrite, "read size exceeds element size");
|
||||
#endif
|
||||
return PHYSFS_read(file, v, S, C);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
static inline typename tt::enable_if<!tt::is_integral<V>::value, PHYSFS_sint64>::type PHYSFSX_check_read(PHYSFS_file *file, V *v, PHYSFS_uint32 S, PHYSFS_uint32 C)
|
||||
{
|
||||
static_assert(tt::is_pod<V>::value, "non-POD non-integral value read");
|
||||
#if defined(DXX_HAVE_BUILTIN_CONSTANT_P) && defined(DXX_HAVE_BUILTIN_OBJECT_SIZE)
|
||||
if (__builtin_object_size(v, 1) != -1 && dxx_builtin_constant_p(S * C > __builtin_object_size(v, 1)) && S * C > __builtin_object_size(v, 1))
|
||||
DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_overwrite, "read size exceeds object size");
|
||||
#endif
|
||||
return PHYSFS_read(file, v, S, C);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
static inline typename tt::enable_if<tt::is_array<V>::value, PHYSFS_sint64>::type PHYSFSX_check_read(PHYSFS_file *file, V &v, PHYSFS_uint32 S, PHYSFS_uint32 C)
|
||||
{
|
||||
typedef typename tt::remove_extent<V>::type V0;
|
||||
static_assert(tt::is_pod<V0>::value, "C array of non-POD elements read");
|
||||
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
|
||||
if (dxx_builtin_constant_p(S * C > sizeof(v)) && S * C > sizeof(v))
|
||||
DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_overwrite, "read size exceeds array size");
|
||||
#endif
|
||||
return PHYSFSX_check_read(file, &v[0], S, C);
|
||||
}
|
||||
|
||||
template <typename V, std::size_t N>
|
||||
static inline PHYSFS_sint64 PHYSFSX_check_read(PHYSFS_file *file, array<V, N> &v, PHYSFS_uint32 S, PHYSFS_uint32 C)
|
||||
{
|
||||
static_assert(tt::is_pod<V>::value, "C++ array of non-POD elements read");
|
||||
#ifdef DXX_HAVE_BUILTIN_CONSTANT_P
|
||||
if (dxx_builtin_constant_p(S * C > sizeof(v)) && S * C > sizeof(v))
|
||||
DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_overwrite, "read size exceeds array size");
|
||||
#endif
|
||||
return PHYSFSX_check_read(file, &v[0], S, C);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
static inline PHYSFS_sint64 PHYSFSX_check_read(PHYSFS_file *file, const RAIIdmem<V> &v, PHYSFS_uint32 S, PHYSFS_uint32 C)
|
||||
{
|
||||
#if defined(DXX_HAVE_BUILTIN_CONSTANT_P) && defined(DXX_HAVE_BUILTIN_OBJECT_SIZE)
|
||||
if (__builtin_object_size(v, 1) != -1 && dxx_builtin_constant_p(S * C > __builtin_object_size(v, 1)) && S * C > __builtin_object_size(v, 1))
|
||||
DXX_ALWAYS_ERROR_FUNCTION(dxx_trap_overwrite, "read size exceeds allocated size");
|
||||
#endif
|
||||
return PHYSFS_read(file, v, S, C);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
static inline typename tt::enable_if<tt::is_integral<V>::value, PHYSFS_sint64>::type PHYSFSX_check_write(PHYSFS_file *file, const V *v, PHYSFS_uint32 S, PHYSFS_uint32 C)
|
||||
{
|
||||
|
@ -97,8 +152,11 @@ static inline PHYSFS_sint64 PHYSFSX_check_write(PHYSFS_file *file, const RAIIdme
|
|||
return PHYSFS_write(file, v, S, C);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
PHYSFS_sint64 PHYSFSX_check_read(PHYSFS_file *file, exact_type<V> v, PHYSFS_uint32 S, PHYSFS_uint32 C) DXX_CXX11_EXPLICIT_DELETE;
|
||||
template <typename V>
|
||||
PHYSFS_sint64 PHYSFSX_check_write(PHYSFS_file *file, exact_type<V> v, PHYSFS_uint32 S, PHYSFS_uint32 C) DXX_CXX11_EXPLICIT_DELETE;
|
||||
#define PHYSFS_read(F,V,S,C) PHYSFSX_check_read(F,V,S,C)
|
||||
#define PHYSFS_write(F,V,S,C) PHYSFSX_check_write(F,V,S,C)
|
||||
|
||||
extern void PHYSFSX_init(int argc, char *argv[]);
|
||||
|
|
Loading…
Reference in a new issue