summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2019-07-24 13:03:32 +0200
committerRichard Levitte <levitte@openssl.org>2019-07-31 06:42:45 +0200
commit7c0e20dc6f11aa506abc99ccc90b3a39c48c3052 (patch)
tree9826a7692351ef85ee1c06bd015670ccf84b1f95 /crypto
parent8a4dc425cc73040c55bc01d89c5541e37dab939a (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.info2
-rw-r--r--crypto/err/err_blocks.c113
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);
+}