[git] GCRYPT - branch, LIBGCRYPT-1-6-BRANCH, updated. libgcrypt-1.6.0-20-g8ca5966
by Werner Koch
cvs at cvs.gnupg.org
Tue Jan 28 16:05:41 CET 2014
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU crypto library".
The branch, LIBGCRYPT-1-6-BRANCH has been updated
via 8ca5966198b4d0d3932978880dc21cb75bf75d56 (commit)
from 420f42a5752e90a8b27d58ffa1ddfe6e4ab341e8 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 8ca5966198b4d0d3932978880dc21cb75bf75d56
Author: Werner Koch <wk at gnupg.org>
Date: Thu Jan 9 19:14:09 2014 +0100
sexp: Fix broken gcry_sexp_nth.
* src/sexp.c (_gcry_sexp_nth): Return a valid S-expression for a data
element.
(NODE): Remove unused typedef.
(ST_HINT): Comment unused macro.
* tests/tsexp.c (bug_1594): New.
(main): Run new test.
--
Before 1.6.0 gcry_sexp_nth (list, 0) with a LIST of "(a (b 3:pqr) (c
3:456) (d 3:xyz))" returned the entire list. 1.6.0 instead returned
NULL. However, this is also surprising and the expected value would
be "(a)". This patch fixes this.
Somewhat related to that gcry_sexp_nth returned a broken list if
requesting index 1 of a list like "(n foo)". It returned just the
"foo" but not as a list which is required by the S-expression specs.
Due to this patch the returned value is now "(foo)".
Thanks to Ludovic Courtès for pointing out these problems.
GnuPG-bug-id: 1594
(cherry picked from commit cbdc355415f83ed62da4f3618767eba54d7e6d37)
Resolved conflicts:
tests/tsexp.c: Fix for renamed file in master.
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
index c2534a2..58491fb 100644
--- a/doc/gcrypt.texi
+++ b/doc/gcrypt.texi
@@ -4137,8 +4137,9 @@ no such element, @code{NULL} is returned.
@deftypefun gcry_sexp_t gcry_sexp_car (@w{const gcry_sexp_t @var{list}})
Create and return a new S-expression from the first element in
- at var{list}; this called the "type" and should always exist and be a
-string. @code{NULL} is returned in case of a problem.
+ at var{list}; this is called the "type" and should always exist per
+S-expression specification and in general be a string. @code{NULL} is
+returned in case of a problem.
@end deftypefun
@deftypefun gcry_sexp_t gcry_sexp_cdr (@w{const gcry_sexp_t @var{list}})
diff --git a/src/sexp.c b/src/sexp.c
index f31da00..0e4af52 100644
--- a/src/sexp.c
+++ b/src/sexp.c
@@ -1,7 +1,7 @@
/* sexp.c - S-Expression handling
* Copyright (C) 1999, 2000, 2001, 2002, 2003,
* 2004, 2006, 2007, 2008, 2011 Free Software Foundation, Inc.
- * Copyright (C) 2013 g10 Code GmbH
+ * Copyright (C) 2013, 2014 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@@ -32,7 +32,55 @@
#define GCRYPT_NO_MPI_MACROS 1
#include "g10lib.h"
-typedef struct gcry_sexp *NODE;
+
+/* Notes on the internal memory layout.
+
+ We store an S-expression as one memory buffer with tags, length and
+ value. The simplest list would thus be:
+
+ /----------+----------+---------+------+-----------+----------\
+ | open_tag | data_tag | datalen | data | close_tag | stop_tag |
+ \----------+----------+---------+------+-----------+----------/
+
+ Expressed more compact and with an example:
+
+ /----+----+----+---+----+----\
+ | OT | DT | DL | D | CT | ST | "(foo)"
+ \----+----+----+---+----+----/
+
+ The open tag must always be the first tag of a list as requires by
+ the S-expression specs. At least data element (data_tag, datalen,
+ data) is required as well. The close_tag finishes the list and
+ would actually be sufficient. For fail-safe reasons a final stop
+ tag is always the last byte in a buffer; it has a value of 0 so
+ that string function accidently applied to an S-expression will
+ never access unallocated data. We do not support display hints and
+ thus don't need to represent them. A list may have more an
+ arbitrary number of data elements but at least one is required.
+ The length of each data must be greater than 0 and has a current
+ limit to 65535 bytes (by means of the DATALEN type).
+
+ A list with two data elements:
+
+ /----+----+----+---+----+----+---+----+----\
+ | OT | DT | DL | D | DT | DL | D | CT | ST | "(foo bar)"
+ \----+----+----+---+----+----+---+----+----/
+
+ In the above example both DL fields have a value of 3.
+ A list of a list with one data element:
+
+ /----+----+----+----+---+----+----+----\
+ | OT | OT | DT | DL | D | CT | CT | ST | "((foo))"
+ \----+----+----+----+---+----+----+----/
+
+ A list with one element followed by another list:
+
+ /----+----+----+---+----+----+----+---+----+----+----\
+ | OT | DT | DL | D | OT | DT | DL | D | CT | CT | ST | "(foo (bar))"
+ \----+----+----+---+----+----+----+---+----+----+----/
+
+ */
+
typedef unsigned short DATALEN;
struct gcry_sexp
@@ -42,11 +90,11 @@ struct gcry_sexp
#define ST_STOP 0
#define ST_DATA 1 /* datalen follows */
-#define ST_HINT 2 /* datalen follows */
+/*#define ST_HINT 2 datalen follows (currently not used) */
#define ST_OPEN 3
#define ST_CLOSE 4
-/* the atoi macros assume that the buffer has only valid digits */
+/* The atoi macros assume that the buffer has only valid digits. */
#define atoi_1(p) (*(p) - '0' )
#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
*(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
@@ -167,9 +215,10 @@ _gcry_sexp_dump (const gcry_sexp_t a)
}
}
-/****************
- * Pass list through except when it is an empty list - in that case
- * return NULL and release the passed list.
+
+/* Pass list through except when it is an empty list - in that case
+ * return NULL and release the passed list. This is used to make sure
+ * that no forbidden empty lists are created.
*/
static gcry_sexp_t
normalize ( gcry_sexp_t list )
@@ -501,7 +550,7 @@ _gcry_sexp_length (const gcry_sexp_t list)
/* Return the internal lengths offset of LIST. That is the size of
- the buffer from the first ST_OPEN, which is retruned at R_OFF, to
+ the buffer from the first ST_OPEN, which is returned at R_OFF, to
the corresponding ST_CLOSE inclusive. */
static size_t
get_internal_buffer (const gcry_sexp_t list, size_t *r_off)
@@ -542,8 +591,8 @@ get_internal_buffer (const gcry_sexp_t list, size_t *r_off)
-/* Extract the CAR of the given list. May return NULL for bad lists
- or memory failure. */
+/* Extract the n-th element of the given LIST. Returns NULL for
+ no-such-element, a corrupt list, or memory failure. */
gcry_sexp_t
_gcry_sexp_nth (const gcry_sexp_t list, int number)
{
@@ -587,15 +636,16 @@ _gcry_sexp_nth (const gcry_sexp_t list, int number)
if (*p == ST_DATA)
{
- memcpy (&n, p, sizeof n);
- p += sizeof n;
- newlist = xtrymalloc (sizeof *newlist + n + 1);
+ memcpy (&n, p+1, sizeof n);
+ newlist = xtrymalloc (sizeof *newlist + 1 + 1 + sizeof n + n + 1);
if (!newlist)
return NULL;
d = newlist->d;
- memcpy (d, p, n);
- d += n;
- *d++ = ST_STOP;
+ *d++ = ST_OPEN;
+ memcpy (d, p, 1 + sizeof n + n);
+ d += 1 + sizeof n + n;
+ *d++ = ST_CLOSE;
+ *d = ST_STOP;
}
else if (*p == ST_OPEN)
{
@@ -639,6 +689,7 @@ _gcry_sexp_nth (const gcry_sexp_t list, int number)
return normalize (newlist);
}
+
gcry_sexp_t
_gcry_sexp_car (const gcry_sexp_t list)
{
diff --git a/tests/tsexp.c b/tests/tsexp.c
index 704f9b1..5a02c26 100644
--- a/tests/tsexp.c
+++ b/tests/tsexp.c
@@ -1043,6 +1043,76 @@ check_extract_param (void)
}
+/* A test based on bug 1594. */
+static void
+bug_1594 (void)
+{
+static char thing[] =
+ "(signature"
+ " (public-key"
+ " (rsa"
+ " (n #00A53A6B3A50BE571F805BD98ECE1FCE4CE291C3D4D3E971740E1EE6D447F526"
+ " 6AC8973DDC82F0ADD234CC82E0A0A3F48B81ACC8B038DB8ACC3E78DC2ED2642F"
+ " 6BA353FCA60F47C2801DEB477B37FB8B2F5508AA1C6D922780DB142DEA19B812"
+ " C4E64F1138AD3BD61C58DB2D2591BE0BF36A1AC588AA45763BCDFF581050ABA8"
+ " CA47BD9723ADD6A308AE28471EDD2B16D03C941D4F2B7E019C43AF8972880633"
+ " 54E97B7E19F1677D84B69A26B184A77B719DD72C48E0EE36107046F786566A9D"
+ " 13BAD724D6D78F24700FC22FC000E1B2A8C1B08ED62008395B0764CD9B55E80D"
+ " A0A2B61C698DC27EA98E68BB576ACFC2B91B4D7283E7D960948D049D6E3C4CB1"
+ " F489B460A120A4BB6C04A843FD3A67454136DE61CF68A927871EFFA9141BD372"
+ " A748593C703E0301F039A9E674C50301BFC385BABE5B154250E7D57B82DB31F1"
+ " E1AC696F870DCD8FE8DEC75608B988FCA3B484F1FD7755BF452F99597269AF02"
+ " E8AF87D0F93DB427291659183D077254C835BFB6DDFD87CD0B5E0738682FCD34"
+ " 923F22551F73944E6CBE3ED6879B4414676B5DA0F30ED21DFA12BD2230C3C5D2"
+ " EA116A3EFEB4AEC21C58E63FAFA549A63190F01859445E9B80F427B80FD4C884"
+ " 2AD41FE760A3E9DEDFB56CEBE8EA783838B2B392CACDDC760CCE212E388AFBC1"
+ " 95DC6D0ED87E9091F82A82CE372738C8DE8ABD76ACD06AC8B80AA0597162DF59"
+ " 67#)"
+ " (e #010001#))))";
+ gcry_sexp_t sig, pubkey, n, n_val;
+
+ info ("checking fix for bug 1594\n");
+
+ if (gcry_sexp_new (&sig, thing, 0, 1))
+ die ("scanning fixed string failed\n");
+ pubkey = gcry_sexp_find_token (sig, "public-key", 0);
+ gcry_sexp_release (sig);
+ if (!pubkey)
+ {
+ fail ("'public-key' token not found");
+ return;
+ }
+ n = gcry_sexp_find_token (pubkey, "n", 0);
+ if (!n)
+ {
+ fail ("'n' token not found");
+ gcry_sexp_release (pubkey);
+ return;
+ }
+ n_val = gcry_sexp_nth (n, 1);
+ /* Bug 1594 would require the following test:
+ * if (n_val)
+ * fail ("extracting 1-th of 'n' list did not fail");
+ * However, we meanwhile modified the S-expression functions to
+ * behave like Scheme to allow the access of any element of a list.
+ */
+ if (!n_val)
+ fail ("extracting 1-th of 'n' list failed");
+ /*gcry_log_debugsxp ("1-th", n_val); => "(#00A5...#)" */
+ gcry_sexp_release (n_val);
+ n_val = gcry_sexp_nth (n, 2);
+ if (n_val)
+ fail ("extracting 2-th of 'n' list did not fail");
+ n_val = gcry_sexp_nth (n, 0);
+ if (!n_val)
+ fail ("extracting 0-th of 'n' list failed");
+ /*gcry_log_debugsxp ("0-th", n_val); => "(n)" */
+ if (gcry_sexp_nth (n_val, 1))
+ fail ("extracting 1-th of car of 'n' list did not fail");
+ gcry_sexp_release (n_val);
+}
+
+
int
main (int argc, char **argv)
{
@@ -1057,6 +1127,7 @@ main (int argc, char **argv)
back_and_forth ();
check_sscan ();
check_extract_param ();
+ bug_1594 ();
return error_count? 1:0;
}
-----------------------------------------------------------------------
Summary of changes:
doc/gcrypt.texi | 5 ++--
src/sexp.c | 83 ++++++++++++++++++++++++++++++++++++++++++++-----------
tests/tsexp.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 141 insertions(+), 18 deletions(-)
hooks/post-receive
--
The GNU crypto library
http://git.gnupg.org
More information about the Gnupg-commits
mailing list