diff options
Diffstat (limited to 'crypto/err')
-rw-r--r-- | crypto/err/err.c | 62 | ||||
-rw-r--r-- | crypto/err/err.h | 1 | ||||
-rw-r--r-- | crypto/err/err_prn.c | 6 |
3 files changed, 50 insertions, 19 deletions
diff --git a/crypto/err/err.c b/crypto/err/err.c index cbbd326f74..a0135579f0 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -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); } diff --git a/crypto/err/err.h b/crypto/err/err.h index 35c4d97b76..e3984bb7a4 100644 --- a/crypto/err/err.h +++ b/crypto/err/err.h @@ -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); diff --git a/crypto/err/err_prn.c b/crypto/err/err_prn.c index 0999ff214b..6f60b016c3 100644 --- a/crypto/err/err_prn.c +++ b/crypto/err/err_prn.c @@ -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) |