mirror of https://github.com/encounter/SDL.git
stdinc: Add overflow-checking add and multiply for size_t
This can be used to check whether untrusted sizes would cause overflow when used to calculate how much memory is needed. Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
parent
6e6e425e23
commit
f661654fad
|
@ -115,6 +115,12 @@ char *alloca();
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SIZE_MAX
|
||||||
|
# define SDL_SIZE_MAX SIZE_MAX
|
||||||
|
#else
|
||||||
|
# define SDL_SIZE_MAX ((size_t) -1)
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the compiler supports a given builtin.
|
* Check if the compiler supports a given builtin.
|
||||||
* Supported by virtually all clang versions and recent gcc. Use this
|
* Supported by virtually all clang versions and recent gcc. Use this
|
||||||
|
@ -728,6 +734,60 @@ SDL_FORCE_INLINE void *SDL_memcpy4(SDL_OUT_BYTECAP(dwords*4) void *dst, SDL_IN_B
|
||||||
return SDL_memcpy(dst, src, dwords * 4);
|
return SDL_memcpy(dst, src, dwords * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a * b would overflow, return -1. Otherwise store a * b via ret
|
||||||
|
* and return 0.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 2.24.0.
|
||||||
|
*/
|
||||||
|
SDL_FORCE_INLINE int SDL_size_mul_overflow (size_t a,
|
||||||
|
size_t b,
|
||||||
|
size_t *ret)
|
||||||
|
{
|
||||||
|
if (a != 0 && b > SDL_SIZE_MAX / a) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*ret = a * b;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if _SDL_HAS_BUILTIN(__builtin_mul_overflow)
|
||||||
|
SDL_FORCE_INLINE int _SDL_size_mul_overflow_builtin (size_t a,
|
||||||
|
size_t b,
|
||||||
|
size_t *ret)
|
||||||
|
{
|
||||||
|
return __builtin_mul_overflow(a, b, ret) == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
#define SDL_size_mul_overflow(a, b, ret) (_SDL_size_mul_overflow_builtin(a, b, ret))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a + b would overflow, return -1. Otherwise store a + b via ret
|
||||||
|
* and return 0.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 2.24.0.
|
||||||
|
*/
|
||||||
|
SDL_FORCE_INLINE int SDL_size_add_overflow (size_t a,
|
||||||
|
size_t b,
|
||||||
|
size_t *ret)
|
||||||
|
{
|
||||||
|
if (b > SDL_SIZE_MAX - a) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*ret = a + b;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if _SDL_HAS_BUILTIN(__builtin_add_overflow)
|
||||||
|
SDL_FORCE_INLINE int _SDL_size_add_overflow_builtin (size_t a,
|
||||||
|
size_t b,
|
||||||
|
size_t *ret)
|
||||||
|
{
|
||||||
|
return __builtin_add_overflow(a, b, ret) == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
#define SDL_size_add_overflow(a, b, ret) (_SDL_size_add_overflow_builtin(a, b, ret))
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Ends C function definitions when using C++ */
|
/* Ends C function definitions when using C++ */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue