diff options
author | Matt Caswell <matt@openssl.org> | 2020-11-06 11:43:44 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2020-11-19 14:56:58 +0000 |
commit | 4e08ea6f111d7bdcef0659baca700a78aa867913 (patch) | |
tree | 3175437f9561940d5191f96a4c71285f0f5909a5 | |
parent | 5b1d94c11c680c2b9527c3da55593468bcf65efd (diff) |
Allow multiple nested marks
Previously we only ever allowed one mark to be set against an error in the
statck. If we attempted to nest them, then we would end up clearing all
the errors in the stack when we popped to the mark.
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/13335)
-rw-r--r-- | crypto/err/err.c | 10 | ||||
-rw-r--r-- | crypto/err/err_local.h | 1 | ||||
-rw-r--r-- | include/openssl/err.h.in | 1 |
3 files changed, 7 insertions, 5 deletions
diff --git a/crypto/err/err.c b/crypto/err/err.c index 2c8240f0ba..a66ea63adf 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -838,7 +838,7 @@ int ERR_set_mark(void) if (es->bottom == es->top) return 0; - es->err_flags[es->top] |= ERR_FLAG_MARK; + es->err_marks[es->top]++; return 1; } @@ -851,14 +851,14 @@ int ERR_pop_to_mark(void) return 0; while (es->bottom != es->top - && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) { + && es->err_marks[es->top] == 0) { err_clear(es, es->top, 0); es->top = es->top > 0 ? es->top - 1 : ERR_NUM_ERRORS - 1; } if (es->bottom == es->top) return 0; - es->err_flags[es->top] &= ~ERR_FLAG_MARK; + es->err_marks[es->top]--; return 1; } @@ -873,13 +873,13 @@ int ERR_clear_last_mark(void) top = es->top; while (es->bottom != top - && (es->err_flags[top] & ERR_FLAG_MARK) == 0) { + && es->err_marks[top] == 0) { top = top > 0 ? top - 1 : ERR_NUM_ERRORS - 1; } if (es->bottom == top) return 0; - es->err_flags[top] &= ~ERR_FLAG_MARK; + es->err_marks[top]--; return 1; } diff --git a/crypto/err/err_local.h b/crypto/err/err_local.h index 2f9caf2e0e..cad67cc476 100644 --- a/crypto/err/err_local.h +++ b/crypto/err/err_local.h @@ -64,6 +64,7 @@ static ossl_inline void err_set_data(ERR_STATE *es, size_t i, static ossl_inline void err_clear(ERR_STATE *es, size_t i, int deall) { err_clear_data(es, i, (deall)); + es->err_marks[i] = 0; es->err_flags[i] = 0; es->err_buffer[i] = 0; es->err_file[i] = NULL; diff --git a/include/openssl/err.h.in b/include/openssl/err.h.in index 35db02fad6..1f2fde8317 100644 --- a/include/openssl/err.h.in +++ b/include/openssl/err.h.in @@ -56,6 +56,7 @@ extern "C" { # define ERR_NUM_ERRORS 16 struct err_state_st { int err_flags[ERR_NUM_ERRORS]; + int err_marks[ERR_NUM_ERRORS]; unsigned long err_buffer[ERR_NUM_ERRORS]; char *err_data[ERR_NUM_ERRORS]; size_t err_data_size[ERR_NUM_ERRORS]; |