diff options
Diffstat (limited to 'lib/malloca.c')
-rw-r--r-- | lib/malloca.c | 51 |
1 files changed, 25 insertions, 26 deletions
diff --git a/lib/malloca.c b/lib/malloca.c index 2ec944c..e7beaaf 100644 --- a/lib/malloca.c +++ b/lib/malloca.c @@ -1,28 +1,19 @@ /* Safe automatic memory allocation. - Copyright (C) 2003, 2006-2007, 2009-2018 Free Software Foundation, Inc. + Copyright (C) 2003, 2006-2007, 2009-2022 Free Software Foundation, Inc. Written by Bruno Haible <bruno@clisp.org>, 2003, 2018. - This program is free software: you can redistribute it and/or - modify it under the terms of either: + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. - * the GNU Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your - option) any later version. - - or - - * the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your - option) any later version. - - or both in parallel, as here. - This program is distributed in the hope that it will be useful, + This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + GNU Lesser General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, see <https://www.gnu.org/licenses/>. */ + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. */ #define _GL_USE_STDLIB_ALLOC 1 #include <config.h> @@ -30,6 +21,8 @@ /* Specification. */ #include "malloca.h" +#include "idx.h" +#include "intprops.h" #include "verify.h" /* The speed critical point in this file is freea() applied to an alloca() @@ -54,24 +47,30 @@ mmalloca (size_t n) #if HAVE_ALLOCA /* Allocate one more word, used to determine the address to pass to freea(), and room for the alignment ≡ sa_alignment_max mod 2*sa_alignment_max. */ - size_t nplus = n + sizeof (small_t) + 2 * sa_alignment_max - 1; - - if (nplus >= n) + uintptr_t alignment2_mask = 2 * sa_alignment_max - 1; + int plus = sizeof (small_t) + alignment2_mask; + idx_t nplus; + if (!INT_ADD_WRAPV (n, plus, &nplus) && !xalloc_oversized (nplus, 1)) { char *mem = (char *) malloc (nplus); if (mem != NULL) { - char *p = - (char *)((((uintptr_t)mem + sizeof (small_t) + sa_alignment_max - 1) - & ~(uintptr_t)(2 * sa_alignment_max - 1)) - + sa_alignment_max); + uintptr_t umem = (uintptr_t)mem, umemplus; + /* The INT_ADD_WRAPV avoids signed integer overflow on + theoretical platforms where UINTPTR_MAX <= INT_MAX. */ + INT_ADD_WRAPV (umem, sizeof (small_t) + sa_alignment_max - 1, + &umemplus); + idx_t offset = ((umemplus & ~alignment2_mask) + + sa_alignment_max - umem); + void *vp = mem + offset; + small_t *p = vp; /* Here p >= mem + sizeof (small_t), and p <= mem + sizeof (small_t) + 2 * sa_alignment_max - 1 hence p + n <= mem + nplus. So, the memory range [p, p+n) lies in the allocated memory range [mem, mem + nplus). */ - ((small_t *) p)[-1] = p - mem; + p[-1] = offset; /* p ≡ sa_alignment_max mod 2*sa_alignment_max. */ return p; } |