From 969abd302211262562df93ae5412ee319aae69e6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 3 Mar 2020 15:41:39 +0100 Subject: core: New function gpgrt_reallocarray. * src/init.c (_gpgrt_reallocarray): New. * src/visibility.c (gpgrt_reallocarray): New. * src/gpg-error.vers, src/gpg-error.def.in: Add new function. * src/gpg-error.h.in: Add new interface. * tests/t-malloc.c: New. * tests/Makefile.am (TESTS): Add new test. -- Note that this function is different from the glibc function because it has an extra parameter which allows to clear the new elements. A realloc after a calloc with forgotten memset after it is a common source of error, thus we introduce this slightly different function. Signed-off-by: Werner Koch --- tests/Makefile.am | 2 +- tests/t-malloc.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 tests/t-malloc.c (limited to 'tests') diff --git a/tests/Makefile.am b/tests/Makefile.am index 2d199da..be04df3 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -30,7 +30,7 @@ EXTRA_DIST = t-argparse.conf etc/t-argparse.conf gpg_error_lib = ../src/libgpg-error.la TESTS = t-version t-strerror t-syserror t-lock t-printf t-poll t-b64 \ - t-argparse t-logging t-stringutils + t-argparse t-logging t-stringutils t-malloc AM_CPPFLAGS = -I$(top_builddir)/src $(extra_includes) diff --git a/tests/t-malloc.c b/tests/t-malloc.c new file mode 100644 index 0000000..be2ec81 --- /dev/null +++ b/tests/t-malloc.c @@ -0,0 +1,141 @@ +/* t-malloc.c - Check some malloc functions + * Copyright (C) 2020 g10 Code GmbH + * + * This file is part of Libgpg-error. + * + * Libgpg-error 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. + * + * Libgpg-error 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#define PGM "t-malloc" +#include "t-common.h" + + +static const char * +my_strusage (int level) +{ + const char *p; + + switch (level) + { + case 9: p = "LGPL-2.1-or-later"; break; + case 11: p = PGM; break; + default: p = NULL; + } + return p; +} + + +static void +check_reallocarray (void) +{ + struct foo_s { const char *a; int b; } *array; + size_t n; + + array = gpgrt_calloc (10, sizeof *array); + if (!array) + die ("%s: malloc failed\n", __func__); + + for (n=0; n < 10; n++) + if (array[n].a || array[n].b) + fail ("%s: array not cleared at index %zu\n", __func__, n); + + for (n=0; n < 10; n++) + { + array[n].a = "dummy string"; + array[n].b = 100+n; + } + + array = gpgrt_reallocarray (array, 10, 20, sizeof *array); + if (!array) + die ("%s: realloc failed\n", __func__); + + for (n=0; n < 10; n++) + { + if (!array[n].a || strcmp (array[n].a, "dummy string")) + fail ("%s: string in realloced array changed at index %zu\n", + __func__, n); + + if (array[n].b != 100 + n) + fail ("%s: number in realloced array changed at index %zu\n", + __func__, n); + } + for (n=10; n < 20; n++) + if (array[n].a || array[n].b) + fail ("%s: realloced array not cleared at index %zu\n", __func__, n); + + /* We can't easily check whether the reallocated array does not + * iniitialze in the case OLDN is equal or larger to N, so we skip + * this. Let's do a simple shrink test instead. */ + + array = gpgrt_reallocarray (array, 20, 7, sizeof *array); + if (!array) + die ("%s: realloc (shrinking) failed\n", __func__); + + for (n=0; n < 7; n++) + { + if (!array[n].a || strcmp (array[n].a, "dummy string")) + fail ("%s: string in shrunk array changed at index %zu\n", + __func__, n); + + if (array[n].b != 100 + n) + fail ("%s: number in shrunk array changed at index %zu\n", + __func__, n); + } + + xfree (array); +} + + +int +main (int argc, char **argv) +{ + gpgrt_opt_t opts[] = { + ARGPARSE_x ('v', "verbose", NONE, 0, "Print more diagnostics"), + ARGPARSE_s_n('d', "debug", "Flyswatter"), + ARGPARSE_end() + }; + gpgrt_argparse_t pargs = { &argc, &argv, 0 }; + + gpgrt_set_strusage (my_strusage); + gpgrt_log_set_prefix (gpgrt_strusage (11), GPGRT_LOG_WITH_PREFIX); + + while (gpgrt_argparse (NULL, &pargs, opts)) + { + switch (pargs.r_opt) + { + case 'v': verbose++; break; + case 'd': debug++; break; + default : pargs.err = ARGPARSE_PRINT_ERROR; break; + } + } + gpgrt_argparse (NULL, &pargs, NULL); + + show ("testing malloc functions\n"); + + check_reallocarray (); + + return !!errorcount; +} -- cgit v1.2.1