/*
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (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
 */

// Ensure we can't call OPENSSL_malloc circularly.
#define _BORINGSSL_PROHIBIT_OPENSSL_MALLOC
#include <openssl/err.h>

#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <stdarg.h>
#include <string.h>

#if defined(OPENSSL_WINDOWS)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <windows.h>
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif

#include <openssl/mem.h>
#include <openssl/thread.h>

#include "../internal.h"
#include "./internal.h"


namespace {
struct err_error_st {
  // file contains the filename where the error occurred.
  const char *file;
  // data contains a NUL-terminated string with optional data. It is allocated
  // with system |malloc| and must be freed with |free| (not |OPENSSL_free|)
  char *data;
  // packed contains the error library and reason, as packed by ERR_PACK.
  uint32_t packed;
  // line contains the line number where the error occurred.
  uint16_t line;
  // mark indicates a reversion point in the queue. See |ERR_pop_to_mark|.
  unsigned mark : 1;
};

// ERR_STATE contains the per-thread, error queue.
typedef struct err_state_st {
  // errors contains up to ERR_NUM_ERRORS - 1 most recent errors, organised as a
  // ring buffer.
  struct err_error_st errors[ERR_NUM_ERRORS];
  // top contains the index of the most recent error. If |top| equals |bottom|
  // then the queue is empty.
  unsigned top;
  // bottom contains the index before the least recent error in the queue.
  unsigned bottom;

  // to_free, if not NULL, contains a pointer owned by this structure that was
  // previously a |data| pointer of one of the elements of |errors|.
  void *to_free;
} ERR_STATE;
}  // namespace

extern const uint32_t kOpenSSLReasonValues[];
extern const size_t kOpenSSLReasonValuesLen;
extern const char kOpenSSLReasonStringData[];

static char *strdup_libc_malloc(const char *str) {
  // |strdup| is not in C until C23, so MSVC triggers deprecation warnings, and
  // glibc and musl gate it on a feature macro. Reimplementing it is easier.
  size_t len = strlen(str);
  char *ret = reinterpret_cast<char *>(malloc(len + 1));
  if (ret != NULL) {
    memcpy(ret, str, len + 1);
  }
  return ret;
}

// err_clear clears the given queued error.
static void err_clear(struct err_error_st *error) {
  free(error->data);
  OPENSSL_memset(error, 0, sizeof(struct err_error_st));
}

static void err_copy(struct err_error_st *dst, const struct err_error_st *src) {
  err_clear(dst);
  dst->file = src->file;
  if (src->data != NULL) {
    // We can't use OPENSSL_strdup because we don't want to call OPENSSL_malloc,
    // which can affect the error stack.
    dst->data = strdup_libc_malloc(src->data);
  }
  dst->packed = src->packed;
  dst->line = src->line;
}


// global_next_library contains the next custom library value to return.
static int global_next_library = ERR_NUM_LIBS;

// global_next_library_mutex protects |global_next_library| from concurrent
// updates.
static CRYPTO_MUTEX global_next_library_mutex = CRYPTO_MUTEX_INIT;

static void err_state_free(void *statep) {
  ERR_STATE *state = reinterpret_cast<ERR_STATE *>(statep);

  if (state == NULL) {
    return;
  }

  for (unsigned i = 0; i < ERR_NUM_ERRORS; i++) {
    err_clear(&state->errors[i]);
  }
  free(state->to_free);
  free(state);
}

// err_get_state gets the ERR_STATE object for the current thread.
static ERR_STATE *err_get_state(void) {
  ERR_STATE *state = reinterpret_cast<ERR_STATE *>(
      CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_ERR));
  if (state == NULL) {
    state = reinterpret_cast<ERR_STATE *>(malloc(sizeof(ERR_STATE)));
    if (state == NULL) {
      return NULL;
    }
    OPENSSL_memset(state, 0, sizeof(ERR_STATE));
    if (!CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_ERR, state,
                                 err_state_free)) {
      return NULL;
    }
  }

  return state;
}

static uint32_t get_error_values(int inc, int top, const char **file, int *line,
                                 const char **data, int *flags) {
  unsigned i = 0;
  ERR_STATE *state;
  struct err_error_st *error;
  uint32_t ret;

  state = err_get_state();
  if (state == NULL || state->bottom == state->top) {
    return 0;
  }

  if (top) {
    assert(!inc);
    // last error
    i = state->top;
  } else {
    i = (state->bottom + 1) % ERR_NUM_ERRORS;
  }

  error = &state->errors[i];
  ret = error->packed;

  if (file != NULL && line != NULL) {
    if (error->file == NULL) {
      *file = "NA";
      *line = 0;
    } else {
      *file = error->file;
      *line = error->line;
    }
  }

  if (data != NULL) {
    if (error->data == NULL) {
      *data = "";
      if (flags != NULL) {
        *flags = 0;
      }
    } else {
      *data = error->data;
      if (flags != NULL) {
        // Without |ERR_FLAG_MALLOCED|, rust-openssl assumes the string has a
        // static lifetime. In both cases, we retain ownership of the string,
        // and the caller is not expected to free it.
        *flags = ERR_FLAG_STRING | ERR_FLAG_MALLOCED;
      }
      // If this error is being removed, take ownership of data from
      // the error. The semantics are such that the caller doesn't
      // take ownership either. Instead the error system takes
      // ownership and retains it until the next call that affects the
      // error queue.
      if (inc) {
        if (error->data != NULL) {
          free(state->to_free);
          state->to_free = error->data;
        }
        error->data = NULL;
      }
    }
  }

  if (inc) {
    assert(!top);
    err_clear(error);
    state->bottom = i;
  }

  return ret;
}

uint32_t ERR_get_error(void) {
  return get_error_values(1 /* inc */, 0 /* bottom */, NULL, NULL, NULL, NULL);
}

uint32_t ERR_get_error_line(const char **file, int *line) {
  return get_error_values(1 /* inc */, 0 /* bottom */, file, line, NULL, NULL);
}

uint32_t ERR_get_error_line_data(const char **file, int *line,
                                 const char **data, int *flags) {
  return get_error_values(1 /* inc */, 0 /* bottom */, file, line, data, flags);
}

uint32_t ERR_peek_error(void) {
  return get_error_values(0 /* peek */, 0 /* bottom */, NULL, NULL, NULL, NULL);
}

uint32_t ERR_peek_error_line(const char **file, int *line) {
  return get_error_values(0 /* peek */, 0 /* bottom */, file, line, NULL, NULL);
}

uint32_t ERR_peek_error_line_data(const char **file, int *line,
                                  const char **data, int *flags) {
  return get_error_values(0 /* peek */, 0 /* bottom */, file, line, data,
                          flags);
}

uint32_t ERR_peek_last_error(void) {
  return get_error_values(0 /* peek */, 1 /* top */, NULL, NULL, NULL, NULL);
}

uint32_t ERR_peek_last_error_line(const char **file, int *line) {
  return get_error_values(0 /* peek */, 1 /* top */, file, line, NULL, NULL);
}

uint32_t ERR_peek_last_error_line_data(const char **file, int *line,
                                       const char **data, int *flags) {
  return get_error_values(0 /* peek */, 1 /* top */, file, line, data, flags);
}

void ERR_clear_error(void) {
  ERR_STATE *const state = err_get_state();
  unsigned i;

  if (state == NULL) {
    return;
  }

  for (i = 0; i < ERR_NUM_ERRORS; i++) {
    err_clear(&state->errors[i]);
  }
  free(state->to_free);
  state->to_free = NULL;

  state->top = state->bottom = 0;
}

void ERR_remove_thread_state(const CRYPTO_THREADID *tid) {
  if (tid != NULL) {
    assert(0);
    return;
  }

  ERR_clear_error();
}

int ERR_get_next_error_library(void) {
  int ret;

  CRYPTO_MUTEX_lock_write(&global_next_library_mutex);
  ret = global_next_library++;
  CRYPTO_MUTEX_unlock_write(&global_next_library_mutex);

  return ret;
}

void ERR_remove_state(unsigned long pid) { ERR_clear_error(); }

void ERR_clear_system_error(void) { errno = 0; }

// err_string_cmp is a compare function for searching error values with
// |bsearch| in |err_string_lookup|.
static int err_string_cmp(const void *a, const void *b) {
  const uint32_t a_key = *((const uint32_t *)a) >> 15;
  const uint32_t b_key = *((const uint32_t *)b) >> 15;

  if (a_key < b_key) {
    return -1;
  } else if (a_key > b_key) {
    return 1;
  } else {
    return 0;
  }
}

// err_string_lookup looks up the string associated with |lib| and |key| in
// |values| and |string_data|. It returns the string or NULL if not found.
static const char *err_string_lookup(uint32_t lib, uint32_t key,
                                     const uint32_t *values, size_t num_values,
                                     const char *string_data) {
  // |values| points to data in err_data.h, which is generated by
  // err_data_generate.go. It's an array of uint32_t values. Each value has the
  // following structure:
  //   | lib  |    key    |    offset     |
  //   |6 bits|  11 bits  |    15 bits    |
  //
  // The |lib| value is a library identifier: one of the |ERR_LIB_*| values.
  // The |key| is a reason code, depending on the context.
  // The |offset| is the number of bytes from the start of |string_data| where
  // the (NUL terminated) string for this value can be found.
  //
  // Values are sorted based on treating the |lib| and |key| part as an
  // unsigned integer.
  if (lib >= (1 << 6) || key >= (1 << 11)) {
    return NULL;
  }
  uint32_t search_key = lib << 26 | key << 15;
  const uint32_t *result = reinterpret_cast<const uint32_t *>(bsearch(
      &search_key, values, num_values, sizeof(uint32_t), err_string_cmp));
  if (result == NULL) {
    return NULL;
  }

  return &string_data[(*result) & 0x7fff];
}

namespace {
typedef struct library_name_st {
  const char *str;
  const char *symbol;
  const char *reason_symbol;
} LIBRARY_NAME;
}  // namespace

static const LIBRARY_NAME kLibraryNames[ERR_NUM_LIBS] = {
    {"invalid library (0)", NULL, NULL},
    {"unknown library", "NONE", "NONE_LIB"},
    {"system library", "SYS", "SYS_LIB"},
    {"bignum routines", "BN", "BN_LIB"},
    {"RSA routines", "RSA", "RSA_LIB"},
    {"Diffie-Hellman routines", "DH", "DH_LIB"},
    {"public key routines", "EVP", "EVP_LIB"},
    {"memory buffer routines", "BUF", "BUF_LIB"},
    {"object identifier routines", "OBJ", "OBJ_LIB"},
    {"PEM routines", "PEM", "PEM_LIB"},
    {"DSA routines", "DSA", "DSA_LIB"},
    {"X.509 certificate routines", "X509", "X509_LIB"},
    {"ASN.1 encoding routines", "ASN1", "ASN1_LIB"},
    {"configuration file routines", "CONF", "CONF_LIB"},
    {"common libcrypto routines", "CRYPTO", "CRYPTO_LIB"},
    {"elliptic curve routines", "EC", "EC_LIB"},
    {"SSL routines", "SSL", "SSL_LIB"},
    {"BIO routines", "BIO", "BIO_LIB"},
    {"PKCS7 routines", "PKCS7", "PKCS7_LIB"},
    {"PKCS8 routines", "PKCS8", "PKCS8_LIB"},
    {"X509 V3 routines", "X509V3", "X509V3_LIB"},
    {"random number generator", "RAND", "RAND_LIB"},
    {"ENGINE routines", "ENGINE", "ENGINE_LIB"},
    {"OCSP routines", "OCSP", "OCSP_LIB"},
    {"UI routines", "UI", "UI_LIB"},
    {"COMP routines", "COMP", "COMP_LIB"},
    {"ECDSA routines", "ECDSA", "ECDSA_LIB"},
    {"ECDH routines", "ECDH", "ECDH_LIB"},
    {"HMAC routines", "HMAC", "HMAC_LIB"},
    {"Digest functions", "DIGEST", "DIGEST_LIB"},
    {"Cipher functions", "CIPHER", "CIPHER_LIB"},
    {"HKDF functions", "HKDF", "HKDF_LIB"},
    {"Trust Token functions", "TRUST_TOKEN", "TRUST_TOKEN_LIB"},
    {"User defined functions", "USER", "USER_LIB"},
};

static const char *err_lib_error_string(uint32_t packed_error) {
  const uint32_t lib = ERR_GET_LIB(packed_error);
  return lib >= ERR_NUM_LIBS ? NULL : kLibraryNames[lib].str;
}

const char *ERR_lib_error_string(uint32_t packed_error) {
  const char *ret = err_lib_error_string(packed_error);
  return ret == NULL ? "unknown library" : ret;
}

const char *ERR_lib_symbol_name(uint32_t packed_error) {
  const uint32_t lib = ERR_GET_LIB(packed_error);
  return lib >= ERR_NUM_LIBS ? NULL : kLibraryNames[lib].symbol;
}

const char *ERR_func_error_string(uint32_t packed_error) {
  return "OPENSSL_internal";
}

static const char *err_reason_error_string(uint32_t packed_error, int symbol) {
  const uint32_t lib = ERR_GET_LIB(packed_error);
  const uint32_t reason = ERR_GET_REASON(packed_error);

  if (lib == ERR_LIB_SYS) {
    if (!symbol && reason < 127) {
      return strerror(reason);
    }
    return NULL;
  }

  if (reason < ERR_NUM_LIBS) {
    return symbol ? kLibraryNames[reason].reason_symbol
                  : kLibraryNames[reason].str;
  }

  if (reason < 100) {
    // TODO(davidben): All our other reason strings match the symbol name. Only
    // the common ones differ. Should we just consistently return the symbol
    // name?
    switch (reason) {
      case ERR_R_MALLOC_FAILURE:
        return symbol ? "MALLOC_FAILURE" : "malloc failure";
      case ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED:
        return symbol ? "SHOULD_NOT_HAVE_BEEN_CALLED"
                      : "function should not have been called";
      case ERR_R_PASSED_NULL_PARAMETER:
        return symbol ? "PASSED_NULL_PARAMETER" : "passed a null parameter";
      case ERR_R_INTERNAL_ERROR:
        return symbol ? "INTERNAL_ERROR" : "internal error";
      case ERR_R_OVERFLOW:
        return symbol ? "OVERFLOW" : "overflow";
      default:
        return NULL;
    }
  }

  // Unlike OpenSSL, BoringSSL's reason strings already match symbol name, so we
  // do not need to check |symbol|.
  return err_string_lookup(lib, reason, kOpenSSLReasonValues,
                           kOpenSSLReasonValuesLen, kOpenSSLReasonStringData);
}

const char *ERR_reason_error_string(uint32_t packed_error) {
  const char *ret = err_reason_error_string(packed_error, /*symbol=*/0);
  return ret == NULL ? "unknown error" : ret;
}

const char *ERR_reason_symbol_name(uint32_t packed_error) {
  return err_reason_error_string(packed_error, /*symbol=*/1);
}

char *ERR_error_string(uint32_t packed_error, char *ret) {
  static char buf[ERR_ERROR_STRING_BUF_LEN];

  if (ret == NULL) {
    // TODO(fork): remove this.
    ret = buf;
  }

#if !defined(NDEBUG)
  // This is aimed to help catch callers who don't provide
  // |ERR_ERROR_STRING_BUF_LEN| bytes of space.
  OPENSSL_memset(ret, 0, ERR_ERROR_STRING_BUF_LEN);
#endif

  return ERR_error_string_n(packed_error, ret, ERR_ERROR_STRING_BUF_LEN);
}

char *ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) {
  if (len == 0) {
    return NULL;
  }

  unsigned lib = ERR_GET_LIB(packed_error);
  unsigned reason = ERR_GET_REASON(packed_error);

  const char *lib_str = err_lib_error_string(packed_error);
  const char *reason_str = err_reason_error_string(packed_error, /*symbol=*/0);

  char lib_buf[32], reason_buf[32];
  if (lib_str == NULL) {
    snprintf(lib_buf, sizeof(lib_buf), "lib(%u)", lib);
    lib_str = lib_buf;
  }

  if (reason_str == NULL) {
    snprintf(reason_buf, sizeof(reason_buf), "reason(%u)", reason);
    reason_str = reason_buf;
  }

  int ret = snprintf(buf, len, "error:%08" PRIx32 ":%s:OPENSSL_internal:%s",
                     packed_error, lib_str, reason_str);
  if (ret >= 0 && (size_t)ret >= len) {
    // The output was truncated; make sure we always have 5 colon-separated
    // fields, i.e. 4 colons.
    static const unsigned num_colons = 4;
    unsigned i;
    char *s = buf;

    if (len <= num_colons) {
      // In this situation it's not possible to ensure that the correct number
      // of colons are included in the output.
      return buf;
    }

    for (i = 0; i < num_colons; i++) {
      char *colon = strchr(s, ':');
      char *last_pos = &buf[len - 1] - num_colons + i;

      if (colon == NULL || colon > last_pos) {
        // set colon |i| at last possible position (buf[len-1] is the
        // terminating 0). If we're setting this colon, then all whole of the
        // rest of the string must be colons in order to have the correct
        // number.
        OPENSSL_memset(last_pos, ':', num_colons - i);
        break;
      }

      s = colon + 1;
    }
  }

  return buf;
}

void ERR_print_errors_cb(ERR_print_errors_callback_t callback, void *ctx) {
  char buf[ERR_ERROR_STRING_BUF_LEN];
  char buf2[1024];
  const char *file, *data;
  int line, flags;
  uint32_t packed_error;

  // thread_hash is the least-significant bits of the |ERR_STATE| pointer value
  // for this thread.
  const unsigned long thread_hash = (uintptr_t)err_get_state();

  for (;;) {
    packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
    if (packed_error == 0) {
      break;
    }

    ERR_error_string_n(packed_error, buf, sizeof(buf));
    snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", thread_hash, buf, file,
             line, (flags & ERR_FLAG_STRING) ? data : "");
    if (callback(buf2, strlen(buf2), ctx) <= 0) {
      break;
    }
  }
}

static int print_errors_to_file(const char *msg, size_t msg_len, void *ctx) {
  assert(msg[msg_len] == '\0');
  FILE *fp = reinterpret_cast<FILE *>(ctx);
  int res = fputs(msg, fp);
  return res < 0 ? 0 : 1;
}

void ERR_print_errors_fp(FILE *file) {
  ERR_print_errors_cb(print_errors_to_file, file);
}

// err_set_error_data sets the data on the most recent error.
static void err_set_error_data(char *data) {
  ERR_STATE *const state = err_get_state();
  struct err_error_st *error;

  if (state == NULL || state->top == state->bottom) {
    free(data);
    return;
  }

  error = &state->errors[state->top];

  free(error->data);
  error->data = data;
}

void ERR_put_error(int library, int unused, int reason, const char *file,
                   unsigned line) {
  ERR_STATE *const state = err_get_state();
  struct err_error_st *error;

  if (state == NULL) {
    return;
  }

  if (library == ERR_LIB_SYS && reason == 0) {
#if defined(OPENSSL_WINDOWS)
    reason = GetLastError();
#else
    reason = errno;
#endif
  }

  state->top = (state->top + 1) % ERR_NUM_ERRORS;
  if (state->top == state->bottom) {
    state->bottom = (state->bottom + 1) % ERR_NUM_ERRORS;
  }

  error = &state->errors[state->top];
  err_clear(error);
  error->file = file;
  error->line = line;
  error->packed = ERR_PACK(library, reason);
}

// ERR_add_error_data_vdata takes a variable number of const char* pointers,
// concatenates them and sets the result as the data on the most recent
// error.
static void err_add_error_vdata(unsigned num, va_list args) {
  size_t total_size = 0;
  const char *substr;
  char *buf;

  va_list args_copy;
  va_copy(args_copy, args);
  for (size_t i = 0; i < num; i++) {
    substr = va_arg(args_copy, const char *);
    if (substr == NULL) {
      continue;
    }
    size_t substr_len = strlen(substr);
    if (SIZE_MAX - total_size < substr_len) {
      return;  // Would overflow.
    }
    total_size += substr_len;
  }
  va_end(args_copy);
  if (total_size == SIZE_MAX) {
    return;  // Would overflow.
  }
  total_size += 1;  // NUL terminator.
  if ((buf = reinterpret_cast<char *>(malloc(total_size))) == NULL) {
    return;
  }
  buf[0] = '\0';
  for (size_t i = 0; i < num; i++) {
    substr = va_arg(args, const char *);
    if (substr == NULL) {
      continue;
    }
    if (OPENSSL_strlcat(buf, substr, total_size) >= total_size) {
      assert(0);  // should not be possible.
    }
  }
  err_set_error_data(buf);
}

void ERR_add_error_data(unsigned count, ...) {
  va_list args;
  va_start(args, count);
  err_add_error_vdata(count, args);
  va_end(args);
}

void ERR_add_error_dataf(const char *format, ...) {
  char *buf = NULL;
  va_list ap;

  va_start(ap, format);
  if (OPENSSL_vasprintf_internal(&buf, format, ap, /*system_malloc=*/1) == -1) {
    return;
  }
  va_end(ap);

  err_set_error_data(buf);
}

void ERR_set_error_data(char *data, int flags) {
  if (!(flags & ERR_FLAG_STRING)) {
    // We do not support non-string error data.
    assert(0);
    return;
  }
  // We can not use OPENSSL_strdup because we don't want to call OPENSSL_malloc,
  // which can affect the error stack.
  char *copy = strdup_libc_malloc(data);
  if (copy != NULL) {
    err_set_error_data(copy);
  }
  if (flags & ERR_FLAG_MALLOCED) {
    // We can not take ownership of |data| directly because it is allocated with
    // |OPENSSL_malloc| and we will free it with system |free| later.
    OPENSSL_free(data);
  }
}

int ERR_set_mark(void) {
  ERR_STATE *const state = err_get_state();

  if (state == NULL || state->bottom == state->top) {
    return 0;
  }
  state->errors[state->top].mark = 1;
  return 1;
}

int ERR_pop_to_mark(void) {
  ERR_STATE *const state = err_get_state();

  if (state == NULL) {
    return 0;
  }

  while (state->bottom != state->top) {
    struct err_error_st *error = &state->errors[state->top];

    if (error->mark) {
      error->mark = 0;
      return 1;
    }

    err_clear(error);
    if (state->top == 0) {
      state->top = ERR_NUM_ERRORS - 1;
    } else {
      state->top--;
    }
  }

  return 0;
}

void ERR_load_crypto_strings(void) {}

void ERR_free_strings(void) {}

void ERR_load_BIO_strings(void) {}

void ERR_load_ERR_strings(void) {}

void ERR_load_RAND_strings(void) {}

struct err_save_state_st {
  struct err_error_st *errors;
  size_t num_errors;
};

void ERR_SAVE_STATE_free(ERR_SAVE_STATE *state) {
  if (state == NULL) {
    return;
  }
  for (size_t i = 0; i < state->num_errors; i++) {
    err_clear(&state->errors[i]);
  }
  free(state->errors);
  free(state);
}

ERR_SAVE_STATE *ERR_save_state(void) {
  ERR_STATE *const state = err_get_state();
  if (state == NULL || state->top == state->bottom) {
    return NULL;
  }

  ERR_SAVE_STATE *ret =
      reinterpret_cast<ERR_SAVE_STATE *>(malloc(sizeof(ERR_SAVE_STATE)));
  if (ret == NULL) {
    return NULL;
  }

  // Errors are stored in the range (bottom, top].
  size_t num_errors = state->top >= state->bottom
                          ? state->top - state->bottom
                          : ERR_NUM_ERRORS + state->top - state->bottom;
  assert(num_errors < ERR_NUM_ERRORS);
  ret->errors = reinterpret_cast<err_error_st *>(
      malloc(num_errors * sizeof(struct err_error_st)));
  if (ret->errors == NULL) {
    free(ret);
    return NULL;
  }
  OPENSSL_memset(ret->errors, 0, num_errors * sizeof(struct err_error_st));
  ret->num_errors = num_errors;

  for (size_t i = 0; i < num_errors; i++) {
    size_t j = (state->bottom + i + 1) % ERR_NUM_ERRORS;
    err_copy(&ret->errors[i], &state->errors[j]);
  }
  return ret;
}

void ERR_restore_state(const ERR_SAVE_STATE *state) {
  if (state == NULL || state->num_errors == 0) {
    ERR_clear_error();
    return;
  }

  if (state->num_errors >= ERR_NUM_ERRORS) {
    abort();
  }

  ERR_STATE *const dst = err_get_state();
  if (dst == NULL) {
    return;
  }

  for (size_t i = 0; i < state->num_errors; i++) {
    err_copy(&dst->errors[i], &state->errors[i]);
  }
  dst->top = (unsigned)(state->num_errors - 1);
  dst->bottom = ERR_NUM_ERRORS - 1;
}
