summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2002-01-31 08:06:14 +0000
committerWerner Koch <wk@gnupg.org>2002-01-31 08:06:14 +0000
commit7d7ed402d9fc0f09ed2ab327e7a6fb6dc18cc9ac (patch)
tree53d0412649b38b903fb2cc1c336d49931be763b8
parent0bcbc7ba80d41c8197cb1eee60c13801b276f99c (diff)
downloadlibgcrypt-7d7ed402d9fc0f09ed2ab327e7a6fb6dc18cc9ac.tar.gz
* sexp.c (suitable_encoding,convert_to_hex,convert_to_string)
(convert_to_token): New. (gcry_sexp_sprint): Better formatting of advanced encoding, does now insert LFs and escapes all unprintable characters.
-rw-r--r--src/ChangeLog15
-rw-r--r--src/libgcrypt-config.in11
-rw-r--r--src/sexp.c304
3 files changed, 274 insertions, 56 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 044b0bd7..bd58f3ef 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,10 +1,21 @@
+2002-01-31 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (suitable_encoding,convert_to_hex,convert_to_string)
+ (convert_to_token): New.
+ (gcry_sexp_sprint): Better formatting of advanced encoding, does
+ now insert LFs and escapes all unprintable characters.
+
+2002-01-26 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt-config.in: Add copyright notice.
+
2002-01-11 Werner Koch <wk@gnupg.org>
* sexp.c (gcry_sexp_canon_len): Fixed last change.
2002-01-01 Timo Schulz <ts@winpt.org>
- * stdmem.c (_gcry_private_realloc): if pointer is NULL now realloc
+ * stdmem.c (_gcry_private_realloc): If pointer is NULL now realloc
behaves like malloc.
2001-12-20 Werner Koch <wk@gnupg.org>
@@ -20,7 +31,7 @@
* Makefile.am (DISTCLEANFILES): Include libgcrypt.sym
* sexp.c: Removed the commented test code because we now have a
- text in ../tests/
+ test in ../tests/
2001-12-17 Werner Koch <wk@gnupg.org>
diff --git a/src/libgcrypt-config.in b/src/libgcrypt-config.in
index dbe315bc..e1183e19 100644
--- a/src/libgcrypt-config.in
+++ b/src/libgcrypt-config.in
@@ -1,4 +1,13 @@
#!/bin/sh
+# Copyright (C) 1999 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
prefix=@prefix@
exec_prefix=@exec_prefix@
@@ -89,5 +98,3 @@ fi
if test "$echo_libs" = "yes"; then
echo ${libgcrypt_libs}
fi
-
-
diff --git a/src/sexp.c b/src/sexp.c
index 085ebc96..9b0dda7a 100644
--- a/src/sexp.c
+++ b/src/sexp.c
@@ -45,12 +45,16 @@ struct gcry_sexp {
#define ST_CLOSE 4
#define digitp(p) (*(p) >= '0' && *(p) <= '9')
+#define alphap(a) ( (*(a) >= 'A' && *(a) <= 'Z') \
+ || (*(a) >= 'a' && *(a) <= 'z'))
#define hexdigitp(a) (digitp (a) \
|| (*(a) >= 'A' && *(a) <= 'F') \
|| (*(a) >= 'a' && *(a) <= 'f'))
/* the atoi macros assume that the buffer has only valid digits */
#define atoi_1(p) (*(p) - '0' )
+#define TOKEN_SPECIALS "-./_:*+="
+
#if 0
static void
@@ -1025,6 +1029,123 @@ gcry_sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff,
return sexp_sscan( retsexp, erroff, buffer, length, dummy_arg_ptr, 0 );
}
+
+/* Figure out a suitable encoding for BUFFER of LENGTH.
+ Returns: 0 = Binary
+ 1 = String possible
+ 2 = Token possible
+*/
+static int
+suitable_encoding (const unsigned char *buffer, size_t length)
+{
+ const unsigned char *s;
+ int maybe_token = 1;
+
+ if (!length)
+ return 1;
+
+ for (s=buffer; length; s++, length--)
+ {
+ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))
+ && !strchr ("\b\t\v\n\f\r\"\'\\", *s))
+ return 0; /*binary*/
+ if ( maybe_token
+ && !alphap (s) && !digitp (s) && !strchr (TOKEN_SPECIALS, *s))
+ maybe_token = 0;
+ }
+ s = buffer;
+ if ( maybe_token && !digitp (s) )
+ return 2;
+ return 1;
+}
+
+
+static int
+convert_to_hex (const unsigned char *src, size_t len, unsigned char *dest)
+{
+ int i;
+
+ if (dest)
+ {
+ *dest++ = '#';
+ for (i=0; i < len; i++, dest += 2 )
+ sprintf (dest, "%02X", src[i]);
+ *dest++ = '#';
+ }
+ return len*2+2;
+}
+
+static int
+convert_to_string (const unsigned char *s, size_t len, unsigned char *dest)
+{
+ if (dest)
+ {
+ unsigned char *p = dest;
+ *p++ = '\"';
+ for (; len; len--, s++ )
+ {
+ switch (*s)
+ {
+ case '\b': *p++ = '\\'; *p++ = 'b'; break;
+ case '\t': *p++ = '\\'; *p++ = 't'; break;
+ case '\v': *p++ = '\\'; *p++ = 'v'; break;
+ case '\n': *p++ = '\\'; *p++ = 'n'; break;
+ case '\f': *p++ = '\\'; *p++ = 'f'; break;
+ case '\r': *p++ = '\\'; *p++ = 'r'; break;
+ case '\"': *p++ = '\\'; *p++ = '\"'; break;
+ case '\'': *p++ = '\\'; *p++ = '\''; break;
+ case '\\': *p++ = '\\'; *p++ = '\\'; break;
+ default:
+ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
+ {
+ sprintf (p, "\\x%02x", *s);
+ p += 4;
+ }
+ else
+ *p++ = *s;
+ }
+ }
+ *p++ = '\"';
+ return p - dest;
+ }
+ else
+ {
+ int count = 2;
+ for (; len; len--, s++ )
+ {
+ switch (*s)
+ {
+ case '\b':
+ case '\t':
+ case '\v':
+ case '\n':
+ case '\f':
+ case '\r':
+ case '\"':
+ case '\'':
+ case '\\': count += 2; break;
+ default:
+ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
+ count += 4;
+ else
+ count++;
+ }
+ }
+ return count;
+ }
+}
+
+
+
+static int
+convert_to_token (const unsigned char *src, size_t len, unsigned char *dest)
+{
+ if (dest)
+ memcpy (dest, src, len);
+ return len;
+}
+
+
/****************
* Print SEXP to buffer using the MODE. Returns the length of the
* SEXP in buffer or 0 if the buffer is too short (We have at least an
@@ -1035,65 +1156,144 @@ size_t
gcry_sexp_sprint( const GCRY_SEXP list, int mode,
char *buffer, size_t maxlength )
{
- static byte empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
- const byte *s;
- char *d;
- DATALEN n;
- char numbuf[20];
- size_t len = 0;
-
- s = list? list->d : empty;
- d = buffer;
- while ( *s != ST_STOP ) {
- switch ( *s ) {
- case ST_OPEN:
- s++;
- len++;
- if ( buffer ) {
- if ( len >= maxlength )
- return 0;
- *d++ = '(';
+ static byte empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
+ const byte *s;
+ char *d;
+ DATALEN n;
+ char numbuf[20];
+ size_t len = 0;
+ int i, indent = 0;
+
+ s = list? list->d : empty;
+ d = buffer;
+ while ( *s != ST_STOP )
+ {
+ switch ( *s )
+ {
+ case ST_OPEN:
+ s++;
+ if ( mode != GCRYSEXP_FMT_CANON )
+ {
+ if (indent)
+ len++;
+ len += indent;
+ }
+ len++;
+ if ( buffer )
+ {
+ if ( len >= maxlength )
+ return 0;
+ if ( mode != GCRYSEXP_FMT_CANON )
+ {
+ if (indent)
+ *d++ = '\n';
+ for (i=0; i < indent; i++)
+ *d++ = ' ';
+ }
+ *d++ = '(';
}
- break;
- case ST_CLOSE:
- s++;
- len++;
- if ( mode != GCRYSEXP_FMT_CANON )
- len++;
- if ( buffer ) {
- if ( len >= maxlength )
- return 0;
- *d++ = ')';
- if ( mode != GCRYSEXP_FMT_CANON )
- *d++ = '\n';
+ indent++;
+ break;
+ case ST_CLOSE:
+ s++;
+ len++;
+ if ( buffer )
+ {
+ if ( len >= maxlength )
+ return 0;
+ *d++ = ')';
}
- break;
- case ST_DATA:
- s++;
- memcpy ( &n, s, sizeof n ); s += sizeof n;
- sprintf (numbuf, "%u:", (unsigned int)n );
- len += strlen (numbuf) + n;
- if ( buffer ) {
- if ( len >= maxlength )
+ indent--;
+ if (*s != ST_OPEN && *s != ST_STOP && mode != GCRYSEXP_FMT_CANON)
+ {
+ len++;
+ len += indent;
+ if (buffer)
+ {
+ if (len >= maxlength)
+ return 0;
+ *d++ = '\n';
+ for (i=0; i < indent; i++)
+ *d++ = ' ';
+ }
+ }
+ break;
+ case ST_DATA:
+ s++;
+ memcpy ( &n, s, sizeof n ); s += sizeof n;
+ if (mode == GCRYSEXP_FMT_ADVANCED)
+ {
+ int type;
+ size_t nn;
+
+ switch ( (type=suitable_encoding (s, n)))
+ {
+ case 1: nn = convert_to_string (s, n, NULL); break;
+ case 2: nn = convert_to_token (s, n, NULL); break;
+ default: nn = convert_to_hex (s, n, NULL); break;
+ }
+ len += nn;
+ if (buffer)
+ {
+ if (len >= maxlength)
+ return 0;
+ switch (type)
+ {
+ case 1: convert_to_string (s, n, d); break;
+ case 2: convert_to_token (s, n, d); break;
+ default: convert_to_hex (s, n, d); break;
+ }
+ d += nn;
+ }
+ if (s[n] != ST_CLOSE)
+ {
+ len++;
+ if (buffer)
+ {
+ if (len >= maxlength)
+ return 0;
+ *d++ = ' ';
+ }
+ }
+ }
+ else
+ {
+ sprintf (numbuf, "%u:", (unsigned int)n );
+ len += strlen (numbuf) + n;
+ if ( buffer )
+ {
+ if ( len >= maxlength )
return 0;
- d = stpcpy ( d, numbuf );
- memcpy ( d, s, n ); d += n;
- }
- s += n;
- break;
- default:
- BUG ();
+ d = stpcpy ( d, numbuf );
+ memcpy ( d, s, n ); d += n;
+ }
+ }
+ s += n;
+ break;
+ default:
+ BUG ();
}
}
- if (buffer) {
- if ( len >= maxlength )
- return 0;
- *d++ = 0; /* for convenience we make a C string */
+ if ( mode != GCRYSEXP_FMT_CANON )
+ {
+ len++;
+ if (buffer)
+ {
+ if ( len >= maxlength )
+ return 0;
+ *d++ = '\n';
+ }
+ }
+ if (buffer)
+ {
+ if ( len >= maxlength )
+ return 0;
+ *d++ = 0; /* for convenience we make a C string */
}
- else
- len++; /* we need one byte more for this */
+ else
+ len++; /* we need one byte more for this */
- return len;
+ return len;
}