summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Pousse <benjamin.pousse@member.fsf.org>2012-02-17 22:16:12 +0100
committerWerner Koch <wk@gnupg.org>2013-03-18 09:52:08 +0100
commit5770a016ef6e55771a593c692b741f053a7a0412 (patch)
tree28341926fb9209e3e81f91d84afd50aa5986afd2
parentd313255350e6f397500ce23714ddec8780f32449 (diff)
downloadlibgcrypt-5770a016ef6e55771a593c692b741f053a7a0412.tar.gz
Fix malfunction of gcry_sexp_car.
* src/sexp.c (gcry_sexp_nth): Return a proper list for ST_DATA. -- Bug: The function gcry_sexp_car seems buggy to me (tested on libgcrypt version 1.4.6, 1.5.0, 1.6.0-git6078b05): it doesn't return any result on S-expression starting with a data element. For example, applied to the S-expression (hello "123"), it returns an empty S-expression (I expect the S-expression (hello)).
-rw-r--r--src/sexp.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/sexp.c b/src/sexp.c
index 0877773a..78013fdf 100644
--- a/src/sexp.c
+++ b/src/sexp.c
@@ -576,13 +576,25 @@ gcry_sexp_nth( const gcry_sexp_t list, int number )
p++;
if ( *p == ST_DATA ) {
- memcpy ( &n, p, sizeof n ); p += sizeof n;
- newlist = gcry_malloc ( sizeof *newlist + n + 1 );
+ memcpy ( &n, p, sizeof n );
+ /* Allocate 1 (=sizeof *newlist) byte for ST_OPEN
+ 1 byte for ST_DATA
+ sizeof n byte for n
+ n byte for the data
+ 1 byte for ST_CLOSE
+ 1 byte for ST_STOP */
+ newlist = gcry_malloc ( sizeof *newlist + 1 + sizeof n + n + 2 );
if (!newlist)
- return NULL;
- d = newlist->d;
- memcpy ( d, p, n ); d += n;
- *d++ = ST_STOP;
+ return NULL;
+ d = newlist->d;
+ *d = ST_OPEN; /* Put the ST_OPEN flag */
+ d++; /* Move forward */
+ /* Copy ST_DATA, n and the data from p to d */
+ memcpy ( d, p, 1 + sizeof n + n );
+ d += 1 + sizeof n + n; /* Move after the data copied */
+ *d = ST_CLOSE; /* Put the ST_CLOSE flag */
+ d++; /* Move forward */
+ *d = ST_STOP; /* Put the ST_STOP flag */
}
else if ( *p == ST_OPEN ) {
const byte *head = p;