summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2020-02-18 08:53:30 +0100
committerWerner Koch <wk@gnupg.org>2020-02-18 08:56:33 +0100
commit5742b8eaf3fa9cda3dfb6b3ad0fea7485fff1a12 (patch)
tree7bb1347295569e10184f65ccfb3aea8e44495275 /tests
parenta6ab8e3a710b899ecfb2ff518725314a1e0e64ff (diff)
downloadlibgpg-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.am2
-rw-r--r--tests/t-common.h29
-rw-r--r--tests/t-stringutils.c282
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;
+}