diff options
author | Werner Koch <wk@gnupg.org> | 2002-05-16 17:11:21 +0000 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2002-05-16 17:11:21 +0000 |
commit | 848c32beeb723d8e06499ec119222dae77a3cd8e (patch) | |
tree | 1c29feda82dc9927881d6706e8f9338c77e86b2d | |
parent | 9e93c817955b8e876227df3c1ae0285f911c138a (diff) | |
download | libgcrypt-848c32beeb723d8e06499ec119222dae77a3cd8e.tar.gz |
* tsexp.c (back_and_forth): Very minimal test of the new functions.
* missing-string.c: New.
* gcrypt.h: Add new error codes GCRYERR_SEXP_ and typedefs
GcryMPI, GcrySexp, GcryCipherHd, GcryMDHd as aliases for the old
ones using an underscore.
* global.c (gcry_strerror): Add strings fro the new error codes.
* sexp.c (gcry_sexp_canon_len): Use a macro to convert from new to
old error codes.
(gcry_sexp_create,gcry_sexp_new): New.
-rw-r--r-- | src/ChangeLog | 13 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/g10lib.h | 21 | ||||
-rw-r--r-- | src/gcrypt.h | 49 | ||||
-rw-r--r-- | src/global.c | 13 | ||||
-rw-r--r-- | src/missing-string.c | 209 | ||||
-rw-r--r-- | src/sexp.c | 111 | ||||
-rw-r--r-- | tests/ChangeLog | 4 | ||||
-rw-r--r-- | tests/tsexp.c | 63 |
9 files changed, 450 insertions, 36 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index b012286f..e1419dbd 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2002-05-16 Werner Koch <wk@gnupg.org> + + * missing-string.c: New. + + * gcrypt.h: Add new error codes GCRYERR_SEXP_ and typedefs + GcryMPI, GcrySexp, GcryCipherHd, GcryMDHd as aliases for the old + ones using an underscore. + + * global.c (gcry_strerror): Add strings fro the new error codes. + * sexp.c (gcry_sexp_canon_len): Use a macro to convert from new to + old error codes. + (gcry_sexp_create,gcry_sexp_new): New. + 2002-05-15 Werner Koch <wk@gnupg.org> * mutex.h (DEFINE_LOCAL_MUTEX): Macro to define a mutex and diff --git a/src/Makefile.am b/src/Makefile.am index 71b82d1e..447da749 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -50,7 +50,8 @@ libgcrypt_la_SOURCES = g10lib.h \ secmem.c \ secmem.h \ mpi.h \ - mutex.h + mutex.h \ + missing-string.c libgcrypt_la_DEPENDENCIES = libgcrypt.sym \ ../cipher/libcipher.la ../mpi/libmpi.la diff --git a/src/g10lib.h b/src/g10lib.h index 125c7826..bfbe7f80 100644 --- a/src/g10lib.h +++ b/src/g10lib.h @@ -128,16 +128,22 @@ MPI _gcry_generate_elg_prime( int mode, unsigned pbits, unsigned qbits, -/* replacements of missing functions */ -#ifndef HAVE_MEMICMP -int memicmp( const char *a, const char *b, size_t n ); -#endif +/* replacements of missing functions (missing-string.c)*/ #ifndef HAVE_STPCPY -char *stpcpy(char *a,const char *b); +char *stpcpy (char *a, const char *b); +#endif +#ifndef HAVE_STRSEP +char *strsep (char **stringp, const char *delim); #endif #ifndef HAVE_STRLWR -char *strlwr(char *a); +char *strlwr (char *a); #endif +#ifndef HAVE_STRCASECMP +int strcasecmp (const char *a, const char *b); +#endif + + +/* macros used to rename missing functions */ #ifndef HAVE_STRTOUL #define strtoul(a,b,c) ((unsigned long)strtol((a),(b),(c))) #endif @@ -154,6 +160,7 @@ char *strlwr(char *a); #define raise(a) kill(getpid(), (a)) #endif + /* some handy macros */ #ifndef STR #define STR(v) #v @@ -164,3 +171,5 @@ char *strlwr(char *a); #endif /* G10LIB_H */ + + diff --git a/src/gcrypt.h b/src/gcrypt.h index c0b979ff..aa382a38 100644 --- a/src/gcrypt.h +++ b/src/gcrypt.h @@ -52,6 +52,7 @@ extern "C" { struct gcry_mpi; typedef struct gcry_mpi *GCRY_MPI; +typedef struct gcry_mpi *GcryMPI; /******************************************* * * @@ -90,7 +91,23 @@ enum { GCRYERR_NO_OBJ = 68, /* Missing item in an object */ GCRYERR_NOT_IMPL = 69, /* Not implemented */ GCRYERR_CONFLICT = 70, - GCRYERR_INV_CIPHER_MODE = 71 + GCRYERR_INV_CIPHER_MODE = 71, + + /* error codes pertaining to S-expressions */ + GCRYERR_SEXP_INV_LEN_SPEC = 201, + GCRYERR_SEXP_STRING_TOO_LONG = 202, + GCRYERR_SEXP_UNMATCHED_PAREN = 203, + GCRYERR_SEXP_NOT_CANONICAL = 204, + GCRYERR_SEXP_BAD_CHARACTER = 205, + GCRYERR_SEXP_BAD_QUOTATION = 206,/* or invalid hex or octal value */ + GCRYERR_SEXP_ZERO_PREFIX = 207,/* first character of a length is 0 */ + GCRYERR_SEXP_NESTED_DH = 208,/* nested display hints */ + GCRYERR_SEXP_UNMATCHED_DH = 209,/* unmatched display hint */ + GCRYERR_SEXP_UNEXPECTED_PUNC = 210,/* unexpected reserved punctuation */ + GCRYERR_SEXP_BAD_HEX_CHAR = 211, + GCRYERR_SEXP_ODD_HEX_NUMBERS = 212, + GCRYERR_SEXP_BAD_OCT_CHAR = 213 + }; const char *gcry_check_version( const char *req_version ); @@ -151,6 +168,7 @@ enum gcry_random_level { struct gcry_sexp; typedef struct gcry_sexp *GCRY_SEXP; +typedef struct gcry_sexp *GcrySexp; /* this type looks more pretty */ enum gcry_sexp_format { GCRYSEXP_FMT_DEFAULT = 0, @@ -159,20 +177,29 @@ enum gcry_sexp_format { GCRYSEXP_FMT_ADVANCED = 3 }; -void gcry_sexp_release( GCRY_SEXP sexp ); +int gcry_sexp_new (GCRY_SEXP *retsexp, const void *buffer, size_t length, + int autodetect); +int gcry_sexp_create (GCRY_SEXP *retsexp, void *buffer, size_t length, + int autodetect, void (*freefnc)(void*) ); +int gcry_sexp_sscan (GCRY_SEXP *retsexp, size_t *erroff, + const char *buffer, size_t length ); +int gcry_sexp_build (GCRY_SEXP *retsexp, size_t *erroff, + const char *format, ... ); +void gcry_sexp_release (GCRY_SEXP sexp); + +size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length, + size_t *erroff, int *errcode); + +size_t gcry_sexp_sprint (GCRY_SEXP sexp, int mode, char *buffer, + size_t maxlength ); + void gcry_sexp_dump( const GCRY_SEXP a ); GCRY_SEXP gcry_sexp_cons( const GCRY_SEXP a, const GCRY_SEXP b ); GCRY_SEXP gcry_sexp_alist( const GCRY_SEXP *array ); GCRY_SEXP gcry_sexp_vlist( const GCRY_SEXP a, ... ); GCRY_SEXP gcry_sexp_append( const GCRY_SEXP a, const GCRY_SEXP n ); GCRY_SEXP gcry_sexp_prepend( const GCRY_SEXP a, const GCRY_SEXP n ); -int gcry_sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff, - const char *buffer, size_t length ); -int gcry_sexp_build( GCRY_SEXP *retsexp, size_t *erroff, - const char *format, ... ); -size_t gcry_sexp_sprint( GCRY_SEXP sexp, int mode, char *buffer, - size_t maxlength ); -GCRY_SEXP gcry_sexp_find_token( GCRY_SEXP list, +GCRY_SEXP gcry_sexp_find_token( GCRY_SEXP list, const char *tok, size_t toklen ); int gcry_sexp_length( const GCRY_SEXP list ); GCRY_SEXP gcry_sexp_nth( const GCRY_SEXP list, int number ); @@ -183,8 +210,6 @@ const char *gcry_sexp_nth_data( const GCRY_SEXP list, int number, size_t *datalen ); GCRY_MPI gcry_sexp_nth_mpi( GCRY_SEXP list, int number, int mpifmt ); -size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length, - size_t *erroff, int *errcode); /******************************************* @@ -305,6 +330,7 @@ int gcry_mpi_get_flag( GCRY_MPI a, enum gcry_mpi_flag flag ); struct gcry_cipher_handle; typedef struct gcry_cipher_handle *GCRY_CIPHER_HD; +typedef struct gcry_cipher_handle *GcryCipherHd; enum gcry_cipher_algos { GCRY_CIPHER_NONE = 0, @@ -436,6 +462,7 @@ struct gcry_md_handle { byte buf[1]; }; typedef struct gcry_md_handle *GCRY_MD_HD; +typedef struct gcry_md_handle *GcryMDHd; GCRY_MD_HD gcry_md_open( int algo, unsigned flags ); diff --git a/src/global.c b/src/global.c index 7d922b70..192cf503 100644 --- a/src/global.c +++ b/src/global.c @@ -280,6 +280,19 @@ gcry_strerror( int ec ) X(CONFLICT, N_("conflict")) X(INV_CIPHER_MODE,N_("invalid cipher mode")) + X(SEXP_INV_LEN_SPEC ,N_("invalid length specification")) + X(SEXP_STRING_TOO_LONG,N_("string too long")) + X(SEXP_UNMATCHED_PAREN,N_("unmatched parenthesis")) + X(SEXP_NOT_CANONICAL ,N_("not a canonical S-expression")) + X(SEXP_BAD_CHARACTER ,N_("bad character")) + X(SEXP_BAD_QUOTATION ,N_("invalid hex/octal value or bad quotation")) + X(SEXP_ZERO_PREFIX ,N_("a length may not begin with zero")) + X(SEXP_NESTED_DH ,N_("nested display hints")) + X(SEXP_UNMATCHED_DH ,N_("unmatched display hint close")) + X(SEXP_UNEXPECTED_PUNC,N_("unexpected reserved punctuation")) + X(SEXP_BAD_HEX_CHAR, N_("invalid hex character")) + X(SEXP_ODD_HEX_NUMBERS,N_("odd number of hex characters")) + X(SEXP_BAD_OCT_CHAR, N_("invalid octal character")) default: sprintf( buf, "ec=%d", ec ); diff --git a/src/missing-string.c b/src/missing-string.c new file mode 100644 index 00000000..f9c5df1a --- /dev/null +++ b/src/missing-string.c @@ -0,0 +1,209 @@ +/* missing-string.c - missing string utilities + * Copyright (C) 1994, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt 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. + * + * Libgcrypt 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include <config.h> +#include <stdlib.h> +#include <string.h> + +#include "g10lib.h" + + +#ifndef HAVE_STPCPY +char * +stpcpy(char *a,const char *b) +{ + while( *b ) + *a++ = *b++; + *a = 0; + + return (char*)a; +} +#endif + + +#ifndef HAVE_STRSEP +/* code taken from glibc-2.2.1/sysdeps/generic/strsep.c */ +char * +strsep (char **stringp, const char *delim) +{ + char *begin, *end; + + begin = *stringp; + if (begin == NULL) + return NULL; + + /* A frequent case is when the delimiter string contains only one + character. Here we don't need to call the expensive `strpbrk' + function and instead work using `strchr'. */ + if (delim[0] == '\0' || delim[1] == '\0') + { + char ch = delim[0]; + + if (ch == '\0') + end = NULL; + else + { + if (*begin == ch) + end = begin; + else if (*begin == '\0') + end = NULL; + else + end = strchr (begin + 1, ch); + } + } + else + /* Find the end of the token. */ + end = strpbrk (begin, delim); + + if (end) + { + /* Terminate the token and set *STRINGP past NUL character. */ + *end++ = '\0'; + *stringp = end; + } + else + /* No more delimiters; this is the last token. */ + *stringp = NULL; + + return begin; +} +#endif /*HAVE_STRSEP*/ + + +#ifndef HAVE_STRLWR +char * +strlwr(char *s) +{ + char *p; + for(p=s; *p; p++ ) + *p = tolower(*p); + return s; +} +#endif + +#ifndef HAVE_STRCASECMP +int +strcasecmp( const char *a, const char *b ) +{ + for( ; *a && *b; a++, b++ ) { + if( *a != *b && toupper(*a) != toupper(*b) ) + break; + } + return *(const byte*)a - *(const byte*)b; +} +#endif + + +#ifdef __MINGW32__ +/* + * Like vsprintf but provides a pointer to malloc'd storage, which + * must be freed by the caller (m_free). Taken from libiberty as + * found in gcc-2.95.2 and a little bit modernized. + * FIXME: Write a new CRT for W32. + */ +int +vasprintf ( char **result, const char *format, va_list args) +{ + const char *p = format; + /* Add one to make sure that it is never zero, which might cause malloc + to return NULL. */ + int total_width = strlen (format) + 1; + va_list ap; + + /* this is not really portable but works under Windows */ + memcpy ( &ap, &args, sizeof (va_list)); + + while (*p != '\0') + { + if (*p++ == '%') + { + while (strchr ("-+ #0", *p)) + ++p; + if (*p == '*') + { + ++p; + total_width += abs (va_arg (ap, int)); + } + else + { + char *endp; + total_width += strtoul (p, &endp, 10); + p = endp; + } + if (*p == '.') + { + ++p; + if (*p == '*') + { + ++p; + total_width += abs (va_arg (ap, int)); + } + else + { + char *endp; + total_width += strtoul (p, &endp, 10); + p = endp; + } + } + while (strchr ("hlL", *p)) + ++p; + /* Should be big enough for any format specifier except %s + and floats. */ + total_width += 30; + switch (*p) + { + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + case 'c': + (void) va_arg (ap, int); + break; + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + (void) va_arg (ap, double); + /* Since an ieee double can have an exponent of 307, we'll + make the buffer wide enough to cover the gross case. */ + total_width += 307; + + case 's': + total_width += strlen (va_arg (ap, char *)); + break; + case 'p': + case 'n': + (void) va_arg (ap, char *); + break; + } + } + } + *result = m_alloc (total_width); + if (*result != NULL) + return vsprintf (*result, format, args); + else + return 0; +} + +#endif /*__MINGW32__*/ + @@ -59,6 +59,13 @@ struct gcry_sexp { #define TOKEN_SPECIALS "-./_:*+=" +#define OLDPARSECODE(a) (-((GCRYERR_SEXP_ ## a)-GCRYERR_SEXP_INV_LEN_SPEC+1)) + + +static int +sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff , + const char *buffer, size_t length, va_list arg_ptr, int argflag); + #if 0 static void @@ -174,6 +181,73 @@ normalize ( GCRY_SEXP list ) return list; } +/* Create a new S-expression object by reading LENGTH bytes from + BUFFER, assuming it is canonilized encoded or autodetected encoding + when AUTODETECT is set to 1. With FREEFNC not NULL, ownership of + the buffer is transferred to tyhe newle created object. FREEFNC + should be the freefnc used to release BUFFER; there is no guarantee + at which point this function is called; most likey you want to use + free() or gcry_free(). + + Passing LENGTH and AUTODETECT as 0 is allowed to indicate that + BUFFER points to a valid canonical encoded S-expression. A LENGTH + of 0 and AUTODETECT 1 indicates that buffer points to a + null-terminated string. + + This function returns 0 and and the pointer to the new object in + RETSEXP or an error code in which case RETSEXP is set to NULL. */ +int +gcry_sexp_create (GCRY_SEXP *retsexp, void *buffer, size_t length, + int autodetect, void (*freefnc)(void*) ) +{ + int errcode; + GCRY_SEXP se; + volatile va_list dummy_arg_ptr; + + if (!retsexp) + return GCRYERR_INV_ARG; + *retsexp = NULL; + if (autodetect < 0 || autodetect > 1 || !buffer) + return GCRYERR_INV_ARG; + + if (!length && !autodetect) + { /* What a brave caller to assume that there is really a canonical + encoded S-expression in buffer */ + length = gcry_sexp_canon_len (buffer, 0, NULL, &errcode); + if (!length) + return 200 - errcode; + } + else if (!length && autodetect) + { /* buffer is a string */ + length = strlen ((char *)buffer); + } + + errcode = sexp_sscan (&se, NULL, buffer, length, dummy_arg_ptr, 0); + if (errcode) + return 200 - errcode; + + *retsexp = se; + if (freefnc) + { + /* For now we release the buffer immediately. As soon as we + have changed the internal represenation of S-expression to + the canoncial format - which has the advantage of faster + parsing - we will use this function as a closure in our + GCRYSEXP object and use the BUFFER directly */ + freefnc (buffer); + } + return 0; +} + +/* Same as gcry_sexp_create but don't transfer ownership */ +int +gcry_sexp_new (GCRY_SEXP *retsexp, const void *buffer, size_t length, + int autodetect) +{ + return gcry_sexp_create (retsexp, (void *)buffer, length, autodetect, NULL); +} + + /**************** * Release resource of the given SEXP object. */ @@ -890,7 +964,7 @@ sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff , else if( *p == '#' ) { if( (hexcount & 1) ) { *erroff = p - buffer; - return -12; /* odd number of hex digits */ + return OLDPARSECODE (ODD_HEX_NUMBERS); } datalen = hexcount/2; @@ -907,7 +981,7 @@ sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff , } else if( !isspace( *p ) ) { *erroff = p - buffer; - return -11; /* invalid hex character */ + return OLDPARSECODE (BAD_HEX_CHAR); } } else if( base64 ) { @@ -1394,7 +1468,7 @@ gcry_sexp_sprint( const GCRY_SEXP list, int mode, return the actual length this S-expression uses. For a valid S-Exp it should never return 0. If LENGTH is not zero, the maximum length to scan is given - this can be used for syntax checks of - data passed from outside. erroce and erroff may both be passed as + data passed from outside. errorcode and erroff may both be passed as NULL Errorcodes (for historic reasons they are all negative): @@ -1407,7 +1481,10 @@ gcry_sexp_sprint( const GCRY_SEXP list, int mode, -7 := a length may not begin with zero -8 := nested display hints -9 := unmatched display hint close - -10 := unexpected reserved punctuation + -10 := unexpected reserved punctuation + + Use this formula to convert the errorcodes: + gcryerr = 200 - errcode; */ size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length, @@ -1432,7 +1509,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length, return 0; if (*buffer != '(') { - *errcode = -4; /* not a canonical S-expression */ + *errcode = OLDPARSECODE (NOT_CANONICAL); return 0; } @@ -1441,7 +1518,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length, if (length && count >= length) { *erroff = count; - *errcode = -2; /* string too long */ + *errcode = OLDPARSECODE (STRING_TOO_LONG); return 0; } @@ -1452,7 +1529,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length, if (length && (count+datalen) >= length) { *erroff = count; - *errcode = -2; /* string too long */ + *errcode = OLDPARSECODE (STRING_TOO_LONG); return 0; } count += datalen; @@ -1464,7 +1541,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length, else { *erroff = count; - *errcode = -1; + *errcode = OLDPARSECODE (INV_LEN_SPEC); return 0; } } @@ -1473,7 +1550,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length, if (disphint) { *erroff = count; - *errcode = -9; /* open display hint */ + *errcode = OLDPARSECODE (UNMATCHED_DH); return 0; } level++; @@ -1483,13 +1560,13 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length, if (!level) { *erroff = count; - *errcode = -3; /* unmatched parenthesis */ + *errcode = OLDPARSECODE (UNMATCHED_PAREN); return 0; } if (disphint) { *erroff = count; - *errcode = -9; /* open display hint */ + *errcode = OLDPARSECODE (UNMATCHED_DH); return 0; } if (!--level) @@ -1500,7 +1577,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length, if (disphint) { *erroff = count; - *errcode = -8; /* nested display hints */ + *errcode = OLDPARSECODE (NESTED_DH); return 0; } disphint = p; @@ -1510,7 +1587,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length, if( !disphint ) { *erroff = count; - *errcode = -9; /* unmatched display hint close */ + *errcode = OLDPARSECODE (UNMATCHED_DH); return 0; } disphint = NULL; @@ -1520,7 +1597,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length, if (*p == '0') { *erroff = count; - *errcode = -7; /* a length may not begin with zero */ + *errcode = OLDPARSECODE (ZERO_PREFIX); return 0; } datalen = atoi_1 (p); @@ -1528,16 +1605,14 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length, else if (*p == '&' || *p == '\\') { *erroff = count; - *errcode = -10; /* unexpected reserved punctuation */ + *errcode = OLDPARSECODE (UNEXPECTED_PUNC); return 0; } else { *erroff = count; - *errcode = -5; /* bad character */ + *errcode = OLDPARSECODE (BAD_CHARACTER); return 0; } } } - - diff --git a/tests/ChangeLog b/tests/ChangeLog index ca1b5ef1..e0c73312 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +2002-05-16 Werner Koch <wk@gnupg.org> + + * tsexp.c (back_and_forth): Very minimal test of the new functions. + 2002-05-14 Werner Koch <wk@gnupg.org> Changed license of all files to the LGPL. diff --git a/tests/tsexp.c b/tests/tsexp.c index 2615f424..dd852f96 100644 --- a/tests/tsexp.c +++ b/tests/tsexp.c @@ -213,6 +213,64 @@ canon_len (void) } +static void +back_and_forth_one (int testno, const char *buffer, size_t length) +{ + int rc; + GcrySexp se, se1; + size_t n, n1; + char *p1; + + rc = gcry_sexp_new (&se, buffer, length, 1); + if (rc) + { + fail ("baf %d: gcry_sexp_new failed: %s\n", testno, gcry_strerror (rc)); + return; + } + n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0); + if (!n1) + { + fail ("baf %d: get required length for canon failed\n", testno); + return; + } + p1 = gcry_xmalloc (n1); + n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1); + if (n1 != n+1) /* sprints adds an extra 0 but dies not return it */ + { + fail ("baf %d: length mismatch for canon\n", testno); + return; + } + rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free); + if (rc) + { + fail ("baf %d: gcry_sexp_create failed: %s\n", + testno, gcry_strerror (rc)); + return; + } + gcry_sexp_release (se1); + + /* FIXME: we need a lot more tests */ + + gcry_sexp_release (se); +} + + + +static void +back_and_forth (void) +{ + static struct { char *buf; int len; } tests[] = { + { "(7:g34:fgh1::2:())", 0 }, + { "(7:g34:fgh1::2:())", 18 }, + { NULL, 0 } + }; + int idx; + + for (idx=0; tests[idx].buf; idx++) + back_and_forth_one (idx, tests[idx].buf, tests[idx].len); +} + + int main (int argc, char **argv) { @@ -221,8 +279,13 @@ main (int argc, char **argv) basic (); canon_len (); + back_and_forth (); return error_count? 1:0; } + + + + |