diff options
author | Werner Koch <wk@gnupg.org> | 2020-02-18 08:53:30 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2020-02-18 08:56:33 +0100 |
commit | 5742b8eaf3fa9cda3dfb6b3ad0fea7485fff1a12 (patch) | |
tree | 7bb1347295569e10184f65ccfb3aea8e44495275 /tests | |
parent | a6ab8e3a710b899ecfb2ff518725314a1e0e64ff (diff) | |
download | libgpg-error-5742b8eaf3fa9cda3dfb6b3ad0fea7485fff1a12.tar.gz |
core: Add gpgrt_fnameconcat and gpgrt_absfnameconcat.
* src/gpg-error.h.in (gpgrt_fnameconcat): New.
(gpgrt_absfnameconcat): New.
* src/visibility.c (gpgrt_fnameconcat, gpgrt_absfnameconcat): New.
* src/stringutils.c: New file.
(_gpgrt_vfnameconcat): New.
(_gpgrt_fnameconcat, _gpgrt_absfnameconcat): New.
* src/gpg-error.def.in: Add new functions.
* src/gpg-error.vers: Ditto.
* src/sysutils.c: Include pwd.h.
(_gpgrt_getpwdir): New.
* configure.ac: Test for pwd.h, getpwnam, getpwuid, and their _r
variants.
* src/Makefile.am (libgpg_error_la_SOURCES): Add new file.
* tests/t-stringutils.c: New.
* tests/t-common.h (xmalloc, xstrdup, xfree): New.
(die): Kludge to avoid compiler warnings.
--
The new functions are based on the code of make_filename from GnuPG.
They have been written by me ages ago with only minor modifications by
David Shaw. I re-license them from LGPL-3.0+ OR GPL-2.0+ to
LGPL-2.1-or-later.
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/t-common.h | 29 | ||||
-rw-r--r-- | tests/t-stringutils.c | 282 |
3 files changed, 312 insertions, 1 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index ea02da1..39ca241 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -28,7 +28,7 @@ endif 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-argparse t-logging t-stringutils AM_CPPFLAGS = -I$(top_builddir)/src $(extra_includes) diff --git a/tests/t-common.h b/tests/t-common.h index e70e04d..db496e2 100644 --- a/tests/t-common.h +++ b/tests/t-common.h @@ -39,6 +39,33 @@ static void fail (const char *format, ...) GPGRT_ATTR_PRINTF(1,2); static void show (const char *format, ...) GPGRT_ATTR_PRINTF(1,2); +static void * +xmalloc (size_t n) +{ + char *p = gpgrt_malloc (n); + if (!p) + die ("out of core\n"); + return p; +} + +static char * +xstrdup (const char *s) +{ + char *p = gpgrt_strdup (s); + if (!p) + die ("out of core\n"); + return p; +} + +static void +xfree (void *p) +{ + if (p) + gpgrt_free (p); +} + + + static void die (const char *format, ...) { @@ -57,6 +84,8 @@ die (const char *format, ...) #ifdef HAVE_FLOCKFILE funlockfile (stderr); #endif + xfree (xstrdup ("")); /* To avoid compiler warnings. */ + xfree (xmalloc (16)); /* To avoid compiler warnings. */ exit (1); } diff --git a/tests/t-stringutils.c b/tests/t-stringutils.c new file mode 100644 index 0000000..01094bf --- /dev/null +++ b/tests/t-stringutils.c @@ -0,0 +1,282 @@ +/* t-stringutils.c - Check some string utilities + * 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 <https://www.gnu.org/licenses/>. + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <unistd.h> +#ifdef HAVE_STAT +# include <sys/stat.h> +#endif +#include <sys/types.h> +#ifdef HAVE_PWD_H +# include <pwd.h> +#endif +#include <errno.h> + +#define PGM "t-stringutils" +#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; +} + + +const char * +mygethome (void) +{ + static char *home_buffer; + + if (!home_buffer) + { + char *home = getenv("HOME"); + + if(home) + home_buffer = xstrdup (home); +#if defined(HAVE_GETPWUID) && defined(HAVE_PWD_H) + else + { + struct passwd *pwd; + + pwd = getpwuid (getuid()); + if (pwd) + home_buffer = xstrdup (pwd->pw_dir); + } +#endif + } + return home_buffer; +} + + +static char * +mygetcwd (void) +{ + char *buffer; + size_t size = 100; + + for (;;) + { + buffer = xmalloc (size+1); + if (getcwd (buffer, size) == buffer) + return buffer; + xfree (buffer); + if (errno != ERANGE) + die ("error getting current cwd: %s\n", strerror (errno)); + size *= 2; + } +} + + +static void +check_fnameconcat (void) +{ + char *out; + const char *home = mygethome (); + size_t homelen = home? strlen (home):0; + + out = gpgrt_fnameconcat ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", NULL); + if (out) + fail ("fnameconcat succeeded but should not at line %d\n", __LINE__); + else if (errno != EINVAL) + fail ("fnameconcat return wrong error at line %d\n", __LINE__); + xfree (out); + + out = gpgrt_fnameconcat ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", "4", NULL); + if (out) + fail ("fnameconcat succeeded but should not at line %d\n", __LINE__); + else if (errno != EINVAL) + fail ("fnameconcat return wrong error at line %d\n", __LINE__); + xfree (out); + + out = gpgrt_fnameconcat ("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", + "1", "2", NULL); + if (!out || strcmp (out, + "1/2/3/4/5/6/7/8/9/10/" + "1/2/3/4/5/6/7/8/9/10/" + "1/2/3/4/5/6/7/8/9/10/" + "1/2")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_fnameconcat ("foo", "~/bar", "baz/cde", NULL); + if (!out || strcmp (out, "foo/~/bar/baz/cde")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_fnameconcat ("foo", "~/bar", "baz/cde/", NULL); + if (!out || strcmp (out, "foo/~/bar/baz/cde/")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_fnameconcat ("/foo", "~/bar", "baz/cde/", NULL); + if (!out || strcmp (out, "/foo/~/bar/baz/cde/")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_fnameconcat ("//foo", "~/bar", "baz/cde/", NULL); + if (!out || strcmp (out, "//foo/~/bar/baz/cde/")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_fnameconcat ("", "~/bar", "baz/cde", NULL); + if (!out || strcmp (out, "/~/bar/baz/cde")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_fnameconcat ("~/foo", "bar", NULL); + if (!out) + fail ("fnameconcat failed at line %d\n", __LINE__); + else if (home) + { + if (strlen (out) < homelen + 7) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strncmp (out, home, homelen)) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strcmp (out+homelen, "/foo/bar")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + } + else + { + if (strcmp (out, "~/foo/bar")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + } + xfree (out); + + out = gpgrt_fnameconcat ("~", "bar", NULL); + if (!out) + fail ("fnameconcat failed at line %d\n", __LINE__); + else if (home) + { + if (strlen (out) < homelen + 3) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strncmp (out, home, homelen)) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strcmp (out+homelen, "/bar")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + } + else + { + if (strcmp (out, "~/bar")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + } + xfree (out); +} + + +static void +check_absfnameconcat (void) +{ + char *out; + char *cwd = mygetcwd (); + size_t cwdlen = strlen (cwd); + + out = gpgrt_absfnameconcat ("foo", "bar", NULL); + if (!out) + fail ("fnameconcat failed at line %d\n", __LINE__); + else if (strlen (out) < cwdlen + 7) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strncmp (out, cwd, cwdlen)) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strcmp (out+cwdlen, "/foo/bar")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_absfnameconcat ("./foo", NULL); + if (!out) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strlen (out) < cwdlen + 5) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strncmp (out, cwd, cwdlen)) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strcmp (out+cwdlen, "/./foo")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + out = gpgrt_absfnameconcat (".", NULL); + if (!out) + fail ("fnameconcat failed at line %d\n", __LINE__); + else if (strlen (out) < cwdlen) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strncmp (out, cwd, cwdlen)) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + else if (strcmp (out+cwdlen, "")) + fail ("fnameconcat failed at line %d (out=%s)\n", __LINE__, out); + xfree (out); + + xfree (cwd); +} + + +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 string utilities\n"); + + check_fnameconcat (); + check_absfnameconcat (); + + show ("testing string utilities finished\n"); + return !!errorcount; +} |