1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

Use estream_asprintf instead of the GNU asprintf.

This commit is contained in:
Werner Koch 2007-05-15 16:10:48 +00:00
parent edb3dc99e9
commit 5f3bca9682
25 changed files with 2413 additions and 351 deletions

View file

@ -1,3 +1,20 @@
2007-05-15 Werner Koch <wk@g10code.com>
* util.h: Do not include gnulib's vasprintf. Redefine asprintf
and vasprintf.
* xasprintf.c (xasprintf, xtryasprintf): Use estream_vasprintf.
* estream-printf.h, estream-printf.c: New. Taken from current
libestream SVN.
* Makefile.am (common_sources): Add them.
2007-05-14 Werner Koch <wk@g10code.com>
* sexp-parse.h (smklen): New.
* sexputil.c: Include sexp-parse.h.
(make_simple_sexp_from_hexstr): Replace sprintf by smklen.
2007-05-07 Werner Koch <wk@g10code.com>
* signal.c (got_fatal_signal): Protect SIG from being clobbered by

View file

@ -54,7 +54,7 @@ common_sources = \
w32reg.c \
signal.c \
dynload.h \
estream.c estream.h \
estream.c estream.h estream-printf.c estream-printf.h \
srv.c srv.h \
dns-cert.c dns-cert.h \
pka.c pka.h \

2139
common/estream-printf.c Normal file

File diff suppressed because it is too large Load diff

60
common/estream-printf.h Normal file
View file

@ -0,0 +1,60 @@
/* estream-printf.h - Versatile C-99 compliant printf formatting.
* Copyright (C) 2007 g10 Code GmbH
*
* This file is part of Libestream.
*
* Libestream is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* Libestream is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Libestream; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* $Id: estream-printf.h 54 2007-05-15 14:12:06Z wk $
*/
#ifndef ESTREAM_PRINTF_H
#define ESTREAM_PRINTF_H
#include <stdarg.h>
#include <stdio.h>
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
# define ESTREAM_GCC_A_PRINTF( f, a ) __attribute__ ((format (printf,f,a)))
#else
# define ESTREAM_GCC_A_PRINTF( f, a )
#endif
typedef int (*estream_printf_out_t)
(void *outfncarg, const char *buf, size_t buflen);
int estream_format (estream_printf_out_t outfnc, void *outfncarg,
const char *format, va_list vaargs)
ESTREAM_GCC_A_PRINTF(3,0);
int estream_printf (const char *format, ...)
ESTREAM_GCC_A_PRINTF(1,2);
int estream_fprintf (FILE *fp, const char *format, ... )
ESTREAM_GCC_A_PRINTF(2,3);
int estream_vfprintf (FILE *fp, const char *format, va_list arg_ptr)
ESTREAM_GCC_A_PRINTF(2,0);
int estream_snprintf (char *buf, size_t bufsize, const char *format, ...)
ESTREAM_GCC_A_PRINTF(3,4);
int estream_vsnprintf (char *buf,size_t bufsize,
const char *format, va_list arg_ptr)
ESTREAM_GCC_A_PRINTF(3,0);
int estream_asprintf (char **bufp, const char *format, ...)
ESTREAM_GCC_A_PRINTF(2,3);
int estream_vasprintf (char **bufp, const char *format, va_list arg_ptr)
ESTREAM_GCC_A_PRINTF(2,0);
#endif /*ESTREAM_PRINTF_H*/

View file

@ -1,5 +1,5 @@
/* estream.c - Extended Stream I/O Library
* Copyright (C) 2004, 2006, 2007 g10 Code GmbH
* Copyright (C) 2004, 2005, 2006, 2007 g10 Code GmbH
*
* This file is part of Libestream.
*
@ -11,7 +11,7 @@
* Libestream is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Libestream; if not, write to the Free Software
@ -49,6 +49,7 @@
# include <pth.h>
#endif
/* This is for the special hack to use estream.c in GnuPG. */
#ifdef GNUPG_MAJOR_VERSION
#include "../common/util.h"
#endif
@ -62,7 +63,7 @@ void *memrchr (const void *block, int c, size_t size);
#endif
#include <estream.h>
#include <estream-printf.h>
@ -747,8 +748,8 @@ static int
es_convert_mode (const char *mode, unsigned int *flags)
{
/* FIXME: We need to allow all combinations for mode flags and for
binary we need to do a
/* FIXME: We need to allow all mode flags permutations and for
binary mode we need to do a
#ifdef HAVE_DOSISH_SYSTEM
setmode (fd, O_BINARY);
@ -1671,29 +1672,19 @@ doreadline (estream_t ES__RESTRICT stream, size_t max_length,
}
/* Helper for esprint. */
#if defined(HAVE_FOPENCOOKIE) || defined(HAVE_FUNOPEN)
static my_funopen_hook_ret_t
print_fun_writer (void *cookie_arg, const char *buffer, size_t size)
/* Output fucntion used for estream_format. */
static int
print_writer (void *outfncarg, const char *buf, size_t buflen)
{
estream_t stream = cookie_arg;
estream_t stream = outfncarg;
size_t nwritten;
/* We don't return an error but let es_print check whether an error
has occured. Internally we skip everything after an error. */
if (!stream->intern->print_err)
{
if (es_writen (stream, buffer, size, &nwritten))
{
stream->intern->print_err = 1;
stream->intern->print_errno = errno;
}
else
stream->intern->print_ntotal += nwritten;
}
return 0;
int rc;
nwritten = 0;
rc = es_writen (stream, buf, buflen, &nwritten);
stream->intern->print_ntotal += nwritten;
return rc;
}
#endif /* HAVE_FOPENCOOKIE || HAVE_FUNOPEN */
/* The core of our printf function. This is called in locked state. */
@ -1701,98 +1692,13 @@ static int
es_print (estream_t ES__RESTRICT stream,
const char *ES__RESTRICT format, va_list ap)
{
#if defined(HAVE_FOPENCOOKIE) || defined(HAVE_FUNOPEN)
int rc;
if (!stream->intern->print_fp)
{
#ifdef HAVE_FOPENCOOKIE
{
cookie_io_functions_t io = { NULL };
io.write = print_fun_writer;
stream->intern->print_fp = fopencookie (stream, "w", io);
}
#else /*!HAVE_FOPENCOOKIE*/
stream->intern->print_fp = funopen (stream, NULL,
print_fun_writer, NULL, NULL);
#endif /*!HAVE_FOPENCOOKIE*/
if (!stream->intern->print_fp)
return -1;
}
stream->intern->print_err = 0;
stream->intern->print_errno = 0;
stream->intern->print_ntotal = 0;
if ( vfprintf (stream->intern->print_fp, format, ap) < 0
|| fflush (stream->intern->print_fp) )
{
stream->intern->print_errno = errno;
stream->intern->print_err = 1;
fclose (stream->intern->print_fp);
stream->intern->print_fp = NULL;
}
if (stream->intern->print_err)
{
errno = stream->intern->print_errno;
return -1;
}
rc = estream_format (print_writer, stream, format, ap);
if (rc)
return -1;
return (int)stream->intern->print_ntotal;
#else /* No funopen or fopencookie. */
char data[BUFFER_BLOCK_SIZE];
size_t bytes_read;
size_t bytes_written;
FILE *tmp_stream;
int err;
bytes_written = 0;
tmp_stream = NULL;
err = 0;
tmp_stream = tmpfile ();
if (! tmp_stream)
{
err = errno;
goto out;
}
err = vfprintf (tmp_stream, format, ap);
if (err < 0)
goto out;
err = fseek (tmp_stream, 0, SEEK_SET);
if (err)
goto out;
while (1)
{
bytes_read = fread (data, 1, sizeof (data), tmp_stream);
if (ferror (tmp_stream))
{
err = -1;
break;
}
err = es_writen (stream, data, bytes_read, NULL);
if (err)
break;
else
bytes_written += bytes_read;
if (feof (tmp_stream))
break;
}
if (err)
goto out;
out:
if (tmp_stream)
fclose (tmp_stream);
return err ? -1 : bytes_written;
#endif /* no funopen or fopencookie */
}
@ -2718,7 +2624,7 @@ es_vfprintf (estream_t ES__RESTRICT stream, const char *ES__RESTRICT format,
static int
es_fprintf_unlocked (estream_t ES__RESTRICT stream,
const char *ES__RESTRICT format, ...)
const char *ES__RESTRICT format, ...)
{
int ret;
@ -2868,8 +2774,6 @@ es_opaque_get (estream_t stream)
return opaque;
}
/* Print a BUFFER to STREAM while replacing all control characters and
the characters in DELIMITERS by standard C escape sequences.
Returns 0 on success or -1 on error. If BYTES_WRITTEN is not NULL
@ -2992,7 +2896,7 @@ es_write_hexstring (estream_t ES__RESTRICT stream,
encoding. The interface is the same as es_write_sanitized, however
only one delimiter may be supported.
THIS IS NOT A STANDARD ESTREAM FUNCTION AND ONLY USED BY GNUPG. */
THIS IS NOT A STANDARD ESTREAM FUNCTION AND ONLY USED BY GNUPG!. */
int
es_write_sanitized_utf8_buffer (estream_t stream,
const void *buffer, size_t length,
@ -3025,6 +2929,3 @@ es_write_sanitized_utf8_buffer (estream_t stream,
return es_write_sanitized (stream, p, length, delimiters, bytes_written);
}
#endif /*GNUPG_MAJOR_VERSION*/

View file

@ -1,5 +1,5 @@
/* estream.h - Extended stream I/O/ Library
* Copyright (C) 2004 g10 Code GmbH
* Copyright (C) 2004, 2005, 2006, 2007 g10 Code GmbH
*
* This file is part of Libestream.
*
@ -211,7 +211,6 @@ void es_opaque_set (estream_t ES__RESTRICT stream, void *ES__RESTRICT opaque);
void *es_opaque_get (estream_t stream);
#ifdef GNUPG_MAJOR_VERSION
int es_write_sanitized_utf8_buffer (estream_t stream,
const void *buffer, size_t length,
@ -220,5 +219,6 @@ int es_write_sanitized_utf8_buffer (estream_t stream,
#endif /*GNUPG_MAJOR_VERSION*/
#endif /*ESTREAM_H*/

View file

@ -1,5 +1,5 @@
/* sexp-parse.h - S-Exp helper functions
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -97,4 +97,34 @@ smatch (unsigned char const **buf, size_t buflen, const char *token)
return 1;
}
/* Format VALUE for use as the length indicatior of an S-expression.
The caller needs to provide a buffer HELP_BUFFER wth a length of
HELP_BUFLEN. The return value is a pointer into HELP_BUFFER with
the formatted length string. The colon and a trailing nul are
appended. HELP_BUFLEN must be at least 3 - a more useful value is
15. If LENGTH is not NULL, the LENGTH of the resulting string
(excluding the terminating nul) is stored at that address. */
static inline char *
smklen (char *help_buffer, size_t help_buflen, size_t value, size_t *length)
{
char *p = help_buffer + help_buflen;
if (help_buflen >= 3)
{
*--p = 0;
*--p = ':';
do
{
*--p = '0' + (value % 10);
value /= 10;
}
while (value && p > help_buffer);
}
if (length)
*length = (help_buffer + help_buflen) - p;
return p;
}
#endif /*SEXP_PARSE_H*/

View file

@ -34,7 +34,7 @@
#endif
#include "util.h"
#include "sexp-parse.h"
/* Return the so called "keygrip" which is the SHA-1 hash of the
public key parameters expressed in a way depended on the algorithm.
@ -115,7 +115,8 @@ make_simple_sexp_from_hexstr (const char *line, size_t *nscanned)
const char *s;
unsigned char *buf;
unsigned char *p;
char numbuf[50];
char numbuf[50], *numbufp;
size_t numbuflen;
for (n=0, s=line; hexdigitp (s); s++, n++)
;
@ -124,11 +125,12 @@ make_simple_sexp_from_hexstr (const char *line, size_t *nscanned)
if (!n)
return NULL;
len = ((n+1) & ~0x01)/2;
sprintf (numbuf, "(%u:", (unsigned int)len);
buf = xtrymalloc (strlen (numbuf) + len + 1 + 1);
numbufp = smklen (numbuf, sizeof numbuf, len, &numbuflen);
buf = xtrymalloc (1 + numbuflen + len + 1 + 1);
if (!buf)
return NULL;
p = (unsigned char *)stpcpy ((char *)buf, numbuf);
buf[0] = '(';
p = (unsigned char *)stpcpy ((char *)buf+1, numbufp);
s = line;
if ((n&1))
{

View file

@ -27,10 +27,6 @@
#include <errno.h> /* We need errno. */
#include <gpg-error.h> /* We need gpg_error_t. */
/* Common GNUlib includes (-I ../gl/). */
#include "vasprintf.h"
/* Hash function used with libksba. */
#define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write)
@ -43,6 +39,14 @@
#include "../jnlib/dotlock.h"
#include "../jnlib/utf8conv.h"
/* Redefine asprintf by our estream version which uses our own memory
allocator.. */
#include "estream-printf.h"
#define asprintf estream_asprintf
#define vasprintf estream_vasprintf
/* GCC attributes. */
#if __GNUC__ >= 4
# define GNUPG_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a)))
#else
@ -175,13 +179,9 @@ void gnupg_rl_initialize (void);
logging subsystem. */
void setup_libgcrypt_logging (void);
/* Same as asprintf but return an allocated buffer suitable to be
freed using xfree. This function simply dies on memory failure,
thus no extra check is required. */
/* Same as estream_asprintf but die on memory failure. */
char *xasprintf (const char *fmt, ...) JNLIB_GCC_A_PRINTF(1,2);
/* Same as asprintf but return an allocated buffer suitable to be
freed using xfree. This function returns NULL on memory failure and
sets errno. */
/* This is now an alias to estream_asprintf. */
char *xtryasprintf (const char *fmt, ...) JNLIB_GCC_A_PRINTF(1,2);
const char *print_fname_stdout (const char *s);

View file

@ -1,169 +0,0 @@
/* Like vsprintf but provides a pointer to malloc'd storage, which must
be freed by the caller.
Copyright (C) 1994, 2002 Free Software Foundation, Inc.
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
Libiberty is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 51 Franklin Street,
Fifth Floor, Boston, MA 02110-1301, USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#ifdef TEST
int global_total_width;
#endif
int
vasprintf (char **result, const char *format, va_list args)
{
const char *p = format;
/* Add one to make sure that it is never zero, which might cause malloc
to return NULL. */
int total_width = strlen (format) + 1;
va_list ap;
#ifdef va_copy
va_copy (ap, args);
#else
#ifdef __va_copy
__va_copy (ap, args);
#else
memcpy (&ap, args, sizeof (va_list));
#endif /* __va_copy */
#endif /* va_copy */
while (*p != '\0')
{
if (*p++ == '%')
{
while (strchr ("-+ #0", *p))
++p;
if (*p == '*')
{
++p;
total_width += abs (va_arg (ap, int));
}
else
total_width += strtoul (p, (char**)&p, 10);
if (*p == '.')
{
++p;
if (*p == '*')
{
++p;
total_width += abs (va_arg (ap, int));
}
else
total_width += strtoul (p, (char**)&p, 10);
}
while (strchr ("hlL", *p))
++p;
/* Should be big enough for any format specifier except %s
and floats. */
total_width += 30;
switch (*p)
{
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
case 'c':
(void) va_arg (ap, int);
break;
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
(void) va_arg (ap, double);
/* Since an ieee double can have an exponent of 307, we'll
make the buffer wide enough to cover the gross case. */
total_width += 307;
break;
case 's':
{
char *tmp = va_arg (ap, char *);
if (tmp)
total_width += strlen (tmp);
else /* in case the vsprintf does prints a text */
total_width += 25; /* e.g. "(null pointer reference)" */
}
break;
case 'p':
case 'n':
(void) va_arg (ap, char *);
break;
}
}
}
#ifdef TEST
global_total_width = total_width;
#endif
*result = malloc (total_width);
if (*result != NULL)
return vsprintf (*result, format, args);
else
return 0;
}
int
asprintf (char **buf, const char *fmt, ...)
{
int status;
va_list ap;
va_start (ap, fmt);
status = vasprintf (buf, fmt, ap);
va_end (ap);
return status;
}
#ifdef TEST
void
checkit (const char* format, ...)
{
va_list args;
char *result;
va_start (args, format);
vasprintf (&result, format, args);
if (strlen (result) < global_total_width)
printf ("PASS: ");
else
printf ("FAIL: ");
printf ("%d %s\n", global_total_width, result);
}
int
main (void)
{
checkit ("%d", 0x12345678);
checkit ("%200d", 5);
checkit ("%.300d", 6);
checkit ("%100.150d", 7);
checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\
777777777777777777333333333333366666666666622222222222777777777777733333");
checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx");
}
#endif /* TEST */

View file

@ -25,6 +25,11 @@
#include "util.h"
#include "iobuf.h"
#include "estream-printf.h"
#if !defined(ESTREAM_ASPRINTF_MALLOC) || !defined(ESTREAM_ASPRINTF_FREE)
#error Need to define ESTREAM_ASPRINTF_MALLOC and _FREE
#endif
/* Same as asprintf but return an allocated buffer suitable to be
freed using xfree. This function simply dies on memory failure,
@ -33,15 +38,13 @@ char *
xasprintf (const char *fmt, ...)
{
va_list ap;
char *buf, *p;
char *buf;
va_start (ap, fmt);
if (vasprintf (&buf, fmt, ap) < 0)
log_fatal ("asprintf failed: %s\n", strerror (errno));
if (estream_vasprintf (&buf, fmt, ap) < 0)
log_fatal ("estream_asprintf failed: %s\n", strerror (errno));
va_end (ap);
p = xstrdup (buf);
free (buf);
return p;
return buf;
}
/* Same as above but return NULL on memory failure. */
@ -50,14 +53,12 @@ xtryasprintf (const char *fmt, ...)
{
int rc;
va_list ap;
char *buf, *p;
char *buf;
va_start (ap, fmt);
rc = vasprintf (&buf, fmt, ap);
rc = estream_vasprintf (&buf, fmt, ap);
va_end (ap);
if (rc < 0)
return NULL;
p = xtrystrdup (buf);
free (buf);
return p;
return buf;
}