1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-04-17 15:44:34 +02:00

gpg: Fix buffering problem in --list-config.

* g10/gpg.c (list_config): Replace print_sanitized_string2 by
es_write_sanitized.

* common/stringhelp.c (print_sanitized_buffer2): Remove.
(print_sanitized_buffer, print_sanitized_utf8_buffer): Remove.
(print_sanitized_utf8_buffer, print_sanitized_utf8_string): Remove.
(print_sanitized_string): Remove.

* sm/certdump.c (print_dn_part, print_dn_parts): Remove arg FP.
(pretty_print_sexp, gpgsm_print_name2, gpgsm_print_name): Remove.
--

Mixing stdio and estream is never a good idea.  This fix also allows
us to remove a lot of garbage.

Reported-by: Jason A. Donenfeld <Jason@zx2c4.com>
GnuPG-bug-id: 1822
Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2015-01-28 20:12:21 +01:00
parent 0c2bfd9d5a
commit d8eea25b8b
4 changed files with 14 additions and 259 deletions

View File

@ -671,129 +671,6 @@ hextobyte (const char *s)
} }
/* Print a BUFFER to stream FP while replacing all control characters
and the characters DELIM and DELIM2 with standard C escape
sequences. Returns the number of characters printed. */
size_t
print_sanitized_buffer2 (FILE *fp, const void *buffer, size_t length,
int delim, int delim2)
{
const unsigned char *p = buffer;
size_t count = 0;
for (; length; length--, p++, count++)
{
if (*p < 0x20
|| *p == 0x7f
|| *p == delim
|| *p == delim2
|| ((delim || delim2) && *p=='\\'))
{
putc ('\\', fp);
count++;
if (*p == '\n')
{
putc ('n', fp);
count++;
}
else if (*p == '\r')
{
putc ('r', fp);
count++;
}
else if (*p == '\f')
{
putc ('f', fp);
count++;
}
else if (*p == '\v')
{
putc ('v', fp);
count++;
}
else if (*p == '\b')
{
putc ('b', fp);
count++;
}
else if (!*p)
{
putc('0', fp);
count++;
}
else
{
fprintf (fp, "x%02x", *p);
count += 3;
}
}
else
{
putc (*p, fp);
count++;
}
}
return count;
}
/* Same as print_sanitized_buffer2 but with just one delimiter. */
size_t
print_sanitized_buffer (FILE *fp, const void *buffer, size_t length,
int delim)
{
return print_sanitized_buffer2 (fp, buffer, length, delim, 0);
}
size_t
print_sanitized_utf8_buffer (FILE *fp, const void *buffer,
size_t length, int delim)
{
const char *p = buffer;
size_t i;
/* We can handle plain ascii simpler, so check for it first. */
for (i=0; i < length; i++ )
{
if ( (p[i] & 0x80) )
break;
}
if (i < length)
{
char *buf = utf8_to_native (p, length, delim);
/*(utf8 conversion already does the control character quoting)*/
i = strlen (buf);
fputs (buf, fp);
jnlib_free (buf);
return i;
}
else
return print_sanitized_buffer (fp, p, length, delim);
}
size_t
print_sanitized_string2 (FILE *fp, const char *string, int delim, int delim2)
{
return string? print_sanitized_buffer2 (fp, string, strlen (string),
delim, delim2):0;
}
size_t
print_sanitized_string (FILE *fp, const char *string, int delim)
{
return string? print_sanitized_buffer (fp, string, strlen (string), delim):0;
}
size_t
print_sanitized_utf8_string (FILE *fp, const char *string, int delim)
{
return string? print_sanitized_utf8_buffer (fp,
string, strlen (string),
delim) : 0;
}
/* Create a string from the buffer P_ARG of length N which is suitable /* Create a string from the buffer P_ARG of length N which is suitable
for printing. Caller must release the created string using xfree. for printing. Caller must release the created string using xfree.
This function terminates the process on memory shortage. */ This function terminates the process on memory shortage. */

View File

@ -60,16 +60,6 @@ int compare_filenames( const char *a, const char *b );
int hextobyte (const char *s); int hextobyte (const char *s);
size_t print_sanitized_buffer (FILE *fp, const void *buffer, size_t length,
int delim);
size_t print_sanitized_buffer2 (FILE *fp, const void *buffer, size_t length,
int delim, int delim2);
size_t print_sanitized_utf8_buffer (FILE *fp, const void *buffer,
size_t length, int delim);
size_t print_sanitized_string (FILE *fp, const char *string, int delim);
size_t print_sanitized_string2 (FILE *fp, const char *string,
int delim, int delim2);
size_t print_sanitized_utf8_string (FILE *fp, const char *string, int delim);
char *sanitize_buffer (const void *p, size_t n, int delim); char *sanitize_buffer (const void *p, size_t n, int delim);

View File

@ -1599,7 +1599,8 @@ list_config(char *items)
for(sl=iter->values;sl;sl=sl->next) for(sl=iter->values;sl;sl=sl->next)
{ {
print_sanitized_string2 (stdout, sl->d, ':',';'); es_write_sanitized (es_stdout, sl->d, strlen (sl->d),
":;", NULL);
if(sl->next) if(sl->next)
es_printf(";"); es_printf(";");
} }

View File

@ -479,9 +479,9 @@ parse_dn (const unsigned char *string)
} }
/* Print a DN part to STREAM or if STREAM is NULL to FP. */ /* Print a DN part to STREAM. */
static void static void
print_dn_part (FILE *fp, estream_t stream, print_dn_part (estream_t stream,
struct dn_array_s *dn, const char *key, int translate) struct dn_array_s *dn, const char *key, int translate)
{ {
struct dn_array_s *first_dn = dn; struct dn_array_s *first_dn = dn;
@ -500,24 +500,13 @@ print_dn_part (FILE *fp, estream_t stream,
next: next:
if (!dn->done && dn->value && *dn->value) if (!dn->done && dn->value && *dn->value)
{ {
if (stream) es_fprintf (stream, "/%s=", dn->key);
{ if (translate)
es_fprintf (stream, "/%s=", dn->key); print_utf8_buffer3 (stream, dn->value, strlen (dn->value),
if (translate) "/");
print_utf8_buffer3 (stream, dn->value, strlen (dn->value),
"/");
else
es_write_sanitized (stream, dn->value, strlen (dn->value),
"/", NULL);
}
else else
{ es_write_sanitized (stream, dn->value, strlen (dn->value),
fprintf (fp, "/%s=", dn->key); "/", NULL);
if (translate)
print_sanitized_utf8_string (fp, dn->value, '/');
else
print_sanitized_string (fp, dn->value, '/');
}
} }
dn->done = 1; dn->done = 1;
if (dn > first_dn && dn[-1].multivalued) if (dn > first_dn && dn[-1].multivalued)
@ -532,7 +521,7 @@ print_dn_part (FILE *fp, estream_t stream,
/* Print all parts of a DN in a "standard" sequence. We first print /* Print all parts of a DN in a "standard" sequence. We first print
all the known parts, followed by the uncommon ones */ all the known parts, followed by the uncommon ones */
static void static void
print_dn_parts (FILE *fp, estream_t stream, print_dn_parts (estream_t stream,
struct dn_array_s *dn, int translate) struct dn_array_s *dn, int translate)
{ {
const char *stdpart[] = { const char *stdpart[] = {
@ -541,59 +530,14 @@ print_dn_parts (FILE *fp, estream_t stream,
int i; int i;
for (i=0; stdpart[i]; i++) for (i=0; stdpart[i]; i++)
print_dn_part (fp, stream, dn, stdpart[i], translate); print_dn_part (stream, dn, stdpart[i], translate);
/* Now print the rest without any specific ordering */ /* Now print the rest without any specific ordering */
for (; dn->key; dn++) for (; dn->key; dn++)
print_dn_part (fp, stream, dn, dn->key, translate); print_dn_part (stream, dn, dn->key, translate);
} }
/* Print the S-Expression in BUF, which has a valid length of BUFLEN,
as a human readable string in one line to FP. */
static void
pretty_print_sexp (FILE *fp, const unsigned char *buf, size_t buflen)
{
size_t len;
gcry_sexp_t sexp;
char *result, *p;
if ( gcry_sexp_sscan (&sexp, NULL, (const char*)buf, buflen) )
{
fputs (_("[Error - invalid encoding]"), fp);
return;
}
len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
assert (len);
result = xtrymalloc (len);
if (!result)
{
fputs (_("[Error - out of core]"), fp);
gcry_sexp_release (sexp);
return;
}
len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, result, len);
assert (len);
for (p = result; len; len--, p++)
{
if (*p == '\n')
{
if (len > 1) /* Avoid printing the trailing LF. */
fputs ("\\n", fp);
}
else if (*p == '\r')
fputs ("\\r", fp);
else if (*p == '\v')
fputs ("\\v", fp);
else if (*p == '\t')
fputs ("\\t", fp);
else
putc (*p, fp);
}
xfree (result);
gcry_sexp_release (sexp);
}
/* Print the S-Expression in BUF to extended STREAM, which has a valid /* Print the S-Expression in BUF to extended STREAM, which has a valid
length of BUFLEN, as a human readable string in one line to FP. */ length of BUFLEN, as a human readable string in one line to FP. */
static void static void
@ -640,63 +584,6 @@ pretty_es_print_sexp (estream_t fp, const unsigned char *buf, size_t buflen)
} }
void
gpgsm_print_name2 (FILE *fp, const char *name, int translate)
{
const unsigned char *s = (const unsigned char *)name;
int i;
if (!s)
{
fputs (_("[Error - No name]"), fp);
}
else if (*s == '<')
{
const char *s2 = strchr ( (char*)s+1, '>');
if (s2)
{
if (translate)
print_sanitized_utf8_buffer (fp, s + 1, s2 - (char*)s - 1, 0);
else
print_sanitized_buffer (fp, s + 1, s2 - (char*)s - 1, 0);
}
}
else if (*s == '(')
{
pretty_print_sexp (fp, s, gcry_sexp_canon_len (s, 0, NULL, NULL));
}
else if (!((*s >= '0' && *s < '9')
|| (*s >= 'A' && *s <= 'Z')
|| (*s >= 'a' && *s <= 'z')))
fputs (_("[Error - invalid encoding]"), fp);
else
{
struct dn_array_s *dn = parse_dn (s);
if (!dn)
fputs (_("[Error - invalid DN]"), fp);
else
{
print_dn_parts (fp, NULL, dn, translate);
for (i=0; dn[i].key; i++)
{
xfree (dn[i].key);
xfree (dn[i].value);
}
xfree (dn);
}
}
}
void
gpgsm_print_name (FILE *fp, const char *name)
{
gpgsm_print_name2 (fp, name, 1);
}
/* This is a variant of gpgsm_print_name sending it output to an estream. */ /* This is a variant of gpgsm_print_name sending it output to an estream. */
void void
gpgsm_es_print_name2 (estream_t fp, const char *name, int translate) gpgsm_es_print_name2 (estream_t fp, const char *name, int translate)
@ -736,7 +623,7 @@ gpgsm_es_print_name2 (estream_t fp, const char *name, int translate)
es_fputs (_("[Error - invalid DN]"), fp); es_fputs (_("[Error - invalid DN]"), fp);
else else
{ {
print_dn_parts (NULL, fp, dn, translate); print_dn_parts (fp, dn, translate);
for (i=0; dn[i].key; i++) for (i=0; dn[i].key; i++)
{ {
xfree (dn[i].key); xfree (dn[i].key);