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)
This commit is contained in:
parent
8a4dc425cc
commit
7c0e20dc6f
5 changed files with 205 additions and 1 deletions
|
@ -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
|
||||
|
|
113
crypto/err/err_blocks.c
Normal file
113
crypto/err/err_blocks.c
Normal file
|
@ -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);
|
||||
}
|
78
doc/man3/ERR_new.pod
Normal file
78
doc/man3/ERR_new.pod
Normal file
|
@ -0,0 +1,78 @@
|
|||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
ERR_new, ERR_set_debug, ERR_set_error, ERR_vset_error
|
||||
- Error recording building blocks
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <openssl/err.h>
|
||||
|
||||
void ERR_new(void);
|
||||
void ERR_set_debug(const char *file, int line, const char *func);
|
||||
void ERR_set_error(int lib, int reason, const char *fmt, ...);
|
||||
void ERR_vset_error(int lib, int reason, const char *fmt, va_list args);
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The functions described here are generally not used directly, but
|
||||
rather through macros such as L<ERR_raise(3)>.
|
||||
They can still be useful for anyone that wants to make their own
|
||||
macros.
|
||||
|
||||
ERR_new() allocates a new slot in the thread's error queue.
|
||||
|
||||
ERR_set_debug() sets the debug information related to the current
|
||||
error in the thread's error queue.
|
||||
The values that can be given are the file name I<file>, line in the
|
||||
file I<line> and the name of the function I<func> where the error
|
||||
occured.
|
||||
The names must be constant, this function will only save away the
|
||||
pointers, not copy the strings.
|
||||
|
||||
ERR_set_error() sets the error information, which are the library
|
||||
number I<lib> and the reason code I<reason>, and additional data as a
|
||||
format string I<fmt> and an arbitrary number of arguments.
|
||||
The additional data is processed with L<BIO_snprintf(3)> to form the
|
||||
additional data string, which is allocated and store in the error
|
||||
record.
|
||||
|
||||
ERR_vset_error() works like ERR_set_error(), but takes a B<va_list>
|
||||
argument instead of a variable number of arguments.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
ERR_new, ERR_set_debug, ERR_set_error and ERR_vset_error
|
||||
do not return any values.
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
The library number is unique to each unit that records errors.
|
||||
OpenSSL has a number of pre-allocated ones for its own uses, but
|
||||
others may allocate their own library number dynamically with
|
||||
L<ERR_get_next_error_library(3)>.
|
||||
|
||||
Reason codes are unique within each library, and may have an
|
||||
associated set of strings as a short description of the reason.
|
||||
For dynamically allocated library numbers, reason strings are recorded
|
||||
with L<ERR_load_strings(3)>.
|
||||
|
||||
Provider authors are supplied with core versions of these functions,
|
||||
see L<provider-base(7)>.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<ERR_raise(3)>, L<ERR_get_next_error_library(3)>,
|
||||
L<ERR_load_strings(3)>, L<BIO_snprintf(3)>, L<provider-base(7)>
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2000-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
|
||||
L<https://www.openssl.org/source/license.html>.
|
||||
|
||||
=cut
|
|
@ -236,6 +236,15 @@ typedef struct ERR_string_data_st {
|
|||
|
||||
DEFINE_LHASH_OF(ERR_STRING_DATA);
|
||||
|
||||
/* 12 lines and some on an 80 column terminal */
|
||||
#define ERR_MAX_DATA_SIZE 1024
|
||||
|
||||
/* Building blocks */
|
||||
void ERR_new(void);
|
||||
void ERR_set_debug(const char *file, int line, const char *func);
|
||||
void ERR_set_error(int lib, int reason, const char *fmt, ...);
|
||||
void ERR_vset_error(int lib, int reason, const char *fmt, va_list args);
|
||||
|
||||
void ERR_put_error(int lib, int func, int reason, const char *file, int line);
|
||||
void ERR_put_func_error(int lib, const char *func, int reason,
|
||||
const char *file, int line);
|
||||
|
|
|
@ -4700,3 +4700,7 @@ EVP_CIPHER_do_all_ex 4805 3_0_0 EXIST::FUNCTION:
|
|||
EVP_MD_do_all_ex 4806 3_0_0 EXIST::FUNCTION:
|
||||
EVP_KEYEXCH_provider 4807 3_0_0 EXIST::FUNCTION:
|
||||
OSSL_PROVIDER_available 4808 3_0_0 EXIST::FUNCTION:
|
||||
ERR_new 4809 3_0_0 EXIST::FUNCTION:
|
||||
ERR_set_debug 4810 3_0_0 EXIST::FUNCTION:
|
||||
ERR_set_error 4811 3_0_0 EXIST::FUNCTION:
|
||||
ERR_vset_error 4812 3_0_0 EXIST::FUNCTION:
|
||||
|
|
Loading…
Reference in a new issue