summaryrefslogtreecommitdiff
path: root/src/sexp.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2001-12-18 10:02:02 +0000
committerWerner Koch <wk@gnupg.org>2001-12-18 10:02:02 +0000
commitffe5dbc708a464f7a1f9eba1d02cdd56ec80e1e1 (patch)
treebd2dd37ad8aa3a87542a8c9aa0083a7bac4a9c3d /src/sexp.c
parent7164f1524b883d1d44289c66520b357e9f7cf24a (diff)
downloadlibgcrypt-ffe5dbc708a464f7a1f9eba1d02cdd56ec80e1e1.tar.gz
* sexp.c: Removed the commented test code because we now have a
test in ../tests/
Diffstat (limited to 'src/sexp.c')
-rw-r--r--src/sexp.c333
1 files changed, 139 insertions, 194 deletions
diff --git a/src/sexp.c b/src/sexp.c
index 1c88ac2d..239b32b7 100644
--- a/src/sexp.c
+++ b/src/sexp.c
@@ -44,6 +44,14 @@ struct gcry_sexp {
#define ST_OPEN 3
#define ST_CLOSE 4
+#define digitp(p) (*(p) >= '0' && *(p) <= '9')
+#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' )
+
+
#if 0
static void
dump_mpi( GCRY_MPI a )
@@ -996,15 +1004,6 @@ sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff ,
}
int
-gcry_sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff,
- const char *buffer, size_t length )
-{
- va_list dummy_arg_ptr = 0;
-
- return sexp_sscan( retsexp, erroff, buffer, length, dummy_arg_ptr, 0 );
-}
-
-int
gcry_sexp_build( GCRY_SEXP *retsexp, size_t *erroff, const char *format, ... )
{
int rc;
@@ -1017,6 +1016,15 @@ gcry_sexp_build( GCRY_SEXP *retsexp, size_t *erroff, const char *format, ... )
return rc;
}
+int
+gcry_sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff,
+ const char *buffer, size_t length )
+{
+ va_list dummy_arg_ptr = 0;
+
+ return sexp_sscan( retsexp, erroff, buffer, length, dummy_arg_ptr, 0 );
+}
+
/****************
* 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
@@ -1091,198 +1099,135 @@ gcry_sexp_sprint( const GCRY_SEXP list, int mode,
-
-#if 0
-/***********************************************************/
-
-const char *
-strusage( int level )
-{
- return "?";
-}
-
-
-int
-main(int argc, char **argv)
+/* Scan a cannocial encoded buffer with implicit length values and
+ 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
+ NULL */
+size_t
+gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+ size_t *erroff, int *errcode)
{
- char buffer[5000];
- size_t erroff;
- int rc, n;
- FILE *fp;
- GCRY_SEXP s_pk, s_dsa, s_p, s_q, s_g, s_y, sexp;
-
- #if 1
- fp = stdin;
- n = fread(buffer, 1, 5000, fp );
- rc = gcry_sexp_sscan( &sexp, buffer, n, &erroff );
- if( rc ) {
- fprintf(stderr, "parse error %d at offset %u\n", rc, erroff );
- exit(1);
- }
- fputs("We have this S-Exp:\n",stderr);
- dump_sexp( sexp );
- #else
- s_pk = SEXP_NEW( "public-key", 10 );
- fputs("pk:\n",stderr);dump_sexp( s_pk );
- s_dsa = SEXP_NEW( "dsa", 3 );
- s_p = SEXP_CONS( SEXP_NEW( "p", 1 ), SEXP_NEW( "PPPPPP", 6 ) );
- fputs("p:\n",stderr);dump_sexp( s_p );
- s_y = SEXP_CONS( SEXP_NEW( "y", 1 ), SEXP_NEW( "YYYYYYYY", 8 ) );
- fputs("y:\n",stderr);dump_sexp( s_y );
- s_q = gcry_sexp_new_name_data( "q", "QQQ", 3 );
- fputs("q:\n",stderr);dump_sexp( s_q );
- s_g = gcry_sexp_new_name_mpi( "g" , gcry_mpi_set_ui(NULL, 42) );
- fputs("g:\n",stderr);dump_sexp( s_g );
- sexp = SEXP_CONS( s_pk, gcry_sexp_vlist( s_dsa,
- s_y,
- s_p,
- s_q,
- s_g,
- NULL ));
- fputs("Here is what we have:\n",stderr);
- dump_sexp( sexp );
- #endif
-
- /* now find something */
- if( argc > 1 )
- {
- GCRY_SEXP s1;
-
- s1 = gcry_sexp_find_token( sexp, argv[1], strlen(argv[1]) );
- if( !s1 )
- {
- fprintf(stderr, "didn't found `%s'\n", argv[1] );
- }
- else
- {
- fprintf(stderr, "found `%s':\n", argv[1] );
- dump_sexp( s1 );
- }
-
- #if 0
- { int i,rc, algo;
- GCRY_MPI *array;
-
- rc = sexp_to_pk( s1, 0, &array, &algo);
- if( rc )
- fprintf(stderr, "sexp_to_pk failed: rc=%d\n", rc );
- else {
- for(i=0; array[i]; i++ ) {
- fprintf(stderr, "MPI[%d]: ", i);
- dump_mpi( array[i] );
- fprintf(stderr, "\n");
- }
- }
- }
- #endif
-
-
- if( argc > 2 ) /* get the MPI out of the list */
- #if 0
- {
- GCRY_SEXP s2;
- const char *p;
- size_t n;
-
- p = gcry_sexp_car_data( s1, &n );
- if( !p ) {
- fputs("no CAR\n", stderr );
- exit(1);
- }
- fprintf(stderr, "CAR=`%.*s'\n", (int)n, p );
-
- p = gcry_sexp_cdr_data( s1, &n );
- if( !p ) {
- s2 = gcry_sexp_cdr( s1 );
- if( !s2 ) {
- fputs("no CDR at all\n", stderr );
- exit(1);
- }
- p = gcry_sexp_car_data( s2, &n );
+ const unsigned char *p;
+ const char *disphint=NULL;
+ unsigned int datalen = 0;
+ size_t dummy_erroff;
+ int dummy_errcode;
+ size_t count = 0;
+ int level = 0;
+
+ if (!erroff)
+ erroff = &dummy_erroff;
+ if (!errcode)
+ errcode = &dummy_errcode;
+
+ *errcode = 0;
+ *erroff = 0;
+ for (p=buffer; ; p++, count++ )
+ {
+ if (length && count >= length)
+ {
+ *erroff = count;
+ *errcode = -2; /* string too long */
+ return 0;
+ }
+
+ if (datalen)
+ {
+ if (*p == ':')
+ {
+ if (length && (count+datalen) >= length)
+ {
+ *erroff = count;
+ *errcode = -2; /* string too long */
+ return 0;
+ }
+ count += datalen;
+ p += datalen;
+ datalen = 0;
+ if (!level)
+ return count+1; /* expression is not a list - return now */
}
- if( !p ) {
- fputs("no CDR data\n", stderr );
- exit(1);
+ else if (digitp(p))
+ datalen = datalen*10 + atoi_1(p);
+ else
+ {
+ *erroff = count;
+ *errcode = -1;
+ return 0;
}
- fprintf(stderr, "CDR=`%.*s'\n", (int)n, p );
-
-
-
- }
- #elif 1
- {
- GCRY_SEXP s2;
- MPI a;
- const char *p;
- size_t n;
-
- fprintf(stderr,"*********************************\n");
- p = gcry_sexp_car_data( s1, &n );
- if( !p ) {
- fputs("no CAR\n", stderr );
- exit(1);
+ }
+ else if (*p == '(')
+ {
+ if (disphint)
+ {
+ *erroff = count;
+ *errcode = -9; /* open display hint */
+ return 0;
}
- fprintf(stderr, "CAR=`%.*s'\n", (int)n, p );
- s2 = gcry_sexp_cdr( s1 );
- if( !s2 ) {
- fputs("no CDR\n", stderr );
- exit(1);
-
+ level++;
+ }
+ else if (*p == ')')
+ { /* walk up */
+ if (!level)
+ {
+ *erroff = count;
+ *errcode = -3; /* unmatched parenthesis */
+ return 0;
}
- p = gcry_sexp_car_data( s2, &n );
- if( !p ) {
- fputs("no data at CAR\n", stderr );
- exit(1);
+ if (disphint)
+ {
+ *erroff = count;
+ *errcode = -9; /* open display hint */
+ return 0;
}
- fprintf(stderr, "CAR=`%.*s'\n", (int)n, p );
-
- s2 = gcry_sexp_find_token( s1, argv[2], strlen(argv[2]) );
- if( !s2 )
- {
- fprintf(stderr, "didn't found `%s'\n", argv[2] );
- exit(1);
+ if (!--level)
+ return ++count; /* ready */
+ }
+ else if (*p == '[')
+ {
+ if (disphint)
+ {
+ *erroff = count;
+ *errcode = -8; /* nested display hints */
+ return 0;
+ }
+ disphint = p;
+ }
+ else if (*p == ']')
+ {
+ if( !disphint )
+ {
+ *erroff = count;
+ *errcode = -9; /* unmatched display hint close */
+ return 0;
}
- p = gcry_sexp_car_data( s2, &n );
- if( !p ) {
- fputs("no CAR\n", stderr );
- exit(1);
+ disphint = NULL;
+ }
+ else if (digitp (p) )
+ {
+ if (*p == '0')
+ {
+ *erroff = count;
+ *errcode = -7; /* a length may not begin with zero */
+ return 0;
}
- fprintf(stderr, "CAR=`%.*s'\n", (int)n, p );
+ datalen = atoi_1 (p);
+ }
+ else if (*p == '&' || *p == '\\')
+ {
+ *erroff = count;
+ *errcode = -10; /* unexpected reserved punctuation */
+ return 0;
+ }
+ else
+ {
+ *erroff = count;
+ *errcode = -5; /* bad character */
+ return 0;
+ }
+ }
+}
- a = gcry_sexp_cdr_mpi( s2, GCRYMPI_FMT_USG );
- if( a ) {
- fprintf(stderr, "MPI: ");
- dump_mpi( a );
- fprintf(stderr, "\n");
- }
- else
- fprintf(stderr, "cannot cdr a mpi\n" );
- }
- #else
- { /* print all MPIs */
- void *ctx = NULL;
- GCRY_SEXP s2;
- MPI a;
-
- while( (s2 = gcry_sexp_enum( s1, &ctx, 0 )) )
- {
- const char *car_d;
- size_t car_n;
-
- car_d = gcry_sexp_car_data( s2, &car_n );
- if( car_d ) {
- fprintf(stderr, "CAR: %.*s=", (int)car_n, car_d );
- a = gcry_sexp_cdr_mpi( s2, GCRYMPI_FMT_USG );
- dump_mpi( a );
- fprintf(stderr, "\n");
- }
- else
- fprintf(stderr, "no CAR\n");
- }
- }
- #endif
- }
- return 0;
-}
-#endif