mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-18 14:17:03 +01:00
wkd: Fix client issue with leading or trailing spaces in user-ids.
* common/recsel.c (recsel_parse_expr): Add flag -t. * common/stringhelp.c: Remove assert.h. (strtokenize): Factor code out to do_strtokenize. (strtokenize_nt): New. (do_strtokenize): Add arg trim to support the strtokenize_nt. * common/t-stringhelp.c (test_strtokenize_nt): New test cases. * tools/wks-util.c (wks_list_key): Use strtokenize_nt and the recsel flag -t. -- This fixes a bug with user ids with leading spaces because: wks-client lists all mail addresses from the key and matches them to the requested mail address. If there are several user-ids all with the same mail address wks-client picks one of them and then extracts exactly that user id. However, here it does not match by the mail address but by the full user-id so that we can be sure that there will be only one user-id in the final key. The filter built expression unfortunately strips leading blanks but requires a verbatim match. Thus it won't find the user id again and errors out. The new -t flag and a non-trimming strtokenize solves the problem. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
1565baa93a
commit
b4345f7521
@ -172,6 +172,8 @@ find_next_lc (char *string)
|
|||||||
*
|
*
|
||||||
* -- VALUE spans to the end of the expression.
|
* -- VALUE spans to the end of the expression.
|
||||||
* -c The string match in this part is done case-sensitive.
|
* -c The string match in this part is done case-sensitive.
|
||||||
|
* -t Do not trim leading and trailing spaces from VALUE.
|
||||||
|
* Note that a space after <op> is here required.
|
||||||
*
|
*
|
||||||
* For example four calls to recsel_parse_expr() with these values for
|
* For example four calls to recsel_parse_expr() with these values for
|
||||||
* EXPR
|
* EXPR
|
||||||
@ -203,6 +205,7 @@ recsel_parse_expr (recsel_expr_t *selector, const char *expression)
|
|||||||
char *s0, *s;
|
char *s0, *s;
|
||||||
int toend = 0;
|
int toend = 0;
|
||||||
int xcase = 0;
|
int xcase = 0;
|
||||||
|
int notrim = 0;
|
||||||
int disjun = 0;
|
int disjun = 0;
|
||||||
char *next_lc = NULL;
|
char *next_lc = NULL;
|
||||||
|
|
||||||
@ -232,6 +235,7 @@ recsel_parse_expr (recsel_expr_t *selector, const char *expression)
|
|||||||
{
|
{
|
||||||
case '-': toend = 1; break;
|
case '-': toend = 1; break;
|
||||||
case 'c': xcase = 1; break;
|
case 'c': xcase = 1; break;
|
||||||
|
case 't': notrim = 1; break;
|
||||||
default:
|
default:
|
||||||
log_error ("invalid flag '-%c' in expression\n", *expr);
|
log_error ("invalid flag '-%c' in expression\n", *expr);
|
||||||
recsel_release (se_head);
|
recsel_release (se_head);
|
||||||
@ -397,6 +401,9 @@ recsel_parse_expr (recsel_expr_t *selector, const char *expression)
|
|||||||
return my_error (GPG_ERR_INV_OP);
|
return my_error (GPG_ERR_INV_OP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*s == ' ' || *s == '\t')
|
||||||
|
s++;
|
||||||
|
if (!notrim)
|
||||||
while (*s == ' ' || *s == '\t')
|
while (*s == ' ' || *s == '\t')
|
||||||
s++;
|
s++;
|
||||||
|
|
||||||
@ -431,6 +438,7 @@ recsel_parse_expr (recsel_expr_t *selector, const char *expression)
|
|||||||
return my_error (GPG_ERR_NO_NAME);
|
return my_error (GPG_ERR_NO_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!notrim)
|
||||||
trim_spaces (se->name + (s - expr));
|
trim_spaces (se->name + (s - expr));
|
||||||
se->value = se->name + (s - expr);
|
se->value = se->name + (s - expr);
|
||||||
if (!se->value[0] && !(se->op == SELECT_NONEMPTY || se->op == SELECT_ISTRUE))
|
if (!se->value[0] && !(se->op == SELECT_NONEMPTY || se->op == SELECT_ISTRUE))
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007,
|
* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007,
|
||||||
* 2008, 2009, 2010 Free Software Foundation, Inc.
|
* 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||||
* Copyright (C) 2014 Werner Koch
|
* Copyright (C) 2014 Werner Koch
|
||||||
* Copyright (C) 2015 g10 Code GmbH
|
* Copyright (C) 2015, 2021 g10 Code GmbH
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -29,6 +29,7 @@
|
|||||||
* You should have received a copies of the GNU General Public License
|
* You should have received a copies of the GNU General Public License
|
||||||
* and the GNU Lesser General Public License along with this program;
|
* and the GNU Lesser General Public License along with this program;
|
||||||
* if not, see <https://www.gnu.org/licenses/>.
|
* if not, see <https://www.gnu.org/licenses/>.
|
||||||
|
* SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
@ -48,7 +49,6 @@
|
|||||||
# endif
|
# endif
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <assert.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -216,7 +216,7 @@ trim_spaces( char *str )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Same as trim_spaces but only condider, space, tab, cr and lf as space. */
|
/* Same as trim_spaces but only consider, space, tab, cr and lf as space. */
|
||||||
char *
|
char *
|
||||||
ascii_trim_spaces (char *str)
|
ascii_trim_spaces (char *str)
|
||||||
{
|
{
|
||||||
@ -1293,8 +1293,8 @@ strsplit (char *string, char delim, char replacement, int *count)
|
|||||||
* Returns: A malloced and NULL delimited array with the tokens. On
|
* Returns: A malloced and NULL delimited array with the tokens. On
|
||||||
* memory error NULL is returned and ERRNO is set.
|
* memory error NULL is returned and ERRNO is set.
|
||||||
*/
|
*/
|
||||||
char **
|
static char **
|
||||||
strtokenize (const char *string, const char *delim)
|
do_strtokenize (const char *string, const char *delim, int trim)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
size_t fields;
|
size_t fields;
|
||||||
@ -1333,24 +1333,51 @@ strtokenize (const char *string, const char *delim)
|
|||||||
for (n = 0, p = buffer; (pend = strpbrk (p, delim)); p = pend + 1)
|
for (n = 0, p = buffer; (pend = strpbrk (p, delim)); p = pend + 1)
|
||||||
{
|
{
|
||||||
*pend = 0;
|
*pend = 0;
|
||||||
|
if (trim)
|
||||||
|
{
|
||||||
while (spacep (p))
|
while (spacep (p))
|
||||||
p++;
|
p++;
|
||||||
for (px = pend - 1; px >= p && spacep (px); px--)
|
for (px = pend - 1; px >= p && spacep (px); px--)
|
||||||
*px = 0;
|
*px = 0;
|
||||||
|
}
|
||||||
result[n++] = p;
|
result[n++] = p;
|
||||||
}
|
}
|
||||||
|
if (trim)
|
||||||
|
{
|
||||||
while (spacep (p))
|
while (spacep (p))
|
||||||
p++;
|
p++;
|
||||||
for (px = p + strlen (p) - 1; px >= p && spacep (px); px--)
|
for (px = p + strlen (p) - 1; px >= p && spacep (px); px--)
|
||||||
*px = 0;
|
*px = 0;
|
||||||
|
}
|
||||||
result[n++] = p;
|
result[n++] = p;
|
||||||
result[n] = NULL;
|
result[n] = NULL;
|
||||||
|
|
||||||
assert ((char*)(result + n + 1) == buffer);
|
log_assert ((char*)(result + n + 1) == buffer);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tokenize STRING using the set of delimiters in DELIM. Leading
|
||||||
|
* spaces and tabs are removed from all tokens. The caller must xfree
|
||||||
|
* the result.
|
||||||
|
*
|
||||||
|
* Returns: A malloced and NULL delimited array with the tokens. On
|
||||||
|
* memory error NULL is returned and ERRNO is set.
|
||||||
|
*/
|
||||||
|
char **
|
||||||
|
strtokenize (const char *string, const char *delim)
|
||||||
|
{
|
||||||
|
return do_strtokenize (string, delim, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Same as strtokenize but does not trim leading and trailing spaces
|
||||||
|
* from the fields. */
|
||||||
|
char **
|
||||||
|
strtokenize_nt (const char *string, const char *delim)
|
||||||
|
{
|
||||||
|
return do_strtokenize (string, delim, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Split a string into space delimited fields and remove leading and
|
/* Split a string into space delimited fields and remove leading and
|
||||||
* trailing spaces from each field. A pointer to each field is stored
|
* trailing spaces from each field. A pointer to each field is stored
|
||||||
|
@ -148,6 +148,9 @@ char **strsplit (char *string, char delim, char replacement, int *count);
|
|||||||
|
|
||||||
/* Tokenize STRING using the set of delimiters in DELIM. */
|
/* Tokenize STRING using the set of delimiters in DELIM. */
|
||||||
char **strtokenize (const char *string, const char *delim);
|
char **strtokenize (const char *string, const char *delim);
|
||||||
|
/* Tokenize STRING using the set of delimiters in DELIM but do not
|
||||||
|
* trim the tokens. */
|
||||||
|
char **strtokenize_nt (const char *string, const char *delim);
|
||||||
|
|
||||||
/* Split STRING into space delimited fields and store them in the
|
/* Split STRING into space delimited fields and store them in the
|
||||||
* provided ARRAY. */
|
* provided ARRAY. */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* t-stringhelp.c - Regression tests for stringhelp.c
|
/* t-stringhelp.c - Regression tests for stringhelp.c
|
||||||
* Copyright (C) 2007 Free Software Foundation, Inc.
|
* Copyright (C) 2007 Free Software Foundation, Inc.
|
||||||
* 2015 g10 Code GmbH
|
* 2015, 2021 g10 Code GmbH
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -27,6 +27,7 @@
|
|||||||
* You should have received a copies of the GNU General Public License
|
* You should have received a copies of the GNU General Public License
|
||||||
* and the GNU Lesser General Public License along with this program;
|
* and the GNU Lesser General Public License along with this program;
|
||||||
* if not, see <https://www.gnu.org/licenses/>.
|
* if not, see <https://www.gnu.org/licenses/>.
|
||||||
|
* SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
@ -34,7 +35,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <assert.h>
|
|
||||||
#ifdef HAVE_PWD_H
|
#ifdef HAVE_PWD_H
|
||||||
# include <pwd.h>
|
# include <pwd.h>
|
||||||
#endif
|
#endif
|
||||||
@ -686,6 +686,144 @@ test_strtokenize (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_strtokenize_nt (void)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
const char *s;
|
||||||
|
const char *delim;
|
||||||
|
const char *fields_expected[10];
|
||||||
|
} tv[] = {
|
||||||
|
{
|
||||||
|
"", ":",
|
||||||
|
{ "", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a", ":",
|
||||||
|
{ "a", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
":", ":",
|
||||||
|
{ "", "", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"::", ":",
|
||||||
|
{ "", "", "", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:b:c", ":",
|
||||||
|
{ "a", "b", "c", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:b:", ":",
|
||||||
|
{ "a", "b", "", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:b", ":",
|
||||||
|
{ "a", "b", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"aa:b:cd", ":",
|
||||||
|
{ "aa", "b", "cd", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"aa::b:cd", ":",
|
||||||
|
{ "aa", "", "b", "cd", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"::b:cd", ":",
|
||||||
|
{ "", "", "b", "cd", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"aa: : b:cd ", ":",
|
||||||
|
{ "aa", " ", " b", "cd ", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
" aa: : b: cd ", ":",
|
||||||
|
{ " aa", " ", " b", " cd ", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
" ", ":",
|
||||||
|
{ " ", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
" :", ":",
|
||||||
|
{ " ", "", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
" : ", ":",
|
||||||
|
{ " ", " ", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
": ", ":",
|
||||||
|
{ "", " ", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
": x ", ":",
|
||||||
|
{ "", " x ", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"a:bc:cde:fghi:jklmn::foo:", ":",
|
||||||
|
{ "a", "bc", "cde", "fghi", "jklmn", "", "foo", "", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
",a,bc,,def,", ",",
|
||||||
|
{ "", "a", "bc", "", "def", "", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
" a ", " ",
|
||||||
|
{ "", "a", "", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
" ", " ",
|
||||||
|
{ "", "", NULL }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"", " ",
|
||||||
|
{ "", NULL }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int tidx;
|
||||||
|
|
||||||
|
for (tidx = 0; tidx < DIM(tv); tidx++)
|
||||||
|
{
|
||||||
|
char **fields;
|
||||||
|
int field_count;
|
||||||
|
int field_count_expected;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (field_count_expected = 0;
|
||||||
|
tv[tidx].fields_expected[field_count_expected];
|
||||||
|
field_count_expected ++)
|
||||||
|
;
|
||||||
|
|
||||||
|
fields = strtokenize_nt (tv[tidx].s, tv[tidx].delim);
|
||||||
|
if (!fields)
|
||||||
|
fail (tidx * 1000);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (field_count = 0; fields[field_count]; field_count++)
|
||||||
|
;
|
||||||
|
if (field_count != field_count_expected)
|
||||||
|
fail (tidx * 1000);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < field_count_expected; i++)
|
||||||
|
if (strcmp (tv[tidx].fields_expected[i], fields[i]))
|
||||||
|
{
|
||||||
|
printf ("For field %d, expected '%s', but got '%s'\n",
|
||||||
|
i, tv[tidx].fields_expected[i], fields[i]);
|
||||||
|
fail (tidx * 1000 + i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xfree (fields);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_split_fields (void)
|
test_split_fields (void)
|
||||||
{
|
{
|
||||||
@ -724,7 +862,7 @@ test_split_fields (void)
|
|||||||
for (tidx = 0; tidx < DIM(tv); tidx++)
|
for (tidx = 0; tidx < DIM(tv); tidx++)
|
||||||
{
|
{
|
||||||
nfields = tv[tidx].nfields;
|
nfields = tv[tidx].nfields;
|
||||||
assert (nfields <= DIM (fields));
|
log_assert (nfields <= DIM (fields));
|
||||||
|
|
||||||
/* Count the fields. */
|
/* Count the fields. */
|
||||||
for (field_count_expected = 0;
|
for (field_count_expected = 0;
|
||||||
@ -799,7 +937,7 @@ test_split_fields_colon (void)
|
|||||||
for (tidx = 0; tidx < DIM(tv); tidx++)
|
for (tidx = 0; tidx < DIM(tv); tidx++)
|
||||||
{
|
{
|
||||||
nfields = tv[tidx].nfields;
|
nfields = tv[tidx].nfields;
|
||||||
assert (nfields <= DIM (fields));
|
log_assert (nfields <= DIM (fields));
|
||||||
|
|
||||||
/* Count the fields. */
|
/* Count the fields. */
|
||||||
for (field_count_expected = 0;
|
for (field_count_expected = 0;
|
||||||
@ -1070,6 +1208,7 @@ main (int argc, char **argv)
|
|||||||
test_make_absfilename_try ();
|
test_make_absfilename_try ();
|
||||||
test_strsplit ();
|
test_strsplit ();
|
||||||
test_strtokenize ();
|
test_strtokenize ();
|
||||||
|
test_strtokenize_nt ();
|
||||||
test_split_fields ();
|
test_split_fields ();
|
||||||
test_split_fields_colon ();
|
test_split_fields_colon ();
|
||||||
test_compare_version_strings ();
|
test_compare_version_strings ();
|
||||||
|
@ -4072,6 +4072,9 @@ are:
|
|||||||
@var{VALUE} spans to the end of the expression.
|
@var{VALUE} spans to the end of the expression.
|
||||||
@item -c
|
@item -c
|
||||||
The string match in this part is done case-sensitive.
|
The string match in this part is done case-sensitive.
|
||||||
|
@item -t
|
||||||
|
Leading and trailing spaces are not removed from @var{VALUE}.
|
||||||
|
The optional single space after @var{op} is here required.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
The filter options concatenate several specifications for a filter of
|
The filter options concatenate several specifications for a filter of
|
||||||
|
@ -348,7 +348,7 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes)
|
|||||||
/* log_debug ("line '%s'\n", line); */
|
/* log_debug ("line '%s'\n", line); */
|
||||||
|
|
||||||
xfree (fields);
|
xfree (fields);
|
||||||
fields = strtokenize (line, ":");
|
fields = strtokenize_nt (line, ":");
|
||||||
if (!fields)
|
if (!fields)
|
||||||
{
|
{
|
||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
@ -467,7 +467,7 @@ wks_filter_uid (estream_t *r_newkey, estream_t key, const char *uid,
|
|||||||
es_fputs ("Content-Type: application/pgp-keys\n"
|
es_fputs ("Content-Type: application/pgp-keys\n"
|
||||||
"\n", newkey);
|
"\n", newkey);
|
||||||
|
|
||||||
filterexp = es_bsprintf ("keep-uid=uid= %s", uid);
|
filterexp = es_bsprintf ("keep-uid=-t uid= %s", uid);
|
||||||
if (!filterexp)
|
if (!filterexp)
|
||||||
{
|
{
|
||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user