119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* xsize.h -- Checked size_t computations. 219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project Copyright (C) 2003 Free Software Foundation, Inc. 419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project This program is free software; you can redistribute it and/or modify it 619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project under the terms of the GNU Library General Public License as published 719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project by the Free Software Foundation; either version 2, or (at your option) 819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project any later version. 919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project This program is distributed in the hope that it will be useful, 1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project but WITHOUT ANY WARRANTY; without even the implied warranty of 1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project Library General Public License for more details. 1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project You should have received a copy of the GNU Library General Public 1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project License along with this program; if not, write to the Free Software 1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project USA. */ 1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifndef _XSIZE_H 2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define _XSIZE_H 2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* Get size_t. */ 2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stddef.h> 2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* Get SIZE_MAX. */ 2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <limits.h> 2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if HAVE_STDINT_H 2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project# include <stdint.h> 3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* The size of memory objects is often computed through expressions of 3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project type size_t. Example: 3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void* p = malloc (header_size + n * element_size). 3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project These computations can lead to overflow. When this happens, malloc() 3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project returns a piece of memory that is way too small, and the program then 3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project crashes while attempting to fill the memory. 3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project To avoid this, the functions and macros in this file check for overflow. 3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project The convention is that SIZE_MAX represents overflow. 4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc 4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project implementation that uses mmap --, it's recommended to use size_overflow_p() 4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project or size_in_bounds_p() before invoking malloc(). 4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project The example thus becomes: 4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project size_t size = xsum (header_size, xtimes (n, element_size)); 4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project void *p = (size_in_bounds_p (size) ? malloc (size) : NULL); 4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project*/ 4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* Convert an arbitrary value >= 0 to type size_t. */ 4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define xcast_size_t(N) \ 5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX) 5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* Sum of two sizes, with overflow check. */ 5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic inline size_t 5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if __GNUC__ >= 3 5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project__attribute__ ((__pure__)) 5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectxsum (size_t size1, size_t size2) 5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project size_t sum = size1 + size2; 6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return (sum >= size1 ? sum : SIZE_MAX); 6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* Sum of three sizes, with overflow check. */ 6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic inline size_t 6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if __GNUC__ >= 3 6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project__attribute__ ((__pure__)) 6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectxsum3 (size_t size1, size_t size2, size_t size3) 6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return xsum (xsum (size1, size2), size3); 7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* Sum of four sizes, with overflow check. */ 7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic inline size_t 7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if __GNUC__ >= 3 7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project__attribute__ ((__pure__)) 7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectxsum4 (size_t size1, size_t size2, size_t size3, size_t size4) 7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return xsum (xsum (xsum (size1, size2), size3), size4); 8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* Maximum of two sizes, with overflow check. */ 8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic inline size_t 8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#if __GNUC__ >= 3 8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project__attribute__ ((__pure__)) 8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif 8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectxmax (size_t size1, size_t size2) 8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{ 9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project /* No explicit check is needed here, because for any n: 9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX. */ 9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project return (size1 >= size2 ? size1 : size2); 9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project} 9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* Multiplication of a count with an element size, with overflow check. 9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project The count must be >= 0 and the element size must be > 0. 9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project This is a macro, not an inline function, so that it works correctly even 9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project when N is of a wider tupe and N > SIZE_MAX. */ 9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define xtimes(N, ELSIZE) \ 10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX) 10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* Check for overflow. */ 10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define size_overflow_p(SIZE) \ 10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((SIZE) == SIZE_MAX) 10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* Check against overflow. */ 10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define size_in_bounds_p(SIZE) \ 10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project ((SIZE) != SIZE_MAX) 10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project 10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* _XSIZE_H */ 110