提交 e5c84d51 编写于 作者: B Bodo Möller

New function ERR_error_string_n.

上级 d49f3797
......@@ -4,6 +4,12 @@
Changes between 0.9.5a and 0.9.6 [xx XXX 2000]
*) New function ERR_error_string_n(e, buf, len) which is like
ERR_error_string(e, buf), but writes at most 'len' bytes
including the 0 terminator. For ERR_error_string_n, 'buf'
may not be NULL.
[Damien Miller <djm@mindrot.org>, Bodo Moeller]
*) CONF library reworked to become more general. A new CONF
configuration file reader "class" is implemented as well as a
new functions (NCONF_*, for "New CONF") to handle it. The now
......
OpenSSL STATUS Last modified at
______________ $Date: 2000/04/01 12:32:10 $
______________ $Date: 2000/04/14 23:35:50 $
DEVELOPMENT STATE
......@@ -89,10 +89,6 @@
use a key length decided by the size of the RSA encrypted key and expect
RC2 to adapt).
o ERR_error_string(..., buf) does not know how large buf is,
there should be ERR_error_string_n(..., buf, bufsize)
or similar.
WISHES
o
......@@ -104,7 +104,10 @@ int MAIN(int argc, char **argv)
for (i=1; i<argc; i++)
{
if (sscanf(argv[i],"%lx",&l))
printf("%s\n",ERR_error_string(l,buf));
{
ERR_error_string_n(l, buf, sizeof buf);
printf("%s\n",buf);
}
else
{
printf("%s: bad error code\n",argv[i]);
......
......@@ -78,48 +78,7 @@
# endif
#endif
static void dopr (char *buffer, size_t maxlen, size_t *retlen,
const char *format, va_list args);
#ifdef USE_ALLOCATING_PRINT
static void doapr (char **buffer, size_t *retlen,
const char *format, va_list args);
#endif
int BIO_printf (BIO *bio, ...)
{
va_list args;
char *format;
int ret;
size_t retlen;
#ifdef USE_ALLOCATING_PRINT
char *hugebuf;
#else
MS_STATIC char hugebuf[1024*2]; /* 10k in one chunk is the limit */
#endif
va_start(args, bio);
format=va_arg(args, char *);
#ifndef USE_ALLOCATING_PRINT
hugebuf[0]='\0';
dopr(hugebuf, sizeof(hugebuf), &retlen, format, args);
#else
hugebuf = NULL;
CRYPTO_push_info("doapr()");
doapr(&hugebuf, &retlen, format, args);
if (hugebuf)
{
#endif
ret=BIO_write(bio, hugebuf, (int)retlen);
#ifdef USE_ALLOCATING_PRINT
Free(hugebuf);
}
CRYPTO_pop_info();
#endif
va_end(args);
return(ret);
}
/***************************************************************************/
/*
* Copyright Patrick Powell 1995
......@@ -140,6 +99,7 @@ int BIO_printf (BIO *bio, ...)
* o Andrew Tridgell <tridge@samba.org> (1998, for Samba)
* o Luke Mewburn <lukem@netbsd.org> (1999, for LukemFTP)
* o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth)
* o ... (for OpenSSL)
*/
#if HAVE_LONG_DOUBLE
......@@ -161,18 +121,17 @@ static void fmtint (void (*)(char **, size_t *, size_t *, int),
char **, size_t *, size_t *, LLONG, int, int, int, int);
static void fmtfp (void (*)(char **, size_t *, size_t *, int),
char **, size_t *, size_t *, LDOUBLE, int, int, int);
#ifndef USE_ALLOCATING_PRINT
static int dopr_isbig (size_t, size_t);
static int dopr_copy (size_t);
static void dopr_outch (char **, size_t *, size_t *, int);
#else
#ifdef USE_ALLOCATING_PRINT
static int doapr_isbig (size_t, size_t);
static int doapr_copy (size_t);
static void doapr_outch (char **, size_t *, size_t *, int);
#endif
static void _dopr(void (*)(char **, size_t *, size_t *, int),
int (*)(size_t, size_t), int (*)(size_t),
char **buffer, size_t *maxlen, size_t *retlen,
char **buffer, size_t *maxlen, size_t *retlen, int *truncated,
const char *format, va_list args);
/* format read states */
......@@ -213,8 +172,9 @@ dopr(
const char *format,
va_list args)
{
int ignored;
_dopr(dopr_outch, dopr_isbig, dopr_copy,
&buffer, &maxlen, retlen, format, args);
&buffer, &maxlen, retlen, &ignored, format, args);
}
#else
......@@ -226,8 +186,9 @@ doapr(
va_list args)
{
size_t dummy_maxlen = 0;
int ignored;
_dopr(doapr_outch, doapr_isbig, doapr_copy,
buffer, &dummy_maxlen, retlen, format, args);
buffer, &dummy_maxlen, retlen, &ignored, format, args);
}
#endif
......@@ -239,6 +200,7 @@ _dopr(
char **buffer,
size_t *maxlen,
size_t *retlen,
int *truncated,
const char *format,
va_list args)
{
......@@ -374,7 +336,7 @@ _dopr(
break;
}
fmtint(outch_fn, buffer, &currlen, maxlen,
value, 10, min, max, flags);
value, 10, min, max, flags);
break;
case 'X':
flags |= DP_F_UP;
......@@ -409,7 +371,7 @@ _dopr(
else
fvalue = va_arg(args, double);
fmtfp(outch_fn, buffer, &currlen, maxlen,
fvalue, min, max, flags);
fvalue, min, max, flags);
break;
case 'E':
flags |= DP_F_UP;
......@@ -436,7 +398,7 @@ _dopr(
if (max < 0)
max = (*copy_fn)(*maxlen);
fmtstr(outch_fn, buffer, &currlen, maxlen, strvalue,
flags, min, max);
flags, min, max);
break;
case 'p':
value = (long)va_arg(args, void *);
......@@ -484,7 +446,8 @@ _dopr(
break;
}
}
if (currlen >= *maxlen - 1)
*truncated = (currlen > *maxlen - 1);
if (*truncated)
currlen = *maxlen - 1;
(*buffer)[currlen] = '\0';
*retlen = currlen;
......@@ -842,3 +805,62 @@ doapr_outch(
return;
}
#endif
/***************************************************************************/
int BIO_printf (BIO *bio, const char *format, ...)
{
va_list args;
int ret;
size_t retlen;
#ifdef USE_ALLOCATING_PRINT
char *hugebuf;
#else
MS_STATIC char hugebuf[1024*2]; /* 10k in one chunk is the limit */
#endif
va_start(args, format);
#ifndef USE_ALLOCATING_PRINT
hugebuf[0]='\0';
dopr(hugebuf, sizeof(hugebuf), &retlen, format, args);
#else
hugebuf = NULL;
CRYPTO_push_info("doapr()");
doapr(&hugebuf, &retlen, format, args);
if (hugebuf)
{
#endif
ret=BIO_write(bio, hugebuf, (int)retlen);
#ifdef USE_ALLOCATING_PRINT
Free(hugebuf);
}
CRYPTO_pop_info();
#endif
va_end(args);
return(ret);
}
/* As snprintf is not available everywhere, we provide our own implementation.
* This function has nothing to do with BIOs, but it's closely related
* to BIO_printf, and we need *some* name prefix ...
* (XXX the function should be renamed, but to what?) */
int BIO_snprintf(char *buf, size_t n, const char *format, ...)
{
va_list args;
size_t retlen;
int truncated;
va_start(args, format);
_dopr(dopr_outch, dopr_isbig, dopr_copy,
&buf, &n, &retlen, &truncated, format, args);
if (truncated)
/* In case of truncation, return -1 like traditional snprintf.
* (Current drafts for ISO/IEC 9899 say snprintf should return
* the number of characters that would have been written,
* had the buffer been large enough.) */
return -1;
else
return (retlen <= INT_MAX) ? retlen : -1;
}
......@@ -592,7 +592,8 @@ void BIO_copy_next_retry(BIO *b);
long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);
int BIO_printf(BIO *bio, ...);
int BIO_printf(BIO *bio, const char *format, ...);
int BIO_snprintf(char *buf, size_t n, const char *format, ...);
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
......
......@@ -118,6 +118,7 @@
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/crypto.h>
#include <openssl/bio.h>
static LHASH *error_hash=NULL;
......@@ -477,13 +478,11 @@ static unsigned long get_error_values(int inc, const char **file, int *line,
return(ret);
}
/* BAD for multi-threaded, uses a local buffer if ret == NULL */
char *ERR_error_string(unsigned long e, char *ret)
void ERR_error_string_n(unsigned long e, char *buf, size_t len)
{
static char buf[256];
char lsbuf[64], fsbuf[64], rsbuf[64];
const char *ls,*fs,*rs;
unsigned long l,f,r;
int i;
l=ERR_GET_LIB(e);
f=ERR_GET_FUNC(e);
......@@ -493,21 +492,50 @@ char *ERR_error_string(unsigned long e, char *ret)
fs=ERR_func_error_string(e);
rs=ERR_reason_error_string(e);
if (ret == NULL) ret=buf;
sprintf(&(ret[0]),"error:%08lX:",e);
i=strlen(ret);
if (ls == NULL)
sprintf(&(ret[i]),":lib(%lu) ",l);
else sprintf(&(ret[i]),"%s",ls);
i=strlen(ret);
if (ls == NULL)
BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l);
if (fs == NULL)
sprintf(&(ret[i]),":func(%lu) ",f);
else sprintf(&(ret[i]),":%s",fs);
i=strlen(ret);
BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f);
if (rs == NULL)
sprintf(&(ret[i]),":reason(%lu)",r);
else sprintf(&(ret[i]),":%s",rs);
BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r);
BIO_snprintf(buf, len,"error:%08lX:%s:%s:%s", e, ls?ls:lsbuf,
fs?fs:fsbuf, rs?rs:rsbuf);
if (strlen(buf) == len-1)
{
/* output may be truncated; make sure we always have 5
* colon-separated fields, i.e. 4 colons ... */
#define NUM_COLONS 4
if (len > NUM_COLONS) /* ... if possible */
{
int i;
char *s = buf;
for (i = 0; i < NUM_COLONS; i++)
{
char *colon = strchr(s, ':');
if (colon == NULL || colon > &buf[len-1] - NUM_COLONS + i)
{
/* set colon no. i at last possible position
* (buf[len-1] is the terminating 0)*/
colon = &buf[len-1] - NUM_COLONS + i;
*colon = ':';
}
s = colon + 1;
}
}
}
}
/* BAD for multi-threading: uses a local buffer if ret == NULL */
/* ERR_error_string_n should be used instead for ret != NULL
* as ERR_error_string cannot know how large the buffer is */
char *ERR_error_string(unsigned long e, char *ret)
{
static char buf[256];
if (ret == NULL) ret=buf;
ERR_error_string_n(e, buf, 256);
return(ret);
}
......
......@@ -233,6 +233,7 @@ unsigned long ERR_peek_error_line_data(const char **file,int *line,
const char **data,int *flags);
void ERR_clear_error(void );
char *ERR_error_string(unsigned long e,char *buf);
void ERR_error_string_n(unsigned long e, char *buf, size_t len);
const char *ERR_lib_error_string(unsigned long e);
const char *ERR_func_error_string(unsigned long e);
const char *ERR_reason_error_string(unsigned long e);
......
......@@ -76,7 +76,8 @@ void ERR_print_errors_fp(FILE *fp)
es=CRYPTO_thread_id();
while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
{
fprintf(fp,"%lu:%s:%s:%d:%s\n",es,ERR_error_string(l,buf),
ERR_error_string_n(l, buf, sizeof buf);
fprintf(fp,"%lu:%s:%s:%d:%s\n",es,buf,
file,line,(flags&ERR_TXT_STRING)?data:"");
}
}
......@@ -94,7 +95,8 @@ void ERR_print_errors(BIO *bp)
es=CRYPTO_thread_id();
while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
{
sprintf(buf2,"%lu:%s:%s:%d:",es,ERR_error_string(l,buf),
ERR_error_string_n(l, buf, sizeof buf);
sprintf(buf2,"%lu:%s:%s:%d:",es,buf,
file,line);
BIO_write(bp,buf2,strlen(buf2));
if (flags & ERR_TXT_STRING)
......
......@@ -9,6 +9,7 @@ ERR_error_string - obtain human-readable error message
#include <openssl/err.h>
char *ERR_error_string(unsigned long e, char *buf);
char *ERR_error_string_n(unsigned long e, char *buf, size_t len);
const char *ERR_lib_error_string(unsigned long e);
const char *ERR_func_error_string(unsigned long e);
......@@ -17,9 +18,13 @@ ERR_error_string - obtain human-readable error message
=head1 DESCRIPTION
ERR_error_string() generates a human-readable string representing the
error code B<e>, and places it at B<buf>. B<buf> must be at least 120
bytes long. If B<buf> is B<NULL>, the error string is placed in a
error code I<e>, and places it at I<buf>. I<buf> must be at least 120
bytes long. If I<buf> is B<NULL>, the error string is placed in a
static buffer.
ERR_error_string_n() is a variant of ERR_error_string() that writes
at most I<len> characters (including the terminating 0)
and truncates the resulting string if necessary.
For ERR_error_string_n(), I<buf> may not be B<NULL>.
The string will have the following format:
......@@ -45,7 +50,7 @@ all error codes currently in the queue.
=head1 RETURN VALUES
ERR_error_string() returns a pointer to a static buffer containing the
string if B<buf == NULL>, B<buf> otherwise.
string if I<buf> B<== NULL>, I<buf> otherwise.
ERR_lib_error_string(), ERR_func_error_string() and
ERR_reason_error_string() return the strings, and B<NULL> if
......@@ -61,5 +66,6 @@ L<ERR_print_errors(3)|ERR_print_errors(3)>
=head1 HISTORY
ERR_error_string() is available in all versions of SSLeay and OpenSSL.
ERR_error_string_n() was added in OpenSSL 0.9.6.
=cut
......@@ -2262,3 +2262,5 @@ NCONF_dump_bio 2287
CONF_dump_bio 2288
NCONF_free_data 2289
CONF_set_default_method 2290
ERR_error_string_n 2291
BIO_snprintf 2292
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册