Back to index

nagios-plugins  1.4.16
xsize.h
Go to the documentation of this file.
00001 /* xsize.h -- Checked size_t computations.
00002 
00003    Copyright (C) 2003, 2008, 2009, 2010 Free Software Foundation, Inc.
00004 
00005    This program is free software; you can redistribute it and/or modify
00006    it under the terms of the GNU General Public License as published by
00007    the Free Software Foundation; either version 3, or (at your option)
00008    any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013    GNU General Public License for more details.
00014 
00015    You should have received a copy of the GNU General Public License
00016    along with this program; if not, write to the Free Software Foundation,
00017    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
00018 
00019 #ifndef _XSIZE_H
00020 #define _XSIZE_H
00021 
00022 /* Get size_t.  */
00023 #include <stddef.h>
00024 
00025 /* Get SIZE_MAX.  */
00026 #include <limits.h>
00027 #if HAVE_STDINT_H
00028 # include <stdint.h>
00029 #endif
00030 
00031 /* The size of memory objects is often computed through expressions of
00032    type size_t. Example:
00033       void* p = malloc (header_size + n * element_size).
00034    These computations can lead to overflow.  When this happens, malloc()
00035    returns a piece of memory that is way too small, and the program then
00036    crashes while attempting to fill the memory.
00037    To avoid this, the functions and macros in this file check for overflow.
00038    The convention is that SIZE_MAX represents overflow.
00039    malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc
00040    implementation that uses mmap --, it's recommended to use size_overflow_p()
00041    or size_in_bounds_p() before invoking malloc().
00042    The example thus becomes:
00043       size_t size = xsum (header_size, xtimes (n, element_size));
00044       void *p = (size_in_bounds_p (size) ? malloc (size) : NULL);
00045 */
00046 
00047 /* Convert an arbitrary value >= 0 to type size_t.  */
00048 #define xcast_size_t(N) \
00049   ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX)
00050 
00051 /* Sum of two sizes, with overflow check.  */
00052 static inline size_t
00053 #if __GNUC__ >= 3
00054 __attribute__ ((__pure__))
00055 #endif
00056 xsum (size_t size1, size_t size2)
00057 {
00058   size_t sum = size1 + size2;
00059   return (sum >= size1 ? sum : SIZE_MAX);
00060 }
00061 
00062 /* Sum of three sizes, with overflow check.  */
00063 static inline size_t
00064 #if __GNUC__ >= 3
00065 __attribute__ ((__pure__))
00066 #endif
00067 xsum3 (size_t size1, size_t size2, size_t size3)
00068 {
00069   return xsum (xsum (size1, size2), size3);
00070 }
00071 
00072 /* Sum of four sizes, with overflow check.  */
00073 static inline size_t
00074 #if __GNUC__ >= 3
00075 __attribute__ ((__pure__))
00076 #endif
00077 xsum4 (size_t size1, size_t size2, size_t size3, size_t size4)
00078 {
00079   return xsum (xsum (xsum (size1, size2), size3), size4);
00080 }
00081 
00082 /* Maximum of two sizes, with overflow check.  */
00083 static inline size_t
00084 #if __GNUC__ >= 3
00085 __attribute__ ((__pure__))
00086 #endif
00087 xmax (size_t size1, size_t size2)
00088 {
00089   /* No explicit check is needed here, because for any n:
00090      max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX.  */
00091   return (size1 >= size2 ? size1 : size2);
00092 }
00093 
00094 /* Multiplication of a count with an element size, with overflow check.
00095    The count must be >= 0 and the element size must be > 0.
00096    This is a macro, not an inline function, so that it works correctly even
00097    when N is of a wider type and N > SIZE_MAX.  */
00098 #define xtimes(N, ELSIZE) \
00099   ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX)
00100 
00101 /* Check for overflow.  */
00102 #define size_overflow_p(SIZE) \
00103   ((SIZE) == SIZE_MAX)
00104 /* Check against overflow.  */
00105 #define size_in_bounds_p(SIZE) \
00106   ((SIZE) != SIZE_MAX)
00107 
00108 #endif /* _XSIZE_H */