nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* xsize.h -- Checked size_t computations. |
2 | |||
3 | Copyright (C) 2003, 2008-2015 Free Software Foundation, Inc. |
||
4 | |||
5 | This program is free software; you can redistribute it and/or modify |
||
6 | it under the terms of the GNU General Public License as published by |
||
7 | the Free Software Foundation; either version 2, or (at your option) |
||
8 | any later version. |
||
9 | |||
10 | This program is distributed in the hope that it will be useful, |
||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
13 | GNU General Public License for more details. |
||
14 | |||
15 | You should have received a copy of the GNU General Public License |
||
16 | along with this program; if not, see <http://www.gnu.org/licenses/>. */ |
||
17 | |||
18 | #ifndef _XSIZE_H |
||
19 | #define _XSIZE_H |
||
20 | |||
21 | #include <glib.h> |
||
22 | |||
23 | /* Get size_t. */ |
||
24 | #include <stddef.h> |
||
25 | |||
26 | /* Get G_MAXSIZE. */ |
||
27 | #include <limits.h> |
||
28 | #if HAVE_STDINT_H |
||
29 | # include <stdint.h> |
||
30 | #endif |
||
31 | |||
32 | #ifndef XSIZE_INLINE |
||
33 | # define XSIZE_INLINE _GL_INLINE |
||
34 | #endif |
||
35 | |||
36 | /* The size of memory objects is often computed through expressions of |
||
37 | type size_t. Example: |
||
38 | void* p = malloc (header_size + n * element_size). |
||
39 | These computations can lead to overflow. When this happens, malloc() |
||
40 | returns a piece of memory that is way too small, and the program then |
||
41 | crashes while attempting to fill the memory. |
||
42 | To avoid this, the functions and macros in this file check for overflow. |
||
43 | The convention is that G_MAXSIZE represents overflow. |
||
44 | malloc (G_MAXSIZE) is not guaranteed to fail -- think of a malloc |
||
45 | implementation that uses mmap --, it's recommended to use size_overflow_p() |
||
46 | or size_in_bounds_p() before invoking malloc(). |
||
47 | The example thus becomes: |
||
48 | size_t size = xsum (header_size, xtimes (n, element_size)); |
||
49 | void *p = (size_in_bounds_p (size) ? malloc (size) : NULL); |
||
50 | */ |
||
51 | |||
52 | /* Convert an arbitrary value >= 0 to type size_t. */ |
||
53 | #define xcast_size_t(N) \ |
||
54 | ((N) <= G_MAXSIZE ? (size_t) (N) : G_MAXSIZE) |
||
55 | |||
56 | /* Sum of two sizes, with overflow check. */ |
||
57 | static inline size_t |
||
58 | xsum (size_t size1, size_t size2) |
||
59 | { |
||
60 | size_t sum = size1 + size2; |
||
61 | return (sum >= size1 ? sum : G_MAXSIZE); |
||
62 | } |
||
63 | |||
64 | /* Sum of three sizes, with overflow check. */ |
||
65 | static inline size_t |
||
66 | xsum3 (size_t size1, size_t size2, size_t size3) |
||
67 | { |
||
68 | return xsum (xsum (size1, size2), size3); |
||
69 | } |
||
70 | |||
71 | /* Sum of four sizes, with overflow check. */ |
||
72 | static inline size_t |
||
73 | xsum4 (size_t size1, size_t size2, size_t size3, size_t size4) |
||
74 | { |
||
75 | return xsum (xsum (xsum (size1, size2), size3), size4); |
||
76 | } |
||
77 | |||
78 | /* Maximum of two sizes, with overflow check. */ |
||
79 | static inline size_t |
||
80 | xmax (size_t size1, size_t size2) |
||
81 | { |
||
82 | /* No explicit check is needed here, because for any n: |
||
83 | max (G_MAXSIZE, n) == G_MAXSIZE and max (n, G_MAXSIZE) == G_MAXSIZE. */ |
||
84 | return (size1 >= size2 ? size1 : size2); |
||
85 | } |
||
86 | |||
87 | /* Multiplication of a count with an element size, with overflow check. |
||
88 | The count must be >= 0 and the element size must be > 0. |
||
89 | This is a macro, not a function, so that it works correctly even |
||
90 | when N is of a wider type and N > G_MAXSIZE. */ |
||
91 | #define xtimes(N, ELSIZE) \ |
||
92 | ((N) <= G_MAXSIZE / (ELSIZE) ? (size_t) (N) * (ELSIZE) : G_MAXSIZE) |
||
93 | |||
94 | /* Check for overflow. */ |
||
95 | #define size_overflow_p(SIZE) \ |
||
96 | ((SIZE) == G_MAXSIZE) |
||
97 | /* Check against overflow. */ |
||
98 | #define size_in_bounds_p(SIZE) \ |
||
99 | ((SIZE) != G_MAXSIZE) |
||
100 | |||
101 | #endif /* _XSIZE_H */ |