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