diff options
author | Richard Levitte <levitte@openssl.org> | 2019-07-24 13:03:32 +0200 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2019-07-31 06:42:45 +0200 |
commit | 7c0e20dc6f11aa506abc99ccc90b3a39c48c3052 (patch) | |
tree | 9826a7692351ef85ee1c06bd015670ccf84b1f95 /crypto | |
parent | 8a4dc425cc73040c55bc01d89c5541e37dab939a (diff) |
ERR: Add new building blocks for reporting errors
The new building block are ERR_new(), ERR_set_debug(),
ERR_set_error(), ERR_vset_error(), which allocate a new error record
and set the diverse data in them. They are designed in such a way
that it's reasonably easy to create macros that use all of them but
then rely completely on the function signature of ERR_set_error() or
ERR_vset_error().
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9452)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/err/build.info | 2 | ||||
-rw-r--r-- | crypto/err/err_blocks.c | 113 |
2 files changed, 114 insertions, 1 deletions
diff --git a/crypto/err/build.info b/crypto/err/build.info index 6163d95b74..c010ea4cb9 100644 --- a/crypto/err/build.info +++ b/crypto/err/build.info @@ -1,3 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - err.c err_all.c err_prn.c + err_blocks.c err.c err_all.c err_prn.c diff --git a/crypto/err/err_blocks.c b/crypto/err/err_blocks.c new file mode 100644 index 0000000000..49086bd0c2 --- /dev/null +++ b/crypto/err/err_blocks.c @@ -0,0 +1,113 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <string.h> +#include <openssl/err.h> +#include "err_locl.h" + +void ERR_new(void) +{ + ERR_STATE *es; + + es = ERR_get_state(); + if (es == NULL) + return; + + /* Allocate a slot */ + err_get_slot(es); + err_clear(es, es->top, 0); +} + +void ERR_set_debug(const char *file, int line, const char *func) +{ + ERR_STATE *es; + + es = ERR_get_state(); + if (es == NULL) + return; + + err_set_debug(es, es->top, file, line, func); +} + +void ERR_set_error(int lib, int reason, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + ERR_vset_error(lib, reason, fmt, args); + va_end(args); +} + +void ERR_vset_error(int lib, int reason, const char *fmt, va_list args) +{ + ERR_STATE *es; + char *buf = NULL; + size_t buf_size = 0; + unsigned long flags = 0; + size_t i; + + es = ERR_get_state(); + if (es == NULL) + return; + i = es->top; + + if (fmt != NULL) { + int printed_len = 0; + char *rbuf = NULL; + + buf = es->err_data[i]; + buf_size = es->err_data_size[i]; + + /* + * To protect the string we just grabbed from tampering by other + * functions we may call, or to protect them from freeing a pointer + * that may no longer be valid at that point, we clear away the + * data pointer and the flags. We will set them again at the end + * of this function. + */ + es->err_data[i] = NULL; + es->err_data_flags[i] = 0; + + /* + * Try to maximize the space available. If that fails, we use what + * we have. + */ + if (buf_size < ERR_MAX_DATA_SIZE + && (rbuf = OPENSSL_realloc(buf, ERR_MAX_DATA_SIZE)) != NULL) { + buf = rbuf; + buf_size = ERR_MAX_DATA_SIZE; + } + + if (buf != NULL) { + printed_len = BIO_vsnprintf(buf, ERR_MAX_DATA_SIZE, fmt, args); + } + if (printed_len < 0) + printed_len = 0; + buf[printed_len] = '\0'; + + /* + * Try to reduce the size, but only if we maximized above. If that + * fails, we keep what we have. + * (According to documentation, realloc leaves the old buffer untouched + * if it fails) + */ + if ((rbuf = OPENSSL_realloc(buf, printed_len + 1)) != NULL) { + buf = rbuf; + buf_size = printed_len + 1; + } + + if (buf != NULL) + flags = ERR_TXT_MALLOCED | ERR_TXT_STRING; + } + + err_clear_data(es, es->top, 0); + err_set_error(es, es->top, lib, reason); + if (fmt != NULL) + err_set_data(es, es->top, buf, buf_size, flags); +} |