aboutsummaryrefslogtreecommitdiffstats
path: root/jnlib
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2007-06-19 09:11:11 +0000
committerWerner Koch <[email protected]>2007-06-19 09:11:11 +0000
commit540f9164c01dbbd1f8fc9abcd2ee67dbf6e1ee10 (patch)
tree298058ec8adf7c7c059ce7db127334a9ddb49bec /jnlib
parentjnlib/ (diff)
downloadgnupg-540f9164c01dbbd1f8fc9abcd2ee67dbf6e1ee10.tar.gz
gnupg-540f9164c01dbbd1f8fc9abcd2ee67dbf6e1ee10.zip
Made percent_escape more general.
Added regression tests support to jnlib. W32 changes.
Diffstat (limited to '')
-rw-r--r--jnlib/ChangeLog14
-rw-r--r--jnlib/Makefile.am19
-rw-r--r--jnlib/stringhelp.c26
-rw-r--r--jnlib/stringhelp.h5
-rw-r--r--jnlib/t-stringhelp.c94
-rw-r--r--jnlib/t-support.c111
-rw-r--r--jnlib/t-support.h52
-rw-r--r--jnlib/w32-afunix.c54
8 files changed, 355 insertions, 20 deletions
diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog
index f98b1a282..4826ce4cd 100644
--- a/jnlib/ChangeLog
+++ b/jnlib/ChangeLog
@@ -1,3 +1,17 @@
+2007-06-19 Werner Koch <[email protected]>
+
+ * Makefile.am: Add support for regression tests.
+ * t-support.h, t-support.c: New.
+ * t-stringhelp.c: New.
+
+ * stringhelp.c (percent_escape): Add arg EXTRA to make it a more
+ general function. Changed all callers.
+
+2007-06-18 Werner Koch <[email protected]>
+
+ * w32-afunix.c (_w32_sock_bind): Changed to properly detect an
+ already used socket.
+
2007-06-18 Marcus Brinkmann <[email protected]>
* stringhelp.h (percent_escape): New prototype.
diff --git a/jnlib/Makefile.am b/jnlib/Makefile.am
index 0f593bb3f..eb447b592 100644
--- a/jnlib/Makefile.am
+++ b/jnlib/Makefile.am
@@ -23,6 +23,8 @@
## Process this file with automake to produce Makefile.in
EXTRA_DIST = README
+noinst_PROGRAMS = $(module_tests)
+TESTS = $(module_tests)
AM_CPPFLAGS = -I$(top_srcdir)/intl
@@ -51,3 +53,20 @@ endif
# For GnuPG we don't need the xmalloc stuff.
# xmalloc.c xmalloc.h
+
+#
+# Module tests.
+#
+# These tests should only be used at the canonical location of jnlib
+# which is the GnuPG package. The reason for this is that t-support.c
+# defines replacements for the actual used memory allocation functions
+# so that there is no dependency on libgcrypt.
+#
+module_tests = t-stringhelp
+
+t_jnlib_src = t-support.c t-support.h
+t_jnlib_ldadd = libjnlib.a $(LIBINTL) $(LIBICONV)
+
+t_stringhelp_SOURCES = t-stringhelp.c $(t_jnlib_src)
+t_stringhelp_LDADD = $(t_jnlib_ldadd)
+
diff --git a/jnlib/stringhelp.c b/jnlib/stringhelp.c
index 49d91c075..2050cddb3 100644
--- a/jnlib/stringhelp.c
+++ b/jnlib/stringhelp.c
@@ -34,6 +34,8 @@
#include "stringhelp.h"
+#define tohex_lower(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'a'))
+
/*
* Look for the substring SUB in buffer and return a pointer to that
* substring in BUFFER or NULL if not found.
@@ -827,19 +829,19 @@ memrchr (const void *buffer, int c, size_t n)
#endif /*HAVE_MEMRCHR*/
-/* Percent-escape the string STR by replacing colons with '%3a'. */
+/* Percent-escape the string STR by replacing colons with '%3a'. If
+ EXTRA is not NULL all characters in it are also escaped. */
char *
-percent_escape (const char *str)
+percent_escape (const char *str, const char *extra)
{
- int i = 0;
- int j = 0;
+ int i, j;
char *ptr;
if (!str)
return NULL;
- while (str[i])
- if (str[i++] == ':')
+ for (i=j=0; str[i]; i++)
+ if (str[i] == ':' || str[i] == '%' || (extra && strchr (extra, str[i])))
j++;
ptr = jnlib_xmalloc (i + 2 * j + 1);
i = 0;
@@ -851,6 +853,18 @@ percent_escape (const char *str)
ptr[i++] = '3';
ptr[i++] = 'a';
}
+ else if (*str == '%')
+ {
+ ptr[i++] = '%';
+ ptr[i++] = '2';
+ ptr[i++] = '5';
+ }
+ else if (extra && strchr (extra, *str))
+ {
+ ptr[i++] = '%';
+ ptr[i++] = tohex_lower ((*str>>4)&15);
+ ptr[i++] = tohex_lower (*str&15);
+ }
else
ptr[i++] = *str;
str++;
diff --git a/jnlib/stringhelp.h b/jnlib/stringhelp.h
index fdd887bf2..5f08745cb 100644
--- a/jnlib/stringhelp.h
+++ b/jnlib/stringhelp.h
@@ -117,8 +117,9 @@ isascii (int c)
#endif
#define STR2(v) STR(v)
-/* Percent-escape the string STR by replacing colons with '%3a'. */
-char *percent_escape (const char *str);
+/* Percent-escape the string STR by replacing colons with '%3a'. If
+ EXTRA is not NULL, also replace all characters given in EXTRA. */
+char *percent_escape (const char *str, const char *extra);
#endif /*LIBJNLIB_STRINGHELP_H*/
diff --git a/jnlib/t-stringhelp.c b/jnlib/t-stringhelp.c
new file mode 100644
index 000000000..27bea8940
--- /dev/null
+++ b/jnlib/t-stringhelp.c
@@ -0,0 +1,94 @@
+/* t-stringhelp.c - Regression tests for stringhelp.c
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of JNLIB.
+ *
+ * JNLIB 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.
+ *
+ * JNLIB 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "stringhelp.h"
+
+#include "t-support.h"
+
+
+
+static void
+test_percent_escape (void)
+{
+ char *result;
+ static struct {
+ const char *extra;
+ const char *value;
+ const char *expected;
+ } tests[] =
+ {
+ { NULL, "", "" },
+ { NULL, "%", "%25" },
+ { NULL, "%%", "%25%25" },
+ { NULL, " %", " %25" },
+ { NULL, ":", "%3a" },
+ { NULL, " :", " %3a" },
+ { NULL, ": ", "%3a " },
+ { NULL, " : ", " %3a " },
+ { NULL, "::", "%3a%3a" },
+ { NULL, ": :", "%3a %3a" },
+ { NULL, "%:", "%25%3a" },
+ { NULL, ":%", "%3a%25" },
+ { "\\\n:", ":%", "%3a%25" },
+ { "\\\n:", "\\:%", "%5c%3a%25" },
+ { "\\\n:", "\n:%", "%0a%3a%25" },
+ { "\\\n:", "\xff:%", "\xff%3a%25" },
+ { "\\\n:", "\xfe:%", "\xfe%3a%25" },
+ { "\\\n:", "\x01:%", "\x01%3a%25" },
+ { "\x01", "\x01:%", "%01%3a%25" },
+ { "\xfe", "\xfe:%", "%fe%3a%25" },
+ { "\xfe", "\xff:%", "\xff%3a%25" },
+
+ { NULL, NULL, NULL }
+ };
+ int testno;
+
+ result = percent_escape (NULL, NULL);
+ if (result)
+ fail (0);
+ for (testno=0; tests[testno].value; testno++)
+ {
+ result = percent_escape (tests[testno].value, tests[testno].extra);
+ if (!result)
+ fail (testno);
+ if (strcmp (result, tests[testno].expected))
+ fail (testno);
+ xfree (result);
+ }
+
+}
+
+
+
+
+int
+main (int argc, char **argv)
+{
+ test_percent_escape ();
+
+ return 0;
+}
+
diff --git a/jnlib/t-support.c b/jnlib/t-support.c
new file mode 100644
index 000000000..d9d50e9a4
--- /dev/null
+++ b/jnlib/t-support.c
@@ -0,0 +1,111 @@
+/* t-support.c - helper functions for the regression tests.
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of JNLIB.
+ *
+ * JNLIB 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.
+ *
+ * JNLIB 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "t-support.h"
+
+/* Replacements for the malloc functions as used here. */
+
+static void
+out_of_memory (void)
+{
+ fprintf (stderr,"error: out of core in regression tests: %s\n",
+ strerror (errno));
+ exit (2);
+}
+
+
+void *
+gcry_malloc (size_t n)
+{
+ return malloc (n);
+}
+
+void *
+gcry_xmalloc (size_t n)
+{
+ void *p = malloc (n);
+ if (!p)
+ out_of_memory ();
+ return p;
+}
+
+char *
+gcry_strdup (const char *string)
+{
+ return malloc (strlen (string)+1);
+}
+
+
+void *
+gcry_realloc (void *a, size_t n)
+{
+ return realloc (a, n);
+}
+
+void *
+gcry_xrealloc (void *a, size_t n)
+{
+ void *p = realloc (a, n);
+ if (!p)
+ out_of_memory ();
+ return p;
+}
+
+
+
+void *
+gcry_calloc (size_t n, size_t m)
+{
+ return calloc (n, m);
+}
+
+void *
+gcry_xcalloc (size_t n, size_t m)
+{
+ void *p = calloc (n, m);
+ if (!p)
+ out_of_memory ();
+ return p;
+}
+
+
+char *
+gcry_xstrdup (const char *string)
+{
+ void *p = malloc (strlen (string)+1);
+ if (!p)
+ out_of_memory ();
+ strcpy (p, string);
+ return p;
+}
+
+void
+gcry_free (void *a)
+{
+ if (a)
+ free (a);
+}
diff --git a/jnlib/t-support.h b/jnlib/t-support.h
new file mode 100644
index 000000000..661dfb46e
--- /dev/null
+++ b/jnlib/t-support.h
@@ -0,0 +1,52 @@
+/* t-support.h - Helper for the regression tests
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of JNLIB.
+ *
+ * JNLIB 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.
+ *
+ * JNLIB 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef LIBJNLIB_T_SUPPORT_H
+#define LIBJNLIB_T_SUPPORT_H 1
+
+#ifdef GCRYPT_VERSION
+#error The regression tests should not include with gcrypt.h
+#endif
+
+/* Repalcement prototypes. */
+void *gcry_xmalloc (size_t n);
+void *gcry_xcalloc (size_t n, size_t m);
+void *gcry_xrealloc (void *a, size_t n);
+char *gcry_xstrdup (const char * a);
+void gcry_free (void *a);
+
+/* Map the used xmalloc functions to those implemented by t-support.c */
+#define xmalloc(a) gcry_xmalloc ( (a) )
+#define xcalloc(a,b) gcry_xcalloc ( (a), (b) )
+#define xrealloc(a,n) gcry_xrealloc ( (a), (n) )
+#define xstrdup(a) gcry_xstrdup ( (a) )
+#define xfree(a) gcry_free ( (a) )
+
+
+/* Macros to print the result of a test. */
+#define pass() do { ; } while(0)
+#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\
+ __FILE__,__LINE__, (a)); \
+ exit (1); \
+ } while(0)
+
+
+#endif /*LIBJNLIB_T_SUPPORT_H*/
diff --git a/jnlib/w32-afunix.c b/jnlib/w32-afunix.c
index dcce423c7..16132a230 100644
--- a/jnlib/w32-afunix.c
+++ b/jnlib/w32-afunix.c
@@ -22,11 +22,19 @@
#ifdef _WIN32
#include <stdio.h>
#include <windows.h>
+#include <fcntl.h>
+#include <sys/stat.h>
#include <io.h>
#include <errno.h>
#include "w32-afunix.h"
+#ifndef S_IRGRP
+# define S_IRGRP 0
+# define S_IWGRP 0
+#endif
+
+
int
_w32_close (int fd)
{
@@ -81,34 +89,56 @@ _w32_sock_connect (int sockfd, struct sockaddr * addr, int addrlen)
int
-_w32_sock_bind (int sockfd, struct sockaddr * addr, int addrlen)
+_w32_sock_bind (int sockfd, struct sockaddr *addr, int addrlen)
{
if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
{
struct sockaddr_in myaddr;
- struct sockaddr_un * unaddr;
- FILE * fp;
+ struct sockaddr_un *unaddr;
+ int filefd;
+ FILE *fp;
int len = sizeof myaddr;
int rc;
+ unaddr = (struct sockaddr_un *)addr;
+
myaddr.sin_port = 0;
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ filefd = open (unaddr->sun_path,
+ (O_WRONLY|O_CREAT|O_EXCL|O_BINARY),
+ (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP));
+ if (filefd == -1)
+ {
+ if (errno == EEXIST)
+ errno = WSAEADDRINUSE;
+ return -1;
+ }
+ fp = fdopen (filefd, "wb");
+ if (!fp)
+ {
+ int save_e = errno;
+ close (filefd);
+ errno = save_e;
+ return -1;
+ }
+
rc = bind (sockfd, (struct sockaddr *)&myaddr, len);
+ if (!rc)
+ rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len);
if (rc)
- return rc;
- rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len);
- if (rc)
- return rc;
- unaddr = (struct sockaddr_un *)addr;
- fp = fopen (unaddr->sun_path, "wb");
- if (!fp)
- return -1;
+ {
+ int save_e = errno;
+ fclose (fp);
+ remove (unaddr->sun_path);
+ errno = save_e;
+ return rc;
+ }
fprintf (fp, "%d", myaddr.sin_port);
fclose (fp);
- /* we need this later. */
+ /* The caller expects these values. */
unaddr->sun_family = myaddr.sin_family;
unaddr->sun_port = myaddr.sin_port;
unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr;