summaryrefslogtreecommitdiff
path: root/src/sexp.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2013-10-22 14:26:53 +0200
committerWerner Koch <wk@gnupg.org>2013-12-07 15:37:40 +0100
commitd4555433b6e422fa69a85cae99961f513e55d82b (patch)
treecc4768b73d041ad77bc7de12bfbfdb7cfa0e6131 /src/sexp.c
parent405021cb6d4e470337302c65dec5bc91491a89c1 (diff)
downloadlibgcrypt-d4555433b6e422fa69a85cae99961f513e55d82b.tar.gz
sexp: Allow long names and white space in gcry_sexp_extract_param.
* src/sexp.c (_gcry_sexp_vextract_param): Skip white space. Support long parameter names. * tests/tsexp.c (check_extract_param): Add test cases for long parameter names and white space. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'src/sexp.c')
-rw-r--r--src/sexp.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/src/sexp.c b/src/sexp.c
index 16def5b4..7ff4c0a5 100644
--- a/src/sexp.c
+++ b/src/sexp.c
@@ -2113,10 +2113,9 @@ _gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
}
-/* Extract MPIs from an s-expression using a list of one letter
- * parameters. The names of these parameters are given by the string
- * LIST. Some special characters may be given to control the
- * conversion:
+/* Extract MPIs from an s-expression using a list of parameters. The
+ * names of these parameters are given by the string LIST. Some
+ * special characters may be given to control the conversion:
*
* + :: Switch to unsigned integer format (default).
* - :: Switch to standard signed format.
@@ -2124,6 +2123,9 @@ _gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
* & :: Switch to buffer descriptor mode - see below.
* ? :: The previous parameter is optional.
*
+ * In general parameter names are single letters. To use a string for
+ * a parameter name, enclose the name in single quotes.
+ *
* Unless in gcry_buffer_t mode for each parameter name a pointer to
* an MPI variable is expected and finally a NULL is expected.
* Example:
@@ -2158,7 +2160,7 @@ _gcry_sexp_vextract_param (gcry_sexp_t sexp, const char *path,
const char *list, va_list arg_ptr)
{
gpg_err_code_t rc;
- const char *s;
+ const char *s, *s2;
gcry_mpi_t *array[20];
char arrayisdesc[20];
int idx;
@@ -2173,10 +2175,23 @@ _gcry_sexp_vextract_param (gcry_sexp_t sexp, const char *path,
was found. */
for (s=list, idx=0; *s && idx < DIM (array); s++)
{
- if (*s == '&' || *s == '+' || *s == '-' || *s == '/' || *s == '?' )
+ if (*s == '&' || *s == '+' || *s == '-' || *s == '/' || *s == '?')
+ ;
+ else if (whitespacep (s))
;
else
{
+ if (*s == '\'')
+ {
+ s++;
+ s2 = strchr (s, '\'');
+ if (!s2 || s2 == s)
+ {
+ /* Closing quote not found or empty string. */
+ return GPG_ERR_SYNTAX;
+ }
+ s = s2;
+ }
array[idx] = va_arg (arg_ptr, gcry_mpi_t *);
if (!array[idx])
return GPG_ERR_MISSING_VALUE; /* NULL pointer given. */
@@ -2221,11 +2236,29 @@ _gcry_sexp_vextract_param (gcry_sexp_t sexp, const char *path,
{
if (*s == '&' || *s == '+' || *s == '-' || *s == '/')
mode = *s;
+ else if (whitespacep (s))
+ ;
else if (*s == '?')
; /* Only used via lookahead. */
else
{
- l1 = _gcry_sexp_find_token (sexp, s, 1);
+ if (*s == '\'')
+ {
+ /* Find closing quote, find token, set S to closing quote. */
+ s++;
+ s2 = strchr (s, '\'');
+ if (!s2 || s2 == s)
+ {
+ /* Closing quote not found or empty string. */
+ rc = GPG_ERR_SYNTAX;
+ goto cleanup;
+ }
+ l1 = _gcry_sexp_find_token (sexp, s, s2 - s);
+ s = s2;
+ }
+ else
+ l1 = _gcry_sexp_find_token (sexp, s, 1);
+
if (!l1 && s[1] == '?')
{
/* Optional element not found. */