105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* xsize.h -- Checked size_t computations. 205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 305436638acc7c010349a69c3395f1a57c642dc62Ying Wang Copyright (C) 2003, 2008-2012 Free Software Foundation, Inc. 405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 505436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is free software; you can redistribute it and/or modify 605436638acc7c010349a69c3395f1a57c642dc62Ying Wang it under the terms of the GNU General Public License as published by 705436638acc7c010349a69c3395f1a57c642dc62Ying Wang the Free Software Foundation; either version 3, or (at your option) 805436638acc7c010349a69c3395f1a57c642dc62Ying Wang any later version. 905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1005436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is distributed in the hope that it will be useful, 1105436638acc7c010349a69c3395f1a57c642dc62Ying Wang but WITHOUT ANY WARRANTY; without even the implied warranty of 1205436638acc7c010349a69c3395f1a57c642dc62Ying Wang MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1305436638acc7c010349a69c3395f1a57c642dc62Ying Wang GNU General Public License for more details. 1405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1505436638acc7c010349a69c3395f1a57c642dc62Ying Wang You should have received a copy of the GNU General Public License 1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang along with this program; if not, see <http://www.gnu.org/licenses/>. */ 1705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#ifndef _XSIZE_H 1905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define _XSIZE_H 2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Get size_t. */ 2205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <stddef.h> 2305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2405436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Get SIZE_MAX. */ 2505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <limits.h> 2605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if HAVE_STDINT_H 2705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# include <stdint.h> 2805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 2905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 3005436638acc7c010349a69c3395f1a57c642dc62Ying Wang_GL_INLINE_HEADER_BEGIN 3105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#ifndef XSIZE_INLINE 3205436638acc7c010349a69c3395f1a57c642dc62Ying Wang# define XSIZE_INLINE _GL_INLINE 3305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 3405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 3505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* The size of memory objects is often computed through expressions of 3605436638acc7c010349a69c3395f1a57c642dc62Ying Wang type size_t. Example: 3705436638acc7c010349a69c3395f1a57c642dc62Ying Wang void* p = malloc (header_size + n * element_size). 3805436638acc7c010349a69c3395f1a57c642dc62Ying Wang These computations can lead to overflow. When this happens, malloc() 3905436638acc7c010349a69c3395f1a57c642dc62Ying Wang returns a piece of memory that is way too small, and the program then 4005436638acc7c010349a69c3395f1a57c642dc62Ying Wang crashes while attempting to fill the memory. 4105436638acc7c010349a69c3395f1a57c642dc62Ying Wang To avoid this, the functions and macros in this file check for overflow. 4205436638acc7c010349a69c3395f1a57c642dc62Ying Wang The convention is that SIZE_MAX represents overflow. 4305436638acc7c010349a69c3395f1a57c642dc62Ying Wang malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc 4405436638acc7c010349a69c3395f1a57c642dc62Ying Wang implementation that uses mmap --, it's recommended to use size_overflow_p() 4505436638acc7c010349a69c3395f1a57c642dc62Ying Wang or size_in_bounds_p() before invoking malloc(). 4605436638acc7c010349a69c3395f1a57c642dc62Ying Wang The example thus becomes: 4705436638acc7c010349a69c3395f1a57c642dc62Ying Wang size_t size = xsum (header_size, xtimes (n, element_size)); 4805436638acc7c010349a69c3395f1a57c642dc62Ying Wang void *p = (size_in_bounds_p (size) ? malloc (size) : NULL); 4905436638acc7c010349a69c3395f1a57c642dc62Ying Wang*/ 5005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 5105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Convert an arbitrary value >= 0 to type size_t. */ 5205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define xcast_size_t(N) \ 5305436638acc7c010349a69c3395f1a57c642dc62Ying Wang ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX) 5405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 5505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Sum of two sizes, with overflow check. */ 5605436638acc7c010349a69c3395f1a57c642dc62Ying WangXSIZE_INLINE size_t 5705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if __GNUC__ >= 3 5805436638acc7c010349a69c3395f1a57c642dc62Ying Wang__attribute__ ((__pure__)) 5905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 6005436638acc7c010349a69c3395f1a57c642dc62Ying Wangxsum (size_t size1, size_t size2) 6105436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 6205436638acc7c010349a69c3395f1a57c642dc62Ying Wang size_t sum = size1 + size2; 6305436638acc7c010349a69c3395f1a57c642dc62Ying Wang return (sum >= size1 ? sum : SIZE_MAX); 6405436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 6505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 6605436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Sum of three sizes, with overflow check. */ 6705436638acc7c010349a69c3395f1a57c642dc62Ying WangXSIZE_INLINE size_t 6805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if __GNUC__ >= 3 6905436638acc7c010349a69c3395f1a57c642dc62Ying Wang__attribute__ ((__pure__)) 7005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 7105436638acc7c010349a69c3395f1a57c642dc62Ying Wangxsum3 (size_t size1, size_t size2, size_t size3) 7205436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 7305436638acc7c010349a69c3395f1a57c642dc62Ying Wang return xsum (xsum (size1, size2), size3); 7405436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 7505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 7605436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Sum of four sizes, with overflow check. */ 7705436638acc7c010349a69c3395f1a57c642dc62Ying WangXSIZE_INLINE size_t 7805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if __GNUC__ >= 3 7905436638acc7c010349a69c3395f1a57c642dc62Ying Wang__attribute__ ((__pure__)) 8005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 8105436638acc7c010349a69c3395f1a57c642dc62Ying Wangxsum4 (size_t size1, size_t size2, size_t size3, size_t size4) 8205436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 8305436638acc7c010349a69c3395f1a57c642dc62Ying Wang return xsum (xsum (xsum (size1, size2), size3), size4); 8405436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 8505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 8605436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Maximum of two sizes, with overflow check. */ 8705436638acc7c010349a69c3395f1a57c642dc62Ying WangXSIZE_INLINE size_t 8805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#if __GNUC__ >= 3 8905436638acc7c010349a69c3395f1a57c642dc62Ying Wang__attribute__ ((__pure__)) 9005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif 9105436638acc7c010349a69c3395f1a57c642dc62Ying Wangxmax (size_t size1, size_t size2) 9205436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 9305436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* No explicit check is needed here, because for any n: 9405436638acc7c010349a69c3395f1a57c642dc62Ying Wang max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX. */ 9505436638acc7c010349a69c3395f1a57c642dc62Ying Wang return (size1 >= size2 ? size1 : size2); 9605436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 9705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 9805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Multiplication of a count with an element size, with overflow check. 9905436638acc7c010349a69c3395f1a57c642dc62Ying Wang The count must be >= 0 and the element size must be > 0. 10005436638acc7c010349a69c3395f1a57c642dc62Ying Wang This is a macro, not a function, so that it works correctly even 10105436638acc7c010349a69c3395f1a57c642dc62Ying Wang when N is of a wider type and N > SIZE_MAX. */ 10205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define xtimes(N, ELSIZE) \ 10305436638acc7c010349a69c3395f1a57c642dc62Ying Wang ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX) 10405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 10505436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Check for overflow. */ 10605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define size_overflow_p(SIZE) \ 10705436638acc7c010349a69c3395f1a57c642dc62Ying Wang ((SIZE) == SIZE_MAX) 10805436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Check against overflow. */ 10905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define size_in_bounds_p(SIZE) \ 11005436638acc7c010349a69c3395f1a57c642dc62Ying Wang ((SIZE) != SIZE_MAX) 11105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 11205436638acc7c010349a69c3395f1a57c642dc62Ying Wang_GL_INLINE_HEADER_END 11305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 11405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif /* _XSIZE_H */ 115