diff options
author | Matt Caswell <matt@openssl.org> | 2021-06-11 12:43:00 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2021-06-14 10:05:50 +0100 |
commit | f77208693ec3bda99618e6f76c0f8d279c0077bb (patch) | |
tree | e6ab05aa94fdd14106774c4443c19ce5c8d05f8a /crypto | |
parent | 8c7c1c84cbaa38a4053404883d666ea8dff81b3a (diff) |
Avoid excessive OSSL_DECODER_do_all_provided calls
OSSL_DECODER_CTX_add_extra was calling OSSL_DECODER_do_all_provided in a
loop which was resulting in a large number of calls. Since
OSSL_DECODER_do_all_provided is quite "heavy" this was causing performance
issues.
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15716)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/encode_decode/decoder_lib.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c index eb90a9eaf5..4053eac62e 100644 --- a/crypto/encode_decode/decoder_lib.c +++ b/crypto/encode_decode/decoder_lib.c @@ -343,6 +343,16 @@ struct collect_extra_decoder_data_st { size_t w_new_start, w_new_end; /* "new" decoders */ }; +DEFINE_STACK_OF(OSSL_DECODER) + +static void collect_all_decoders(OSSL_DECODER *decoder, void *arg) +{ + STACK_OF(OSSL_DECODER) *skdecoders = arg; + + if (OSSL_DECODER_up_ref(decoder)) + sk_OSSL_DECODER_push(skdecoders, decoder); +} + static void collect_extra_decoder(OSSL_DECODER *decoder, void *arg) { struct collect_extra_decoder_data_st *data = arg; @@ -459,6 +469,8 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, struct collect_extra_decoder_data_st data; size_t depth = 0; /* Counts the number of iterations */ size_t count; /* Calculates how many were added in each iteration */ + size_t numdecoders; + STACK_OF(OSSL_DECODER) *skdecoders; if (!ossl_assert(ctx != NULL)) { ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); @@ -477,12 +489,21 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, (void *)ctx); } OSSL_TRACE_END(DECODER); + + skdecoders = sk_OSSL_DECODER_new_null(); + if (skdecoders == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + return 0; + } + OSSL_DECODER_do_all_provided(libctx, collect_all_decoders, skdecoders); + numdecoders = sk_OSSL_DECODER_num(skdecoders); + memset(&data, 0, sizeof(data)); data.ctx = ctx; data.w_prev_start = 0; data.w_prev_end = sk_OSSL_DECODER_INSTANCE_num(ctx->decoder_insts); do { - size_t i; + size_t i, j; data.w_new_start = data.w_new_end = data.w_prev_end; @@ -504,8 +525,9 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, = OSSL_DECODER_INSTANCE_get_input_type(decoder_inst); - OSSL_DECODER_do_all_provided(libctx, - collect_extra_decoder, &data); + for (j = 0; j < numdecoders; j++) + collect_extra_decoder(sk_OSSL_DECODER_value(skdecoders, j), + &data); } } /* How many were added in this iteration */ @@ -518,6 +540,7 @@ int OSSL_DECODER_CTX_add_extra(OSSL_DECODER_CTX *ctx, depth++; } while (count != 0 && depth <= 10); + sk_OSSL_DECODER_pop_free(skdecoders, OSSL_DECODER_free); return 1; } |